Botan 3.0.0-alpha0
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_DIFFIE_HELLMAN)
62 #include <botan/dh.h>
63#endif
64
65
66namespace {
67
68#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
69
70// These are always called within an existing try/catch block
71
72template<class ECPrivateKey_t>
73int privkey_load_ec(std::unique_ptr<ECPrivateKey_t>& key,
74 const Botan::BigInt& scalar,
75 const char* curve_name)
76 {
77 if(curve_name == nullptr)
79
80 Botan::Null_RNG null_rng;
81 Botan::EC_Group grp(curve_name);
82 key.reset(new ECPrivateKey_t(null_rng, grp, scalar));
83 return BOTAN_FFI_SUCCESS;
84 }
85
86template<class ECPublicKey_t>
87int pubkey_load_ec(std::unique_ptr<ECPublicKey_t>& key,
88 const Botan::BigInt& public_x,
89 const Botan::BigInt& public_y,
90 const char* curve_name)
91 {
92 if(curve_name == nullptr)
94
95 Botan::EC_Group grp(curve_name);
96 Botan::PointGFp uncompressed_point = grp.point(public_x, public_y);
97 key.reset(new ECPublicKey_t(grp, uncompressed_point));
98 return BOTAN_FFI_SUCCESS;
99 }
100
101#endif
102
103Botan::BigInt pubkey_get_field(const Botan::Public_Key& key,
104 const std::string& field)
105 {
106 // Maybe this should be `return key.get_integer_field(field_name)`?
107
108#if defined(BOTAN_HAS_RSA)
109 if(const Botan::RSA_PublicKey* rsa = dynamic_cast<const Botan::RSA_PublicKey*>(&key))
110 {
111 if(field == "n")
112 return rsa->get_n();
113 else if(field == "e")
114 return rsa->get_e();
115 else
117 }
118#endif
119
120#if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY)
121 // Handles DSA, ElGamal, etc
122 if(const Botan::DL_Scheme_PublicKey* dl = dynamic_cast<const Botan::DL_Scheme_PublicKey*>(&key))
123 {
124 if(field == "p")
125 return dl->group_p();
126 else if(field == "q")
127 return dl->group_q();
128 else if(field == "g")
129 return dl->group_g();
130 else if(field == "y")
131 return dl->get_y();
132 else
134 }
135#endif
136
137#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
138 if(const Botan::EC_PublicKey* ecc = dynamic_cast<const Botan::EC_PublicKey*>(&key))
139 {
140 if(field == "public_x")
141 return ecc->public_point().get_affine_x();
142 else if(field == "public_y")
143 return ecc->public_point().get_affine_y();
144 else if(field == "base_x")
145 return ecc->domain().get_g_x();
146 else if(field == "base_y")
147 return ecc->domain().get_g_y();
148 else if(field == "p")
149 return ecc->domain().get_p();
150 else if(field == "a")
151 return ecc->domain().get_a();
152 else if(field == "b")
153 return ecc->domain().get_b();
154 else if(field == "cofactor")
155 return ecc->domain().get_cofactor();
156 else if(field == "order")
157 return ecc->domain().get_order();
158 else
160 }
161#endif
162
163 // Some other algorithm type not supported by this function
164 throw Botan_FFI::FFI_Error("Field getter not implemented for this algorithm type",
166 }
167
168Botan::BigInt privkey_get_field(const Botan::Private_Key& key,
169 const std::string& field)
170 {
171 //return key.get_integer_field(field);
172
173#if defined(BOTAN_HAS_RSA)
174
175 if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<const Botan::RSA_PrivateKey*>(&key))
176 {
177 if(field == "p")
178 return rsa->get_p();
179 else if(field == "q")
180 return rsa->get_q();
181 else if(field == "d")
182 return rsa->get_d();
183 else if(field == "c")
184 return rsa->get_c();
185 else if(field == "d1")
186 return rsa->get_d1();
187 else if(field == "d2")
188 return rsa->get_d2();
189 else
190 return pubkey_get_field(key, field);
191 }
192#endif
193
194#if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY)
195 // Handles DSA, ElGamal, etc
196 if(const Botan::DL_Scheme_PrivateKey* dl = dynamic_cast<const Botan::DL_Scheme_PrivateKey*>(&key))
197 {
198 if(field == "x")
199 return dl->get_x();
200 else
201 return pubkey_get_field(key, field);
202 }
203#endif
204
205#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
206 if(const Botan::EC_PrivateKey* ecc = dynamic_cast<const Botan::EC_PrivateKey*>(&key))
207 {
208 if(field == "x")
209 return ecc->private_value();
210 else
211 return pubkey_get_field(key, field);
212 }
213#endif
214
215 return pubkey_get_field(key, field);
216 }
217
218}
219
220extern "C" {
221
222using namespace Botan_FFI;
223
225 botan_pubkey_t key,
226 const char* field_name_cstr)
227 {
228 if(field_name_cstr == nullptr)
230
231 const std::string field_name(field_name_cstr);
232
233 return BOTAN_FFI_DO(Botan::Public_Key, key, k, {
234 safe_get(output) = pubkey_get_field(k, field_name);
235 });
236 }
237
239 botan_privkey_t key,
240 const char* field_name_cstr)
241 {
242 if(field_name_cstr == nullptr)
244
245 const std::string field_name(field_name_cstr);
246
247 return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
248 safe_get(output) = privkey_get_field(k, field_name);
249 });
250 }
251
252/* RSA specific operations */
253
254int botan_privkey_create_rsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n_bits)
255 {
256 if(n_bits < 1024 || n_bits > 16*1024)
258
259 std::string n_str = std::to_string(n_bits);
260
261 return botan_privkey_create(key_obj, "RSA", n_str.c_str(), rng_obj);
262 }
263
265 botan_mp_t rsa_p, botan_mp_t rsa_q, botan_mp_t rsa_e)
266 {
267#if defined(BOTAN_HAS_RSA)
268 *key = nullptr;
269
270 return ffi_guard_thunk(__func__, [=]() -> int {
271
272 auto rsa = std::make_unique<Botan::RSA_PrivateKey>(safe_get(rsa_p),
273 safe_get(rsa_q),
274 safe_get(rsa_e));
275 *key = new botan_privkey_struct(std::move(rsa));
276 return BOTAN_FFI_SUCCESS;
277 });
278#else
279 BOTAN_UNUSED(key, rsa_p, rsa_q, rsa_e);
281#endif
282 }
283
285 const uint8_t bits[],
286 size_t len)
287 {
288#if defined(BOTAN_HAS_RSA)
289 *key = nullptr;
290
291 Botan::secure_vector<uint8_t> src(bits, bits + len);
292 return ffi_guard_thunk(__func__, [=]() -> int {
294 auto rsa = std::make_unique<Botan::RSA_PrivateKey>(alg_id, src);
295 *key = new botan_privkey_struct(std::move(rsa));
296 return BOTAN_FFI_SUCCESS;
297 });
298#else
299 BOTAN_UNUSED(key, bits, len);
301#endif
302 }
303
306 {
307#if defined(BOTAN_HAS_RSA)
308 *key = nullptr;
309 return ffi_guard_thunk(__func__, [=]() -> int {
310 auto rsa = std::make_unique<Botan::RSA_PublicKey>(safe_get(n), safe_get(e));
311 *key = new botan_pubkey_struct(std::move(rsa));
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 auto dsa = std::make_unique<Botan::DSA_PrivateKey>(rng, group);
400 *key = new botan_privkey_struct(std::move(dsa));
401 return BOTAN_FFI_SUCCESS;
402 });
403#else
404 BOTAN_UNUSED(key, rng_obj, pbits, qbits);
406#endif
407 }
408
411 {
412#if defined(BOTAN_HAS_DSA)
413 *key = nullptr;
414
415 return ffi_guard_thunk(__func__, [=]() -> int {
416 Botan::Null_RNG null_rng;
417 Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
418 auto dsa = std::make_unique<Botan::DSA_PrivateKey>(null_rng, group, safe_get(x));
419 *key = new botan_privkey_struct(std::move(dsa));
420 return BOTAN_FFI_SUCCESS;
421 });
422#else
423 BOTAN_UNUSED(key, p, q, g, x);
425#endif
426 }
427
430 {
431#if defined(BOTAN_HAS_DSA)
432 *key = nullptr;
433
434 return ffi_guard_thunk(__func__, [=]() -> int {
435 Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
436 auto dsa = std::make_unique<Botan::DSA_PublicKey>(group, safe_get(y));
437 *key = new botan_pubkey_struct(std::move(dsa));
438 return BOTAN_FFI_SUCCESS;
439 });
440#else
441 BOTAN_UNUSED(key, p, q, g, y);
443#endif
444 }
445
447 {
448 return botan_privkey_get_field(x, key, "x");
449 }
450
452 {
453 return botan_pubkey_get_field(p, key, "p");
454 }
455
457 {
458 return botan_pubkey_get_field(q, key, "q");
459 }
460
462 {
463 return botan_pubkey_get_field(g, key, "g");
464 }
465
467 {
468 return botan_pubkey_get_field(y, key, "y");
469 }
470
471int botan_privkey_create_ecdsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
472 {
473 return botan_privkey_create(key_obj, "ECDSA", param_str, rng_obj);
474 }
475
476/* ECDSA specific operations */
477
479 const botan_mp_t public_x,
480 const botan_mp_t public_y,
481 const char* curve_name)
482 {
483#if defined(BOTAN_HAS_ECDSA)
484 return ffi_guard_thunk(__func__, [=]() -> int {
485 std::unique_ptr<Botan::ECDSA_PublicKey> p_key;
486
487 int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
488 if(rc == BOTAN_FFI_SUCCESS)
489 *key = new botan_pubkey_struct(std::move(p_key));
490
491 return rc;
492 });
493#else
494 BOTAN_UNUSED(key, public_x, public_y, curve_name);
496#endif
497 }
498
500 const botan_mp_t scalar,
501 const char* curve_name)
502 {
503#if defined(BOTAN_HAS_ECDSA)
504 return ffi_guard_thunk(__func__, [=]() -> int {
505 std::unique_ptr<Botan::ECDSA_PrivateKey> p_key;
506 int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
507 if(rc == BOTAN_FFI_SUCCESS)
508 *key = new botan_privkey_struct(std::move(p_key));
509 return rc;
510 });
511#else
512 BOTAN_UNUSED(key, scalar, curve_name);
514#endif
515 }
516
517/* ElGamal specific operations */
519 botan_rng_t rng_obj,
520 size_t pbits,
521 size_t qbits)
522 {
523#if defined(BOTAN_HAS_ELGAMAL)
524
525 if ((rng_obj == nullptr) || (key == nullptr))
527
528 if ((pbits < 1024) || (qbits<160)) {
530 }
531
532 Botan::DL_Group::PrimeType prime_type = ((pbits-1) == qbits)
535
536 return ffi_guard_thunk(__func__, [=]() -> int {
538 Botan::DL_Group group(rng, prime_type, pbits, qbits);
539 auto elg = std::make_unique<Botan::ElGamal_PrivateKey>(rng, group);
540 *key = new botan_privkey_struct(std::move(elg));
541 return BOTAN_FFI_SUCCESS;
542 });
543#else
544 BOTAN_UNUSED(key, rng_obj, pbits);
546#endif
547 }
548
551 {
552#if defined(BOTAN_HAS_ELGAMAL)
553 *key = nullptr;
554 return ffi_guard_thunk(__func__, [=]() -> int {
555 Botan::DL_Group group(safe_get(p), safe_get(g));
556 auto elg = std::make_unique<Botan::ElGamal_PublicKey>(group, safe_get(y));
557 *key = new botan_pubkey_struct(std::move(elg));
558 return BOTAN_FFI_SUCCESS;
559 });
560#else
561 BOTAN_UNUSED(key, p, g, y);
563#endif
564 }
565
568 {
569#if defined(BOTAN_HAS_ELGAMAL)
570 *key = nullptr;
571 return ffi_guard_thunk(__func__, [=]() -> int {
572 Botan::Null_RNG null_rng;
573 Botan::DL_Group group(safe_get(p), safe_get(g));
574 auto elg = std::make_unique<Botan::ElGamal_PrivateKey>(null_rng, group, safe_get(x));
575 *key = new botan_privkey_struct(std::move(elg));
576 return BOTAN_FFI_SUCCESS;
577 });
578#else
579 BOTAN_UNUSED(key, p, g, x);
581#endif
582 }
583
584/* Diffie Hellman specific operations */
585
586int botan_privkey_create_dh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
587 {
588 return botan_privkey_create(key_obj, "DH", param_str, rng_obj);
589 }
590
593 {
594#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
595 *key = nullptr;
596 return ffi_guard_thunk(__func__, [=]() -> int {
597 Botan::Null_RNG null_rng;
598 Botan::DL_Group group(safe_get(p), safe_get(g));
599 auto dh = std::make_unique<Botan::DH_PrivateKey>(null_rng, group, safe_get(x));
600 *key = new botan_privkey_struct(std::move(dh));
601 return BOTAN_FFI_SUCCESS;
602 });
603#else
604 BOTAN_UNUSED(key, p, g, x);
606#endif
607 }
608
611 {
612#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
613 *key = nullptr;
614 return ffi_guard_thunk(__func__, [=]() -> int {
615 Botan::DL_Group group(safe_get(p), safe_get(g));
616 auto dh = std::make_unique<Botan::DH_PublicKey>(group, safe_get(y));
617 *key = new botan_pubkey_struct(std::move(dh));
618 return BOTAN_FFI_SUCCESS;
619 });
620#else
621 BOTAN_UNUSED(key, p, g, y);
623#endif
624 }
625
626/* ECDH + x25519 specific operations */
627
628int botan_privkey_create_ecdh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
629 {
630 if(param_str == nullptr)
632
633 const std::string params(param_str);
634
635 if(params == "curve25519")
636 return botan_privkey_create(key_obj, "Curve25519", "", rng_obj);
637
638 return botan_privkey_create(key_obj, "ECDH", param_str, rng_obj);
639 }
640
642 const botan_mp_t public_x,
643 const botan_mp_t public_y,
644 const char* curve_name)
645 {
646#if defined(BOTAN_HAS_ECDH)
647 return ffi_guard_thunk(__func__, [=]() -> int {
648 std::unique_ptr<Botan::ECDH_PublicKey> p_key;
649 int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
650
651 if(rc == BOTAN_FFI_SUCCESS)
652 *key = new botan_pubkey_struct(std::move(p_key));
653 return rc;
654 });
655#else
656 BOTAN_UNUSED(key, public_x, public_y, curve_name);
658#endif
659 }
660
662 const botan_mp_t scalar,
663 const char* curve_name)
664 {
665#if defined(BOTAN_HAS_ECDH)
666 return ffi_guard_thunk(__func__, [=]() -> int {
667 std::unique_ptr<Botan::ECDH_PrivateKey> p_key;
668 int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
669 if(rc == BOTAN_FFI_SUCCESS)
670 *key = new botan_privkey_struct(std::move(p_key));
671 return rc;
672 });
673#else
674 BOTAN_UNUSED(key, scalar, curve_name);
676#endif
677 }
678
679/* SM2 specific operations */
680
682 size_t* out_len,
683 const char* ident,
684 const char* hash_algo,
685 const botan_pubkey_t key)
686 {
687 if(out == nullptr || out_len == nullptr)
689 if(ident == nullptr || hash_algo == nullptr || key == nullptr)
691
692#if defined(BOTAN_HAS_SM2)
693 return ffi_guard_thunk(__func__, [=]() -> int {
694 const Botan::Public_Key& pub_key = safe_get(key);
695 const Botan::EC_PublicKey* ec_key = dynamic_cast<const Botan::EC_PublicKey*>(&pub_key);
696
697 if(ec_key == nullptr)
699
700 if(ec_key->algo_name() != "SM2")
702
703 const std::string ident_str(ident);
704 std::unique_ptr<Botan::HashFunction> hash =
706
707 const std::vector<uint8_t> za =
708 Botan::sm2_compute_za(*hash, ident_str, ec_key->domain(), ec_key->public_point());
709
710 return write_vec_output(out, out_len, za);
711 });
712#else
714#endif
715 }
716
718 const botan_mp_t public_x,
719 const botan_mp_t public_y,
720 const char* curve_name)
721 {
722#if defined(BOTAN_HAS_SM2)
723 return ffi_guard_thunk(__func__, [=]() -> int {
724 std::unique_ptr<Botan::SM2_PublicKey> p_key;
725 if(!pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name))
726 {
727 *key = new botan_pubkey_struct(std::move(p_key));
728 return BOTAN_FFI_SUCCESS;
729 }
731 });
732#else
733 BOTAN_UNUSED(key, public_x, public_y, curve_name);
735#endif
736 }
737
739 const botan_mp_t scalar,
740 const char* curve_name)
741 {
742#if defined(BOTAN_HAS_SM2)
743 return ffi_guard_thunk(__func__, [=]() -> int {
744 std::unique_ptr<Botan::SM2_PrivateKey> p_key;
745 int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
746
747 if(rc == BOTAN_FFI_SUCCESS)
748 *key = new botan_privkey_struct(std::move(p_key));
749 return rc;
750 });
751#else
752 BOTAN_UNUSED(key, scalar, curve_name);
754#endif
755 }
756
758 const botan_mp_t public_x,
759 const botan_mp_t public_y,
760 const char* curve_name)
761 {
762 return botan_pubkey_load_sm2(key, public_x, public_y, curve_name);
763 }
764
766 const botan_mp_t scalar,
767 const char* curve_name)
768 {
769 return botan_privkey_load_sm2(key, scalar, curve_name);
770 }
771
772/* Ed25519 specific operations */
773
775 const uint8_t privkey[32])
776 {
777#if defined(BOTAN_HAS_ED25519)
778 *key = nullptr;
779 return ffi_guard_thunk(__func__, [=]() -> int {
780 const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 32);
781 auto ed25519 = std::make_unique<Botan::Ed25519_PrivateKey>(privkey_vec);
782 *key = new botan_privkey_struct(std::move(ed25519));
783 return BOTAN_FFI_SUCCESS;
784 });
785#else
786 BOTAN_UNUSED(key, privkey);
788#endif
789 }
790
792 const uint8_t pubkey[32])
793 {
794#if defined(BOTAN_HAS_ED25519)
795 *key = nullptr;
796 return ffi_guard_thunk(__func__, [=]() -> int {
797 const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32);
798 auto ed25519 = std::make_unique<Botan::Ed25519_PublicKey>(pubkey_vec);
799 *key = new botan_pubkey_struct(std::move(ed25519));
800 return BOTAN_FFI_SUCCESS;
801 });
802#else
803 BOTAN_UNUSED(key, pubkey);
805#endif
806 }
807
809 uint8_t output[64])
810 {
811#if defined(BOTAN_HAS_ED25519)
812 return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
813 if(Botan::Ed25519_PrivateKey* ed = dynamic_cast<Botan::Ed25519_PrivateKey*>(&k))
814 {
815 const Botan::secure_vector<uint8_t>& ed_key = ed->get_private_key();
816 if(ed_key.size() != 64)
818 Botan::copy_mem(output, ed_key.data(), ed_key.size());
819 return BOTAN_FFI_SUCCESS;
820 }
821 else
822 {
824 }
825 });
826#else
827 BOTAN_UNUSED(key, output);
829#endif
830 }
831
833 uint8_t output[32])
834 {
835#if defined(BOTAN_HAS_ED25519)
836 return BOTAN_FFI_DO(Botan::Public_Key, key, k, {
837 if(Botan::Ed25519_PublicKey* ed = dynamic_cast<Botan::Ed25519_PublicKey*>(&k))
838 {
839 const std::vector<uint8_t>& ed_key = ed->get_public_key();
840 if(ed_key.size() != 32)
842 Botan::copy_mem(output, ed_key.data(), ed_key.size());
843 return BOTAN_FFI_SUCCESS;
844 }
845 else
846 {
848 }
849 });
850#else
851 BOTAN_UNUSED(key, output);
853#endif
854 }
855
856/* X25519 specific operations */
857
859 const uint8_t privkey[32])
860 {
861#if defined(BOTAN_HAS_X25519)
862 *key = nullptr;
863 return ffi_guard_thunk(__func__, [=]() -> int {
864 const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 32);
865 auto x25519 = std::make_unique<Botan::X25519_PrivateKey>(privkey_vec);
866 *key = new botan_privkey_struct(std::move(x25519));
867 return BOTAN_FFI_SUCCESS;
868 });
869#else
870 BOTAN_UNUSED(key, privkey);
872#endif
873 }
874
876 const uint8_t pubkey[32])
877 {
878#if defined(BOTAN_HAS_X25519)
879 *key = nullptr;
880 return ffi_guard_thunk(__func__, [=]() -> int {
881 const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32);
882 auto x25519 = std::make_unique<Botan::X25519_PublicKey>(pubkey_vec);
883 *key = new botan_pubkey_struct(std::move(x25519));
884 return BOTAN_FFI_SUCCESS;
885 });
886#else
887 BOTAN_UNUSED(key, pubkey);
889#endif
890 }
891
893 uint8_t output[32])
894 {
895#if defined(BOTAN_HAS_X25519)
896 return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
897 if(Botan::X25519_PrivateKey* x25519 = dynamic_cast<Botan::X25519_PrivateKey*>(&k))
898 {
899 const Botan::secure_vector<uint8_t>& x25519_key = x25519->get_x();
900 if(x25519_key.size() != 32)
902 Botan::copy_mem(output, x25519_key.data(), x25519_key.size());
903 return BOTAN_FFI_SUCCESS;
904 }
905 else
906 {
908 }
909 });
910#else
911 BOTAN_UNUSED(key, output);
913#endif
914 }
915
917 uint8_t output[32])
918 {
919#if defined(BOTAN_HAS_X25519)
920 return BOTAN_FFI_DO(Botan::Public_Key, key, k, {
921 if(Botan::X25519_PublicKey* x25519 = dynamic_cast<Botan::X25519_PublicKey*>(&k))
922 {
923 const std::vector<uint8_t>& x25519_key = x25519->public_value();
924 if(x25519_key.size() != 32)
926 Botan::copy_mem(output, x25519_key.data(), x25519_key.size());
927 return BOTAN_FFI_SUCCESS;
928 }
929 else
930 {
932 }
933 });
934#else
935 BOTAN_UNUSED(key, output);
937#endif
938 }
939
940int botan_privkey_create_mceliece(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n, size_t t)
941 {
942 const std::string mce_params = std::to_string(n) + "," + std::to_string(t);
943 return botan_privkey_create(key_obj, "McEliece", mce_params.c_str(), rng_obj);
944 }
945
947 const char* aead,
948 const uint8_t ct[], size_t ct_len,
949 const uint8_t ad[], size_t ad_len,
950 uint8_t out[], size_t* out_len)
951 {
952 BOTAN_UNUSED(mce_key_obj, aead, ct, ct_len, ad, ad_len, out, out_len);
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 BOTAN_UNUSED(mce_key_obj, rng_obj, aead, pt, pt_len, ad, ad_len, out, out_len);
965 }
966
967}
#define BOTAN_UNUSED(...)
Definition: assert.h:141
const EC_Group & domain() const
Definition: ecc_key.h:56
const PointGFp & public_point() const
Definition: ecc_key.h:41
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:312
virtual std::string algo_name() const =0
struct botan_pubkey_struct * botan_pubkey_t
Definition: ffi.h:1123
struct botan_privkey_struct * botan_privkey_t
Definition: ffi.h:976
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:1071
struct botan_mp_struct * botan_mp_t
Definition: ffi.h:775
struct botan_rng_struct * botan_rng_t
Definition: ffi.h:200
#define BOTAN_PRIVKEY_EXPORT_FLAG_DER
Definition: ffi.h:1070
@ 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:96
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:209
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:41
Flags flags(Flag flags)
Definition: p11.h:860
T & safe_get(botan_struct< T, M > *p)
Definition: ffi_util.h:65
int write_str_output(uint8_t out[], size_t *out_len, const std::string &str)
Definition: ffi_util.h:157
int ffi_guard_thunk(const char *func_name, const std::function< int()> &thunk)
Definition: ffi.cpp:92
int write_vec_output(uint8_t out[], size_t *out_len, const std::vector< uint8_t, Alloc > &buf)
Definition: ffi_util.h:152
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:126
std::vector< uint8_t > sm2_compute_za(HashFunction &hash, const std::string &user_id, const EC_Group &domain, const PointGFp &pubkey)
Definition: sm2.cpp:57
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
MechanismType hash
AlgorithmIdentifier hash_algo
Definition: x509_obj.cpp:22