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 
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 
258 int 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 
306  botan_mp_t n, botan_mp_t e)
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 */
383 int 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 {
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
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 {
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
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 
673 int botan_pubkey_sm2_compute_za(uint8_t out[],
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 
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 
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);
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 
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 }
int ffi_guard_thunk(const char *func_name, std::function< int()> thunk)
Definition: ffi.cpp:86
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_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)
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:359
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_rsa_get_p(botan_mp_t p, botan_privkey_t key)
#define BOTAN_PRIVKEY_EXPORT_FLAG_PEM
Definition: ffi.h:1024
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)
const PointGFp & public_point() const
Definition: ecc_key.h:57
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)
int botan_privkey_load_rsa(botan_privkey_t *key, botan_mp_t rsa_p, botan_mp_t rsa_q, botan_mp_t rsa_e)
Flags flags(Flag flags)
Definition: p11.h:858
int botan_pubkey_load_dh(botan_pubkey_t *key, botan_mp_t p, botan_mp_t g, botan_mp_t y)
virtual std::string algo_name() const =0
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 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
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
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)
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
struct botan_mp_struct * botan_mp_t
Definition: ffi.h:728
const EC_Group & domain() const
Definition: ecc_key.h:72
int botan_pubkey_get_field(botan_mp_t output, botan_pubkey_t key, const char *field_name_cstr)
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
int botan_privkey_get_field(botan_mp_t output, botan_privkey_t key, const char *field_name_cstr)
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
int botan_privkey_x25519_get_privkey(botan_privkey_t key, uint8_t output[32])
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)
AlgorithmIdentifier hash_algo
Definition: x509_obj.cpp:23
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
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)
int botan_privkey_load_ecdh(botan_privkey_t *key, const botan_mp_t scalar, const char *curve_name)
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
int botan_privkey_load_ed25519(botan_privkey_t *key, const uint8_t privkey[32])
#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)
int botan_pubkey_dsa_get_g(botan_mp_t g, botan_pubkey_t key)
MechanismType hash
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_dsa_get_y(botan_mp_t y, botan_pubkey_t key)
struct botan_rng_struct * botan_rng_t
Definition: ffi.h:188
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)