Botan 3.11.0
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/assert.h>
12#include <botan/ec_group.h>
13#include <botan/hash.h>
14#include <botan/mem_ops.h>
15#include <botan/pem.h>
16#include <botan/internal/ffi_mp.h>
17#include <botan/internal/ffi_pkey.h>
18#include <botan/internal/ffi_rng.h>
19#include <botan/internal/ffi_util.h>
20
21#if defined(BOTAN_HAS_DL_GROUP)
22 #include <botan/dl_group.h>
23#endif
24
25#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
26 #include <botan/ecc_key.h>
27#endif
28
29#if defined(BOTAN_HAS_RSA)
30 #include <botan/rsa.h>
31#endif
32
33#if defined(BOTAN_HAS_ELGAMAL)
34 #include <botan/elgamal.h>
35#endif
36
37#if defined(BOTAN_HAS_DSA)
38 #include <botan/dsa.h>
39#endif
40
41#if defined(BOTAN_HAS_ECDSA)
42 #include <botan/ecdsa.h>
43#endif
44
45#if defined(BOTAN_HAS_SM2)
46 #include <botan/sm2.h>
47#endif
48
49#if defined(BOTAN_HAS_ECDH)
50 #include <botan/ecdh.h>
51#endif
52
53#if defined(BOTAN_HAS_X25519)
54 #include <botan/x25519.h>
55#endif
56
57#if defined(BOTAN_HAS_X448)
58 #include <botan/x448.h>
59#endif
60
61#if defined(BOTAN_HAS_ED25519)
62 #include <botan/ed25519.h>
63#endif
64
65#if defined(BOTAN_HAS_ED448)
66 #include <botan/ed448.h>
67#endif
68
69#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
70 #include <botan/dh.h>
71#endif
72
73#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
74 #include <botan/kyber.h>
75#endif
76
77#if defined(BOTAN_HAS_ML_KEM)
78 #include <botan/ml_kem.h>
79#endif
80
81#if defined(BOTAN_HAS_FRODOKEM)
82 #include <botan/frodokem.h>
83#endif
84
85#if defined(BOTAN_HAS_ML_DSA)
86 #include <botan/ml_dsa.h>
87#endif
88
89#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
90 #include <botan/slh_dsa.h>
91#endif
92
93#if defined(BOTAN_HAS_CLASSICMCELIECE)
94 #include <botan/cmce.h>
95#endif
96
97namespace {
98
99#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
100
101// These are always called within an existing try/catch block
102
103template <class ECPrivateKey_t>
104int privkey_load_ec(std::unique_ptr<ECPrivateKey_t>& key, const Botan::BigInt& scalar, const char* curve_name) {
105 if(curve_name == nullptr) {
107 }
110 }
111
112 Botan::Null_RNG null_rng;
113 const auto grp = Botan::EC_Group::from_name(curve_name);
114 key.reset(new ECPrivateKey_t(null_rng, grp, scalar));
115 return BOTAN_FFI_SUCCESS;
116}
117
118template <class ECPublicKey_t>
119int pubkey_load_ec(std::unique_ptr<ECPublicKey_t>& key,
120 const Botan::BigInt& public_x,
121 const Botan::BigInt& public_y,
122 const char* curve_name) {
123 if(curve_name == nullptr) {
125 }
126
129 }
130
131 const auto group = Botan::EC_Group::from_name(curve_name);
132
133 if(auto pt = Botan::EC_AffinePoint::from_bigint_xy(group, public_x, public_y)) {
134 key.reset(new ECPublicKey_t(group, pt.value()));
135 return BOTAN_FFI_SUCCESS;
136 } else {
138 }
139}
140
141template <class ECPublicKey_t>
142int pubkey_load_ec_sec1(std::unique_ptr<ECPublicKey_t>& key,
143 std::span<const uint8_t> sec1,
144 std::string_view curve_name) {
147 }
148
149 const auto group = Botan::EC_Group::from_name(curve_name);
150
151 if(auto pt = Botan::EC_AffinePoint::deserialize(group, sec1)) {
152 key.reset(new ECPublicKey_t(group, pt.value()));
153 return BOTAN_FFI_SUCCESS;
154 } else {
156 }
157}
158
159#endif
160
161Botan::BigInt pubkey_get_field(const Botan::Public_Key& key, std::string_view field) {
162#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
163 // Not currently handled by get_int_field
164 if(const Botan::EC_PublicKey* ecc = dynamic_cast<const Botan::EC_PublicKey*>(&key)) {
165 if(field == "public_x") {
166 return Botan::BigInt::from_bytes(ecc->_public_ec_point().x_bytes());
167 } else if(field == "public_y") {
168 return Botan::BigInt::from_bytes(ecc->_public_ec_point().y_bytes());
169 }
170 }
171#endif
172
173 try {
174 return key.get_int_field(field);
176 throw Botan_FFI::FFI_Error("Unknown key field", BOTAN_FFI_ERROR_BAD_PARAMETER);
177 }
178}
179
180Botan::BigInt privkey_get_field(const Botan::Private_Key& key, std::string_view field) {
181#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
182 // Not currently handled by get_int_field
183 if(const Botan::EC_PublicKey* ecc = dynamic_cast<const Botan::EC_PublicKey*>(&key)) {
184 if(field == "public_x") {
185 return Botan::BigInt::from_bytes(ecc->_public_ec_point().x_bytes());
186 } else if(field == "public_y") {
187 return Botan::BigInt::from_bytes(ecc->_public_ec_point().y_bytes());
188 }
189 }
190#endif
191
192 try {
193 return key.get_int_field(field);
195 throw Botan_FFI::FFI_Error("Unknown key field", BOTAN_FFI_ERROR_BAD_PARAMETER);
196 }
197}
198
199} // namespace
200
201extern "C" {
202
203using namespace Botan_FFI;
204
205int botan_pubkey_get_field(botan_mp_t output, botan_pubkey_t key, const char* field_name_cstr) {
206 if(field_name_cstr == nullptr) {
208 }
209
210 const std::string field_name(field_name_cstr);
211
212 return BOTAN_FFI_VISIT(key, [=](const auto& k) { safe_get(output) = pubkey_get_field(k, field_name); });
213}
214
215int botan_privkey_get_field(botan_mp_t output, botan_privkey_t key, const char* field_name_cstr) {
216 if(field_name_cstr == nullptr) {
218 }
219
220 const std::string field_name(field_name_cstr);
221
222 return BOTAN_FFI_VISIT(key, [=](const auto& k) { safe_get(output) = privkey_get_field(k, field_name); });
223}
224
225/* RSA specific operations */
226
227int botan_privkey_create_rsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n_bits) {
228 if(n_bits < 1024 || n_bits > 16 * 1024) {
230 }
231
232 const std::string n_str = std::to_string(n_bits);
233
234 return botan_privkey_create(key_obj, "RSA", n_str.c_str(), rng_obj);
235}
236
238#if defined(BOTAN_HAS_RSA)
239 if(key == nullptr) {
241 }
242 *key = nullptr;
243
244 return ffi_guard_thunk(__func__, [=]() -> int {
245 auto rsa = std::make_unique<Botan::RSA_PrivateKey>(safe_get(rsa_p), safe_get(rsa_q), safe_get(rsa_e));
246 return ffi_new_object(key, std::move(rsa));
247 });
248#else
249 BOTAN_UNUSED(key, rsa_p, rsa_q, rsa_e);
251#endif
252}
253
254int botan_privkey_load_rsa_pkcs1(botan_privkey_t* key, const uint8_t bits[], size_t len) {
255#if defined(BOTAN_HAS_RSA)
256 if(key == nullptr || bits == nullptr) {
258 }
259 *key = nullptr;
260
261 return ffi_guard_thunk(__func__, [=]() -> int {
263 auto rsa = std::make_unique<Botan::RSA_PrivateKey>(alg_id, std::span{bits, len});
264 return ffi_new_object(key, std::move(rsa));
265 });
266#else
267 BOTAN_UNUSED(key, bits, len);
269#endif
270}
271
273#if defined(BOTAN_HAS_RSA)
274 if(key == nullptr) {
276 }
277 *key = nullptr;
278 return ffi_guard_thunk(__func__, [=]() -> int {
279 auto rsa = std::make_unique<Botan::RSA_PublicKey>(safe_get(n), safe_get(e));
280 return ffi_new_object(key, std::move(rsa));
281 });
282#else
283 BOTAN_UNUSED(key, n, e);
285#endif
286}
287
288int botan_pubkey_load_rsa_pkcs1(botan_pubkey_t* key, const uint8_t bits[], size_t len) {
289#if defined(BOTAN_HAS_RSA)
290 if(key == nullptr || bits == nullptr) {
292 }
293 *key = nullptr;
294
295 return ffi_guard_thunk(__func__, [=]() -> int {
297 auto rsa = std::make_unique<Botan::RSA_PublicKey>(alg_id, std::span{bits, len});
298 return ffi_new_object(key, std::move(rsa));
299 });
300#else
301 BOTAN_UNUSED(key, bits, len);
303#endif
304}
305
309
313
317
321
325
327 return botan_pubkey_get_field(e, key, "e");
328}
329
331 return botan_pubkey_get_field(n, key, "n");
332}
333
334int botan_privkey_rsa_get_privkey(botan_privkey_t rsa_key, uint8_t out[], size_t* out_len, uint32_t flags) {
335#if defined(BOTAN_HAS_RSA)
336 return BOTAN_FFI_VISIT(rsa_key, [=](const auto& k) -> int {
337 if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<const Botan::RSA_PrivateKey*>(&k)) {
338 if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_DER) {
339 return write_vec_output(out, out_len, rsa->private_key_bits());
340 } else if(flags == BOTAN_PRIVKEY_EXPORT_FLAG_PEM) {
341 // TODO define new generic functions for this
342 return write_str_output(reinterpret_cast<char*>(out),
343 out_len,
344 Botan::PEM_Code::encode(rsa->private_key_bits(), "RSA PRIVATE KEY"));
345 } else {
347 }
348 } else {
350 }
351 });
352#else
353 BOTAN_UNUSED(rsa_key, out, out_len, flags);
355#endif
356}
357
358/* DSA specific operations */
359int botan_privkey_create_dsa(botan_privkey_t* key, botan_rng_t rng_obj, size_t pbits, size_t qbits) {
360#if defined(BOTAN_HAS_DSA)
361
362 if((rng_obj == nullptr) || (key == nullptr)) {
364 }
365
366 if((pbits % 64 != 0) || (qbits % 8 != 0) || (pbits < 1024) || (pbits > 3072) || (qbits < 160) || (qbits > 256)) {
368 }
369
370 return ffi_guard_thunk(__func__, [=]() -> int {
372 const Botan::DL_Group group(rng, Botan::DL_Group::Prime_Subgroup, pbits, qbits);
373 auto dsa = std::make_unique<Botan::DSA_PrivateKey>(rng, group);
374 return ffi_new_object(key, std::move(dsa));
375 });
376#else
377 BOTAN_UNUSED(key, rng_obj, pbits, qbits);
379#endif
380}
381
383#if defined(BOTAN_HAS_DSA)
384 if(key == nullptr) {
386 }
387 *key = nullptr;
388
389 return ffi_guard_thunk(__func__, [=]() -> int {
390 const Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
391 auto dsa = std::make_unique<Botan::DSA_PrivateKey>(group, safe_get(x));
392 return ffi_new_object(key, std::move(dsa));
393 });
394#else
395 BOTAN_UNUSED(key, p, q, g, x);
397#endif
398}
399
401#if defined(BOTAN_HAS_DSA)
402 if(key == nullptr) {
404 }
405 *key = nullptr;
406
407 return ffi_guard_thunk(__func__, [=]() -> int {
408 const Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
409 auto dsa = std::make_unique<Botan::DSA_PublicKey>(group, safe_get(y));
410 return ffi_new_object(key, std::move(dsa));
411 });
412#else
413 BOTAN_UNUSED(key, p, q, g, y);
415#endif
416}
417
421
423 return botan_pubkey_get_field(p, key, "p");
424}
425
427 return botan_pubkey_get_field(q, key, "q");
428}
429
431 return botan_pubkey_get_field(g, key, "g");
432}
433
435 return botan_pubkey_get_field(y, key, "y");
436}
437
438int botan_privkey_create_ecdsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str) {
439 return botan_privkey_create(key_obj, "ECDSA", param_str, rng_obj);
440}
441
442/* ECDSA specific operations */
443
445#if defined(BOTAN_HAS_ECC_KEY)
446 return ffi_guard_thunk(__func__, [=]() -> int {
447 const Botan::Public_Key& pub_key = safe_get(key);
448 const Botan::EC_PublicKey* ec_key = dynamic_cast<const Botan::EC_PublicKey*>(&pub_key);
449
450 if(ec_key == nullptr) {
452 }
453
454 return ec_key->domain().used_explicit_encoding() ? 1 : 0;
455 });
456#else
457 BOTAN_UNUSED(key);
459#endif
460}
461
462// NOLINTBEGIN(misc-misplaced-const)
463
465 const botan_mp_t public_x,
466 const botan_mp_t public_y,
467 const char* curve_name) {
468#if defined(BOTAN_HAS_ECDSA)
469 if(key == nullptr || curve_name == nullptr) {
471 }
472 *key = nullptr;
473
474 return ffi_guard_thunk(__func__, [=]() -> int {
475 std::unique_ptr<Botan::ECDSA_PublicKey> p_key;
476
477 const int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
478 if(rc == BOTAN_FFI_SUCCESS) {
479 ffi_new_object(key, std::move(p_key));
480 }
481
482 return rc;
483 });
484#else
485 BOTAN_UNUSED(key, public_x, public_y, curve_name);
487#endif
488}
489
490int botan_pubkey_load_ecdsa_sec1(botan_pubkey_t* key, const uint8_t sec1[], size_t sec1_len, const char* curve_name) {
491#if defined(BOTAN_HAS_ECDSA)
492 if(key == nullptr || sec1 == nullptr || curve_name == nullptr) {
494 }
495 *key = nullptr;
496
497 return ffi_guard_thunk(__func__, [=]() -> int {
498 std::unique_ptr<Botan::ECDSA_PublicKey> p_key;
499
500 const int rc = pubkey_load_ec_sec1(p_key, {sec1, sec1_len}, curve_name);
501 if(rc == BOTAN_FFI_SUCCESS) {
502 ffi_new_object(key, std::move(p_key));
503 }
504
505 return rc;
506 });
507#else
508 BOTAN_UNUSED(key, sec1, sec1_len, curve_name);
510#endif
511}
512
513int botan_privkey_load_ecdsa(botan_privkey_t* key, const botan_mp_t scalar, const char* curve_name) {
514#if defined(BOTAN_HAS_ECDSA)
515 if(key == nullptr || curve_name == nullptr) {
517 }
518 *key = nullptr;
519
520 return ffi_guard_thunk(__func__, [=]() -> int {
521 std::unique_ptr<Botan::ECDSA_PrivateKey> p_key;
522 const int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
523 if(rc == BOTAN_FFI_SUCCESS) {
524 ffi_new_object(key, std::move(p_key));
525 }
526 return rc;
527 });
528#else
529 BOTAN_UNUSED(key, scalar, curve_name);
531#endif
532}
533
534/* ElGamal specific operations */
535int botan_privkey_create_elgamal(botan_privkey_t* key, botan_rng_t rng_obj, size_t pbits, size_t qbits) {
536#if defined(BOTAN_HAS_ELGAMAL)
537 if(key == nullptr || rng_obj == nullptr) {
539 }
540 *key = nullptr;
541
542 if(pbits < 1024 || qbits < 160) {
544 }
545
546 const Botan::DL_Group::PrimeType prime_type =
548
549 return ffi_guard_thunk(__func__, [=]() -> int {
551 const Botan::DL_Group group(rng, prime_type, pbits, qbits);
552 auto elg = std::make_unique<Botan::ElGamal_PrivateKey>(rng, group);
553 return ffi_new_object(key, std::move(elg));
554 });
555#else
556 BOTAN_UNUSED(key, rng_obj, pbits, qbits);
558#endif
559}
560
562#if defined(BOTAN_HAS_ELGAMAL)
563 if(key == nullptr) {
565 }
566 *key = nullptr;
567 return ffi_guard_thunk(__func__, [=]() -> int {
568 const Botan::DL_Group group(safe_get(p), safe_get(g));
569 auto elg = std::make_unique<Botan::ElGamal_PublicKey>(group, safe_get(y));
570 return ffi_new_object(key, std::move(elg));
571 });
572#else
573 BOTAN_UNUSED(key, p, g, y);
575#endif
576}
577
579#if defined(BOTAN_HAS_ELGAMAL)
580 if(key == nullptr) {
582 }
583 *key = nullptr;
584 return ffi_guard_thunk(__func__, [=]() -> int {
585 const Botan::DL_Group group(safe_get(p), safe_get(g));
586 auto elg = std::make_unique<Botan::ElGamal_PrivateKey>(group, safe_get(x));
587 return ffi_new_object(key, std::move(elg));
588 });
589#else
590 BOTAN_UNUSED(key, p, g, x);
592#endif
593}
594
595/* Diffie Hellman specific operations */
596
597int botan_privkey_create_dh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str) {
598 return botan_privkey_create(key_obj, "DH", param_str, rng_obj);
599}
600
602#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
603 if(key == nullptr) {
605 }
606 *key = nullptr;
607 return ffi_guard_thunk(__func__, [=]() -> int {
608 const Botan::DL_Group group(safe_get(p), safe_get(g));
609 auto dh = std::make_unique<Botan::DH_PrivateKey>(group, safe_get(x));
610 return ffi_new_object(key, std::move(dh));
611 });
612#else
613 BOTAN_UNUSED(key, p, g, x);
615#endif
616}
617
619#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
620 if(key == nullptr) {
622 }
623 *key = nullptr;
624 return ffi_guard_thunk(__func__, [=]() -> int {
625 const Botan::DL_Group group(safe_get(p), safe_get(g));
626 auto dh = std::make_unique<Botan::DH_PublicKey>(group, safe_get(y));
627 return ffi_new_object(key, std::move(dh));
628 });
629#else
630 BOTAN_UNUSED(key, p, g, y);
632#endif
633}
634
635/* ECDH + x25519/x448 specific operations */
636
637int botan_privkey_create_ecdh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str) {
638 if(key_obj == nullptr || param_str == nullptr) {
640 }
641 *key_obj = nullptr;
642
643 const std::string params(param_str);
644
645 if(params == "X25519" || params == "x25519" || params == "curve25519") {
646 return botan_privkey_create(key_obj, "X25519", "", rng_obj);
647 }
648
649 if(params == "X448" || params == "x448") {
650 return botan_privkey_create(key_obj, "X448", "", rng_obj);
651 }
652
653 return botan_privkey_create(key_obj, "ECDH", param_str, rng_obj);
654}
655
657 const botan_mp_t public_x,
658 const botan_mp_t public_y,
659 const char* curve_name) {
660#if defined(BOTAN_HAS_ECDH)
661 if(key == nullptr || curve_name == nullptr) {
663 }
664 *key = nullptr;
665 return ffi_guard_thunk(__func__, [=]() -> int {
666 std::unique_ptr<Botan::ECDH_PublicKey> p_key;
667 const int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
668
669 if(rc == BOTAN_FFI_SUCCESS) {
670 ffi_new_object(key, std::move(p_key));
671 }
672 return rc;
673 });
674#else
675 BOTAN_UNUSED(key, public_x, public_y, curve_name);
677#endif
678}
679
680int botan_pubkey_load_ecdh_sec1(botan_pubkey_t* key, const uint8_t sec1[], size_t sec1_len, const char* curve_name) {
681#if defined(BOTAN_HAS_ECDH)
682 if(key == nullptr || sec1 == nullptr || curve_name == nullptr) {
684 }
685 *key = nullptr;
686
687 return ffi_guard_thunk(__func__, [=]() -> int {
688 std::unique_ptr<Botan::ECDH_PublicKey> p_key;
689
690 const int rc = pubkey_load_ec_sec1(p_key, {sec1, sec1_len}, curve_name);
691 if(rc == BOTAN_FFI_SUCCESS) {
692 ffi_new_object(key, std::move(p_key));
693 }
694
695 return rc;
696 });
697#else
698 BOTAN_UNUSED(key, sec1, sec1_len, curve_name);
700#endif
701}
702
703int botan_privkey_load_ecdh(botan_privkey_t* key, const botan_mp_t scalar, const char* curve_name) {
704#if defined(BOTAN_HAS_ECDH)
705 if(key == nullptr || curve_name == nullptr) {
707 }
708 *key = nullptr;
709 return ffi_guard_thunk(__func__, [=]() -> int {
710 std::unique_ptr<Botan::ECDH_PrivateKey> p_key;
711 const int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
712 if(rc == BOTAN_FFI_SUCCESS) {
713 ffi_new_object(key, std::move(p_key));
714 }
715 return rc;
716 });
717#else
718 BOTAN_UNUSED(key, scalar, curve_name);
720#endif
721}
722
723/* SM2 specific operations */
724
726 uint8_t out[], size_t* out_len, const char* ident, const char* hash_algo, const botan_pubkey_t key) {
727 if(out == nullptr || out_len == nullptr || ident == nullptr || hash_algo == nullptr || key == nullptr) {
729 }
730
731#if defined(BOTAN_HAS_SM2)
732 return ffi_guard_thunk(__func__, [=]() -> int {
733 const Botan::Public_Key& pub_key = safe_get(key);
734 const Botan::EC_PublicKey* ec_key = dynamic_cast<const Botan::EC_PublicKey*>(&pub_key);
735
736 if(ec_key == nullptr) {
738 }
739
740 if(ec_key->algo_name() != "SM2") {
742 }
743
744 const std::string ident_str(ident);
745 std::unique_ptr<Botan::HashFunction> hash = Botan::HashFunction::create_or_throw(hash_algo);
746
747 const auto& pt = ec_key->_public_ec_point();
748
749 const auto za = Botan::sm2_compute_za(*hash, ident_str, ec_key->domain(), pt);
750
751 return write_vec_output(out, out_len, za);
752 });
753#else
755#endif
756}
757
759 const botan_mp_t public_x,
760 const botan_mp_t public_y,
761 const char* curve_name) {
762#if defined(BOTAN_HAS_SM2)
763 if(key == nullptr || curve_name == nullptr) {
765 }
766 *key = nullptr;
767
768 return ffi_guard_thunk(__func__, [=]() -> int {
769 std::unique_ptr<Botan::SM2_PublicKey> p_key;
770 if(pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name) == 0) {
771 return ffi_new_object(key, std::move(p_key));
772 } else {
774 }
775 });
776#else
777 BOTAN_UNUSED(key, public_x, public_y, curve_name);
779#endif
780}
781
782int botan_pubkey_load_sm2_sec1(botan_pubkey_t* key, const uint8_t sec1[], size_t sec1_len, const char* curve_name) {
783#if defined(BOTAN_HAS_SM2)
784 if(key == nullptr || sec1 == nullptr || curve_name == nullptr) {
786 }
787 *key = nullptr;
788
789 return ffi_guard_thunk(__func__, [=]() -> int {
790 std::unique_ptr<Botan::SM2_PublicKey> p_key;
791
792 const int rc = pubkey_load_ec_sec1(p_key, {sec1, sec1_len}, curve_name);
793 if(rc == BOTAN_FFI_SUCCESS) {
794 ffi_new_object(key, std::move(p_key));
795 }
796
797 return rc;
798 });
799#else
800 BOTAN_UNUSED(key, sec1, sec1_len, curve_name);
802#endif
803}
804
805int botan_privkey_load_sm2(botan_privkey_t* key, const botan_mp_t scalar, const char* curve_name) {
806#if defined(BOTAN_HAS_SM2)
807 if(key == nullptr || curve_name == nullptr) {
809 }
810 *key = nullptr;
811
812 return ffi_guard_thunk(__func__, [=]() -> int {
813 std::unique_ptr<Botan::SM2_PrivateKey> p_key;
814 const int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
815
816 if(rc == BOTAN_FFI_SUCCESS) {
817 ffi_new_object(key, std::move(p_key));
818 }
819 return rc;
820 });
821#else
822 BOTAN_UNUSED(key, scalar, curve_name);
824#endif
825}
826
828 const botan_mp_t public_x,
829 const botan_mp_t public_y,
830 const char* curve_name) {
831 return botan_pubkey_load_sm2(key, public_x, public_y, curve_name);
832}
833
834int botan_privkey_load_sm2_enc(botan_privkey_t* key, const botan_mp_t scalar, const char* curve_name) {
835 return botan_privkey_load_sm2(key, scalar, curve_name);
836}
837
838/* Ed25519 specific operations */
839
840int botan_privkey_load_ed25519(botan_privkey_t* key, const uint8_t privkey[32]) {
841#if defined(BOTAN_HAS_ED25519)
842 if(key == nullptr) {
844 }
845 *key = nullptr;
846 return ffi_guard_thunk(__func__, [=]() -> int {
847 auto ed25519 =
848 std::make_unique<Botan::Ed25519_PrivateKey>(Botan::Ed25519_PrivateKey::from_seed(std::span{privkey, 32}));
849 return ffi_new_object(key, std::move(ed25519));
850 });
851#else
852 BOTAN_UNUSED(key, privkey);
854#endif
855}
856
857int botan_pubkey_load_ed25519(botan_pubkey_t* key, const uint8_t pubkey[32]) {
858#if defined(BOTAN_HAS_ED25519)
859 if(key == nullptr) {
861 }
862 *key = nullptr;
863 return ffi_guard_thunk(__func__, [=]() -> int {
864 const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32);
865 auto ed25519 = std::make_unique<Botan::Ed25519_PublicKey>(pubkey_vec);
866 return ffi_new_object(key, std::move(ed25519));
867 });
868#else
869 BOTAN_UNUSED(key, pubkey);
871#endif
872}
873
875#if defined(BOTAN_HAS_ED25519)
876 return BOTAN_FFI_VISIT(key, [=](const auto& k) {
877 if(auto ed = dynamic_cast<const Botan::Ed25519_PrivateKey*>(&k)) {
878 const auto ed_key = ed->raw_private_key_bits();
879 if(ed_key.size() != 64) {
881 }
882 Botan::copy_mem(output, ed_key.data(), ed_key.size());
883 return BOTAN_FFI_SUCCESS;
884 } else {
886 }
887 });
888#else
889 BOTAN_UNUSED(key, output);
891#endif
892}
893
895#if defined(BOTAN_HAS_ED25519)
896 return BOTAN_FFI_VISIT(key, [=](const auto& k) {
897 if(auto ed = dynamic_cast<const Botan::Ed25519_PublicKey*>(&k)) {
898 const std::vector<uint8_t>& ed_key = ed->get_public_key();
899 if(ed_key.size() != 32) {
901 }
902 Botan::copy_mem(output, ed_key.data(), ed_key.size());
903 return BOTAN_FFI_SUCCESS;
904 } else {
906 }
907 });
908#else
909 BOTAN_UNUSED(key, output);
911#endif
912}
913
914/* Ed448 specific operations */
915
916int botan_privkey_load_ed448(botan_privkey_t* key, const uint8_t privkey[57]) {
917#if defined(BOTAN_HAS_ED448)
918 if(key == nullptr) {
920 }
921 *key = nullptr;
922 return ffi_guard_thunk(__func__, [=]() -> int {
923 auto ed448 = std::make_unique<Botan::Ed448_PrivateKey>(std::span(privkey, 57));
924 return ffi_new_object(key, std::move(ed448));
925 });
926#else
927 BOTAN_UNUSED(key, privkey);
929#endif
930}
931
932int botan_pubkey_load_ed448(botan_pubkey_t* key, const uint8_t pubkey[57]) {
933#if defined(BOTAN_HAS_ED448)
934 if(key == nullptr) {
936 }
937 *key = nullptr;
938 return ffi_guard_thunk(__func__, [=]() -> int {
939 auto ed448 = std::make_unique<Botan::Ed448_PublicKey>(std::span(pubkey, 57));
940 return ffi_new_object(key, std::move(ed448));
941 });
942#else
943 BOTAN_UNUSED(key, pubkey);
945#endif
946}
947
949#if defined(BOTAN_HAS_ED448)
950 return BOTAN_FFI_VISIT(key, [=](const auto& k) {
951 if(auto ed = dynamic_cast<const Botan::Ed448_PrivateKey*>(&k)) {
952 const auto ed_key = ed->raw_private_key_bits();
953 Botan::copy_mem(std::span(output, 57), ed_key);
954 return BOTAN_FFI_SUCCESS;
955 } else {
957 }
958 });
959#else
960 BOTAN_UNUSED(key, output);
962#endif
963}
964
965int botan_pubkey_ed448_get_pubkey(botan_pubkey_t key, uint8_t output[57]) {
966#if defined(BOTAN_HAS_ED448)
967 return BOTAN_FFI_VISIT(key, [=](const auto& k) {
968 if(auto ed = dynamic_cast<const Botan::Ed448_PublicKey*>(&k)) {
969 const auto ed_key = ed->public_key_bits();
970 Botan::copy_mem(std::span(output, 57), ed_key);
971 return BOTAN_FFI_SUCCESS;
972 } else {
974 }
975 });
976#else
977 BOTAN_UNUSED(key, output);
979#endif
980}
981
982/* X25519 specific operations */
983
984int botan_privkey_load_x25519(botan_privkey_t* key, const uint8_t privkey[32]) {
985#if defined(BOTAN_HAS_X25519)
986 if(key == nullptr) {
988 }
989 *key = nullptr;
990 return ffi_guard_thunk(__func__, [=]() -> int {
991 auto x25519 = std::make_unique<Botan::X25519_PrivateKey>(std::span{privkey, 32});
992 return ffi_new_object(key, std::move(x25519));
993 });
994#else
995 BOTAN_UNUSED(key, privkey);
997#endif
998}
999
1000int botan_pubkey_load_x25519(botan_pubkey_t* key, const uint8_t pubkey[32]) {
1001#if defined(BOTAN_HAS_X25519)
1002 if(key == nullptr) {
1004 }
1005 *key = nullptr;
1006 return ffi_guard_thunk(__func__, [=]() -> int {
1007 auto x25519 = std::make_unique<Botan::X25519_PublicKey>(std::span{pubkey, 32});
1008 return ffi_new_object(key, std::move(x25519));
1009 });
1010#else
1011 BOTAN_UNUSED(key, pubkey);
1013#endif
1014}
1015
1017#if defined(BOTAN_HAS_X25519)
1018 return BOTAN_FFI_VISIT(key, [=](const auto& k) {
1019 if(auto x25519 = dynamic_cast<const Botan::X25519_PrivateKey*>(&k)) {
1020 const auto x25519_key = x25519->raw_private_key_bits();
1021 if(x25519_key.size() != 32) {
1023 }
1024 Botan::copy_mem(output, x25519_key.data(), x25519_key.size());
1025 return BOTAN_FFI_SUCCESS;
1026 } else {
1028 }
1029 });
1030#else
1031 BOTAN_UNUSED(key, output);
1033#endif
1034}
1035
1037#if defined(BOTAN_HAS_X25519)
1038 return BOTAN_FFI_VISIT(key, [=](const auto& k) {
1039 if(auto x25519 = dynamic_cast<const Botan::X25519_PublicKey*>(&k)) {
1040 Botan::copy_mem(std::span{output, 32}, x25519->raw_public_key_bits());
1041 return BOTAN_FFI_SUCCESS;
1042 } else {
1044 }
1045 });
1046#else
1047 BOTAN_UNUSED(key, output);
1049#endif
1050}
1051
1052/* X448 specific operations */
1053
1054int botan_privkey_load_x448(botan_privkey_t* key, const uint8_t privkey[56]) {
1055#if defined(BOTAN_HAS_X448)
1056 if(key == nullptr) {
1058 }
1059 *key = nullptr;
1060 return ffi_guard_thunk(__func__, [=]() -> int {
1061 auto x448 = std::make_unique<Botan::X448_PrivateKey>(std::span{privkey, 56});
1062 return ffi_new_object(key, std::move(x448));
1063 });
1064#else
1065 BOTAN_UNUSED(key, privkey);
1067#endif
1068}
1069
1070int botan_pubkey_load_x448(botan_pubkey_t* key, const uint8_t pubkey[56]) {
1071#if defined(BOTAN_HAS_X448)
1072 if(key == nullptr) {
1074 }
1075 *key = nullptr;
1076 return ffi_guard_thunk(__func__, [=]() -> int {
1077 auto x448 = std::make_unique<Botan::X448_PublicKey>(std::span{pubkey, 56});
1078 return ffi_new_object(key, std::move(x448));
1079 });
1080#else
1081 BOTAN_UNUSED(key, pubkey);
1083#endif
1084}
1085
1087#if defined(BOTAN_HAS_X448)
1088 return BOTAN_FFI_VISIT(key, [=](const auto& k) {
1089 if(auto x448 = dynamic_cast<const Botan::X448_PrivateKey*>(&k)) {
1090 const auto x448_key = x448->raw_private_key_bits();
1091 Botan::copy_mem(std::span{output, 56}, x448_key);
1092 return BOTAN_FFI_SUCCESS;
1093 } else {
1095 }
1096 });
1097#else
1098 BOTAN_UNUSED(key, output);
1100#endif
1101}
1102
1103int botan_pubkey_x448_get_pubkey(botan_pubkey_t key, uint8_t output[56]) {
1104#if defined(BOTAN_HAS_X448)
1105 return BOTAN_FFI_VISIT(key, [=](const auto& k) {
1106 if(auto x448 = dynamic_cast<const Botan::X448_PublicKey*>(&k)) {
1107 Botan::copy_mem(std::span{output, 56}, x448->raw_public_key_bits());
1108 return BOTAN_FFI_SUCCESS;
1109 } else {
1111 }
1112 });
1113#else
1114 BOTAN_UNUSED(key, output);
1116#endif
1117}
1118
1119/*
1120* Algorithm specific key operations: Kyber
1121*/
1122
1123int botan_privkey_load_kyber(botan_privkey_t* key, const uint8_t privkey[], size_t key_len) {
1124#if defined(BOTAN_HAS_KYBER)
1125 if(key == nullptr) {
1127 }
1128 *key = nullptr;
1129
1130 const auto mode = [](size_t len) -> std::optional<Botan::KyberMode> {
1131 if(len == 1632) {
1133 } else if(len == 2400) {
1135 } else if(len == 3168) {
1137 } else {
1138 return {};
1139 }
1140 }(key_len);
1141
1142 if(mode.has_value()) {
1143 return ffi_guard_thunk(__func__, [=]() -> int {
1144 auto kyber = std::make_unique<Botan::Kyber_PrivateKey>(std::span{privkey, key_len}, *mode);
1145 return ffi_new_object(key, std::move(kyber));
1146 });
1147 } else {
1149 }
1150#else
1151 BOTAN_UNUSED(key, key_len, privkey);
1153#endif
1154}
1155
1156int botan_pubkey_load_kyber(botan_pubkey_t* key, const uint8_t pubkey[], size_t key_len) {
1157#if defined(BOTAN_HAS_KYBER)
1158 if(key == nullptr) {
1160 }
1161 *key = nullptr;
1162
1163 const auto mode = [](size_t len) -> std::optional<Botan::KyberMode> {
1164 if(len == 800) {
1166 } else if(len == 1184) {
1168 } else if(len == 1568) {
1170 } else {
1171 return {};
1172 }
1173 }(key_len);
1174
1175 if(mode.has_value()) {
1176 auto kyber = std::make_unique<Botan::Kyber_PublicKey>(std::span{pubkey, key_len}, *mode);
1177 return ffi_new_object(key, std::move(kyber));
1178 } else {
1180 }
1181#else
1182 BOTAN_UNUSED(key, pubkey, key_len);
1184#endif
1185}
1186
1188#if defined(BOTAN_HAS_KYBER)
1189 return BOTAN_FFI_VISIT(key, [=](const auto& k) -> int {
1190 if(auto kyber = dynamic_cast<const Botan::Kyber_PrivateKey*>(&k)) {
1191 return invoke_view_callback(view, ctx, kyber->raw_private_key_bits());
1192 } else {
1194 }
1195 });
1196#else
1197 BOTAN_UNUSED(key, ctx, view);
1199#endif
1200}
1201
1203#if defined(BOTAN_HAS_KYBER)
1204 return BOTAN_FFI_VISIT(key, [=](const auto& k) -> int {
1205 if(auto kyber = dynamic_cast<const Botan::Kyber_PublicKey*>(&k)) {
1206 return invoke_view_callback(view, ctx, kyber->public_key_bits());
1207 } else {
1209 }
1210 });
1211#else
1212 BOTAN_UNUSED(key, ctx, view);
1214#endif
1215}
1216
1217/*
1218* Algorithm specific key operations: ML-KEM
1219*/
1220
1221int botan_privkey_load_ml_kem(botan_privkey_t* key, const uint8_t privkey[], size_t key_len, const char* mlkem_mode) {
1222#if defined(BOTAN_HAS_ML_KEM)
1223 if(key == nullptr || privkey == nullptr || mlkem_mode == nullptr) {
1225 }
1226
1227 *key = nullptr;
1228
1229 return ffi_guard_thunk(__func__, [=]() -> int {
1230 auto mode = Botan::ML_KEM_Mode(mlkem_mode);
1231 if(!mode.is_ml_kem()) {
1233 }
1234
1235 auto mlkem_key = std::make_unique<Botan::ML_KEM_PrivateKey>(std::span{privkey, key_len}, mode);
1236 return ffi_new_object(key, std::move(mlkem_key));
1237 });
1238#else
1239 BOTAN_UNUSED(key, key_len, privkey, mlkem_mode);
1241#endif
1242}
1243
1244int botan_pubkey_load_ml_kem(botan_pubkey_t* key, const uint8_t pubkey[], size_t key_len, const char* mlkem_mode) {
1245#if defined(BOTAN_HAS_ML_KEM)
1246 if(key == nullptr || pubkey == nullptr || mlkem_mode == nullptr) {
1248 }
1249
1250 *key = nullptr;
1251
1252 return ffi_guard_thunk(__func__, [=]() -> int {
1253 auto mode = Botan::ML_KEM_Mode(mlkem_mode);
1254 if(!mode.is_ml_kem()) {
1256 }
1257
1258 auto mlkem_key = std::make_unique<Botan::ML_KEM_PublicKey>(std::span{pubkey, key_len}, mode.mode());
1259 return ffi_new_object(key, std::move(mlkem_key));
1260 });
1261#else
1262 BOTAN_UNUSED(key, key_len, pubkey, mlkem_mode);
1264#endif
1265}
1266
1267/*
1268* Algorithm specific key operations: ML-DSA
1269*/
1270
1271int botan_privkey_load_ml_dsa(botan_privkey_t* key, const uint8_t privkey[], size_t key_len, const char* mldsa_mode) {
1272#if defined(BOTAN_HAS_ML_DSA)
1273 if(key == nullptr || privkey == nullptr || mldsa_mode == nullptr) {
1275 }
1276
1277 *key = nullptr;
1278
1279 return ffi_guard_thunk(__func__, [=]() -> int {
1280 auto mode = Botan::ML_DSA_Mode(mldsa_mode);
1281 if(!mode.is_ml_dsa()) {
1283 }
1284
1285 auto mldsa_key = std::make_unique<Botan::ML_DSA_PrivateKey>(std::span{privkey, key_len}, mode);
1286 return ffi_new_object(key, std::move(mldsa_key));
1287 });
1288#else
1289 BOTAN_UNUSED(key, key_len, privkey, mldsa_mode);
1291#endif
1292}
1293
1294int botan_pubkey_load_ml_dsa(botan_pubkey_t* key, const uint8_t pubkey[], size_t key_len, const char* mldsa_mode) {
1295#if defined(BOTAN_HAS_ML_DSA)
1296 if(key == nullptr || pubkey == nullptr || mldsa_mode == nullptr) {
1298 }
1299
1300 *key = nullptr;
1301
1302 return ffi_guard_thunk(__func__, [=]() -> int {
1303 auto mode = Botan::ML_DSA_Mode(mldsa_mode);
1304 if(!mode.is_ml_dsa()) {
1306 }
1307
1308 auto mldsa_key = std::make_unique<Botan::ML_DSA_PublicKey>(std::span{pubkey, key_len}, mode);
1309 return ffi_new_object(key, std::move(mldsa_key));
1310 });
1311#else
1312 BOTAN_UNUSED(key, key_len, pubkey, mldsa_mode);
1314#endif
1315}
1316
1317/*
1318* Algorithm specific key operations: SLH-DSA
1319*/
1320
1321int botan_privkey_load_slh_dsa(botan_privkey_t* key, const uint8_t privkey[], size_t key_len, const char* slhdsa_mode) {
1322#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
1323 if(key == nullptr || privkey == nullptr || slhdsa_mode == nullptr) {
1325 }
1326
1327 *key = nullptr;
1328
1329 return ffi_guard_thunk(__func__, [=]() -> int {
1330 auto mode = Botan::SLH_DSA_Parameters::create(slhdsa_mode);
1331 if(!mode.is_slh_dsa()) {
1333 }
1334
1335 auto slhdsa_key = std::make_unique<Botan::SLH_DSA_PrivateKey>(std::span{privkey, key_len}, mode);
1336 return ffi_new_object(key, std::move(slhdsa_key));
1337 });
1338#else
1339 BOTAN_UNUSED(key, key_len, privkey, slhdsa_mode);
1341#endif
1342}
1343
1344int botan_pubkey_load_slh_dsa(botan_pubkey_t* key, const uint8_t pubkey[], size_t key_len, const char* slhdsa_mode) {
1345#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
1346 if(key == nullptr || pubkey == nullptr || slhdsa_mode == nullptr) {
1348 }
1349
1350 *key = nullptr;
1351
1352 return ffi_guard_thunk(__func__, [=]() -> int {
1353 auto mode = Botan::SLH_DSA_Parameters::create(slhdsa_mode);
1354 if(!mode.is_slh_dsa()) {
1356 }
1357
1358 auto mldsa_key = std::make_unique<Botan::SLH_DSA_PublicKey>(std::span{pubkey, key_len}, mode);
1359 return ffi_new_object(key, std::move(mldsa_key));
1360 });
1361#else
1362 BOTAN_UNUSED(key, key_len, pubkey, slhdsa_mode);
1364#endif
1365}
1366
1367/*
1368* Algorithm specific key operations: FrodoKEM
1369*/
1370
1371int botan_privkey_load_frodokem(botan_privkey_t* key, const uint8_t privkey[], size_t key_len, const char* frodo_mode) {
1372#if defined(BOTAN_HAS_FRODOKEM)
1373 if(key == nullptr || privkey == nullptr || frodo_mode == nullptr) {
1375 }
1376
1377 *key = nullptr;
1378
1379 return ffi_guard_thunk(__func__, [=]() -> int {
1380 const auto mode = Botan::FrodoKEMMode(frodo_mode);
1381 auto frodo_key = std::make_unique<Botan::FrodoKEM_PrivateKey>(std::span{privkey, key_len}, mode);
1382 return ffi_new_object(key, std::move(frodo_key));
1383 });
1384#else
1385 BOTAN_UNUSED(key, privkey, key_len, frodo_mode);
1387#endif
1388}
1389
1390int botan_pubkey_load_frodokem(botan_pubkey_t* key, const uint8_t pubkey[], size_t key_len, const char* frodo_mode) {
1391#if defined(BOTAN_HAS_FRODOKEM)
1392 if(key == nullptr || pubkey == nullptr || frodo_mode == nullptr) {
1394 }
1395
1396 *key = nullptr;
1397
1398 return ffi_guard_thunk(__func__, [=]() -> int {
1399 const auto mode = Botan::FrodoKEMMode(frodo_mode);
1400 auto frodo_key = std::make_unique<Botan::FrodoKEM_PublicKey>(std::span{pubkey, key_len}, mode);
1401 return ffi_new_object(key, std::move(frodo_key));
1402 });
1403#else
1404 BOTAN_UNUSED(key, pubkey, key_len, frodo_mode);
1406#endif
1407}
1408
1409/*
1410* Algorithm specific key operations : Classic McEliece
1411*/
1412
1414 const uint8_t privkey[],
1415 size_t key_len,
1416 const char* cmce_mode) {
1417#if defined(BOTAN_HAS_CLASSICMCELIECE)
1418 if(key == nullptr || privkey == nullptr || cmce_mode == nullptr) {
1420 }
1421
1422 *key = nullptr;
1423
1424 return ffi_guard_thunk(__func__, [=]() -> int {
1425 const auto mode = Botan::Classic_McEliece_Parameter_Set::from_string(cmce_mode);
1426 auto cmce_key = std::make_unique<Botan::Classic_McEliece_PrivateKey>(std::span{privkey, key_len}, mode);
1427 return ffi_new_object(key, std::move(cmce_key));
1428 });
1429#else
1430 BOTAN_UNUSED(key, privkey, key_len, cmce_mode);
1432#endif
1433}
1434
1436 const uint8_t pubkey[],
1437 size_t key_len,
1438 const char* cmce_mode) {
1439#if defined(BOTAN_HAS_CLASSICMCELIECE)
1440 if(key == nullptr || pubkey == nullptr || cmce_mode == nullptr) {
1442 }
1443
1444 *key = nullptr;
1445
1446 return ffi_guard_thunk(__func__, [=]() -> int {
1447 const auto mode = Botan::Classic_McEliece_Parameter_Set::from_string(cmce_mode);
1448 auto cmce_key = std::make_unique<Botan::Classic_McEliece_PublicKey>(std::span{pubkey, key_len}, mode);
1449 return ffi_new_object(key, std::move(cmce_key));
1450 });
1451#else
1452 BOTAN_UNUSED(key, pubkey, key_len, cmce_mode);
1454#endif
1455}
1456
1458#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
1459 return BOTAN_FFI_VISIT(key, [=](const auto& k) -> int {
1460 if(auto ecc = dynamic_cast<const Botan::EC_PublicKey*>(&k)) {
1461 auto pt = ecc->_public_ec_point().serialize_uncompressed();
1462 return invoke_view_callback(view, ctx, pt);
1463 } else {
1465 }
1466 });
1467#else
1468 BOTAN_UNUSED(key, view, ctx);
1470#endif
1471}
1472
1473// NOLINTEND(misc-misplaced-const)
1474
1475int botan_privkey_create_mceliece(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n, size_t t) {
1476 const std::string mce_params = std::to_string(n) + "," + std::to_string(t);
1477 return botan_privkey_create(key_obj, "McEliece", mce_params.c_str(), rng_obj);
1478}
1479
1481 const char* aead,
1482 const uint8_t ct[],
1483 size_t ct_len,
1484 const uint8_t ad[],
1485 size_t ad_len,
1486 uint8_t out[],
1487 size_t* out_len) {
1488 BOTAN_UNUSED(mce_key_obj, aead, ct, ct_len, ad, ad_len, out, out_len);
1490}
1491
1493 botan_rng_t rng_obj,
1494 const char* aead,
1495 const uint8_t pt[],
1496 size_t pt_len,
1497 const uint8_t ad[],
1498 size_t ad_len,
1499 uint8_t out[],
1500 size_t* out_len) {
1501 BOTAN_UNUSED(mce_key_obj, rng_obj, aead, pt, pt_len, ad, ad_len, out, out_len);
1503}
1504}
#define BOTAN_UNUSED
Definition assert.h:144
virtual std::string algo_name() const =0
virtual const BigInt & get_int_field(std::string_view field) const
Definition pk_keys.cpp:18
static BigInt from_bytes(std::span< const uint8_t > bytes)
Definition bigint.cpp:83
static Classic_McEliece_Parameter_Set from_string(std::string_view param_name)
Get the parameter set for a given parameter set name.
static std::optional< EC_AffinePoint > from_bigint_xy(const EC_Group &group, const BigInt &x, const BigInt &y)
Definition ec_apoint.cpp:93
static std::optional< EC_AffinePoint > deserialize(const EC_Group &group, std::span< const uint8_t > bytes)
static EC_Group from_name(std::string_view name)
Definition ec_group.cpp:438
bool used_explicit_encoding() const
Definition ec_group.h:262
static bool supports_named_group(std::string_view name)
Definition ec_group.cpp:404
const EC_Group & domain() const
Definition ecc_key.cpp:64
const EC_AffinePoint & _public_ec_point() const
Definition ecc_key.cpp:76
static Ed25519_PrivateKey from_seed(std::span< const uint8_t > seed)
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:308
A private key for the X448 key agreement scheme according to RFC 7748.
Definition x448.h:69
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:1650
struct botan_privkey_struct * botan_privkey_t
Definition ffi.h:1417
int(* botan_view_bin_fn)(botan_view_ctx view_ctx, const uint8_t *data, size_t len)
Definition ffi.h:163
int botan_privkey_create(botan_privkey_t *key, const char *algo_name, const char *algo_params, botan_rng_t rng)
Definition ffi_pkey.cpp:30
#define BOTAN_PRIVKEY_EXPORT_FLAG_PEM
Definition ffi.h:1511
struct botan_mp_struct * botan_mp_t
Definition ffi.h:1003
void * botan_view_ctx
Definition ffi.h:154
struct botan_rng_struct * botan_rng_t
Definition ffi.h:291
#define BOTAN_PRIVKEY_EXPORT_FLAG_DER
Definition ffi.h:1510
@ BOTAN_FFI_ERROR_NOT_IMPLEMENTED
Definition ffi.h:140
@ BOTAN_FFI_ERROR_UNKNOWN_ERROR
Definition ffi.h:148
@ BOTAN_FFI_ERROR_BAD_FLAG
Definition ffi.h:132
@ BOTAN_FFI_ERROR_NULL_POINTER
Definition ffi.h:133
@ BOTAN_FFI_SUCCESS
Definition ffi.h:116
@ BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE
Definition ffi.h:124
@ BOTAN_FFI_ERROR_BAD_PARAMETER
Definition ffi.h:134
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_pubkey_load_classic_mceliece(botan_pubkey_t *key, const uint8_t pubkey[], size_t key_len, const char *cmce_mode)
int botan_privkey_load_classic_mceliece(botan_privkey_t *key, const uint8_t privkey[], size_t key_len, const char *cmce_mode)
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_pubkey_load_ecdh_sec1(botan_pubkey_t *key, const uint8_t sec1[], size_t sec1_len, const char *curve_name)
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_pubkey_load_rsa_pkcs1(botan_pubkey_t *key, const uint8_t bits[], size_t len)
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_load_sm2_sec1(botan_pubkey_t *key, const uint8_t sec1[], size_t sec1_len, const char *curve_name)
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_load_ecdsa_sec1(botan_pubkey_t *key, const uint8_t sec1[], size_t sec1_len, const char *curve_name)
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:158
std::string encode(const uint8_t der[], size_t length, std::string_view label, size_t width)
Definition pem.cpp:39
int invoke_view_callback(botan_view_bin_fn view, botan_view_ctx ctx, std::span< const uint8_t > buf)
Definition ffi_util.h:187
T & safe_get(botan_struct< T, M > *p)
Definition ffi_util.h:79
BOTAN_FFI_ERROR ffi_new_object(T *obj, Args &&... args)
Definition ffi_util.h:178
int ffi_guard_thunk(const char *func_name, T thunk)
Definition ffi_util.h:95
int write_vec_output(uint8_t out[], size_t *out_len, std::span< const uint8_t > buf)
Definition ffi_util.h:261
int write_str_output(char out[], size_t *out_len, const std::string &str)
Definition ffi_util.h:265
DilithiumMode ML_DSA_Mode
Definition ml_dsa.h:21
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:144
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_AffinePoint &pubkey)
Definition sm2.cpp:82