Botan 3.6.1
Crypto and TLS for C&
ffi_pkey_algs.cpp
Go to the documentation of this file.
1/*
2* (C) 2015,2017 Jack Lloyd
3* (C) 2017 Ribose Inc
4* (C) 2018 René Korthaus, Rohde & Schwarz Cybersecurity
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#include <botan/ffi.h>
10
11#include <botan/hash.h>
12#include <botan/pem.h>
13#include <botan/internal/ffi_mp.h>
14#include <botan/internal/ffi_pkey.h>
15#include <botan/internal/ffi_rng.h>
16#include <botan/internal/ffi_util.h>
17
18#if defined(BOTAN_HAS_DL_GROUP)
19 #include <botan/dl_group.h>
20#endif
21
22#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
23 #include <botan/ecc_key.h>
24#endif
25
26#if defined(BOTAN_HAS_RSA)
27 #include <botan/rsa.h>
28#endif
29
30#if defined(BOTAN_HAS_ELGAMAL)
31 #include <botan/elgamal.h>
32#endif
33
34#if defined(BOTAN_HAS_DSA)
35 #include <botan/dsa.h>
36#endif
37
38#if defined(BOTAN_HAS_ECDSA)
39 #include <botan/ecdsa.h>
40#endif
41
42#if defined(BOTAN_HAS_SM2)
43 #include <botan/sm2.h>
44#endif
45
46#if defined(BOTAN_HAS_ECDH)
47 #include <botan/ecdh.h>
48#endif
49
50#if defined(BOTAN_HAS_X25519)
51 #include <botan/x25519.h>
52#endif
53
54#if defined(BOTAN_HAS_X448)
55 #include <botan/x448.h>
56#endif
57
58#if defined(BOTAN_HAS_ED25519)
59 #include <botan/ed25519.h>
60#endif
61
62#if defined(BOTAN_HAS_ED448)
63 #include <botan/ed448.h>
64#endif
65
66#if defined(BOTAN_HAS_MCELIECE)
67 #include <botan/mceliece.h>
68#endif
69
70#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
71 #include <botan/dh.h>
72#endif
73
74#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
75 #include <botan/kyber.h>
76#endif
77
78#if defined(BOTAN_HAS_ML_KEM)
79 #include <botan/ml_kem.h>
80#endif
81
82#if defined(BOTAN_HAS_FRODOKEM)
83 #include <botan/frodokem.h>
84#endif
85
86#if defined(BOTAN_HAS_ML_DSA)
87 #include <botan/ml_dsa.h>
88#endif
89
90#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
91 #include <botan/slh_dsa.h>
92#endif
93
94namespace {
95
96#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
97
98// These are always called within an existing try/catch block
99
100template <class ECPrivateKey_t>
101int privkey_load_ec(std::unique_ptr<ECPrivateKey_t>& key, const Botan::BigInt& scalar, const char* curve_name) {
102 if(curve_name == nullptr) {
104 }
105
106 Botan::Null_RNG null_rng;
107 const auto grp = Botan::EC_Group::from_name(curve_name);
108 key.reset(new ECPrivateKey_t(null_rng, grp, scalar));
109 return BOTAN_FFI_SUCCESS;
110}
111
112template <class ECPublicKey_t>
113int pubkey_load_ec(std::unique_ptr<ECPublicKey_t>& key,
114 const Botan::BigInt& public_x,
115 const Botan::BigInt& public_y,
116 const char* curve_name) {
117 if(curve_name == nullptr) {
119 }
120
121 const auto group = Botan::EC_Group::from_name(curve_name);
122
123 if(auto pt = Botan::EC_AffinePoint::from_bigint_xy(group, public_x, public_y)) {
124 key.reset(new ECPublicKey_t(group, pt->to_legacy_point()));
125 return BOTAN_FFI_SUCCESS;
126 } else {
128 }
129}
130
131#endif
132
133Botan::BigInt pubkey_get_field(const Botan::Public_Key& key, std::string_view field) {
134#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
135 // Not currently handled by get_int_field
136 if(const Botan::EC_PublicKey* ecc = dynamic_cast<const Botan::EC_PublicKey*>(&key)) {
137 if(field == "public_x") {
138 return ecc->public_point().get_affine_x();
139 } else if(field == "public_y") {
140 return ecc->public_point().get_affine_y();
141 }
142 }
143#endif
144
145 try {
146 return key.get_int_field(field);
148 throw Botan_FFI::FFI_Error("Unknown key field", BOTAN_FFI_ERROR_BAD_PARAMETER);
149 }
150}
151
152Botan::BigInt privkey_get_field(const Botan::Private_Key& key, std::string_view field) {
153#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
154 // Not currently handled by get_int_field
155 if(const Botan::EC_PublicKey* ecc = dynamic_cast<const Botan::EC_PublicKey*>(&key)) {
156 if(field == "public_x") {
157 return ecc->public_point().get_affine_x();
158 } else if(field == "public_y") {
159 return ecc->public_point().get_affine_y();
160 }
161 }
162#endif
163
164 try {
165 return key.get_int_field(field);
167 throw Botan_FFI::FFI_Error("Unknown key field", BOTAN_FFI_ERROR_BAD_PARAMETER);
168 }
169}
170
171} // namespace
172
173extern "C" {
174
175using namespace Botan_FFI;
176
177int botan_pubkey_get_field(botan_mp_t output, botan_pubkey_t key, const char* field_name_cstr) {
178 if(field_name_cstr == nullptr) {
180 }
181
182 const std::string field_name(field_name_cstr);
183
184 return BOTAN_FFI_VISIT(key, [=](const auto& k) { safe_get(output) = pubkey_get_field(k, field_name); });
185}
186
187int botan_privkey_get_field(botan_mp_t output, botan_privkey_t key, const char* field_name_cstr) {
188 if(field_name_cstr == nullptr) {
190 }
191
192 const std::string field_name(field_name_cstr);
193
194 return BOTAN_FFI_VISIT(key, [=](const auto& k) { safe_get(output) = privkey_get_field(k, field_name); });
195}
196
197/* RSA specific operations */
198
199int botan_privkey_create_rsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n_bits) {
200 if(n_bits < 1024 || n_bits > 16 * 1024) {
202 }
203
204 std::string n_str = std::to_string(n_bits);
205
206 return botan_privkey_create(key_obj, "RSA", n_str.c_str(), rng_obj);
207}
208
210#if defined(BOTAN_HAS_RSA)
211 *key = nullptr;
212
213 return ffi_guard_thunk(__func__, [=]() -> int {
214 auto rsa = std::make_unique<Botan::RSA_PrivateKey>(safe_get(rsa_p), safe_get(rsa_q), safe_get(rsa_e));
215 *key = new botan_privkey_struct(std::move(rsa));
216 return BOTAN_FFI_SUCCESS;
217 });
218#else
219 BOTAN_UNUSED(key, rsa_p, rsa_q, rsa_e);
221#endif
222}
223
224int botan_privkey_load_rsa_pkcs1(botan_privkey_t* key, const uint8_t bits[], size_t len) {
225#if defined(BOTAN_HAS_RSA)
226 *key = nullptr;
227
228 Botan::secure_vector<uint8_t> src(bits, bits + len);
229 return ffi_guard_thunk(__func__, [=]() -> int {
231 auto rsa = std::make_unique<Botan::RSA_PrivateKey>(alg_id, src);
232 *key = new botan_privkey_struct(std::move(rsa));
233 return BOTAN_FFI_SUCCESS;
234 });
235#else
236 BOTAN_UNUSED(key, bits, len);
238#endif
239}
240
242#if defined(BOTAN_HAS_RSA)
243 *key = nullptr;
244 return ffi_guard_thunk(__func__, [=]() -> int {
245 auto rsa = std::make_unique<Botan::RSA_PublicKey>(safe_get(n), safe_get(e));
246 *key = new botan_pubkey_struct(std::move(rsa));
247 return BOTAN_FFI_SUCCESS;
248 });
249#else
250 BOTAN_UNUSED(key, n, e);
252#endif
253}
254
258
262
266
270
274
276 return botan_pubkey_get_field(e, key, "e");
277}
278
280 return botan_pubkey_get_field(n, key, "n");
281}
282
283int botan_privkey_rsa_get_privkey(botan_privkey_t rsa_key, uint8_t out[], size_t* out_len, uint32_t flags) {
284#if defined(BOTAN_HAS_RSA)
285 return BOTAN_FFI_VISIT(rsa_key, [=](const auto& k) -> int {
286 if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<const Botan::RSA_PrivateKey*>(&k)) {
288 return write_vec_output(out, out_len, rsa->private_key_bits());
289 else if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_PEM)
290 return write_str_output(out, out_len, Botan::PEM_Code::encode(rsa->private_key_bits(), "RSA PRIVATE KEY"));
291 else
293 } else {
295 }
296 });
297#else
298 BOTAN_UNUSED(rsa_key, out, out_len, flags);
300#endif
301}
302
303/* DSA specific operations */
304int botan_privkey_create_dsa(botan_privkey_t* key, botan_rng_t rng_obj, size_t pbits, size_t qbits) {
305#if defined(BOTAN_HAS_DSA)
306
307 if((rng_obj == nullptr) || (key == nullptr)) {
309 }
310
311 if((pbits % 64) || (qbits % 8) || (pbits < 1024) || (pbits > 3072) || (qbits < 160) || (qbits > 256)) {
313 }
314
315 return ffi_guard_thunk(__func__, [=]() -> int {
317 Botan::DL_Group group(rng, Botan::DL_Group::Prime_Subgroup, pbits, qbits);
318 auto dsa = std::make_unique<Botan::DSA_PrivateKey>(rng, group);
319 *key = new botan_privkey_struct(std::move(dsa));
320 return BOTAN_FFI_SUCCESS;
321 });
322#else
323 BOTAN_UNUSED(key, rng_obj, pbits, qbits);
325#endif
326}
327
329#if defined(BOTAN_HAS_DSA)
330 *key = nullptr;
331
332 return ffi_guard_thunk(__func__, [=]() -> int {
333 Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
334 auto dsa = std::make_unique<Botan::DSA_PrivateKey>(group, safe_get(x));
335 *key = new botan_privkey_struct(std::move(dsa));
336 return BOTAN_FFI_SUCCESS;
337 });
338#else
339 BOTAN_UNUSED(key, p, q, g, x);
341#endif
342}
343
345#if defined(BOTAN_HAS_DSA)
346 *key = nullptr;
347
348 return ffi_guard_thunk(__func__, [=]() -> int {
349 Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
350 auto dsa = std::make_unique<Botan::DSA_PublicKey>(group, safe_get(y));
351 *key = new botan_pubkey_struct(std::move(dsa));
352 return BOTAN_FFI_SUCCESS;
353 });
354#else
355 BOTAN_UNUSED(key, p, q, g, y);
357#endif
358}
359
363
365 return botan_pubkey_get_field(p, key, "p");
366}
367
369 return botan_pubkey_get_field(q, key, "q");
370}
371
373 return botan_pubkey_get_field(g, key, "g");
374}
375
377 return botan_pubkey_get_field(y, key, "y");
378}
379
380int botan_privkey_create_ecdsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str) {
381 return botan_privkey_create(key_obj, "ECDSA", param_str, rng_obj);
382}
383
384/* ECDSA specific operations */
385
387#if defined(BOTAN_HAS_ECC_KEY)
388 return ffi_guard_thunk(__func__, [=]() -> int {
389 const Botan::Public_Key& pub_key = safe_get(key);
390 const Botan::EC_PublicKey* ec_key = dynamic_cast<const Botan::EC_PublicKey*>(&pub_key);
391
392 if(ec_key == nullptr) {
394 }
395
396 return ec_key->domain().used_explicit_encoding() ? 1 : 0;
397 });
398#else
399 BOTAN_UNUSED(key);
401#endif
402}
403
405 const botan_mp_t public_x,
406 const botan_mp_t public_y,
407 const char* curve_name) {
408#if defined(BOTAN_HAS_ECDSA)
409 return ffi_guard_thunk(__func__, [=]() -> int {
410 std::unique_ptr<Botan::ECDSA_PublicKey> p_key;
411
412 int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
413 if(rc == BOTAN_FFI_SUCCESS) {
414 *key = new botan_pubkey_struct(std::move(p_key));
415 }
416
417 return rc;
418 });
419#else
420 BOTAN_UNUSED(key, public_x, public_y, curve_name);
422#endif
423}
424
425int botan_privkey_load_ecdsa(botan_privkey_t* key, const botan_mp_t scalar, const char* curve_name) {
426#if defined(BOTAN_HAS_ECDSA)
427 return ffi_guard_thunk(__func__, [=]() -> int {
428 std::unique_ptr<Botan::ECDSA_PrivateKey> p_key;
429 int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
430 if(rc == BOTAN_FFI_SUCCESS) {
431 *key = new botan_privkey_struct(std::move(p_key));
432 }
433 return rc;
434 });
435#else
436 BOTAN_UNUSED(key, scalar, curve_name);
438#endif
439}
440
441/* ElGamal specific operations */
442int botan_privkey_create_elgamal(botan_privkey_t* key, botan_rng_t rng_obj, size_t pbits, size_t qbits) {
443#if defined(BOTAN_HAS_ELGAMAL)
444
445 if((rng_obj == nullptr) || (key == nullptr)) {
447 }
448
449 if((pbits < 1024) || (qbits < 160)) {
451 }
452
453 Botan::DL_Group::PrimeType prime_type =
455
456 return ffi_guard_thunk(__func__, [=]() -> int {
458 Botan::DL_Group group(rng, prime_type, pbits, qbits);
459 auto elg = std::make_unique<Botan::ElGamal_PrivateKey>(rng, group);
460 *key = new botan_privkey_struct(std::move(elg));
461 return BOTAN_FFI_SUCCESS;
462 });
463#else
464 BOTAN_UNUSED(key, rng_obj, pbits, qbits);
466#endif
467}
468
470#if defined(BOTAN_HAS_ELGAMAL)
471 *key = nullptr;
472 return ffi_guard_thunk(__func__, [=]() -> int {
473 Botan::DL_Group group(safe_get(p), safe_get(g));
474 auto elg = std::make_unique<Botan::ElGamal_PublicKey>(group, safe_get(y));
475 *key = new botan_pubkey_struct(std::move(elg));
476 return BOTAN_FFI_SUCCESS;
477 });
478#else
479 BOTAN_UNUSED(key, p, g, y);
481#endif
482}
483
485#if defined(BOTAN_HAS_ELGAMAL)
486 *key = nullptr;
487 return ffi_guard_thunk(__func__, [=]() -> int {
488 Botan::DL_Group group(safe_get(p), safe_get(g));
489 auto elg = std::make_unique<Botan::ElGamal_PrivateKey>(group, safe_get(x));
490 *key = new botan_privkey_struct(std::move(elg));
491 return BOTAN_FFI_SUCCESS;
492 });
493#else
494 BOTAN_UNUSED(key, p, g, x);
496#endif
497}
498
499/* Diffie Hellman specific operations */
500
501int botan_privkey_create_dh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str) {
502 return botan_privkey_create(key_obj, "DH", param_str, rng_obj);
503}
504
506#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
507 *key = nullptr;
508 return ffi_guard_thunk(__func__, [=]() -> int {
509 Botan::DL_Group group(safe_get(p), safe_get(g));
510 auto dh = std::make_unique<Botan::DH_PrivateKey>(group, safe_get(x));
511 *key = new botan_privkey_struct(std::move(dh));
512 return BOTAN_FFI_SUCCESS;
513 });
514#else
515 BOTAN_UNUSED(key, p, g, x);
517#endif
518}
519
521#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
522 *key = nullptr;
523 return ffi_guard_thunk(__func__, [=]() -> int {
524 Botan::DL_Group group(safe_get(p), safe_get(g));
525 auto dh = std::make_unique<Botan::DH_PublicKey>(group, safe_get(y));
526 *key = new botan_pubkey_struct(std::move(dh));
527 return BOTAN_FFI_SUCCESS;
528 });
529#else
530 BOTAN_UNUSED(key, p, g, y);
532#endif
533}
534
535/* ECDH + x25519/x448 specific operations */
536
537int botan_privkey_create_ecdh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str) {
538 if(param_str == nullptr) {
540 }
541
542 const std::string params(param_str);
543
544 if(params == "x25519" || params == "curve25519") {
545 return botan_privkey_create(key_obj, "X25519", "", rng_obj);
546 }
547
548 if(params == "x448") {
549 return botan_privkey_create(key_obj, "X448", "", rng_obj);
550 }
551
552 return botan_privkey_create(key_obj, "ECDH", param_str, rng_obj);
553}
554
556 const botan_mp_t public_x,
557 const botan_mp_t public_y,
558 const char* curve_name) {
559#if defined(BOTAN_HAS_ECDH)
560 return ffi_guard_thunk(__func__, [=]() -> int {
561 std::unique_ptr<Botan::ECDH_PublicKey> p_key;
562 int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
563
564 if(rc == BOTAN_FFI_SUCCESS) {
565 *key = new botan_pubkey_struct(std::move(p_key));
566 }
567 return rc;
568 });
569#else
570 BOTAN_UNUSED(key, public_x, public_y, curve_name);
572#endif
573}
574
575int botan_privkey_load_ecdh(botan_privkey_t* key, const botan_mp_t scalar, const char* curve_name) {
576#if defined(BOTAN_HAS_ECDH)
577 return ffi_guard_thunk(__func__, [=]() -> int {
578 std::unique_ptr<Botan::ECDH_PrivateKey> p_key;
579 int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
580 if(rc == BOTAN_FFI_SUCCESS) {
581 *key = new botan_privkey_struct(std::move(p_key));
582 }
583 return rc;
584 });
585#else
586 BOTAN_UNUSED(key, scalar, curve_name);
588#endif
589}
590
591/* SM2 specific operations */
592
594 uint8_t out[], size_t* out_len, const char* ident, const char* hash_algo, const botan_pubkey_t key) {
595 if(out == nullptr || out_len == nullptr) {
597 }
598 if(ident == nullptr || hash_algo == nullptr || key == nullptr) {
600 }
601
602#if defined(BOTAN_HAS_SM2)
603 return ffi_guard_thunk(__func__, [=]() -> int {
604 const Botan::Public_Key& pub_key = safe_get(key);
605 const Botan::EC_PublicKey* ec_key = dynamic_cast<const Botan::EC_PublicKey*>(&pub_key);
606
607 if(ec_key == nullptr) {
609 }
610
611 if(ec_key->algo_name() != "SM2") {
613 }
614
615 const std::string ident_str(ident);
616 std::unique_ptr<Botan::HashFunction> hash = Botan::HashFunction::create_or_throw(hash_algo);
617
618 const std::vector<uint8_t> za = Botan::sm2_compute_za(*hash, ident_str, ec_key->domain(), ec_key->public_point());
619
620 return write_vec_output(out, out_len, za);
621 });
622#else
624#endif
625}
626
628 const botan_mp_t public_x,
629 const botan_mp_t public_y,
630 const char* curve_name) {
631#if defined(BOTAN_HAS_SM2)
632 return ffi_guard_thunk(__func__, [=]() -> int {
633 std::unique_ptr<Botan::SM2_PublicKey> p_key;
634 if(!pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name)) {
635 *key = new botan_pubkey_struct(std::move(p_key));
636 return BOTAN_FFI_SUCCESS;
637 }
639 });
640#else
641 BOTAN_UNUSED(key, public_x, public_y, curve_name);
643#endif
644}
645
646int botan_privkey_load_sm2(botan_privkey_t* key, const botan_mp_t scalar, const char* curve_name) {
647#if defined(BOTAN_HAS_SM2)
648 return ffi_guard_thunk(__func__, [=]() -> int {
649 std::unique_ptr<Botan::SM2_PrivateKey> p_key;
650 int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
651
652 if(rc == BOTAN_FFI_SUCCESS) {
653 *key = new botan_privkey_struct(std::move(p_key));
654 }
655 return rc;
656 });
657#else
658 BOTAN_UNUSED(key, scalar, curve_name);
660#endif
661}
662
664 const botan_mp_t public_x,
665 const botan_mp_t public_y,
666 const char* curve_name) {
667 return botan_pubkey_load_sm2(key, public_x, public_y, curve_name);
668}
669
670int botan_privkey_load_sm2_enc(botan_privkey_t* key, const botan_mp_t scalar, const char* curve_name) {
671 return botan_privkey_load_sm2(key, scalar, curve_name);
672}
673
674/* Ed25519 specific operations */
675
676int botan_privkey_load_ed25519(botan_privkey_t* key, const uint8_t privkey[32]) {
677#if defined(BOTAN_HAS_ED25519)
678 *key = nullptr;
679 return ffi_guard_thunk(__func__, [=]() -> int {
680 const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 32);
681 auto ed25519 = std::make_unique<Botan::Ed25519_PrivateKey>(privkey_vec);
682 *key = new botan_privkey_struct(std::move(ed25519));
683 return BOTAN_FFI_SUCCESS;
684 });
685#else
686 BOTAN_UNUSED(key, privkey);
688#endif
689}
690
691int botan_pubkey_load_ed25519(botan_pubkey_t* key, const uint8_t pubkey[32]) {
692#if defined(BOTAN_HAS_ED25519)
693 *key = nullptr;
694 return ffi_guard_thunk(__func__, [=]() -> int {
695 const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32);
696 auto ed25519 = std::make_unique<Botan::Ed25519_PublicKey>(pubkey_vec);
697 *key = new botan_pubkey_struct(std::move(ed25519));
698 return BOTAN_FFI_SUCCESS;
699 });
700#else
701 BOTAN_UNUSED(key, pubkey);
703#endif
704}
705
707#if defined(BOTAN_HAS_ED25519)
708 return BOTAN_FFI_VISIT(key, [=](const auto& k) {
709 if(auto ed = dynamic_cast<const Botan::Ed25519_PrivateKey*>(&k)) {
710 const auto ed_key = ed->raw_private_key_bits();
711 if(ed_key.size() != 64)
713 Botan::copy_mem(output, ed_key.data(), ed_key.size());
714 return BOTAN_FFI_SUCCESS;
715 } else {
717 }
718 });
719#else
720 BOTAN_UNUSED(key, output);
722#endif
723}
724
726#if defined(BOTAN_HAS_ED25519)
727 return BOTAN_FFI_VISIT(key, [=](const auto& k) {
728 if(auto ed = dynamic_cast<const Botan::Ed25519_PublicKey*>(&k)) {
729 const std::vector<uint8_t>& ed_key = ed->get_public_key();
730 if(ed_key.size() != 32)
732 Botan::copy_mem(output, ed_key.data(), ed_key.size());
733 return BOTAN_FFI_SUCCESS;
734 } else {
736 }
737 });
738#else
739 BOTAN_UNUSED(key, output);
741#endif
742}
743
744/* Ed448 specific operations */
745
746int botan_privkey_load_ed448(botan_privkey_t* key, const uint8_t privkey[57]) {
747#if defined(BOTAN_HAS_ED448)
748 *key = nullptr;
749 return ffi_guard_thunk(__func__, [=]() -> int {
750 auto ed448 = std::make_unique<Botan::Ed448_PrivateKey>(std::span(privkey, 57));
751 *key = new botan_privkey_struct(std::move(ed448));
752 return BOTAN_FFI_SUCCESS;
753 });
754#else
755 BOTAN_UNUSED(key, privkey);
757#endif
758}
759
760int botan_pubkey_load_ed448(botan_pubkey_t* key, const uint8_t pubkey[57]) {
761#if defined(BOTAN_HAS_ED448)
762 *key = nullptr;
763 return ffi_guard_thunk(__func__, [=]() -> int {
764 auto ed448 = std::make_unique<Botan::Ed448_PublicKey>(std::span(pubkey, 57));
765 *key = new botan_pubkey_struct(std::move(ed448));
766 return BOTAN_FFI_SUCCESS;
767 });
768#else
769 BOTAN_UNUSED(key, pubkey);
771#endif
772}
773
775#if defined(BOTAN_HAS_ED448)
776 return BOTAN_FFI_VISIT(key, [=](const auto& k) {
777 if(auto ed = dynamic_cast<const Botan::Ed448_PrivateKey*>(&k)) {
778 const auto ed_key = ed->raw_private_key_bits();
779 Botan::copy_mem(std::span(output, 57), ed_key);
780 return BOTAN_FFI_SUCCESS;
781 } else {
783 }
784 });
785#else
786 BOTAN_UNUSED(key, output);
788#endif
789}
790
791int botan_pubkey_ed448_get_pubkey(botan_pubkey_t key, uint8_t output[57]) {
792#if defined(BOTAN_HAS_ED448)
793 return BOTAN_FFI_VISIT(key, [=](const auto& k) {
794 if(auto ed = dynamic_cast<const Botan::Ed448_PublicKey*>(&k)) {
795 const auto ed_key = ed->public_key_bits();
796 Botan::copy_mem(std::span(output, 57), ed_key);
797 return BOTAN_FFI_SUCCESS;
798 } else {
800 }
801 });
802#else
803 BOTAN_UNUSED(key, output);
805#endif
806}
807
808/* X25519 specific operations */
809
810int botan_privkey_load_x25519(botan_privkey_t* key, const uint8_t privkey[32]) {
811#if defined(BOTAN_HAS_X25519)
812 *key = nullptr;
813 return ffi_guard_thunk(__func__, [=]() -> int {
814 const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 32);
815 auto x25519 = std::make_unique<Botan::X25519_PrivateKey>(privkey_vec);
816 *key = new botan_privkey_struct(std::move(x25519));
817 return BOTAN_FFI_SUCCESS;
818 });
819#else
820 BOTAN_UNUSED(key, privkey);
822#endif
823}
824
825int botan_pubkey_load_x25519(botan_pubkey_t* key, const uint8_t pubkey[32]) {
826#if defined(BOTAN_HAS_X25519)
827 *key = nullptr;
828 return ffi_guard_thunk(__func__, [=]() -> int {
829 const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32);
830 auto x25519 = std::make_unique<Botan::X25519_PublicKey>(pubkey_vec);
831 *key = new botan_pubkey_struct(std::move(x25519));
832 return BOTAN_FFI_SUCCESS;
833 });
834#else
835 BOTAN_UNUSED(key, pubkey);
837#endif
838}
839
841#if defined(BOTAN_HAS_X25519)
842 return BOTAN_FFI_VISIT(key, [=](const auto& k) {
843 if(auto x25519 = dynamic_cast<const Botan::X25519_PrivateKey*>(&k)) {
844 const auto x25519_key = x25519->raw_private_key_bits();
845 if(x25519_key.size() != 32)
847 Botan::copy_mem(output, x25519_key.data(), x25519_key.size());
848 return BOTAN_FFI_SUCCESS;
849 } else {
851 }
852 });
853#else
854 BOTAN_UNUSED(key, output);
856#endif
857}
858
859int botan_pubkey_x25519_get_pubkey(botan_pubkey_t key, uint8_t output[32]) {
860#if defined(BOTAN_HAS_X25519)
861 return BOTAN_FFI_VISIT(key, [=](const auto& k) {
862 if(auto x25519 = dynamic_cast<const Botan::X25519_PublicKey*>(&k)) {
863 const std::vector<uint8_t>& x25519_key = x25519->public_value();
864 if(x25519_key.size() != 32)
866 Botan::copy_mem(output, x25519_key.data(), x25519_key.size());
867 return BOTAN_FFI_SUCCESS;
868 } else {
870 }
871 });
872#else
873 BOTAN_UNUSED(key, output);
875#endif
876}
877
878/* X448 specific operations */
879
880int botan_privkey_load_x448(botan_privkey_t* key, const uint8_t privkey[56]) {
881#if defined(BOTAN_HAS_X448)
882 *key = nullptr;
883 return ffi_guard_thunk(__func__, [=]() -> int {
884 auto x448 = std::make_unique<Botan::X448_PrivateKey>(std::span(privkey, 56));
885 *key = new botan_privkey_struct(std::move(x448));
886 return BOTAN_FFI_SUCCESS;
887 });
888#else
889 BOTAN_UNUSED(key, privkey);
891#endif
892}
893
894int botan_pubkey_load_x448(botan_pubkey_t* key, const uint8_t pubkey[56]) {
895#if defined(BOTAN_HAS_X448)
896 *key = nullptr;
897 return ffi_guard_thunk(__func__, [=]() -> int {
898 auto x448 = std::make_unique<Botan::X448_PublicKey>(std::span(pubkey, 56));
899 *key = new botan_pubkey_struct(std::move(x448));
900 return BOTAN_FFI_SUCCESS;
901 });
902#else
903 BOTAN_UNUSED(key, pubkey);
905#endif
906}
907
909#if defined(BOTAN_HAS_X448)
910 return BOTAN_FFI_VISIT(key, [=](const auto& k) {
911 if(auto x448 = dynamic_cast<const Botan::X448_PrivateKey*>(&k)) {
912 const auto x448_key = x448->raw_private_key_bits();
913 Botan::copy_mem(std::span(output, 56), x448_key);
914 return BOTAN_FFI_SUCCESS;
915 } else {
917 }
918 });
919#else
920 BOTAN_UNUSED(key, output);
922#endif
923}
924
925int botan_pubkey_x448_get_pubkey(botan_pubkey_t key, uint8_t output[56]) {
926#if defined(BOTAN_HAS_X448)
927 return BOTAN_FFI_VISIT(key, [=](const auto& k) {
928 if(auto x448 = dynamic_cast<const Botan::X448_PublicKey*>(&k)) {
929 const std::vector<uint8_t>& x448_key = x448->public_value();
930 Botan::copy_mem(std::span(output, 56), x448_key);
931 return BOTAN_FFI_SUCCESS;
932 } else {
934 }
935 });
936#else
937 BOTAN_UNUSED(key, output);
939#endif
940}
941
942/*
943* Algorithm specific key operations: Kyber
944*/
945
946int botan_privkey_load_kyber(botan_privkey_t* key, const uint8_t privkey[], size_t key_len) {
947#if defined(BOTAN_HAS_KYBER)
948 *key = nullptr;
949 switch(key_len) {
950 case 1632:
951 return ffi_guard_thunk(__func__, [=]() -> int {
952 const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 1632);
953 auto kyber512 = std::make_unique<Botan::Kyber_PrivateKey>(privkey_vec, Botan::KyberMode::Kyber512_R3);
954 *key = new botan_privkey_struct(std::move(kyber512));
955 return BOTAN_FFI_SUCCESS;
956 });
957 case 2400:
958 return ffi_guard_thunk(__func__, [=]() -> int {
959 const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 2400);
960 auto kyber768 = std::make_unique<Botan::Kyber_PrivateKey>(privkey_vec, Botan::KyberMode::Kyber768_R3);
961 *key = new botan_privkey_struct(std::move(kyber768));
962 return BOTAN_FFI_SUCCESS;
963 });
964 case 3168:
965 return ffi_guard_thunk(__func__, [=]() -> int {
966 const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 3168);
967 auto kyber1024 = std::make_unique<Botan::Kyber_PrivateKey>(privkey_vec, Botan::KyberMode::Kyber1024_R3);
968 *key = new botan_privkey_struct(std::move(kyber1024));
969 return BOTAN_FFI_SUCCESS;
970 });
971 default:
972 BOTAN_UNUSED(key, privkey, key_len);
974 }
975#else
976 BOTAN_UNUSED(key, key_len, privkey);
978#endif
979}
980
981int botan_pubkey_load_kyber(botan_pubkey_t* key, const uint8_t pubkey[], size_t key_len) {
982#if defined(BOTAN_HAS_KYBER)
983 *key = nullptr;
984 switch(key_len) {
985 case 800:
986 return ffi_guard_thunk(__func__, [=]() -> int {
987 const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 800);
988 auto kyber512 = std::make_unique<Botan::Kyber_PublicKey>(pubkey_vec, Botan::KyberMode::Kyber512_R3);
989 *key = new botan_pubkey_struct(std::move(kyber512));
990 return BOTAN_FFI_SUCCESS;
991 });
992 case 1184:
993 return ffi_guard_thunk(__func__, [=]() -> int {
994 const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 1184);
995 auto kyber768 = std::make_unique<Botan::Kyber_PublicKey>(pubkey_vec, Botan::KyberMode::Kyber768_R3);
996 *key = new botan_pubkey_struct(std::move(kyber768));
997 return BOTAN_FFI_SUCCESS;
998 });
999 case 1568:
1000 return ffi_guard_thunk(__func__, [=]() -> int {
1001 const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 1568);
1002 auto kyber1024 = std::make_unique<Botan::Kyber_PublicKey>(pubkey_vec, Botan::KyberMode::Kyber1024_R3);
1003 *key = new botan_pubkey_struct(std::move(kyber1024));
1004 return BOTAN_FFI_SUCCESS;
1005 });
1006 default:
1007 BOTAN_UNUSED(key, pubkey, key_len);
1009 }
1010#else
1011 BOTAN_UNUSED(key, pubkey, key_len);
1013#endif
1014}
1015
1017#if defined(BOTAN_HAS_KYBER)
1018 return BOTAN_FFI_VISIT(key, [=](const auto& k) -> int {
1019 if(auto kyber = dynamic_cast<const Botan::Kyber_PrivateKey*>(&k)) {
1020 return invoke_view_callback(view, ctx, kyber->raw_private_key_bits());
1021 } else {
1023 }
1024 });
1025#else
1026 BOTAN_UNUSED(key, ctx, view);
1028#endif
1029}
1030
1032#if defined(BOTAN_HAS_KYBER)
1033 return BOTAN_FFI_VISIT(key, [=](const auto& k) -> int {
1034 if(auto kyber = dynamic_cast<const Botan::Kyber_PublicKey*>(&k)) {
1035 return invoke_view_callback(view, ctx, kyber->public_key_bits());
1036 } else {
1038 }
1039 });
1040#else
1041 BOTAN_UNUSED(key, ctx, view);
1043#endif
1044}
1045
1046/*
1047* Algorithm specific key operations: ML-KEM
1048*/
1049
1050int botan_privkey_load_ml_kem(botan_privkey_t* key, const uint8_t privkey[], size_t key_len, const char* mlkem_mode) {
1051#if defined(BOTAN_HAS_ML_KEM)
1052 if(key == nullptr || privkey == nullptr || mlkem_mode == nullptr) {
1054 }
1055
1056 *key = nullptr;
1057
1058 return ffi_guard_thunk(__func__, [=]() -> int {
1059 auto mode = Botan::ML_KEM_Mode(mlkem_mode);
1060 if(!mode.is_ml_kem()) {
1062 }
1063
1064 auto mlkem_key = std::make_unique<Botan::ML_KEM_PrivateKey>(std::span{privkey, key_len}, mode);
1065 *key = new botan_privkey_struct(std::move(mlkem_key));
1066 return BOTAN_FFI_SUCCESS;
1067 });
1068#else
1069 BOTAN_UNUSED(key, key_len, privkey, mlkem_mode);
1071#endif
1072}
1073
1074int botan_pubkey_load_ml_kem(botan_pubkey_t* key, const uint8_t pubkey[], size_t key_len, const char* mlkem_mode) {
1075#if defined(BOTAN_HAS_ML_KEM)
1076 if(key == nullptr || pubkey == nullptr || mlkem_mode == nullptr) {
1078 }
1079
1080 *key = nullptr;
1081
1082 return ffi_guard_thunk(__func__, [=]() -> int {
1083 auto mode = Botan::ML_KEM_Mode(mlkem_mode);
1084 if(!mode.is_ml_kem()) {
1086 }
1087
1088 auto mlkem_key = std::make_unique<Botan::ML_KEM_PublicKey>(std::span{pubkey, key_len}, mode.mode());
1089 *key = new botan_pubkey_struct(std::move(mlkem_key));
1090 return BOTAN_FFI_SUCCESS;
1091 });
1092#else
1093 BOTAN_UNUSED(key, key_len, pubkey, mlkem_mode);
1095#endif
1096}
1097
1098/*
1099* Algorithm specific key operations: ML-DSA
1100*/
1101
1102int botan_privkey_load_ml_dsa(botan_privkey_t* key, const uint8_t privkey[], size_t key_len, const char* mldsa_mode) {
1103#if defined(BOTAN_HAS_ML_DSA)
1104 if(key == nullptr || privkey == nullptr || mldsa_mode == nullptr) {
1106 }
1107
1108 *key = nullptr;
1109
1110 return ffi_guard_thunk(__func__, [=]() -> int {
1111 auto mode = Botan::ML_DSA_Mode(mldsa_mode);
1112 if(!mode.is_ml_dsa()) {
1114 }
1115
1116 auto mldsa_key = std::make_unique<Botan::ML_DSA_PrivateKey>(std::span{privkey, key_len}, mode);
1117 *key = new botan_privkey_struct(std::move(mldsa_key));
1118 return BOTAN_FFI_SUCCESS;
1119 });
1120#else
1121 BOTAN_UNUSED(key, key_len, privkey, mldsa_mode);
1123#endif
1124}
1125
1126int botan_pubkey_load_ml_dsa(botan_pubkey_t* key, const uint8_t pubkey[], size_t key_len, const char* mldsa_mode) {
1127#if defined(BOTAN_HAS_ML_DSA)
1128 if(key == nullptr || pubkey == nullptr || mldsa_mode == nullptr) {
1130 }
1131
1132 *key = nullptr;
1133
1134 return ffi_guard_thunk(__func__, [=]() -> int {
1135 auto mode = Botan::ML_DSA_Mode(mldsa_mode);
1136 if(!mode.is_ml_dsa()) {
1138 }
1139
1140 auto mldsa_key = std::make_unique<Botan::ML_DSA_PublicKey>(std::span{pubkey, key_len}, mode);
1141 *key = new botan_pubkey_struct(std::move(mldsa_key));
1142 return BOTAN_FFI_SUCCESS;
1143 });
1144#else
1145 BOTAN_UNUSED(key, key_len, pubkey, mldsa_mode);
1147#endif
1148}
1149
1150/*
1151* Algorithm specific key operations: SLH-DSA
1152*/
1153
1154int botan_privkey_load_slh_dsa(botan_privkey_t* key, const uint8_t privkey[], size_t key_len, const char* slhdsa_mode) {
1155#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
1156 if(key == nullptr || privkey == nullptr || slhdsa_mode == nullptr) {
1158 }
1159
1160 *key = nullptr;
1161
1162 return ffi_guard_thunk(__func__, [=]() -> int {
1163 auto mode = Botan::SLH_DSA_Parameters::create(slhdsa_mode);
1164 if(!mode.is_slh_dsa()) {
1166 }
1167
1168 auto slhdsa_key = std::make_unique<Botan::SLH_DSA_PrivateKey>(std::span{privkey, key_len}, mode);
1169 *key = new botan_privkey_struct(std::move(slhdsa_key));
1170 return BOTAN_FFI_SUCCESS;
1171 });
1172#else
1173 BOTAN_UNUSED(key, key_len, privkey, slhdsa_mode);
1175#endif
1176}
1177
1178int botan_pubkey_load_slh_dsa(botan_pubkey_t* key, const uint8_t pubkey[], size_t key_len, const char* slhdsa_mode) {
1179#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
1180 if(key == nullptr || pubkey == nullptr || slhdsa_mode == nullptr) {
1182 }
1183
1184 *key = nullptr;
1185
1186 return ffi_guard_thunk(__func__, [=]() -> int {
1187 auto mode = Botan::SLH_DSA_Parameters::create(slhdsa_mode);
1188 if(!mode.is_slh_dsa()) {
1190 }
1191
1192 auto mldsa_key = std::make_unique<Botan::SLH_DSA_PublicKey>(std::span{pubkey, key_len}, mode);
1193 *key = new botan_pubkey_struct(std::move(mldsa_key));
1194 return BOTAN_FFI_SUCCESS;
1195 });
1196#else
1197 BOTAN_UNUSED(key, key_len, pubkey, slhdsa_mode);
1199#endif
1200}
1201
1202/*
1203* Algorithm specific key operations: FrodoKEM
1204*/
1205
1206int botan_privkey_load_frodokem(botan_privkey_t* key, const uint8_t privkey[], size_t key_len, const char* frodo_mode) {
1207#if defined(BOTAN_HAS_FRODOKEM)
1208 if(key == nullptr || privkey == nullptr || frodo_mode == nullptr) {
1210 }
1211
1212 *key = nullptr;
1213
1214 return ffi_guard_thunk(__func__, [=]() -> int {
1215 const auto mode = Botan::FrodoKEMMode(frodo_mode);
1216 auto frodo_key = std::make_unique<Botan::FrodoKEM_PrivateKey>(std::span{privkey, key_len}, mode);
1217 *key = new botan_privkey_struct(std::move(frodo_key));
1218 return BOTAN_FFI_SUCCESS;
1219 });
1220#else
1221 BOTAN_UNUSED(key, privkey, key_len, frodo_mode);
1223#endif
1224}
1225
1226int botan_pubkey_load_frodokem(botan_pubkey_t* key, const uint8_t pubkey[], size_t key_len, const char* frodo_mode) {
1227#if defined(BOTAN_HAS_FRODOKEM)
1228 if(key == nullptr || pubkey == nullptr || frodo_mode == nullptr) {
1230 }
1231
1232 *key = nullptr;
1233
1234 return ffi_guard_thunk(__func__, [=]() -> int {
1235 const auto mode = Botan::FrodoKEMMode(frodo_mode);
1236 auto frodo_key = std::make_unique<Botan::FrodoKEM_PublicKey>(std::span{pubkey, key_len}, mode);
1237 *key = new botan_pubkey_struct(std::move(frodo_key));
1238 return BOTAN_FFI_SUCCESS;
1239 });
1240#else
1241 BOTAN_UNUSED(key, pubkey, key_len, frodo_mode);
1243#endif
1244}
1245
1247#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
1248 return BOTAN_FFI_VISIT(key, [=](const auto& k) -> int {
1249 if(auto ecc = dynamic_cast<const Botan::EC_PublicKey*>(&k)) {
1250 auto pt = ecc->public_point().encode(Botan::EC_Point_Format::Uncompressed);
1251 return invoke_view_callback(view, ctx, pt);
1252 } else {
1254 }
1255 });
1256#else
1257 BOTAN_UNUSED(key, view, ctx);
1259#endif
1260}
1261
1262int botan_privkey_create_mceliece(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n, size_t t) {
1263 const std::string mce_params = std::to_string(n) + "," + std::to_string(t);
1264 return botan_privkey_create(key_obj, "McEliece", mce_params.c_str(), rng_obj);
1265}
1266
1268 const char* aead,
1269 const uint8_t ct[],
1270 size_t ct_len,
1271 const uint8_t ad[],
1272 size_t ad_len,
1273 uint8_t out[],
1274 size_t* out_len) {
1275 BOTAN_UNUSED(mce_key_obj, aead, ct, ct_len, ad, ad_len, out, out_len);
1277}
1278
1280 botan_rng_t rng_obj,
1281 const char* aead,
1282 const uint8_t pt[],
1283 size_t pt_len,
1284 const uint8_t ad[],
1285 size_t ad_len,
1286 uint8_t out[],
1287 size_t* out_len) {
1288 BOTAN_UNUSED(mce_key_obj, rng_obj, aead, pt, pt_len, ad, ad_len, out, out_len);
1290}
1291}
#define BOTAN_UNUSED
Definition assert.h:118
virtual std::string algo_name() const =0
virtual const BigInt & get_int_field(std::string_view field) const
Definition pk_keys.cpp:18
static std::optional< EC_AffinePoint > from_bigint_xy(const EC_Group &group, const BigInt &x, const BigInt &y)
Definition ec_apoint.cpp:54
static EC_Group from_name(std::string_view name)
Definition ec_group.cpp:307
bool used_explicit_encoding() const
Definition ec_group.h:199
const EC_Group & domain() const
Definition ecc_key.cpp:59
const EC_Point & public_point() const
Definition ecc_key.cpp:64
A private key for Ed448/Ed448ph according to RFC 8032.
Definition ed448.h:83
A public key for Ed448/Ed448ph according to RFC 8032.
Definition ed448.h:27
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition hash.cpp:298
A private key for the X448 key agreement scheme according to RFC 7748.
Definition x448.h:67
A public key for the X448 key agreement scheme according to RFC 7748.
Definition x448.h:19
struct botan_pubkey_struct * botan_pubkey_t
Definition ffi.h:1317
struct botan_privkey_struct * botan_privkey_t
Definition ffi.h:1097
int(* botan_view_bin_fn)(botan_view_ctx view_ctx, const uint8_t *data, size_t len)
Definition ffi.h:155
int botan_privkey_create(botan_privkey_t *key, const char *algo_name, const char *algo_params, botan_rng_t rng)
Definition ffi_pkey.cpp:27
#define BOTAN_PRIVKEY_EXPORT_FLAG_PEM
Definition ffi.h:1181
struct botan_mp_struct * botan_mp_t
Definition ffi.h:900
void * botan_view_ctx
Definition ffi.h:146
struct botan_rng_struct * botan_rng_t
Definition ffi.h:272
#define BOTAN_PRIVKEY_EXPORT_FLAG_DER
Definition ffi.h:1180
@ BOTAN_FFI_ERROR_NOT_IMPLEMENTED
Definition ffi.h:135
@ BOTAN_FFI_ERROR_UNKNOWN_ERROR
Definition ffi.h:143
@ BOTAN_FFI_ERROR_BAD_FLAG
Definition ffi.h:128
@ BOTAN_FFI_ERROR_NULL_POINTER
Definition ffi.h:129
@ BOTAN_FFI_SUCCESS
Definition ffi.h:114
@ BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE
Definition ffi.h:120
@ BOTAN_FFI_ERROR_BAD_PARAMETER
Definition ffi.h:130
int botan_privkey_create_elgamal(botan_privkey_t *key, botan_rng_t rng_obj, size_t pbits, size_t qbits)
int botan_pubkey_rsa_get_n(botan_mp_t n, botan_pubkey_t key)
int botan_privkey_load_x448(botan_privkey_t *key, const uint8_t privkey[56])
int botan_pubkey_get_field(botan_mp_t output, botan_pubkey_t key, const char *field_name_cstr)
int botan_pubkey_load_ml_dsa(botan_pubkey_t *key, const uint8_t pubkey[], size_t key_len, const char *mldsa_mode)
int botan_privkey_load_ecdh(botan_privkey_t *key, const botan_mp_t scalar, const char *curve_name)
int botan_privkey_view_kyber_raw_key(botan_privkey_t key, botan_view_ctx ctx, botan_view_bin_fn view)
int botan_pubkey_load_dh(botan_pubkey_t *key, botan_mp_t p, botan_mp_t g, botan_mp_t y)
int botan_pubkey_ed25519_get_pubkey(botan_pubkey_t key, uint8_t output[32])
int botan_privkey_rsa_get_privkey(botan_privkey_t rsa_key, uint8_t out[], size_t *out_len, uint32_t flags)
int botan_privkey_load_rsa_pkcs1(botan_privkey_t *key, const uint8_t bits[], size_t len)
int botan_pubkey_load_sm2(botan_pubkey_t *key, const botan_mp_t public_x, const botan_mp_t public_y, const char *curve_name)
int botan_pubkey_load_slh_dsa(botan_pubkey_t *key, const uint8_t pubkey[], size_t key_len, const char *slhdsa_mode)
int botan_pubkey_sm2_compute_za(uint8_t out[], size_t *out_len, const char *ident, const char *hash_algo, const botan_pubkey_t key)
int botan_privkey_load_x25519(botan_privkey_t *key, const uint8_t privkey[32])
int botan_pubkey_dsa_get_p(botan_mp_t p, botan_pubkey_t key)
int botan_privkey_rsa_get_q(botan_mp_t q, botan_privkey_t key)
int botan_pubkey_ecc_key_used_explicit_encoding(botan_pubkey_t key)
int botan_pubkey_load_frodokem(botan_pubkey_t *key, const uint8_t pubkey[], size_t key_len, const char *frodo_mode)
int botan_privkey_ed25519_get_privkey(botan_privkey_t key, uint8_t output[64])
int botan_privkey_load_sm2_enc(botan_privkey_t *key, const botan_mp_t scalar, const char *curve_name)
int botan_privkey_get_field(botan_mp_t output, botan_privkey_t key, const char *field_name_cstr)
int botan_pubkey_x448_get_pubkey(botan_pubkey_t key, uint8_t output[56])
int botan_privkey_load_rsa(botan_privkey_t *key, botan_mp_t rsa_p, botan_mp_t rsa_q, botan_mp_t rsa_e)
int botan_pubkey_dsa_get_y(botan_mp_t y, botan_pubkey_t key)
int botan_pubkey_load_ml_kem(botan_pubkey_t *key, const uint8_t pubkey[], size_t key_len, const char *mlkem_mode)
int botan_privkey_load_ed448(botan_privkey_t *key, const uint8_t privkey[57])
int botan_pubkey_view_ec_public_point(const botan_pubkey_t key, botan_view_ctx ctx, botan_view_bin_fn view)
int botan_privkey_load_dh(botan_privkey_t *key, botan_mp_t p, botan_mp_t g, botan_mp_t x)
int botan_privkey_load_sm2(botan_privkey_t *key, const botan_mp_t scalar, const char *curve_name)
int botan_pubkey_load_ed25519(botan_pubkey_t *key, const uint8_t pubkey[32])
int botan_privkey_load_ecdsa(botan_privkey_t *key, const botan_mp_t scalar, const char *curve_name)
int botan_mceies_encrypt(botan_pubkey_t mce_key_obj, botan_rng_t rng_obj, const char *aead, const uint8_t pt[], size_t pt_len, const uint8_t ad[], size_t ad_len, uint8_t out[], size_t *out_len)
int botan_pubkey_x25519_get_pubkey(botan_pubkey_t key, uint8_t output[32])
int botan_pubkey_load_elgamal(botan_pubkey_t *key, botan_mp_t p, botan_mp_t g, botan_mp_t y)
int botan_privkey_load_slh_dsa(botan_privkey_t *key, const uint8_t privkey[], size_t key_len, const char *slhdsa_mode)
int botan_privkey_create_dsa(botan_privkey_t *key, botan_rng_t rng_obj, size_t pbits, size_t qbits)
int botan_privkey_rsa_get_p(botan_mp_t p, botan_privkey_t key)
int botan_privkey_create_mceliece(botan_privkey_t *key_obj, botan_rng_t rng_obj, size_t n, size_t t)
int botan_pubkey_load_ed448(botan_pubkey_t *key, const uint8_t pubkey[57])
int botan_privkey_load_ml_kem(botan_privkey_t *key, const uint8_t privkey[], size_t key_len, const char *mlkem_mode)
int botan_privkey_create_ecdh(botan_privkey_t *key_obj, botan_rng_t rng_obj, const char *param_str)
int botan_privkey_rsa_get_d(botan_mp_t d, botan_privkey_t key)
int botan_pubkey_load_sm2_enc(botan_pubkey_t *key, const botan_mp_t public_x, const botan_mp_t public_y, const char *curve_name)
int botan_mceies_decrypt(botan_privkey_t mce_key_obj, const char *aead, const uint8_t ct[], size_t ct_len, const uint8_t ad[], size_t ad_len, uint8_t out[], size_t *out_len)
int botan_pubkey_load_x25519(botan_pubkey_t *key, const uint8_t pubkey[32])
int botan_privkey_load_elgamal(botan_privkey_t *key, botan_mp_t p, botan_mp_t g, botan_mp_t x)
int botan_privkey_create_rsa(botan_privkey_t *key_obj, botan_rng_t rng_obj, size_t n_bits)
int botan_pubkey_load_dsa(botan_pubkey_t *key, botan_mp_t p, botan_mp_t q, botan_mp_t g, botan_mp_t y)
int botan_pubkey_load_kyber(botan_pubkey_t *key, const uint8_t pubkey[], size_t key_len)
int botan_pubkey_ed448_get_pubkey(botan_pubkey_t key, uint8_t output[57])
int botan_privkey_create_dh(botan_privkey_t *key_obj, botan_rng_t rng_obj, const char *param_str)
int botan_privkey_load_dsa(botan_privkey_t *key, botan_mp_t p, botan_mp_t q, botan_mp_t g, botan_mp_t x)
int botan_privkey_rsa_get_n(botan_mp_t n, botan_privkey_t key)
int botan_privkey_load_kyber(botan_privkey_t *key, const uint8_t privkey[], size_t key_len)
int botan_pubkey_rsa_get_e(botan_mp_t e, botan_pubkey_t key)
int botan_pubkey_dsa_get_g(botan_mp_t g, botan_pubkey_t key)
int botan_pubkey_dsa_get_q(botan_mp_t q, botan_pubkey_t key)
int botan_privkey_load_frodokem(botan_privkey_t *key, const uint8_t privkey[], size_t key_len, const char *frodo_mode)
int botan_pubkey_load_ecdsa(botan_pubkey_t *key, const botan_mp_t public_x, const botan_mp_t public_y, const char *curve_name)
int botan_pubkey_load_ecdh(botan_pubkey_t *key, const botan_mp_t public_x, const botan_mp_t public_y, const char *curve_name)
int botan_privkey_load_ml_dsa(botan_privkey_t *key, const uint8_t privkey[], size_t key_len, const char *mldsa_mode)
int botan_privkey_x448_get_privkey(botan_privkey_t key, uint8_t output[56])
int botan_privkey_load_ed25519(botan_privkey_t *key, const uint8_t privkey[32])
int botan_privkey_rsa_get_e(botan_mp_t e, botan_privkey_t key)
int botan_privkey_x25519_get_privkey(botan_privkey_t key, uint8_t output[32])
int botan_privkey_ed448_get_privkey(botan_privkey_t key, uint8_t output[57])
int botan_privkey_dsa_get_x(botan_mp_t x, botan_privkey_t key)
int botan_pubkey_load_rsa(botan_pubkey_t *key, botan_mp_t n, botan_mp_t e)
int botan_privkey_create_ecdsa(botan_privkey_t *key_obj, botan_rng_t rng_obj, const char *param_str)
int botan_pubkey_view_kyber_raw_key(botan_pubkey_t key, botan_view_ctx ctx, botan_view_bin_fn view)
int botan_pubkey_load_x448(botan_pubkey_t *key, const uint8_t pubkey[56])
#define BOTAN_FFI_VISIT(obj, lambda)
Definition ffi_util.h:124
std::string encode(const uint8_t der[], size_t length, std::string_view label, size_t width)
Definition pem.cpp:39
int write_str_output(uint8_t out[], size_t *out_len, std::string_view str)
Definition ffi_util.h:205
T & safe_get(botan_struct< T, M > *p)
Definition ffi_util.h:63
int invoke_view_callback(botan_view_bin_fn view, botan_view_ctx ctx, const std::vector< uint8_t, Alloc > &buf)
Definition ffi_util.h:146
int ffi_guard_thunk(const char *func_name, const std::function< int()> &thunk)
Definition ffi.cpp:118
int write_vec_output(uint8_t out[], size_t *out_len, const std::vector< uint8_t, Alloc > &buf)
Definition ffi_util.h:201
DilithiumMode ML_DSA_Mode
Definition ml_dsa.h:21
KyberMode ML_KEM_Mode
Definition ml_kem.h:21
std::vector< uint8_t > sm2_compute_za(HashFunction &hash, std::string_view user_id, const EC_Group &group, const EC_Point &point)
Definition sm2.cpp:244
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:146