10#include <botan/hash.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>
17#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
18 #include <botan/ecc_key.h>
21#if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY)
22 #include <botan/dl_algo.h>
25#if defined(BOTAN_HAS_RSA)
26 #include <botan/rsa.h>
29#if defined(BOTAN_HAS_ELGAMAL)
30 #include <botan/elgamal.h>
33#if defined(BOTAN_HAS_DSA)
34 #include <botan/dsa.h>
37#if defined(BOTAN_HAS_ECDSA)
38 #include <botan/ecdsa.h>
41#if defined(BOTAN_HAS_SM2)
42 #include <botan/sm2.h>
45#if defined(BOTAN_HAS_ECDH)
46 #include <botan/ecdh.h>
49#if defined(BOTAN_HAS_CURVE_25519)
50 #include <botan/curve25519.h>
53#if defined(BOTAN_HAS_ED25519)
54 #include <botan/ed25519.h>
57#if defined(BOTAN_HAS_MCELIECE)
58 #include <botan/mceliece.h>
61#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
68#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
72template<
class ECPrivateKey_t>
73int privkey_load_ec(std::unique_ptr<ECPrivateKey_t>& key,
75 const char* curve_name)
77 if(curve_name ==
nullptr)
82 key.reset(
new ECPrivateKey_t(null_rng, grp, scalar));
86template<
class ECPublicKey_t>
87int pubkey_load_ec(std::unique_ptr<ECPublicKey_t>& key,
90 const char* curve_name)
92 if(curve_name ==
nullptr)
97 key.reset(
new ECPublicKey_t(grp, uncompressed_point));
104 const std::string& field)
108#if defined(BOTAN_HAS_RSA)
113 else if(field ==
"e")
120#if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY)
125 return dl->group_p();
126 else if(field ==
"q")
127 return dl->group_q();
128 else if(field ==
"g")
129 return dl->group_g();
130 else if(field ==
"y")
137#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
140 if(field ==
"public_x")
141 return ecc->public_point().get_affine_x();
142 else if(field ==
"public_y")
143 return ecc->public_point().get_affine_y();
144 else if(field ==
"base_x")
145 return ecc->domain().get_g_x();
146 else if(field ==
"base_y")
147 return ecc->domain().get_g_y();
148 else if(field ==
"p")
149 return ecc->domain().get_p();
150 else if(field ==
"a")
151 return ecc->domain().get_a();
152 else if(field ==
"b")
153 return ecc->domain().get_b();
154 else if(field ==
"cofactor")
155 return ecc->domain().get_cofactor();
156 else if(field ==
"order")
157 return ecc->domain().get_order();
169 const std::string& field)
173#if defined(BOTAN_HAS_RSA)
179 else if(field ==
"q")
181 else if(field ==
"d")
183 else if(field ==
"c")
185 else if(field ==
"d1")
186 return rsa->get_d1();
187 else if(field ==
"d2")
188 return rsa->get_d2();
190 return pubkey_get_field(key, field);
194#if defined(BOTAN_HAS_DL_PUBLIC_KEY_FAMILY)
201 return pubkey_get_field(key, field);
205#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
209 return ecc->private_value();
211 return pubkey_get_field(key, field);
215 return pubkey_get_field(key, field);
226 const char* field_name_cstr)
228 if(field_name_cstr ==
nullptr)
231 const std::string field_name(field_name_cstr);
234 safe_get(output) = pubkey_get_field(k, field_name);
240 const char* field_name_cstr)
242 if(field_name_cstr ==
nullptr)
245 const std::string field_name(field_name_cstr);
248 safe_get(output) = privkey_get_field(k, field_name);
256 if(n_bits < 1024 || n_bits > 16*1024)
267#if defined(BOTAN_HAS_RSA)
272 auto rsa = std::make_unique<Botan::RSA_PrivateKey>(
safe_get(rsa_p),
275 *key =
new botan_privkey_struct(std::move(rsa));
285 const uint8_t bits[],
288#if defined(BOTAN_HAS_RSA)
294 auto rsa = std::make_unique<Botan::RSA_PrivateKey>(alg_id, src);
295 *key =
new botan_privkey_struct(std::move(rsa));
307#if defined(BOTAN_HAS_RSA)
310 auto rsa = std::make_unique<Botan::RSA_PublicKey>(
safe_get(n),
safe_get(e));
311 *key =
new botan_pubkey_struct(std::move(rsa));
356 uint8_t out[],
size_t* out_len,
359#if defined(BOTAN_HAS_RSA)
385#if defined(BOTAN_HAS_DSA)
387 if ((rng_obj ==
nullptr) || (key ==
nullptr))
390 if ((pbits % 64) || (qbits % 8) ||
391 (pbits < 1024) || (pbits > 3072) ||
392 (qbits < 160) || (qbits > 256)) {
399 auto dsa = std::make_unique<Botan::DSA_PrivateKey>(rng, group);
400 *key =
new botan_privkey_struct(std::move(dsa));
412#if defined(BOTAN_HAS_DSA)
418 auto dsa = std::make_unique<Botan::DSA_PrivateKey>(null_rng, group,
safe_get(x));
419 *key =
new botan_privkey_struct(std::move(dsa));
431#if defined(BOTAN_HAS_DSA)
436 auto dsa = std::make_unique<Botan::DSA_PublicKey>(group,
safe_get(y));
437 *key =
new botan_pubkey_struct(std::move(dsa));
481 const char* curve_name)
483#if defined(BOTAN_HAS_ECDSA)
485 std::unique_ptr<Botan::ECDSA_PublicKey> p_key;
487 int rc = pubkey_load_ec(p_key,
safe_get(public_x),
safe_get(public_y), curve_name);
489 *key =
new botan_pubkey_struct(std::move(p_key));
501 const char* curve_name)
503#if defined(BOTAN_HAS_ECDSA)
505 std::unique_ptr<Botan::ECDSA_PrivateKey> p_key;
506 int rc = privkey_load_ec(p_key,
safe_get(scalar), curve_name);
508 *key =
new botan_privkey_struct(std::move(p_key));
523#if defined(BOTAN_HAS_ELGAMAL)
525 if ((rng_obj ==
nullptr) || (key ==
nullptr))
528 if ((pbits < 1024) || (qbits<160)) {
539 auto elg = std::make_unique<Botan::ElGamal_PrivateKey>(rng, group);
540 *key =
new botan_privkey_struct(std::move(elg));
552#if defined(BOTAN_HAS_ELGAMAL)
556 auto elg = std::make_unique<Botan::ElGamal_PublicKey>(group,
safe_get(y));
557 *key =
new botan_pubkey_struct(std::move(elg));
569#if defined(BOTAN_HAS_ELGAMAL)
574 auto elg = std::make_unique<Botan::ElGamal_PrivateKey>(null_rng, group,
safe_get(x));
575 *key =
new botan_privkey_struct(std::move(elg));
594#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
599 auto dh = std::make_unique<Botan::DH_PrivateKey>(null_rng, group,
safe_get(x));
600 *key =
new botan_privkey_struct(std::move(dh));
612#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
616 auto dh = std::make_unique<Botan::DH_PublicKey>(group,
safe_get(y));
617 *key =
new botan_pubkey_struct(std::move(dh));
630 if(param_str ==
nullptr)
633 const std::string params(param_str);
635 if(params ==
"curve25519")
644 const char* curve_name)
646#if defined(BOTAN_HAS_ECDH)
648 std::unique_ptr<Botan::ECDH_PublicKey> p_key;
649 int rc = pubkey_load_ec(p_key,
safe_get(public_x),
safe_get(public_y), curve_name);
652 *key =
new botan_pubkey_struct(std::move(p_key));
663 const char* curve_name)
665#if defined(BOTAN_HAS_ECDH)
667 std::unique_ptr<Botan::ECDH_PrivateKey> p_key;
668 int rc = privkey_load_ec(p_key,
safe_get(scalar), curve_name);
670 *key =
new botan_privkey_struct(std::move(p_key));
687 if(out ==
nullptr || out_len ==
nullptr)
689 if(ident ==
nullptr ||
hash_algo ==
nullptr || key ==
nullptr)
692#if defined(BOTAN_HAS_SM2)
697 if(ec_key ==
nullptr)
703 const std::string ident_str(ident);
704 std::unique_ptr<Botan::HashFunction>
hash =
707 const std::vector<uint8_t> za =
720 const char* curve_name)
722#if defined(BOTAN_HAS_SM2)
724 std::unique_ptr<Botan::SM2_PublicKey> p_key;
725 if(!pubkey_load_ec(p_key,
safe_get(public_x),
safe_get(public_y), curve_name))
727 *key =
new botan_pubkey_struct(std::move(p_key));
740 const char* curve_name)
742#if defined(BOTAN_HAS_SM2)
744 std::unique_ptr<Botan::SM2_PrivateKey> p_key;
745 int rc = privkey_load_ec(p_key,
safe_get(scalar), curve_name);
748 *key =
new botan_privkey_struct(std::move(p_key));
760 const char* curve_name)
767 const char* curve_name)
775 const uint8_t privkey[32])
777#if defined(BOTAN_HAS_ED25519)
781 auto ed25519 = std::make_unique<Botan::Ed25519_PrivateKey>(privkey_vec);
782 *key =
new botan_privkey_struct(std::move(ed25519));
792 const uint8_t pubkey[32])
794#if defined(BOTAN_HAS_ED25519)
797 const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32);
798 auto ed25519 = std::make_unique<Botan::Ed25519_PublicKey>(pubkey_vec);
799 *key =
new botan_pubkey_struct(std::move(ed25519));
811#if defined(BOTAN_HAS_ED25519)
816 if(ed_key.size() != 64)
835#if defined(BOTAN_HAS_ED25519)
839 const std::vector<uint8_t>& ed_key = ed->get_public_key();
840 if(ed_key.size() != 32)
859 const uint8_t privkey[32])
861#if defined(BOTAN_HAS_X25519)
865 auto x25519 = std::make_unique<Botan::X25519_PrivateKey>(privkey_vec);
866 *key =
new botan_privkey_struct(std::move(x25519));
876 const uint8_t pubkey[32])
878#if defined(BOTAN_HAS_X25519)
881 const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32);
882 auto x25519 = std::make_unique<Botan::X25519_PublicKey>(pubkey_vec);
883 *key =
new botan_pubkey_struct(std::move(x25519));
895#if defined(BOTAN_HAS_X25519)
900 if(x25519_key.size() != 32)
919#if defined(BOTAN_HAS_X25519)
923 const std::vector<uint8_t>& x25519_key = x25519->public_value();
924 if(x25519_key.size() != 32)
948 const uint8_t ct[],
size_t ct_len,
949 const uint8_t ad[],
size_t ad_len,
950 uint8_t out[],
size_t* out_len)
952 BOTAN_UNUSED(mce_key_obj, aead, ct, ct_len, ad, ad_len, out, out_len);
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)
963 BOTAN_UNUSED(mce_key_obj, rng_obj, aead, pt, pt_len, ad, ad_len, out, out_len);
#define BOTAN_UNUSED(...)
const EC_Group & domain() const
const PointGFp & public_point() const
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
virtual std::string algo_name() const =0
struct botan_pubkey_struct * botan_pubkey_t
struct botan_privkey_struct * botan_privkey_t
int botan_privkey_create(botan_privkey_t *key, const char *algo_name, const char *algo_params, botan_rng_t rng)
#define BOTAN_PRIVKEY_EXPORT_FLAG_PEM
struct botan_mp_struct * botan_mp_t
struct botan_rng_struct * botan_rng_t
#define BOTAN_PRIVKEY_EXPORT_FLAG_DER
@ BOTAN_FFI_ERROR_NOT_IMPLEMENTED
@ BOTAN_FFI_ERROR_UNKNOWN_ERROR
@ BOTAN_FFI_ERROR_BAD_FLAG
@ BOTAN_FFI_ERROR_NULL_POINTER
@ BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE
@ BOTAN_FFI_ERROR_BAD_PARAMETER
int botan_privkey_create_elgamal(botan_privkey_t *key, botan_rng_t rng_obj, size_t pbits, size_t qbits)
int botan_pubkey_rsa_get_n(botan_mp_t n, botan_pubkey_t key)
int botan_pubkey_get_field(botan_mp_t output, botan_pubkey_t key, const char *field_name_cstr)
int botan_privkey_load_ecdh(botan_privkey_t *key, const botan_mp_t scalar, const char *curve_name)
int botan_pubkey_load_dh(botan_pubkey_t *key, botan_mp_t p, botan_mp_t g, botan_mp_t y)
int botan_pubkey_ed25519_get_pubkey(botan_pubkey_t key, uint8_t output[32])
int botan_privkey_rsa_get_privkey(botan_privkey_t rsa_key, uint8_t out[], size_t *out_len, uint32_t flags)
int botan_privkey_load_rsa_pkcs1(botan_privkey_t *key, const uint8_t bits[], size_t len)
int botan_pubkey_load_sm2(botan_pubkey_t *key, const botan_mp_t public_x, const botan_mp_t public_y, const char *curve_name)
int botan_pubkey_sm2_compute_za(uint8_t out[], size_t *out_len, const char *ident, const char *hash_algo, const botan_pubkey_t key)
int botan_privkey_load_x25519(botan_privkey_t *key, const uint8_t privkey[32])
int botan_pubkey_dsa_get_p(botan_mp_t p, botan_pubkey_t key)
int botan_privkey_rsa_get_q(botan_mp_t q, botan_privkey_t key)
int botan_privkey_ed25519_get_privkey(botan_privkey_t key, uint8_t output[64])
int botan_privkey_load_sm2_enc(botan_privkey_t *key, const botan_mp_t scalar, const char *curve_name)
int botan_privkey_get_field(botan_mp_t output, botan_privkey_t key, const char *field_name_cstr)
int botan_privkey_load_rsa(botan_privkey_t *key, botan_mp_t rsa_p, botan_mp_t rsa_q, botan_mp_t rsa_e)
int botan_pubkey_dsa_get_y(botan_mp_t y, botan_pubkey_t key)
int botan_privkey_load_dh(botan_privkey_t *key, botan_mp_t p, botan_mp_t g, botan_mp_t x)
int botan_privkey_load_sm2(botan_privkey_t *key, const botan_mp_t scalar, const char *curve_name)
int botan_pubkey_load_ed25519(botan_pubkey_t *key, const uint8_t pubkey[32])
int botan_privkey_load_ecdsa(botan_privkey_t *key, const botan_mp_t scalar, const char *curve_name)
int botan_mceies_encrypt(botan_pubkey_t mce_key_obj, botan_rng_t rng_obj, const char *aead, const uint8_t pt[], size_t pt_len, const uint8_t ad[], size_t ad_len, uint8_t out[], size_t *out_len)
int botan_pubkey_x25519_get_pubkey(botan_pubkey_t key, uint8_t output[32])
int botan_pubkey_load_elgamal(botan_pubkey_t *key, botan_mp_t p, botan_mp_t g, botan_mp_t y)
int botan_privkey_create_dsa(botan_privkey_t *key, botan_rng_t rng_obj, size_t pbits, size_t qbits)
int botan_privkey_rsa_get_p(botan_mp_t p, botan_privkey_t key)
int botan_privkey_create_mceliece(botan_privkey_t *key_obj, botan_rng_t rng_obj, size_t n, size_t t)
int botan_privkey_create_ecdh(botan_privkey_t *key_obj, botan_rng_t rng_obj, const char *param_str)
int botan_privkey_rsa_get_d(botan_mp_t d, botan_privkey_t key)
int botan_pubkey_load_sm2_enc(botan_pubkey_t *key, const botan_mp_t public_x, const botan_mp_t public_y, const char *curve_name)
int botan_mceies_decrypt(botan_privkey_t mce_key_obj, const char *aead, const uint8_t ct[], size_t ct_len, const uint8_t ad[], size_t ad_len, uint8_t out[], size_t *out_len)
int botan_pubkey_load_x25519(botan_pubkey_t *key, const uint8_t pubkey[32])
int botan_privkey_load_elgamal(botan_privkey_t *key, botan_mp_t p, botan_mp_t g, botan_mp_t x)
int botan_privkey_create_rsa(botan_privkey_t *key_obj, botan_rng_t rng_obj, size_t n_bits)
int botan_pubkey_load_dsa(botan_pubkey_t *key, botan_mp_t p, botan_mp_t q, botan_mp_t g, botan_mp_t y)
int botan_privkey_create_dh(botan_privkey_t *key_obj, botan_rng_t rng_obj, const char *param_str)
int botan_privkey_load_dsa(botan_privkey_t *key, botan_mp_t p, botan_mp_t q, botan_mp_t g, botan_mp_t x)
int botan_privkey_rsa_get_n(botan_mp_t n, botan_privkey_t key)
int botan_pubkey_rsa_get_e(botan_mp_t e, botan_pubkey_t key)
int botan_pubkey_dsa_get_g(botan_mp_t g, botan_pubkey_t key)
int botan_pubkey_dsa_get_q(botan_mp_t q, botan_pubkey_t key)
int botan_pubkey_load_ecdsa(botan_pubkey_t *key, const botan_mp_t public_x, const botan_mp_t public_y, const char *curve_name)
int botan_pubkey_load_ecdh(botan_pubkey_t *key, const botan_mp_t public_x, const botan_mp_t public_y, const char *curve_name)
int botan_privkey_load_ed25519(botan_privkey_t *key, const uint8_t privkey[32])
int botan_privkey_rsa_get_e(botan_mp_t e, botan_privkey_t key)
int botan_privkey_x25519_get_privkey(botan_privkey_t key, uint8_t output[32])
int botan_privkey_dsa_get_x(botan_mp_t x, botan_privkey_t key)
int botan_pubkey_load_rsa(botan_pubkey_t *key, botan_mp_t n, botan_mp_t e)
int botan_privkey_create_ecdsa(botan_privkey_t *key_obj, botan_rng_t rng_obj, const char *param_str)
#define BOTAN_FFI_DO(T, obj, param, block)
std::string to_string(const BER_Object &obj)
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
T & safe_get(botan_struct< T, M > *p)
int write_str_output(uint8_t out[], size_t *out_len, const std::string &str)
int ffi_guard_thunk(const char *func_name, const std::function< int()> &thunk)
int write_vec_output(uint8_t out[], size_t *out_len, const std::vector< uint8_t, Alloc > &buf)
constexpr void copy_mem(T *out, const T *in, size_t n)
std::vector< uint8_t > sm2_compute_za(HashFunction &hash, const std::string &user_id, const EC_Group &domain, const PointGFp &pubkey)
std::vector< T, secure_allocator< T > > secure_vector
AlgorithmIdentifier hash_algo