Botan 2.19.2
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#include <botan/hash.h>
11#include <botan/pem.h>
12#include <botan/internal/ffi_util.h>
13#include <botan/internal/ffi_pkey.h>
14#include <botan/internal/ffi_rng.h>
15#include <botan/internal/ffi_mp.h>
16
17#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
18 #include <botan/ecc_key.h>
19#endif
20
21#if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY)
22 #include <botan/dl_algo.h>
23#endif
24
25#if defined(BOTAN_HAS_RSA)
26 #include <botan/rsa.h>
27#endif
28
29#if defined(BOTAN_HAS_ELGAMAL)
30 #include <botan/elgamal.h>
31#endif
32
33#if defined(BOTAN_HAS_DSA)
34 #include <botan/dsa.h>
35#endif
36
37#if defined(BOTAN_HAS_ECDSA)
38 #include <botan/ecdsa.h>
39#endif
40
41#if defined(BOTAN_HAS_SM2)
42 #include <botan/sm2.h>
43#endif
44
45#if defined(BOTAN_HAS_ECDH)
46 #include <botan/ecdh.h>
47#endif
48
49#if defined(BOTAN_HAS_CURVE_25519)
50 #include <botan/curve25519.h>
51#endif
52
53#if defined(BOTAN_HAS_ED25519)
54 #include <botan/ed25519.h>
55#endif
56
57#if defined(BOTAN_HAS_MCELIECE)
58 #include <botan/mceliece.h>
59#endif
60
61#if defined(BOTAN_HAS_MCEIES)
62 #include <botan/mceies.h>
63#endif
64
65#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
66 #include <botan/dh.h>
67#endif
68
69
70namespace {
71
72#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
73
74// These are always called within an existing try/catch block
75
76template<class ECPrivateKey_t>
77int privkey_load_ec(std::unique_ptr<ECPrivateKey_t>& key,
78 const Botan::BigInt& scalar,
79 const char* curve_name)
80 {
81 if(curve_name == nullptr)
83
84 Botan::Null_RNG null_rng;
85 Botan::EC_Group grp(curve_name);
86 key.reset(new ECPrivateKey_t(null_rng, grp, scalar));
87 return BOTAN_FFI_SUCCESS;
88 }
89
90template<class ECPublicKey_t>
91int pubkey_load_ec(std::unique_ptr<ECPublicKey_t>& key,
92 const Botan::BigInt& public_x,
93 const Botan::BigInt& public_y,
94 const char* curve_name)
95 {
96 if(curve_name == nullptr)
98
99 Botan::EC_Group grp(curve_name);
100 Botan::PointGFp uncompressed_point = grp.point(public_x, public_y);
101 key.reset(new ECPublicKey_t(grp, uncompressed_point));
102 return BOTAN_FFI_SUCCESS;
103 }
104
105#endif
106
107Botan::BigInt pubkey_get_field(const Botan::Public_Key& key,
108 const std::string& field)
109 {
110 // Maybe this should be `return key.get_integer_field(field_name)`?
111
112#if defined(BOTAN_HAS_RSA)
113 if(const Botan::RSA_PublicKey* rsa = dynamic_cast<const Botan::RSA_PublicKey*>(&key))
114 {
115 if(field == "n")
116 return rsa->get_n();
117 else if(field == "e")
118 return rsa->get_e();
119 else
121 }
122#endif
123
124#if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY)
125 // Handles DSA, ElGamal, etc
126 if(const Botan::DL_Scheme_PublicKey* dl = dynamic_cast<const Botan::DL_Scheme_PublicKey*>(&key))
127 {
128 if(field == "p")
129 return dl->group_p();
130 else if(field == "q")
131 return dl->group_q();
132 else if(field == "g")
133 return dl->group_g();
134 else if(field == "y")
135 return dl->get_y();
136 else
138 }
139#endif
140
141#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
142 if(const Botan::EC_PublicKey* ecc = dynamic_cast<const Botan::EC_PublicKey*>(&key))
143 {
144 if(field == "public_x")
145 return ecc->public_point().get_affine_x();
146 else if(field == "public_y")
147 return ecc->public_point().get_affine_y();
148 else if(field == "base_x")
149 return ecc->domain().get_g_x();
150 else if(field == "base_y")
151 return ecc->domain().get_g_y();
152 else if(field == "p")
153 return ecc->domain().get_p();
154 else if(field == "a")
155 return ecc->domain().get_a();
156 else if(field == "b")
157 return ecc->domain().get_b();
158 else if(field == "cofactor")
159 return ecc->domain().get_cofactor();
160 else if(field == "order")
161 return ecc->domain().get_order();
162 else
164 }
165#endif
166
167 // Some other algorithm type not supported by this function
168 throw Botan_FFI::FFI_Error("Field getter not implemented for this algorithm type",
170 }
171
172Botan::BigInt privkey_get_field(const Botan::Private_Key& key,
173 const std::string& field)
174 {
175 //return key.get_integer_field(field);
176
177#if defined(BOTAN_HAS_RSA)
178
179 if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<const Botan::RSA_PrivateKey*>(&key))
180 {
181 if(field == "p")
182 return rsa->get_p();
183 else if(field == "q")
184 return rsa->get_q();
185 else if(field == "d")
186 return rsa->get_d();
187 else if(field == "c")
188 return rsa->get_c();
189 else if(field == "d1")
190 return rsa->get_d1();
191 else if(field == "d2")
192 return rsa->get_d2();
193 else
194 return pubkey_get_field(key, field);
195 }
196#endif
197
198#if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY)
199 // Handles DSA, ElGamal, etc
200 if(const Botan::DL_Scheme_PrivateKey* dl = dynamic_cast<const Botan::DL_Scheme_PrivateKey*>(&key))
201 {
202 if(field == "x")
203 return dl->get_x();
204 else
205 return pubkey_get_field(key, field);
206 }
207#endif
208
209#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
210 if(const Botan::EC_PrivateKey* ecc = dynamic_cast<const Botan::EC_PrivateKey*>(&key))
211 {
212 if(field == "x")
213 return ecc->private_value();
214 else
215 return pubkey_get_field(key, field);
216 }
217#endif
218
219 return pubkey_get_field(key, field);
220 }
221
222}
223
224extern "C" {
225
226using namespace Botan_FFI;
227
229 botan_pubkey_t key,
230 const char* field_name_cstr)
231 {
232 if(field_name_cstr == nullptr)
234
235 const std::string field_name(field_name_cstr);
236
237 return BOTAN_FFI_DO(Botan::Public_Key, key, k, {
238 safe_get(output) = pubkey_get_field(k, field_name);
239 });
240 }
241
243 botan_privkey_t key,
244 const char* field_name_cstr)
245 {
246 if(field_name_cstr == nullptr)
248
249 const std::string field_name(field_name_cstr);
250
251 return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
252 safe_get(output) = privkey_get_field(k, field_name);
253 });
254 }
255
256/* RSA specific operations */
257
258int botan_privkey_create_rsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n_bits)
259 {
260 if(n_bits < 1024 || n_bits > 16*1024)
262
263 std::string n_str = std::to_string(n_bits);
264
265 return botan_privkey_create(key_obj, "RSA", n_str.c_str(), rng_obj);
266 }
267
269 botan_mp_t rsa_p, botan_mp_t rsa_q, botan_mp_t rsa_e)
270 {
271#if defined(BOTAN_HAS_RSA)
272 *key = nullptr;
273
274 return ffi_guard_thunk(__func__, [=]() -> int {
275 *key = new botan_privkey_struct(new Botan::RSA_PrivateKey(safe_get(rsa_p),
276 safe_get(rsa_q),
277 safe_get(rsa_e)));
278 return BOTAN_FFI_SUCCESS;
279 });
280#else
281 BOTAN_UNUSED(key, rsa_p, rsa_q, rsa_e);
283#endif
284 }
285
287 const uint8_t bits[],
288 size_t len)
289 {
290#if defined(BOTAN_HAS_RSA)
291 *key = nullptr;
292
293 Botan::secure_vector<uint8_t> src(bits, bits + len);
294 return ffi_guard_thunk(__func__, [=]() -> int {
296 *key = new botan_privkey_struct(new Botan::RSA_PrivateKey(alg_id, src));
297 return BOTAN_FFI_SUCCESS;
298 });
299#else
300 BOTAN_UNUSED(key, bits, len);
302#endif
303 }
304
307 {
308#if defined(BOTAN_HAS_RSA)
309 *key = nullptr;
310 return ffi_guard_thunk(__func__, [=]() -> int {
311 *key = new botan_pubkey_struct(new Botan::RSA_PublicKey(safe_get(n), safe_get(e)));
312 return BOTAN_FFI_SUCCESS;
313 });
314#else
315 BOTAN_UNUSED(key, n, e);
317#endif
318 }
319
321 {
322 return botan_privkey_get_field(p, key, "p");
323 }
324
326 {
327 return botan_privkey_get_field(q, key, "q");
328 }
329
331 {
332 return botan_privkey_get_field(n, key, "n");
333 }
334
336 {
337 return botan_privkey_get_field(e, key, "e");
338 }
339
341 {
342 return botan_privkey_get_field(d, key, "d");
343 }
344
346 {
347 return botan_pubkey_get_field(e, key, "e");
348 }
349
351 {
352 return botan_pubkey_get_field(n, key, "n");
353 }
354
356 uint8_t out[], size_t* out_len,
357 uint32_t flags)
358 {
359#if defined(BOTAN_HAS_RSA)
360 return BOTAN_FFI_DO(Botan::Private_Key, rsa_key, k, {
361 if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<const Botan::RSA_PrivateKey*>(&k))
362 {
364 return write_vec_output(out, out_len, rsa->private_key_bits());
366 return write_str_output(out, out_len, Botan::PEM_Code::encode(rsa->private_key_bits(),
367 "RSA PRIVATE KEY"));
368 else
370 }
371 else
372 {
374 }
375 });
376#else
377 BOTAN_UNUSED(rsa_key, out, out_len);
379#endif
380 }
381
382/* DSA specific operations */
383int botan_privkey_create_dsa(botan_privkey_t* key, botan_rng_t rng_obj, size_t pbits, size_t qbits)
384 {
385#if defined(BOTAN_HAS_DSA)
386
387 if ((rng_obj == nullptr) || (key == nullptr))
389
390 if ((pbits % 64) || (qbits % 8) ||
391 (pbits < 1024) || (pbits > 3072) ||
392 (qbits < 160) || (qbits > 256)) {
394 }
395
396 return ffi_guard_thunk(__func__, [=]() -> int {
398 Botan::DL_Group group(rng, Botan::DL_Group::Prime_Subgroup, pbits, qbits);
399 *key = new botan_privkey_struct(new Botan::DSA_PrivateKey(rng, group));
400 return BOTAN_FFI_SUCCESS;
401 });
402#else
403 BOTAN_UNUSED(key, rng_obj, pbits, qbits);
405#endif
406 }
407
410 {
411#if defined(BOTAN_HAS_DSA)
412 *key = nullptr;
413
414 return ffi_guard_thunk(__func__, [=]() -> int {
415 Botan::Null_RNG null_rng;
416 Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
417 *key = new botan_privkey_struct(new Botan::DSA_PrivateKey(null_rng, group, safe_get(x)));
418 return BOTAN_FFI_SUCCESS;
419 });
420#else
421 BOTAN_UNUSED(key, p, q, g, x);
423#endif
424 }
425
428 {
429#if defined(BOTAN_HAS_DSA)
430 *key = nullptr;
431
432 return ffi_guard_thunk(__func__, [=]() -> int {
433 Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
434 *key = new botan_pubkey_struct(new Botan::DSA_PublicKey(group, safe_get(y)));
435 return BOTAN_FFI_SUCCESS;
436 });
437#else
438 BOTAN_UNUSED(key, p, q, g, y);
440#endif
441 }
442
444 {
445 return botan_privkey_get_field(x, key, "x");
446 }
447
449 {
450 return botan_pubkey_get_field(p, key, "p");
451 }
452
454 {
455 return botan_pubkey_get_field(q, key, "q");
456 }
457
459 {
460 return botan_pubkey_get_field(g, key, "g");
461 }
462
464 {
465 return botan_pubkey_get_field(y, key, "y");
466 }
467
468int botan_privkey_create_ecdsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
469 {
470 return botan_privkey_create(key_obj, "ECDSA", param_str, rng_obj);
471 }
472
473/* ECDSA specific operations */
474
476 const botan_mp_t public_x,
477 const botan_mp_t public_y,
478 const char* curve_name)
479 {
480#if defined(BOTAN_HAS_ECDSA)
481 return ffi_guard_thunk(__func__, [=]() -> int {
482 std::unique_ptr<Botan::ECDSA_PublicKey> p_key;
483
484 int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
485 if(rc == BOTAN_FFI_SUCCESS)
486 *key = new botan_pubkey_struct(p_key.release());
487
488 return rc;
489 });
490#else
491 BOTAN_UNUSED(key, public_x, public_y, curve_name);
493#endif
494 }
495
497 const botan_mp_t scalar,
498 const char* curve_name)
499 {
500#if defined(BOTAN_HAS_ECDSA)
501 return ffi_guard_thunk(__func__, [=]() -> int {
502 std::unique_ptr<Botan::ECDSA_PrivateKey> p_key;
503 int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
504 if(rc == BOTAN_FFI_SUCCESS)
505 *key = new botan_privkey_struct(p_key.release());
506 return rc;
507 });
508#else
509 BOTAN_UNUSED(key, scalar, curve_name);
511#endif
512 }
513
514/* ElGamal specific operations */
516 botan_rng_t rng_obj,
517 size_t pbits,
518 size_t qbits)
519 {
520#if defined(BOTAN_HAS_ELGAMAL)
521
522 if ((rng_obj == nullptr) || (key == nullptr))
524
525 if ((pbits < 1024) || (qbits<160)) {
527 }
528
529 Botan::DL_Group::PrimeType prime_type = ((pbits-1) == qbits)
532
533 return ffi_guard_thunk(__func__, [=]() -> int {
535 Botan::DL_Group group(rng, prime_type, pbits, qbits);
536 *key = new botan_privkey_struct(new Botan::ElGamal_PrivateKey(rng, group));
537 return BOTAN_FFI_SUCCESS;
538 });
539#else
540 BOTAN_UNUSED(key, rng_obj, pbits);
542#endif
543 }
544
547 {
548#if defined(BOTAN_HAS_ELGAMAL)
549 *key = nullptr;
550 return ffi_guard_thunk(__func__, [=]() -> int {
551 Botan::DL_Group group(safe_get(p), safe_get(g));
552 *key = new botan_pubkey_struct(new Botan::ElGamal_PublicKey(group, safe_get(y)));
553 return BOTAN_FFI_SUCCESS;
554 });
555#else
556 BOTAN_UNUSED(key, p, g, y);
558#endif
559 }
560
563 {
564#if defined(BOTAN_HAS_ELGAMAL)
565 *key = nullptr;
566 return ffi_guard_thunk(__func__, [=]() -> int {
567 Botan::Null_RNG null_rng;
568 Botan::DL_Group group(safe_get(p), safe_get(g));
569 *key = new botan_privkey_struct(new Botan::ElGamal_PrivateKey(null_rng, group, safe_get(x)));
570 return BOTAN_FFI_SUCCESS;
571 });
572#else
573 BOTAN_UNUSED(key, p, g, x);
575#endif
576 }
577
578/* Diffie Hellman specific operations */
579
580int botan_privkey_create_dh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
581 {
582 return botan_privkey_create(key_obj, "DH", param_str, rng_obj);
583 }
584
587 {
588#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
589 *key = nullptr;
590 return ffi_guard_thunk(__func__, [=]() -> int {
591 Botan::Null_RNG null_rng;
592 Botan::DL_Group group(safe_get(p), safe_get(g));
593 *key = new botan_privkey_struct(new Botan::DH_PrivateKey(null_rng, group, safe_get(x)));
594 return BOTAN_FFI_SUCCESS;
595 });
596#else
597 BOTAN_UNUSED(key, p, g, x);
599#endif
600 }
601
604 {
605#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
606 *key = nullptr;
607 return ffi_guard_thunk(__func__, [=]() -> int {
608 Botan::DL_Group group(safe_get(p), safe_get(g));
609 *key = new botan_pubkey_struct(new Botan::DH_PublicKey(group, safe_get(y)));
610 return BOTAN_FFI_SUCCESS;
611 });
612#else
613 BOTAN_UNUSED(key, p, g, y);
615#endif
616 }
617
618/* ECDH + x25519 specific operations */
619
620int botan_privkey_create_ecdh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
621 {
622 if(param_str == nullptr)
624
625 const std::string params(param_str);
626
627 if(params == "curve25519")
628 return botan_privkey_create(key_obj, "Curve25519", "", rng_obj);
629
630 return botan_privkey_create(key_obj, "ECDH", param_str, rng_obj);
631 }
632
634 const botan_mp_t public_x,
635 const botan_mp_t public_y,
636 const char* curve_name)
637 {
638#if defined(BOTAN_HAS_ECDH)
639 return ffi_guard_thunk(__func__, [=]() -> int {
640 std::unique_ptr<Botan::ECDH_PublicKey> p_key;
641 int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
642
643 if(rc == BOTAN_FFI_SUCCESS)
644 *key = new botan_pubkey_struct(p_key.release());
645 return rc;
646 });
647#else
648 BOTAN_UNUSED(key, public_x, public_y, curve_name);
650#endif
651 }
652
654 const botan_mp_t scalar,
655 const char* curve_name)
656 {
657#if defined(BOTAN_HAS_ECDH)
658 return ffi_guard_thunk(__func__, [=]() -> int {
659 std::unique_ptr<Botan::ECDH_PrivateKey> p_key;
660 int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
661 if(rc == BOTAN_FFI_SUCCESS)
662 *key = new botan_privkey_struct(p_key.release());
663 return rc;
664 });
665#else
666 BOTAN_UNUSED(key, scalar, curve_name);
668#endif
669 }
670
671/* SM2 specific operations */
672
674 size_t* out_len,
675 const char* ident,
676 const char* hash_algo,
677 const botan_pubkey_t key)
678 {
679 if(out == nullptr || out_len == nullptr)
681 if(ident == nullptr || hash_algo == nullptr || key == nullptr)
683
684#if defined(BOTAN_HAS_SM2)
685 return ffi_guard_thunk(__func__, [=]() -> int {
686 const Botan::Public_Key& pub_key = safe_get(key);
687 const Botan::EC_PublicKey* ec_key = dynamic_cast<const Botan::EC_PublicKey*>(&pub_key);
688
689 if(ec_key == nullptr)
691
692 if(ec_key->algo_name() != "SM2")
694
695 const std::string ident_str(ident);
696 std::unique_ptr<Botan::HashFunction> hash =
698
699 const std::vector<uint8_t> za =
700 Botan::sm2_compute_za(*hash, ident_str, ec_key->domain(), ec_key->public_point());
701
702 return write_vec_output(out, out_len, za);
703 });
704#else
706#endif
707 }
708
710 const botan_mp_t public_x,
711 const botan_mp_t public_y,
712 const char* curve_name)
713 {
714#if defined(BOTAN_HAS_SM2)
715 return ffi_guard_thunk(__func__, [=]() -> int {
716 std::unique_ptr<Botan::SM2_PublicKey> p_key;
717 if(!pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name))
718 {
719 *key = new botan_pubkey_struct(p_key.release());
720 return BOTAN_FFI_SUCCESS;
721 }
723 });
724#else
725 BOTAN_UNUSED(key, public_x, public_y, curve_name);
727#endif
728 }
729
731 const botan_mp_t scalar,
732 const char* curve_name)
733 {
734#if defined(BOTAN_HAS_SM2)
735 return ffi_guard_thunk(__func__, [=]() -> int {
736 std::unique_ptr<Botan::SM2_PrivateKey> p_key;
737 int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
738
739 if(rc == BOTAN_FFI_SUCCESS)
740 *key = new botan_privkey_struct(p_key.release());
741 return rc;
742 });
743#else
744 BOTAN_UNUSED(key, scalar, curve_name);
746#endif
747 }
748
750 const botan_mp_t public_x,
751 const botan_mp_t public_y,
752 const char* curve_name)
753 {
754 return botan_pubkey_load_sm2(key, public_x, public_y, curve_name);
755 }
756
758 const botan_mp_t scalar,
759 const char* curve_name)
760 {
761 return botan_privkey_load_sm2(key, scalar, curve_name);
762 }
763
764/* Ed25519 specific operations */
765
767 const uint8_t privkey[32])
768 {
769#if defined(BOTAN_HAS_ED25519)
770 *key = nullptr;
771 return ffi_guard_thunk(__func__, [=]() -> int {
772 const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 32);
773 *key = new botan_privkey_struct(new Botan::Ed25519_PrivateKey(privkey_vec));
774 return BOTAN_FFI_SUCCESS;
775 });
776#else
777 BOTAN_UNUSED(key, privkey);
779#endif
780 }
781
783 const uint8_t pubkey[32])
784 {
785#if defined(BOTAN_HAS_ED25519)
786 *key = nullptr;
787 return ffi_guard_thunk(__func__, [=]() -> int {
788 const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32);
789 *key = new botan_pubkey_struct(new Botan::Ed25519_PublicKey(pubkey_vec));
790 return BOTAN_FFI_SUCCESS;
791 });
792#else
793 BOTAN_UNUSED(key, pubkey);
795#endif
796 }
797
799 uint8_t output[64])
800 {
801#if defined(BOTAN_HAS_ED25519)
802 return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
803 if(Botan::Ed25519_PrivateKey* ed = dynamic_cast<Botan::Ed25519_PrivateKey*>(&k))
804 {
805 const Botan::secure_vector<uint8_t>& ed_key = ed->get_private_key();
806 if(ed_key.size() != 64)
808 Botan::copy_mem(output, ed_key.data(), ed_key.size());
809 return BOTAN_FFI_SUCCESS;
810 }
811 else
812 {
814 }
815 });
816#else
817 BOTAN_UNUSED(key, output);
819#endif
820 }
821
823 uint8_t output[32])
824 {
825#if defined(BOTAN_HAS_ED25519)
826 return BOTAN_FFI_DO(Botan::Public_Key, key, k, {
827 if(Botan::Ed25519_PublicKey* ed = dynamic_cast<Botan::Ed25519_PublicKey*>(&k))
828 {
829 const std::vector<uint8_t>& ed_key = ed->get_public_key();
830 if(ed_key.size() != 32)
832 Botan::copy_mem(output, ed_key.data(), ed_key.size());
833 return BOTAN_FFI_SUCCESS;
834 }
835 else
836 {
838 }
839 });
840#else
841 BOTAN_UNUSED(key, output);
843#endif
844 }
845
846/* X25519 specific operations */
847
849 const uint8_t privkey[32])
850 {
851#if defined(BOTAN_HAS_X25519)
852 *key = nullptr;
853 return ffi_guard_thunk(__func__, [=]() -> int {
854 const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 32);
855 *key = new botan_privkey_struct(new Botan::X25519_PrivateKey(privkey_vec));
856 return BOTAN_FFI_SUCCESS;
857 });
858#else
859 BOTAN_UNUSED(key, privkey);
861#endif
862 }
863
865 const uint8_t pubkey[32])
866 {
867#if defined(BOTAN_HAS_X25519)
868 *key = nullptr;
869 return ffi_guard_thunk(__func__, [=]() -> int {
870 const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32);
871 *key = new botan_pubkey_struct(new Botan::X25519_PublicKey(pubkey_vec));
872 return BOTAN_FFI_SUCCESS;
873 });
874#else
875 BOTAN_UNUSED(key, pubkey);
877#endif
878 }
879
881 uint8_t output[32])
882 {
883#if defined(BOTAN_HAS_X25519)
884 return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
885 if(Botan::X25519_PrivateKey* x25519 = dynamic_cast<Botan::X25519_PrivateKey*>(&k))
886 {
887 const Botan::secure_vector<uint8_t>& x25519_key = x25519->get_x();
888 if(x25519_key.size() != 32)
890 Botan::copy_mem(output, x25519_key.data(), x25519_key.size());
891 return BOTAN_FFI_SUCCESS;
892 }
893 else
894 {
896 }
897 });
898#else
899 BOTAN_UNUSED(key, output);
901#endif
902 }
903
905 uint8_t output[32])
906 {
907#if defined(BOTAN_HAS_X25519)
908 return BOTAN_FFI_DO(Botan::Public_Key, key, k, {
909 if(Botan::X25519_PublicKey* x25519 = dynamic_cast<Botan::X25519_PublicKey*>(&k))
910 {
911 const std::vector<uint8_t>& x25519_key = x25519->public_value();
912 if(x25519_key.size() != 32)
914 Botan::copy_mem(output, x25519_key.data(), x25519_key.size());
915 return BOTAN_FFI_SUCCESS;
916 }
917 else
918 {
920 }
921 });
922#else
923 BOTAN_UNUSED(key, output);
925#endif
926 }
927
928int botan_privkey_create_mceliece(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n, size_t t)
929 {
930 const std::string mce_params = std::to_string(n) + "," + std::to_string(t);
931 return botan_privkey_create(key_obj, "McEliece", mce_params.c_str(), rng_obj);
932 }
933
935 const char* aead,
936 const uint8_t ct[], size_t ct_len,
937 const uint8_t ad[], size_t ad_len,
938 uint8_t out[], size_t* out_len)
939 {
940 return ffi_guard_thunk(__func__, [=]() -> int {
941 Botan::Private_Key& key = safe_get(mce_key_obj);
942
943#if defined(BOTAN_HAS_MCELIECE) && defined(BOTAN_HAS_MCEIES)
944 Botan::McEliece_PrivateKey* mce = dynamic_cast<Botan::McEliece_PrivateKey*>(&key);
945 if(!mce)
947
948 const Botan::secure_vector<uint8_t> pt = mceies_decrypt(*mce, ct, ct_len, ad, ad_len, aead);
949 return write_vec_output(out, out_len, pt);
950#else
952#endif
953 });
954 }
955
957 botan_rng_t rng_obj,
958 const char* aead,
959 const uint8_t pt[], size_t pt_len,
960 const uint8_t ad[], size_t ad_len,
961 uint8_t out[], size_t* out_len)
962 {
963 return ffi_guard_thunk(__func__, [=]() -> int {
964 Botan::Public_Key& key = safe_get(mce_key_obj);
966
967#if defined(BOTAN_HAS_MCELIECE) && defined(BOTAN_HAS_MCEIES)
968 Botan::McEliece_PublicKey* mce = dynamic_cast<Botan::McEliece_PublicKey*>(&key);
969 if(!mce)
971
972 Botan::secure_vector<uint8_t> ct = mceies_encrypt(*mce, pt, pt_len, ad, ad_len, rng, aead);
973 return write_vec_output(out, out_len, ct);
974#else
976#endif
977 });
978 }
979
980}
#define BOTAN_UNUSED(...)
Definition: assert.h:142
const EC_Group & domain() const
Definition: ecc_key.h:72
const PointGFp & public_point() const
Definition: ecc_key.h:57
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:329
virtual std::string algo_name() const =0
struct botan_pubkey_struct * botan_pubkey_t
Definition: ffi.h:1113
struct botan_privkey_struct * botan_privkey_t
Definition: ffi.h:966
int botan_privkey_create(botan_privkey_t *key, const char *algo_name, const char *algo_params, botan_rng_t rng)
Definition: ffi_pkey.cpp:26
#define BOTAN_PRIVKEY_EXPORT_FLAG_PEM
Definition: ffi.h:1061
struct botan_mp_struct * botan_mp_t
Definition: ffi.h:765
struct botan_rng_struct * botan_rng_t
Definition: ffi.h:190
#define BOTAN_PRIVKEY_EXPORT_FLAG_DER
Definition: ffi.h:1060
@ BOTAN_FFI_ERROR_NOT_IMPLEMENTED
Definition: ffi.h:83
@ BOTAN_FFI_ERROR_UNKNOWN_ERROR
Definition: ffi.h:90
@ BOTAN_FFI_ERROR_BAD_FLAG
Definition: ffi.h:76
@ BOTAN_FFI_ERROR_NULL_POINTER
Definition: ffi.h:77
@ BOTAN_FFI_SUCCESS
Definition: ffi.h:63
@ BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE
Definition: ffi.h:69
@ BOTAN_FFI_ERROR_BAD_PARAMETER
Definition: ffi.h:78
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_pubkey_get_field(botan_mp_t output, botan_pubkey_t key, const char *field_name_cstr)
int botan_privkey_load_ecdh(botan_privkey_t *key, const botan_mp_t scalar, const char *curve_name)
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_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_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_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_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_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_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_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_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_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_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_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)
#define BOTAN_FFI_DO(T, obj, param, block)
Definition: ffi_util.h:92
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:213
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43
Flags flags(Flag flags)
Definition: p11.h:860
int ffi_guard_thunk(const char *func_name, std::function< int()> thunk)
Definition: ffi.cpp:89
T & safe_get(botan_struct< T, M > *p)
Definition: ffi_util.h:61
int write_str_output(uint8_t out[], size_t *out_len, const std::string &str)
Definition: ffi_util.h:160
int write_vec_output(uint8_t out[], size_t *out_len, const std::vector< uint8_t, Alloc > &buf)
Definition: ffi_util.h:155
secure_vector< uint8_t > mceies_encrypt(const McEliece_PublicKey &pubkey, const uint8_t pt[], size_t pt_len, const uint8_t ad[], size_t ad_len, RandomNumberGenerator &rng, const std::string &algo)
Definition: mceies.cpp:35
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:133
std::vector< uint8_t > sm2_compute_za(HashFunction &hash, const std::string &user_id, const EC_Group &domain, const PointGFp &pubkey)
Definition: sm2.cpp:52
secure_vector< uint8_t > mceies_decrypt(const McEliece_PrivateKey &privkey, const uint8_t ct[], size_t ct_len, const uint8_t ad[], size_t ad_len, const std::string &algo)
Definition: mceies.cpp:70
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
MechanismType hash
AlgorithmIdentifier hash_algo
Definition: x509_obj.cpp:22