Botan  2.6.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 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/ffi.h>
9 #include <botan/hash.h>
10 #include <botan/internal/ffi_util.h>
11 #include <botan/internal/ffi_pkey.h>
12 #include <botan/internal/ffi_rng.h>
13 #include <botan/internal/ffi_mp.h>
14 
15 #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
16  #include <botan/ecc_key.h>
17 #endif
18 
19 #if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY)
20  #include <botan/dl_algo.h>
21 #endif
22 
23 #if defined(BOTAN_HAS_RSA)
24  #include <botan/rsa.h>
25 #endif
26 
27 #if defined(BOTAN_HAS_ELGAMAL)
28  #include <botan/elgamal.h>
29 #endif
30 
31 #if defined(BOTAN_HAS_DSA)
32  #include <botan/dsa.h>
33 #endif
34 
35 #if defined(BOTAN_HAS_ECDSA)
36  #include <botan/ecdsa.h>
37 #endif
38 
39 #if defined(BOTAN_HAS_SM2)
40  #include <botan/sm2.h>
41  #include <botan/sm2_enc.h>
42 #endif
43 
44 #if defined(BOTAN_HAS_ECDH)
45  #include <botan/ecdh.h>
46 #endif
47 
48 #if defined(BOTAN_HAS_CURVE_25519)
49  #include <botan/curve25519.h>
50 #endif
51 
52 #if defined(BOTAN_HAS_ED25519)
53  #include <botan/ed25519.h>
54 #endif
55 
56 #if defined(BOTAN_HAS_MCELIECE)
57  #include <botan/mceliece.h>
58 #endif
59 
60 #if defined(BOTAN_HAS_MCEIES)
61  #include <botan/mceies.h>
62 #endif
63 
64 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
65  #include <botan/dh.h>
66 #endif
67 
68 
69 namespace {
70 
71 #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
72 
73 // These are always called within an existing try/catch block
74 
75 template<class ECPrivateKey_t>
76 int privkey_load_ec(std::unique_ptr<ECPrivateKey_t>& key,
77  const Botan::BigInt& scalar,
78  const char* curve_name)
79  {
80  if(curve_name == nullptr)
82 
83  Botan::Null_RNG null_rng;
84  Botan::EC_Group grp(curve_name);
85  key.reset(new ECPrivateKey_t(null_rng, grp, scalar));
86  return BOTAN_FFI_SUCCESS;
87  }
88 
89 template<class ECPublicKey_t>
90 int pubkey_load_ec(std::unique_ptr<ECPublicKey_t>& key,
91  const Botan::BigInt& public_x,
92  const Botan::BigInt& public_y,
93  const char* curve_name)
94  {
95  if(curve_name == nullptr)
97 
98  Botan::EC_Group grp(curve_name);
99  Botan::PointGFp uncompressed_point = grp.point(public_x, public_y);
100  key.reset(new ECPublicKey_t(grp, uncompressed_point));
101  return BOTAN_FFI_SUCCESS;
102  }
103 
104 #endif
105 
106 Botan::BigInt pubkey_get_field(const Botan::Public_Key& key,
107  const std::string& field)
108  {
109  // Maybe this should be `return key.get_integer_field(field_name)`?
110 
111 #if defined(BOTAN_HAS_RSA)
112  if(const Botan::RSA_PublicKey* rsa = dynamic_cast<const Botan::RSA_PublicKey*>(&key))
113  {
114  if(field == "n")
115  return rsa->get_n();
116  else if(field == "e")
117  return rsa->get_e();
118  else
119  throw Botan::Exception("Field not supported");
120  }
121 #endif
122 
123 #if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY)
124  // Handles DSA, ElGamal, etc
125  if(const Botan::DL_Scheme_PublicKey* dl = dynamic_cast<const Botan::DL_Scheme_PublicKey*>(&key))
126  {
127  if(field == "p")
128  return dl->group_p();
129  else if(field == "q")
130  return dl->group_q();
131  else if(field == "g")
132  return dl->group_g();
133  else if(field == "y")
134  return dl->get_y();
135  else
136  throw Botan::Exception("Field not supported");
137  }
138 #endif
139 
140 #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
141  if(const Botan::EC_PublicKey* ecc = dynamic_cast<const Botan::EC_PublicKey*>(&key))
142  {
143  if(field == "public_x")
144  return ecc->public_point().get_affine_x();
145  else if(field == "public_y")
146  return ecc->public_point().get_affine_y();
147  else if(field == "base_x")
148  return ecc->domain().get_g_x();
149  else if(field == "base_y")
150  return ecc->domain().get_g_y();
151  else if(field == "p")
152  return ecc->domain().get_p();
153  else if(field == "a")
154  return ecc->domain().get_a();
155  else if(field == "b")
156  return ecc->domain().get_b();
157  else if(field == "cofactor")
158  return ecc->domain().get_cofactor();
159  else if(field == "order")
160  return ecc->domain().get_order();
161  else
162  throw Botan::Exception("Field not supported");
163  }
164 #endif
165 
166  // Some other algorithm type not supported by this function
167  throw Botan::Exception("Unsupported algorithm type for botan_pubkey_get_field");
168  }
169 
170 Botan::BigInt privkey_get_field(const Botan::Private_Key& key,
171  const std::string& field)
172  {
173  //return key.get_integer_field(field);
174 
175 #if defined(BOTAN_HAS_RSA)
176 
177  if(const Botan::RSA_PrivateKey* rsa = dynamic_cast<const Botan::RSA_PrivateKey*>(&key))
178  {
179  if(field == "p")
180  return rsa->get_p();
181  else if(field == "q")
182  return rsa->get_q();
183  else if(field == "d")
184  return rsa->get_d();
185  else if(field == "c")
186  return rsa->get_c();
187  else if(field == "d1")
188  return rsa->get_d1();
189  else if(field == "d2")
190  return rsa->get_d2();
191  else
192  return pubkey_get_field(key, field);
193  }
194 #endif
195 
196 #if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY)
197  // Handles DSA, ElGamal, etc
198  if(const Botan::DL_Scheme_PrivateKey* dl = dynamic_cast<const Botan::DL_Scheme_PrivateKey*>(&key))
199  {
200  if(field == "x")
201  return dl->get_x();
202  else
203  return pubkey_get_field(key, field);
204  }
205 #endif
206 
207 #if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
208  if(const Botan::EC_PrivateKey* ecc = dynamic_cast<const Botan::EC_PrivateKey*>(&key))
209  {
210  if(field == "x")
211  return ecc->private_value();
212  else
213  return pubkey_get_field(key, field);
214  }
215 #endif
216 
217  // Some other algorithm type not supported by this function
218  throw Botan::Exception("Unsupported algorithm type for botan_privkey_get_field");
219  }
220 
221 }
222 
223 extern "C" {
224 
225 using namespace Botan_FFI;
226 
228  botan_pubkey_t key,
229  const char* field_name_cstr)
230  {
231  if(field_name_cstr == nullptr)
233 
234  const std::string field_name(field_name_cstr);
235 
236  return BOTAN_FFI_DO(Botan::Public_Key, key, k, {
237  safe_get(output) = pubkey_get_field(k, field_name);
238  });
239  }
240 
242  botan_privkey_t key,
243  const char* field_name_cstr)
244  {
245  if(field_name_cstr == nullptr)
247 
248  const std::string field_name(field_name_cstr);
249 
250  return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
251  safe_get(output) = privkey_get_field(k, field_name);
252  });
253  }
254 
255 /* RSA specific operations */
256 
257 int botan_privkey_create_rsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n_bits)
258  {
259  if(n_bits < 1024 || n_bits > 16*1024)
261 
262  std::string n_str = std::to_string(n_bits);
263 
264  return botan_privkey_create(key_obj, "RSA", n_str.c_str(), rng_obj);
265  }
266 
268  botan_mp_t rsa_p, botan_mp_t rsa_q, botan_mp_t rsa_e)
269  {
270 #if defined(BOTAN_HAS_RSA)
271  *key = nullptr;
272 
273  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
274  *key = new botan_privkey_struct(new Botan::RSA_PrivateKey(safe_get(rsa_p),
275  safe_get(rsa_q),
276  safe_get(rsa_e)));
277  return BOTAN_FFI_SUCCESS;
278  });
279 #else
280  BOTAN_UNUSED(key, rsa_p, rsa_q, rsa_e);
282 #endif
283  }
284 
286  botan_mp_t n, botan_mp_t e)
287  {
288 #if defined(BOTAN_HAS_RSA)
289  *key = nullptr;
290  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
291  *key = new botan_pubkey_struct(new Botan::RSA_PublicKey(safe_get(n), safe_get(e)));
292  return BOTAN_FFI_SUCCESS;
293  });
294 #else
295  BOTAN_UNUSED(key, n, e);
297 #endif
298  }
299 
301  {
302  return botan_privkey_get_field(p, key, "p");
303  }
304 
306  {
307  return botan_privkey_get_field(q, key, "q");
308  }
309 
311  {
312  return botan_privkey_get_field(n, key, "n");
313  }
314 
316  {
317  return botan_privkey_get_field(e, key, "e");
318  }
319 
321  {
322  return botan_privkey_get_field(d, key, "d");
323  }
324 
326  {
327  return botan_pubkey_get_field(e, key, "e");
328  }
329 
331  {
332  return botan_pubkey_get_field(n, key, "n");
333  }
334 
335 /* DSA specific operations */
336 int botan_privkey_create_dsa(botan_privkey_t* key, botan_rng_t rng_obj, size_t pbits, size_t qbits)
337  {
338 #if defined(BOTAN_HAS_DSA)
339 
340  if ((rng_obj == nullptr) || (key == nullptr))
342 
343  if ((pbits % 64) || (qbits % 8) ||
344  (pbits < 1024) || (pbits > 3072) ||
345  (qbits < 160) || (qbits > 256)) {
347  }
348 
349  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
350  Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
351  Botan::DL_Group group(rng, Botan::DL_Group::Prime_Subgroup, pbits, qbits);
352  *key = new botan_privkey_struct(new Botan::DSA_PrivateKey(rng, group));
353  return BOTAN_FFI_SUCCESS;
354  });
355 #else
356  BOTAN_UNUSED(key, rng_obj, pbits, qbits);
358 #endif
359  }
360 
363  {
364 #if defined(BOTAN_HAS_DSA)
365  *key = nullptr;
366 
367  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
368  Botan::Null_RNG null_rng;
369  Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
370  *key = new botan_privkey_struct(new Botan::DSA_PrivateKey(null_rng, group, safe_get(x)));
371  return BOTAN_FFI_SUCCESS;
372  });
373 #else
374  BOTAN_UNUSED(key, p, q, g, x);
376 #endif
377  }
378 
381  {
382 #if defined(BOTAN_HAS_DSA)
383  *key = nullptr;
384 
385  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
386  Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
387  *key = new botan_pubkey_struct(new Botan::DSA_PublicKey(group, safe_get(y)));
388  return BOTAN_FFI_SUCCESS;
389  });
390 #else
391  BOTAN_UNUSED(key, p, q, g, y);
393 #endif
394  }
395 
397  {
398  return botan_privkey_get_field(x, key, "x");
399  }
400 
402  {
403  return botan_pubkey_get_field(p, key, "p");
404  }
405 
407  {
408  return botan_pubkey_get_field(q, key, "q");
409  }
410 
412  {
413  return botan_pubkey_get_field(g, key, "g");
414  }
415 
417  {
418  return botan_pubkey_get_field(y, key, "y");
419  }
420 
421 int botan_privkey_create_ecdsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
422  {
423  return botan_privkey_create(key_obj, "ECDSA", param_str, rng_obj);
424  }
425 
426 /* ECDSA specific operations */
427 
429  const botan_mp_t public_x,
430  const botan_mp_t public_y,
431  const char* curve_name)
432  {
433 #if defined(BOTAN_HAS_ECDSA)
434  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
435  std::unique_ptr<Botan::ECDSA_PublicKey> p_key;
436 
437  int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
438  if(rc == BOTAN_FFI_SUCCESS)
439  *key = new botan_pubkey_struct(p_key.release());
440 
441  return rc;
442  });
443 #else
444  BOTAN_UNUSED(key, public_x, public_y, curve_name);
446 #endif
447  }
448 
450  const botan_mp_t scalar,
451  const char* curve_name)
452  {
453 #if defined(BOTAN_HAS_ECDSA)
454  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
455  std::unique_ptr<Botan::ECDSA_PrivateKey> p_key;
456  int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
457  if(rc == BOTAN_FFI_SUCCESS)
458  *key = new botan_privkey_struct(p_key.release());
459  return rc;
460  });
461 #else
462  BOTAN_UNUSED(key, scalar, curve_name);
464 #endif
465  }
466 
467 /* ElGamal specific operations */
469  botan_rng_t rng_obj,
470  size_t pbits,
471  size_t qbits)
472  {
473 #if defined(BOTAN_HAS_ELGAMAL)
474 
475  if ((rng_obj == nullptr) || (key == nullptr))
477 
478  if ((pbits < 1024) || (qbits<160)) {
480  }
481 
482  Botan::DL_Group::PrimeType prime_type = ((pbits-1) == qbits)
485 
486  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
487  Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
488  Botan::DL_Group group(rng, prime_type, pbits, qbits);
489  *key = new botan_privkey_struct(new Botan::ElGamal_PrivateKey(rng, group));
490  return BOTAN_FFI_SUCCESS;
491  });
492 #else
493  BOTAN_UNUSED(key, rng_obj, pbits);
495 #endif
496  }
497 
500  {
501 #if defined(BOTAN_HAS_ELGAMAL)
502  *key = nullptr;
503  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
504  Botan::DL_Group group(safe_get(p), safe_get(g));
505  *key = new botan_pubkey_struct(new Botan::ElGamal_PublicKey(group, safe_get(y)));
506  return BOTAN_FFI_SUCCESS;
507  });
508 #else
509  BOTAN_UNUSED(key, p, g, y);
511 #endif
512  }
513 
516  {
517 #if defined(BOTAN_HAS_ELGAMAL)
518  *key = nullptr;
519  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
520  Botan::Null_RNG null_rng;
521  Botan::DL_Group group(safe_get(p), safe_get(g));
522  *key = new botan_privkey_struct(new Botan::ElGamal_PrivateKey(null_rng, group, safe_get(x)));
523  return BOTAN_FFI_SUCCESS;
524  });
525 #else
526  BOTAN_UNUSED(key, p, g, x);
528 #endif
529  }
530 
531 /* Diffie Hellman specific operations */
532 
533 int botan_privkey_create_dh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
534  {
535  return botan_privkey_create(key_obj, "DH", param_str, rng_obj);
536  }
537 
540  {
541 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
542  *key = nullptr;
543  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
544  Botan::Null_RNG null_rng;
545  Botan::DL_Group group(safe_get(p), safe_get(g));
546  *key = new botan_privkey_struct(new Botan::DH_PrivateKey(null_rng, group, safe_get(x)));
547  return BOTAN_FFI_SUCCESS;
548  });
549 #else
550  BOTAN_UNUSED(key, p, g, x);
552 #endif
553  }
554 
557  {
558 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
559  *key = nullptr;
560  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
561  Botan::DL_Group group(safe_get(p), safe_get(g));
562  *key = new botan_pubkey_struct(new Botan::DH_PublicKey(group, safe_get(y)));
563  return BOTAN_FFI_SUCCESS;
564  });
565 #else
566  BOTAN_UNUSED(key, p, g, y);
568 #endif
569  }
570 
571 /* ECDH + x25519 specific operations */
572 
573 int botan_privkey_create_ecdh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
574  {
575  if(param_str == nullptr)
577 
578  const std::string params(param_str);
579 
580  if(params == "curve25519")
581  return botan_privkey_create(key_obj, "Curve25519", "", rng_obj);
582 
583  return botan_privkey_create(key_obj, "ECDH", param_str, rng_obj);
584  }
585 
587  const botan_mp_t public_x,
588  const botan_mp_t public_y,
589  const char* curve_name)
590  {
591 #if defined(BOTAN_HAS_ECDH)
592  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
593  std::unique_ptr<Botan::ECDH_PublicKey> p_key;
594  int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
595 
596  if(rc == BOTAN_FFI_SUCCESS)
597  *key = new botan_pubkey_struct(p_key.release());
598  return rc;
599  });
600 #else
601  BOTAN_UNUSED(key, public_x, public_y, curve_name);
603 #endif
604  }
605 
607  const botan_mp_t scalar,
608  const char* curve_name)
609  {
610 #if defined(BOTAN_HAS_ECDH)
611  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
612  std::unique_ptr<Botan::ECDH_PrivateKey> p_key;
613  int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
614  if(rc == BOTAN_FFI_SUCCESS)
615  *key = new botan_privkey_struct(p_key.release());
616  return rc;
617  });
618 #else
619  BOTAN_UNUSED(key, scalar, curve_name);
621 #endif
622  }
623 
624 /* SM2 specific operations */
625 
626 int botan_pubkey_sm2_compute_za(uint8_t out[],
627  size_t* out_len,
628  const char* ident,
629  const char* hash_algo,
630  const botan_pubkey_t key)
631  {
632  if(out == nullptr || out_len == nullptr)
634  if(ident == nullptr || hash_algo == nullptr || key == nullptr)
636 
637 #if defined(BOTAN_HAS_SM2)
638  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
639  const Botan::Public_Key& pub_key = safe_get(key);
640  const Botan::EC_PublicKey* ec_key = dynamic_cast<const Botan::EC_PublicKey*>(&pub_key);
641 
642  if(ec_key == nullptr)
644 
645  if(ec_key->algo_name() != "SM2_Sig" && ec_key->algo_name() != "SM2_Enc")
647 
648  const std::string ident_str(ident);
649  std::unique_ptr<Botan::HashFunction> hash =
651 
652  const std::vector<uint8_t> za =
653  Botan::sm2_compute_za(*hash, ident_str, ec_key->domain(), ec_key->public_point());
654 
655  return write_vec_output(out, out_len, za);
656  });
657 #else
659 #endif
660  }
661 
663  const botan_mp_t public_x,
664  const botan_mp_t public_y,
665  const char* curve_name)
666  {
667 #if defined(BOTAN_HAS_SM2)
668  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
669  std::unique_ptr<Botan::SM2_Signature_PublicKey> p_key;
670  if(!pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name))
671  {
672  *key = new botan_pubkey_struct(p_key.release());
673  return BOTAN_FFI_SUCCESS;
674  }
676  });
677 #else
678  BOTAN_UNUSED(key, public_x, public_y, curve_name);
680 #endif
681  }
682 
684  const botan_mp_t scalar,
685  const char* curve_name)
686  {
687 #if defined(BOTAN_HAS_SM2)
688  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
689  std::unique_ptr<Botan::SM2_Signature_PrivateKey> p_key;
690  int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
691 
692  if(rc == BOTAN_FFI_SUCCESS)
693  *key = new botan_privkey_struct(p_key.release());
694  return rc;
695  });
696 #else
697  BOTAN_UNUSED(key, scalar, curve_name);
699 #endif
700  }
701 
703  const botan_mp_t public_x,
704  const botan_mp_t public_y,
705  const char* curve_name)
706  {
707 #if defined(BOTAN_HAS_SM2)
708  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
709  std::unique_ptr<Botan::SM2_Encryption_PublicKey> p_key;
710  if(!pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name))
711  {
712  *key = new botan_pubkey_struct(p_key.release());
713  return BOTAN_FFI_SUCCESS;
714  }
716  });
717 #else
718  BOTAN_UNUSED(key, public_x, public_y, curve_name);
720 #endif
721  }
722 
724  const botan_mp_t scalar,
725  const char* curve_name)
726  {
727 #if defined(BOTAN_HAS_SM2)
728  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
729  std::unique_ptr<Botan::SM2_Encryption_PrivateKey> p_key;
730  int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
731 
732  if(rc == BOTAN_FFI_SUCCESS)
733  *key = new botan_privkey_struct(p_key.release());
734  return rc;
735  });
736 #else
737  BOTAN_UNUSED(key, scalar, curve_name);
739 #endif
740  }
741 
742 /* Ed25519 specific operations */
743 
745  const uint8_t privkey[32])
746  {
747 #if defined(BOTAN_HAS_ED25519)
748  *key = nullptr;
749  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
750  const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 32);
751  *key = new botan_privkey_struct(new Botan::Ed25519_PrivateKey(privkey_vec));
752  return BOTAN_FFI_SUCCESS;
753  });
754 #else
755  BOTAN_UNUSED(key, privkey);
757 #endif
758  }
759 
761  const uint8_t pubkey[32])
762  {
763 #if defined(BOTAN_HAS_ED25519)
764  *key = nullptr;
765  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
766  const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32);
767  *key = new botan_pubkey_struct(new Botan::Ed25519_PublicKey(pubkey_vec));
768  return BOTAN_FFI_SUCCESS;
769  });
770 #else
771  BOTAN_UNUSED(key, pubkey);
773 #endif
774  }
775 
777  uint8_t output[64])
778  {
779 #if defined(BOTAN_HAS_ED25519)
780  return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
781  if(Botan::Ed25519_PrivateKey* ed = dynamic_cast<Botan::Ed25519_PrivateKey*>(&k))
782  {
783  const Botan::secure_vector<uint8_t>& ed_key = ed->get_private_key();
784  if(ed_key.size() != 64)
786  Botan::copy_mem(output, ed_key.data(), ed_key.size());
787  return BOTAN_FFI_SUCCESS;
788  }
789  else
790  {
792  }
793  });
794 #else
795  BOTAN_UNUSED(key, output);
797 #endif
798  }
799 
801  uint8_t output[32])
802  {
803 #if defined(BOTAN_HAS_ED25519)
804  return BOTAN_FFI_DO(Botan::Public_Key, key, k, {
805  if(Botan::Ed25519_PublicKey* ed = dynamic_cast<Botan::Ed25519_PublicKey*>(&k))
806  {
807  const std::vector<uint8_t>& ed_key = ed->get_public_key();
808  if(ed_key.size() != 32)
810  Botan::copy_mem(output, ed_key.data(), ed_key.size());
811  return BOTAN_FFI_SUCCESS;
812  }
813  else
814  {
816  }
817  });
818 #else
819  BOTAN_UNUSED(key, output);
821 #endif
822  }
823 
824 int botan_privkey_create_mceliece(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n, size_t t)
825  {
826  const std::string mce_params = std::to_string(n) + "," + std::to_string(t);
827  return botan_privkey_create(key_obj, "McEliece", mce_params.c_str(), rng_obj);
828  }
829 
831  const char* aead,
832  const uint8_t ct[], size_t ct_len,
833  const uint8_t ad[], size_t ad_len,
834  uint8_t out[], size_t* out_len)
835  {
836  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
837  Botan::Private_Key& key = safe_get(mce_key_obj);
838 
839 #if defined(BOTAN_HAS_MCELIECE) && defined(BOTAN_HAS_MCEIES)
840  Botan::McEliece_PrivateKey* mce = dynamic_cast<Botan::McEliece_PrivateKey*>(&key);
841  if(!mce)
843 
844  const Botan::secure_vector<uint8_t> pt = mceies_decrypt(*mce, ct, ct_len, ad, ad_len, aead);
845  return write_vec_output(out, out_len, pt);
846 #else
848 #endif
849  });
850  }
851 
853  botan_rng_t rng_obj,
854  const char* aead,
855  const uint8_t pt[], size_t pt_len,
856  const uint8_t ad[], size_t ad_len,
857  uint8_t out[], size_t* out_len)
858  {
859  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
860  Botan::Public_Key& key = safe_get(mce_key_obj);
861  Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
862 
863 #if defined(BOTAN_HAS_MCELIECE) && defined(BOTAN_HAS_MCEIES)
864  Botan::McEliece_PublicKey* mce = dynamic_cast<Botan::McEliece_PublicKey*>(&key);
865  if(!mce)
867 
868  Botan::secure_vector<uint8_t> ct = mceies_encrypt(*mce, pt, pt_len, ad, ad_len, rng, aead);
869  return write_vec_output(out, out_len, ct);
870 #else
872 #endif
873  });
874  }
875 
876 }
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_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:345
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:69
int botan_privkey_rsa_get_p(botan_mp_t p, botan_privkey_t key)
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 ffi_guard_thunk(const char *func_name, Thunk thunk)
Definition: ffi_util.h:64
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)
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:44
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:145
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_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)
struct botan_mp_struct * botan_mp_t
Definition: ffi.h:535
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_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:34
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:108
int botan_privkey_load_elgamal(botan_privkey_t *key, botan_mp_t p, botan_mp_t g, botan_mp_t x)
struct botan_privkey_struct * botan_privkey_t
Definition: ffi.h:663
#define BOTAN_UNUSED(...)
Definition: assert.h:117
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:49
int botan_privkey_load_sm2(botan_privkey_t *key, const botan_mp_t scalar, const char *curve_name)
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)
#define BOTAN_CURRENT_FUNCTION
Definition: compiler.h:143
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:88
struct botan_pubkey_struct * botan_pubkey_t
Definition: ffi.h:791
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:98
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:182
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)