Botan  2.4.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.get_curve(), 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_base_point().get_affine_x();
149  else if(field == "base_y")
150  return ecc->domain().get_base_point().get_affine_y();
151  else if(field == "p")
152  return ecc->domain().get_curve().get_p();
153  else if(field == "a")
154  return ecc->domain().get_curve().get_a();
155  else if(field == "b")
156  return ecc->domain().get_curve().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 
339  {
340 #if defined(BOTAN_HAS_DSA)
341  *key = nullptr;
342 
343  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
344  Botan::Null_RNG null_rng;
345  Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
346  *key = new botan_privkey_struct(new Botan::DSA_PrivateKey(null_rng, group, safe_get(x)));
347  return BOTAN_FFI_SUCCESS;
348  });
349 #else
350  BOTAN_UNUSED(key, p, q, g, x);
352 #endif
353  }
354 
357  {
358 #if defined(BOTAN_HAS_DSA)
359  *key = nullptr;
360 
361  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
362  Botan::DL_Group group(safe_get(p), safe_get(q), safe_get(g));
363  *key = new botan_pubkey_struct(new Botan::DSA_PublicKey(group, safe_get(y)));
364  return BOTAN_FFI_SUCCESS;
365  });
366 #else
367  BOTAN_UNUSED(key, p, q, g, y);
369 #endif
370  }
371 
373  {
374  return botan_privkey_get_field(x, key, "x");
375  }
376 
378  {
379  return botan_pubkey_get_field(p, key, "p");
380  }
381 
383  {
384  return botan_pubkey_get_field(q, key, "q");
385  }
386 
388  {
389  return botan_pubkey_get_field(g, key, "g");
390  }
391 
393  {
394  return botan_pubkey_get_field(y, key, "y");
395  }
396 
397 int botan_privkey_create_ecdsa(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
398  {
399  return botan_privkey_create(key_obj, "ECDSA", param_str, rng_obj);
400  }
401 
402 /* ECDSA specific operations */
403 
405  const botan_mp_t public_x,
406  const botan_mp_t public_y,
407  const char* curve_name)
408  {
409 #if defined(BOTAN_HAS_ECDSA)
410  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
411  std::unique_ptr<Botan::ECDSA_PublicKey> p_key;
412 
413  int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
414  if(rc == BOTAN_FFI_SUCCESS)
415  *key = new botan_pubkey_struct(p_key.release());
416 
417  return rc;
418  });
419 #else
420  BOTAN_UNUSED(key, public_x, public_y, curve_name);
422 #endif
423  }
424 
426  const botan_mp_t scalar,
427  const char* curve_name)
428  {
429 #if defined(BOTAN_HAS_ECDSA)
430  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
431  std::unique_ptr<Botan::ECDSA_PrivateKey> p_key;
432  int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
433  if(rc == BOTAN_FFI_SUCCESS)
434  *key = new botan_privkey_struct(p_key.release());
435  return rc;
436  });
437 #else
438  BOTAN_UNUSED(key, scalar, curve_name);
440 #endif
441  }
442 
443 /* ElGamal specific operations */
444 
447  {
448 #if defined(BOTAN_HAS_ELGAMAL)
449  *key = nullptr;
450  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
451  Botan::DL_Group group(safe_get(p), safe_get(g));
452  *key = new botan_pubkey_struct(new Botan::ElGamal_PublicKey(group, safe_get(y)));
453  return BOTAN_FFI_SUCCESS;
454  });
455 #else
456  BOTAN_UNUSED(key, p, g, y);
458 #endif
459  }
460 
463  {
464 #if defined(BOTAN_HAS_ELGAMAL)
465  *key = nullptr;
466  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
467  Botan::Null_RNG null_rng;
468  Botan::DL_Group group(safe_get(p), safe_get(g));
469  *key = new botan_privkey_struct(new Botan::ElGamal_PrivateKey(null_rng, group, safe_get(x)));
470  return BOTAN_FFI_SUCCESS;
471  });
472 #else
473  BOTAN_UNUSED(key, p, g, x);
475 #endif
476  }
477 
478 /* Diffie Hellman specific operations */
479 
480 int botan_privkey_create_dh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
481  {
482  return botan_privkey_create(key_obj, "DH", param_str, rng_obj);
483  }
484 
487  {
488 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
489  *key = nullptr;
490  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
491  Botan::Null_RNG null_rng;
492  Botan::DL_Group group(safe_get(p), safe_get(g));
493  *key = new botan_privkey_struct(new Botan::DH_PrivateKey(null_rng, group, safe_get(x)));
494  return BOTAN_FFI_SUCCESS;
495  });
496 #else
497  BOTAN_UNUSED(key, p, g, x);
499 #endif
500  }
501 
504  {
505 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
506  *key = nullptr;
507  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
508  Botan::DL_Group group(safe_get(p), safe_get(g));
509  *key = new botan_pubkey_struct(new Botan::DH_PublicKey(group, safe_get(y)));
510  return BOTAN_FFI_SUCCESS;
511  });
512 #else
513  BOTAN_UNUSED(key, p, g, y);
515 #endif
516  }
517 
518 /* ECDH + x25519 specific operations */
519 
520 int botan_privkey_create_ecdh(botan_privkey_t* key_obj, botan_rng_t rng_obj, const char* param_str)
521  {
522  if(param_str == nullptr)
524 
525  const std::string params(param_str);
526 
527  if(params == "curve25519")
528  return botan_privkey_create(key_obj, "Curve25519", "", rng_obj);
529 
530  return botan_privkey_create(key_obj, "ECDH", param_str, rng_obj);
531  }
532 
534  const botan_mp_t public_x,
535  const botan_mp_t public_y,
536  const char* curve_name)
537  {
538 #if defined(BOTAN_HAS_ECDH)
539  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
540  std::unique_ptr<Botan::ECDH_PublicKey> p_key;
541  int rc = pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name);
542 
543  if(rc == BOTAN_FFI_SUCCESS)
544  *key = new botan_pubkey_struct(p_key.release());
545  return rc;
546  });
547 #else
548  BOTAN_UNUSED(key, public_x, public_y, curve_name);
550 #endif
551  }
552 
554  const botan_mp_t scalar,
555  const char* curve_name)
556  {
557 #if defined(BOTAN_HAS_ECDH)
558  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
559  std::unique_ptr<Botan::ECDH_PrivateKey> p_key;
560  int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
561  if(rc == BOTAN_FFI_SUCCESS)
562  *key = new botan_privkey_struct(p_key.release());
563  return rc;
564  });
565 #else
566  BOTAN_UNUSED(key, scalar, curve_name);
568 #endif
569  }
570 
571 /* SM2 specific operations */
572 
573 int botan_pubkey_sm2_compute_za(uint8_t out[],
574  size_t* out_len,
575  const char* ident,
576  const char* hash_algo,
577  const botan_pubkey_t key)
578  {
579  if(out == nullptr || out_len == nullptr)
581  if(ident == nullptr || hash_algo == nullptr || key == nullptr)
583 
584 #if defined(BOTAN_HAS_SM2)
585  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
586  const Botan::Public_Key& pub_key = safe_get(key);
587  const Botan::EC_PublicKey* ec_key = dynamic_cast<const Botan::EC_PublicKey*>(&pub_key);
588 
589  if(ec_key == nullptr)
591 
592  if(ec_key->algo_name() != "SM2_Sig" && ec_key->algo_name() != "SM2_Enc")
594 
595  const std::string ident_str(ident);
596  std::unique_ptr<Botan::HashFunction> hash =
598 
599  const std::vector<uint8_t> za =
600  Botan::sm2_compute_za(*hash, ident_str, ec_key->domain(), ec_key->public_point());
601 
602  return write_vec_output(out, out_len, za);
603  });
604 #else
606 #endif
607  }
608 
610  const botan_mp_t public_x,
611  const botan_mp_t public_y,
612  const char* curve_name)
613  {
614 #if defined(BOTAN_HAS_SM2)
615  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
616  std::unique_ptr<Botan::SM2_Signature_PublicKey> p_key;
617  if(!pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name))
618  {
619  *key = new botan_pubkey_struct(p_key.release());
620  return BOTAN_FFI_SUCCESS;
621  }
623  });
624 #else
625  BOTAN_UNUSED(key, public_x, public_y, curve_name);
627 #endif
628  }
629 
631  const botan_mp_t scalar,
632  const char* curve_name)
633  {
634 #if defined(BOTAN_HAS_SM2)
635  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
636  std::unique_ptr<Botan::SM2_Signature_PrivateKey> p_key;
637  int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
638 
639  if(rc == BOTAN_FFI_SUCCESS)
640  *key = new botan_privkey_struct(p_key.release());
641  return rc;
642  });
643 #else
644  BOTAN_UNUSED(key, scalar, curve_name);
646 #endif
647  }
648 
650  const botan_mp_t public_x,
651  const botan_mp_t public_y,
652  const char* curve_name)
653  {
654 #if defined(BOTAN_HAS_SM2)
655  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
656  std::unique_ptr<Botan::SM2_Encryption_PublicKey> p_key;
657  if(!pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name))
658  {
659  *key = new botan_pubkey_struct(p_key.release());
660  return BOTAN_FFI_SUCCESS;
661  }
663  });
664 #else
665  BOTAN_UNUSED(key, public_x, public_y, curve_name);
667 #endif
668  }
669 
671  const botan_mp_t scalar,
672  const char* curve_name)
673  {
674 #if defined(BOTAN_HAS_SM2)
675  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
676  std::unique_ptr<Botan::SM2_Encryption_PrivateKey> p_key;
677  int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
678 
679  if(rc == BOTAN_FFI_SUCCESS)
680  *key = new botan_privkey_struct(p_key.release());
681  return rc;
682  });
683 #else
684  BOTAN_UNUSED(key, scalar, curve_name);
686 #endif
687  }
688 
689 /* Ed25519 specific operations */
690 
692  const uint8_t privkey[32])
693  {
694 #if defined(BOTAN_HAS_ED25519)
695  *key = nullptr;
696  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
697  const Botan::secure_vector<uint8_t> privkey_vec(privkey, privkey + 32);
698  *key = new botan_privkey_struct(new Botan::Ed25519_PrivateKey(privkey_vec));
699  return BOTAN_FFI_SUCCESS;
700  });
701 #else
702  BOTAN_UNUSED(key, privkey);
704 #endif
705  }
706 
708  const uint8_t pubkey[32])
709  {
710 #if defined(BOTAN_HAS_ED25519)
711  *key = nullptr;
712  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
713  const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32);
714  *key = new botan_pubkey_struct(new Botan::Ed25519_PublicKey(pubkey_vec));
715  return BOTAN_FFI_SUCCESS;
716  });
717 #else
718  BOTAN_UNUSED(key, pubkey);
720 #endif
721  }
722 
724  uint8_t output[64])
725  {
726 #if defined(BOTAN_HAS_ED25519)
727  return BOTAN_FFI_DO(Botan::Private_Key, key, k, {
728  if(Botan::Ed25519_PrivateKey* ed = dynamic_cast<Botan::Ed25519_PrivateKey*>(&k))
729  {
730  const Botan::secure_vector<uint8_t>& ed_key = ed->get_private_key();
731  if(ed_key.size() != 64)
733  Botan::copy_mem(output, ed_key.data(), ed_key.size());
734  return BOTAN_FFI_SUCCESS;
735  }
736  else
737  {
739  }
740  });
741 #else
742  BOTAN_UNUSED(key, output);
744 #endif
745  }
746 
748  uint8_t output[32])
749  {
750 #if defined(BOTAN_HAS_ED25519)
751  return BOTAN_FFI_DO(Botan::Public_Key, key, k, {
752  if(Botan::Ed25519_PublicKey* ed = dynamic_cast<Botan::Ed25519_PublicKey*>(&k))
753  {
754  const std::vector<uint8_t>& ed_key = ed->get_public_key();
755  if(ed_key.size() != 32)
757  Botan::copy_mem(output, ed_key.data(), ed_key.size());
758  return BOTAN_FFI_SUCCESS;
759  }
760  else
761  {
763  }
764  });
765 #else
766  BOTAN_UNUSED(key, output);
768 #endif
769  }
770 
771 int botan_privkey_create_mceliece(botan_privkey_t* key_obj, botan_rng_t rng_obj, size_t n, size_t t)
772  {
773  const std::string mce_params = std::to_string(n) + "," + std::to_string(t);
774  return botan_privkey_create(key_obj, "McEliece", mce_params.c_str(), rng_obj);
775  }
776 
778  const char* aead,
779  const uint8_t ct[], size_t ct_len,
780  const uint8_t ad[], size_t ad_len,
781  uint8_t out[], size_t* out_len)
782  {
783  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
784  Botan::Private_Key& key = safe_get(mce_key_obj);
785 
786 #if defined(BOTAN_HAS_MCELIECE) && defined(BOTAN_HAS_MCEIES)
787  Botan::McEliece_PrivateKey* mce = dynamic_cast<Botan::McEliece_PrivateKey*>(&key);
788  if(!mce)
790 
791  const Botan::secure_vector<uint8_t> pt = mceies_decrypt(*mce, ct, ct_len, ad, ad_len, aead);
792  return write_vec_output(out, out_len, pt);
793 #else
795 #endif
796  });
797  }
798 
800  botan_rng_t rng_obj,
801  const char* aead,
802  const uint8_t pt[], size_t pt_len,
803  const uint8_t ad[], size_t ad_len,
804  uint8_t out[], size_t* out_len)
805  {
806  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
807  Botan::Public_Key& key = safe_get(mce_key_obj);
808  Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
809 
810 #if defined(BOTAN_HAS_MCELIECE) && defined(BOTAN_HAS_MCEIES)
811  Botan::McEliece_PublicKey* mce = dynamic_cast<Botan::McEliece_PublicKey*>(&key);
812  if(!mce)
814 
815  Botan::secure_vector<uint8_t> ct = mceies_encrypt(*mce, pt, pt_len, ad, ad_len, rng, aead);
816  return write_vec_output(out, out_len, ct);
817 #else
819 #endif
820  });
821  }
822 
823 }
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)
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:71
int botan_privkey_rsa_get_p(botan_mp_t p, botan_privkey_t key)
#define BOTAN_FFI_SUCCESS
Definition: ffi.h:137
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_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:43
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:108
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)
#define BOTAN_FFI_ERROR_NOT_IMPLEMENTED
Definition: ffi.h:149
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:561
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)
#define BOTAN_FFI_ERROR_UNKNOWN_ERROR
Definition: ffi.h:152
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:97
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:689
#define BOTAN_UNUSED(...)
Definition: assert.h:106
int botan_privkey_rsa_get_e(botan_mp_t e, botan_privkey_t key)
AlgorithmIdentifier hash_algo
Definition: x509_obj.cpp:22
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
#define BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE
Definition: ffi.h:144
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)
#define BOTAN_FFI_ERROR_NULL_POINTER
Definition: ffi.h:147
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88
struct botan_pubkey_struct * botan_pubkey_t
Definition: ffi.h:767
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:208
#define BOTAN_FFI_ERROR_BAD_PARAMETER
Definition: ffi.h:148
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)