Botan  2.11.0
Crypto and TLS for C++11
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 
70 namespace {
71 
72 #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
73 
74 // These are always called within an existing try/catch block
75 
76 template<class ECPrivateKey_t>
77 int 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 
90 template<class ECPublicKey_t>
91 int 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 
107 Botan::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 
172 Botan::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 
224 extern "C" {
225 
226 using namespace Botan_FFI;
227 
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 
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 
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 
294  return ffi_guard_thunk(__func__, [=]() -> int {
295  Botan::AlgorithmIdentifier alg_id("RSA", Botan::AlgorithmIdentifier::USE_NULL_PARAM);
296  *key = new botan_privkey_struct(new Botan::RSA_PrivateKey(alg_id, src));
297  return BOTAN_FFI_SUCCESS;
298  });
299 #else
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
379 #endif
380  }
381 
382 /* DSA specific operations */
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 {
397  Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
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 
468 int 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
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
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)
530  ? Botan::DL_Group::Strong
531  : Botan::DL_Group::Prime_Subgroup;
532 
533  return ffi_guard_thunk(__func__, [=]() -> int {
534  Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
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 
580 int 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 
620 int 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
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
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 =
697  Botan::HashFunction::create_or_throw(hash_algo);
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
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
746 #endif
747  }
748 
750  const botan_mp_t public_x,
751  const botan_mp_t public_y,
752  const char* curve_name)
753  {
755  }
756 
758  const botan_mp_t scalar,
759  const char* curve_name)
760  {
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
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
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
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
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
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
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
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
925 #endif
926  }
927 
928 int 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 
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);
965  Botan::RandomNumberGenerator& rng = safe_get(rng_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 
973  return write_vec_output(out, out_len, ct);
974 #else
976 #endif
977  });
978  }
979 
980 }
int ffi_guard_thunk(const char *func_name, std::function< int()> thunk)
Definition: ffi.cpp:86
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
const uint8_t size_t ad_len
Definition: ffi.h:498
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_privkey_rsa_get_q(botan_mp_t q, botan_privkey_t key)
int botan_pubkey_x25519_get_pubkey(botan_pubkey_t key, uint8_t output[32])
int botan_privkey_create(botan_privkey_t *key_obj, const char *algo_name, const char *algo_params, botan_rng_t rng_obj)
Definition: ffi_pkey.cpp:26
int botan_pubkey_dsa_get_p(botan_mp_t p, botan_pubkey_t key)
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)
uint32_t uint8_t output[]
Definition: ffi.h:512
#define BOTAN_PRIVKEY_EXPORT_FLAG_PEM
Definition: ffi.h:1024
botan_rng_t rng
Definition: ffi.h:864
int botan_privkey_load_sm2_enc(botan_privkey_t *key, const botan_mp_t scalar, const char *curve_name)
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_pubkey_load_rsa(botan_pubkey_t *key, botan_mp_t n, botan_mp_t e)
int botan_privkey_ed25519_get_privkey(botan_privkey_t key, uint8_t output[64])
int botan_privkey_create_elgamal(botan_privkey_t *key, botan_rng_t rng_obj, size_t pbits, size_t qbits)
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_privkey_load_dh(botan_privkey_t *key, botan_mp_t p, botan_mp_t g, botan_mp_t x)
int botan_privkey_rsa_get_d(botan_mp_t d, botan_privkey_t key)
botan_rng_t size_t n_bits
Definition: ffi.h:949
botan_rng_t const char const uint8_t size_t const uint8_t size_t uint8_t ct[]
Definition: ffi.h:1464
botan_rng_t const char const uint8_t pt[]
Definition: ffi.h:1464
int botan_pubkey_load_ed25519(botan_pubkey_t *key, const uint8_t pubkey[32])
int botan_privkey_dsa_get_x(botan_mp_t x, botan_privkey_t key)
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_pubkey_load_sm2(botan_pubkey_t *key, const botan_mp_t public_x, const botan_mp_t public_y, const char *curve_name)
const char * hash
Definition: ffi.h:924
int botan_privkey_load_rsa(botan_privkey_t *key, botan_mp_t rsa_p, botan_mp_t rsa_q, botan_mp_t rsa_e)
const uint8_t pubkey[32]
Definition: ffi.h:1257
int botan_pubkey_load_dh(botan_pubkey_t *key, botan_mp_t p, botan_mp_t g, botan_mp_t y)
const uint8_t privkey[32]
Definition: ffi.h:1254
int write_vec_output(uint8_t out[], size_t *out_len, const std::vector< uint8_t, Alloc > &buf)
Definition: ffi_util.h:146
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:213
const botan_mp_t x
Definition: ffi.h:823
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
int botan_privkey_create_ecdh(botan_privkey_t *key_obj, botan_rng_t rng_obj, const char *param_str)
int botan_pubkey_rsa_get_n(botan_mp_t n, botan_pubkey_t key)
int botan_pubkey_dsa_get_q(botan_mp_t q, botan_pubkey_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_rsa_get_privkey(botan_privkey_t rsa_key, uint8_t out[], size_t *out_len, uint32_t flags)
int write_str_output(uint8_t out[], size_t *out_len, const std::string &str)
Definition: ffi_util.h:151
const uint8_t * y
Definition: ffi.h:139
botan_rng_t size_t size_t t
Definition: ffi.h:955
int botan_pubkey_rsa_get_e(botan_mp_t e, botan_pubkey_t key)
int botan_privkey_load_ecdsa(botan_privkey_t *key, const botan_mp_t scalar, const char *curve_name)
botan_rng_t const char const uint8_t size_t pt_len
Definition: ffi.h:1464
size_t char * out
Definition: ffi.h:162
int botan_privkey_create_ecdsa(botan_privkey_t *key_obj, botan_rng_t rng_obj, const char *param_str)
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43
botan_rng_t size_t n
Definition: ffi.h:955
struct botan_mp_struct * botan_mp_t
Definition: ffi.h:728
size_t const char const uint8_t size_t size_t size_t size_t p
Definition: ffi.h:628
std::vector< uint8_t > sm2_compute_za(HashFunction &hash, const std::string &user_id, const EC_Group &domain, const PointGFp &pubkey)
Definition: sm2.cpp:51
int botan_pubkey_get_field(botan_mp_t output, botan_pubkey_t key, const char *field_name_cstr)
botan_pubkey_t const char * field_name
Definition: ffi.h:1105
int botan_privkey_load_rsa_pkcs1(botan_privkey_t *key, const uint8_t bits[], size_t len)
#define BOTAN_PRIVKEY_EXPORT_FLAG_DER
Definition: ffi.h:1023
const botan_mp_t const botan_mp_t public_y
Definition: ffi.h:1319
size_t uint8_t size_t * out_len
Definition: ffi.h:171
const uint8_t * ad
Definition: ffi.h:498
botan_rng_t const char * aead
Definition: ffi.h:1464
botan_mp_t botan_mp_t botan_mp_t g
Definition: ffi.h:1152
int botan_privkey_get_field(botan_mp_t output, botan_privkey_t key, const char *field_name_cstr)
BigInt const BigInt & d
Definition: bigint.h:1093
int botan_privkey_x25519_get_privkey(botan_privkey_t key, uint8_t output[32])
const botan_mp_t scalar
Definition: ffi.h:1325
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_privkey_rsa_get_n(botan_mp_t n, botan_privkey_t key)
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:122
int botan_privkey_load_elgamal(botan_privkey_t *key, botan_mp_t p, botan_mp_t g, botan_mp_t x)
int botan_privkey_load_x25519(botan_privkey_t *key, const uint8_t privkey[32])
struct botan_privkey_struct * botan_privkey_t
Definition: ffi.h:929
#define BOTAN_UNUSED(...)
Definition: assert.h:142
int botan_privkey_rsa_get_e(botan_mp_t e, botan_privkey_t key)
const uint8_t * key
Definition: ffi.h:362
AlgorithmIdentifier hash_algo
Definition: x509_obj.cpp:23
size_t bits
Definition: ffi.h:219
T & safe_get(botan_struct< T, M > *p)
Definition: ffi_util.h:61
int botan_privkey_load_sm2(botan_privkey_t *key, const botan_mp_t scalar, const char *curve_name)
int botan_pubkey_load_x25519(botan_pubkey_t *key, const uint8_t pubkey[32])
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)
size_t char uint32_t flags
Definition: ffi.h:162
int botan_privkey_load_ecdh(botan_privkey_t *key, const botan_mp_t scalar, const char *curve_name)
botan_rng_t const char const uint8_t size_t const uint8_t size_t uint8_t size_t * ct_len
Definition: ffi.h:1464
botan_mp_t botan_mp_t botan_mp_t e
Definition: ffi.h:1116
const uint8_t size_t len
Definition: ffi.h:139
botan_rng_t size_t size_t qbits
Definition: ffi.h:979
int botan_pubkey_load_elgamal(botan_pubkey_t *key, botan_mp_t p, botan_mp_t g, botan_mp_t y)
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
struct botan_pubkey_struct * botan_pubkey_t
Definition: ffi.h:1076
botan_privkey_t rsa_key
Definition: ffi.h:1125
class BOTAN_PUBLIC_API(2, 0) Curve25519_PublicKey class BOTAN_PUBLIC_API(2, 0) Curve25519_PrivateKey final typedef Curve25519_PublicKey X25519_PublicKey
Definition: curve25519.h:58
RandomNumberGenerator const std::string AlgorithmIdentifier & alg_id
Definition: x509_ca.h:230
botan_rng_t const char * params
Definition: ffi.h:951
int botan_privkey_load_ed25519(botan_privkey_t *key, const uint8_t privkey[32])
Curve25519_PrivateKey X25519_PrivateKey
Definition: curve25519.h:103
#define BOTAN_FFI_DO(T, obj, param, block)
Definition: ffi_util.h:92
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)
botan_mp_t botan_mp_t q
Definition: ffi.h:1116
int botan_pubkey_dsa_get_g(botan_mp_t g, 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)
const botan_mp_t public_x
Definition: ffi.h:1319
int botan_pubkey_dsa_get_y(botan_mp_t y, botan_pubkey_t key)
struct botan_rng_struct * botan_rng_t
Definition: ffi.h:188
const botan_mp_t const botan_mp_t const char * curve_name
Definition: ffi.h:1319
int botan_privkey_create_dh(botan_privkey_t *key_obj, botan_rng_t rng_obj, const char *param_str)
int botan_pubkey_ed25519_get_pubkey(botan_pubkey_t key, uint8_t output[32])
int botan_privkey_create_rsa(botan_privkey_t *key_obj, botan_rng_t rng_obj, size_t n_bits)
botan_rng_t size_t pbits
Definition: ffi.h:979