11#include <botan/hash.h>
13#include <botan/internal/ffi_mp.h>
14#include <botan/internal/ffi_pkey.h>
15#include <botan/internal/ffi_rng.h>
16#include <botan/internal/ffi_util.h>
18#if defined(BOTAN_HAS_DL_GROUP)
19 #include <botan/dl_group.h>
22#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
23 #include <botan/ecc_key.h>
26#if defined(BOTAN_HAS_RSA)
27 #include <botan/rsa.h>
30#if defined(BOTAN_HAS_ELGAMAL)
31 #include <botan/elgamal.h>
34#if defined(BOTAN_HAS_DSA)
35 #include <botan/dsa.h>
38#if defined(BOTAN_HAS_ECDSA)
39 #include <botan/ecdsa.h>
42#if defined(BOTAN_HAS_SM2)
43 #include <botan/sm2.h>
46#if defined(BOTAN_HAS_ECDH)
47 #include <botan/ecdh.h>
50#if defined(BOTAN_HAS_CURVE_25519)
51 #include <botan/curve25519.h>
54#if defined(BOTAN_HAS_ED25519)
55 #include <botan/ed25519.h>
58#if defined(BOTAN_HAS_MCELIECE)
59 #include <botan/mceliece.h>
62#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
66#if defined(BOTAN_HAS_KYBER)
67 #include <botan/kyber.h>
72#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
76template <
class ECPrivateKey_t>
77int privkey_load_ec(std::unique_ptr<ECPrivateKey_t>& key,
const Botan::BigInt& scalar,
const char* curve_name) {
78 if(curve_name ==
nullptr) {
84 key.reset(
new ECPrivateKey_t(null_rng, grp, scalar));
88template <
class ECPublicKey_t>
89int pubkey_load_ec(std::unique_ptr<ECPublicKey_t>& key,
92 const char* curve_name) {
93 if(curve_name ==
nullptr) {
99 key.reset(
new ECPublicKey_t(grp, uncompressed_point));
106#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
109 if(field ==
"public_x") {
110 return ecc->public_point().get_affine_x();
111 }
else if(field ==
"public_y") {
112 return ecc->public_point().get_affine_y();
125#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
128 if(field ==
"public_x") {
129 return ecc->public_point().get_affine_x();
130 }
else if(field ==
"public_y") {
131 return ecc->public_point().get_affine_y();
150 if(field_name_cstr ==
nullptr) {
154 const std::string field_name(field_name_cstr);
160 if(field_name_cstr ==
nullptr) {
164 const std::string field_name(field_name_cstr);
172 if(n_bits < 1024 || n_bits > 16 * 1024) {
176 std::string n_str = std::to_string(n_bits);
182#if defined(BOTAN_HAS_RSA)
187 *key =
new botan_privkey_struct(std::move(rsa));
197#if defined(BOTAN_HAS_RSA)
203 auto rsa = std::make_unique<Botan::RSA_PrivateKey>(alg_id, src);
204 *key =
new botan_privkey_struct(std::move(rsa));
214#if defined(BOTAN_HAS_RSA)
217 auto rsa = std::make_unique<Botan::RSA_PublicKey>(
safe_get(n),
safe_get(e));
218 *key =
new botan_pubkey_struct(std::move(rsa));
256#if defined(BOTAN_HAS_RSA)
277#if defined(BOTAN_HAS_DSA)
279 if((rng_obj ==
nullptr) || (key ==
nullptr)) {
283 if((pbits % 64) || (qbits % 8) || (pbits < 1024) || (pbits > 3072) || (qbits < 160) || (qbits > 256)) {
290 auto dsa = std::make_unique<Botan::DSA_PrivateKey>(rng, group);
291 *key =
new botan_privkey_struct(std::move(dsa));
301#if defined(BOTAN_HAS_DSA)
306 auto dsa = std::make_unique<Botan::DSA_PrivateKey>(group,
safe_get(x));
307 *key =
new botan_privkey_struct(std::move(dsa));
317#if defined(BOTAN_HAS_DSA)
322 auto dsa = std::make_unique<Botan::DSA_PublicKey>(group,
safe_get(y));
323 *key =
new botan_pubkey_struct(std::move(dsa));
359#if defined(BOTAN_HAS_ECC_KEY)
364 if(ec_key ==
nullptr) {
379 const char* curve_name) {
380#if defined(BOTAN_HAS_ECDSA)
382 std::unique_ptr<Botan::ECDSA_PublicKey> p_key;
384 int rc = pubkey_load_ec(p_key,
safe_get(public_x),
safe_get(public_y), curve_name);
386 *key =
new botan_pubkey_struct(std::move(p_key));
398#if defined(BOTAN_HAS_ECDSA)
400 std::unique_ptr<Botan::ECDSA_PrivateKey> p_key;
401 int rc = privkey_load_ec(p_key,
safe_get(scalar), curve_name);
403 *key =
new botan_privkey_struct(std::move(p_key));
415#if defined(BOTAN_HAS_ELGAMAL)
417 if((rng_obj ==
nullptr) || (key ==
nullptr)) {
421 if((pbits < 1024) || (qbits < 160)) {
431 auto elg = std::make_unique<Botan::ElGamal_PrivateKey>(rng, group);
432 *key =
new botan_privkey_struct(std::move(elg));
442#if defined(BOTAN_HAS_ELGAMAL)
446 auto elg = std::make_unique<Botan::ElGamal_PublicKey>(group,
safe_get(y));
447 *key =
new botan_pubkey_struct(std::move(elg));
457#if defined(BOTAN_HAS_ELGAMAL)
461 auto elg = std::make_unique<Botan::ElGamal_PrivateKey>(group,
safe_get(x));
462 *key =
new botan_privkey_struct(std::move(elg));
478#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
482 auto dh = std::make_unique<Botan::DH_PrivateKey>(group,
safe_get(x));
483 *key =
new botan_privkey_struct(std::move(dh));
493#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
497 auto dh = std::make_unique<Botan::DH_PublicKey>(group,
safe_get(y));
498 *key =
new botan_pubkey_struct(std::move(dh));
510 if(param_str ==
nullptr) {
514 const std::string params(param_str);
516 if(params ==
"curve25519") {
526 const char* curve_name) {
527#if defined(BOTAN_HAS_ECDH)
529 std::unique_ptr<Botan::ECDH_PublicKey> p_key;
530 int rc = pubkey_load_ec(p_key,
safe_get(public_x),
safe_get(public_y), curve_name);
533 *key =
new botan_pubkey_struct(std::move(p_key));
544#if defined(BOTAN_HAS_ECDH)
546 std::unique_ptr<Botan::ECDH_PrivateKey> p_key;
547 int rc = privkey_load_ec(p_key,
safe_get(scalar), curve_name);
549 *key =
new botan_privkey_struct(std::move(p_key));
562 uint8_t out[],
size_t* out_len,
const char* ident,
const char* hash_algo,
const botan_pubkey_t key) {
563 if(out ==
nullptr || out_len ==
nullptr) {
566 if(ident ==
nullptr || hash_algo ==
nullptr || key ==
nullptr) {
570#if defined(BOTAN_HAS_SM2)
575 if(ec_key ==
nullptr) {
583 const std::string ident_str(ident);
598 const char* curve_name) {
599#if defined(BOTAN_HAS_SM2)
601 std::unique_ptr<Botan::SM2_PublicKey> p_key;
602 if(!pubkey_load_ec(p_key,
safe_get(public_x),
safe_get(public_y), curve_name)) {
603 *key =
new botan_pubkey_struct(std::move(p_key));
615#if defined(BOTAN_HAS_SM2)
617 std::unique_ptr<Botan::SM2_PrivateKey> p_key;
618 int rc = privkey_load_ec(p_key,
safe_get(scalar), curve_name);
621 *key =
new botan_privkey_struct(std::move(p_key));
634 const char* curve_name) {
645#if defined(BOTAN_HAS_ED25519)
649 auto ed25519 = std::make_unique<Botan::Ed25519_PrivateKey>(privkey_vec);
650 *key =
new botan_privkey_struct(std::move(ed25519));
660#if defined(BOTAN_HAS_ED25519)
663 const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32);
664 auto ed25519 = std::make_unique<Botan::Ed25519_PublicKey>(pubkey_vec);
665 *key =
new botan_pubkey_struct(std::move(ed25519));
675#if defined(BOTAN_HAS_ED25519)
678 const auto ed_key = ed->raw_private_key_bits();
679 if(ed_key.size() != 64)
694#if defined(BOTAN_HAS_ED25519)
697 const std::vector<uint8_t>& ed_key = ed->get_public_key();
698 if(ed_key.size() != 32)
715#if defined(BOTAN_HAS_X25519)
719 auto x25519 = std::make_unique<Botan::X25519_PrivateKey>(privkey_vec);
720 *key =
new botan_privkey_struct(std::move(x25519));
730#if defined(BOTAN_HAS_X25519)
733 const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 32);
734 auto x25519 = std::make_unique<Botan::X25519_PublicKey>(pubkey_vec);
735 *key =
new botan_pubkey_struct(std::move(x25519));
745#if defined(BOTAN_HAS_X25519)
748 const auto x25519_key = x25519->raw_private_key_bits();
749 if(x25519_key.size() != 32)
764#if defined(BOTAN_HAS_X25519)
767 const std::vector<uint8_t>& x25519_key = x25519->public_value();
768 if(x25519_key.size() != 32)
787#if defined(BOTAN_HAS_KYBER)
794 *key =
new botan_privkey_struct(std::move(kyber512));
801 *key =
new botan_privkey_struct(std::move(kyber768));
808 *key =
new botan_privkey_struct(std::move(kyber1024));
822#if defined(BOTAN_HAS_KYBER)
827 const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 800);
829 *key =
new botan_pubkey_struct(std::move(kyber512));
834 const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 1184);
836 *key =
new botan_pubkey_struct(std::move(kyber768));
841 const std::vector<uint8_t> pubkey_vec(pubkey, pubkey + 1568);
843 *key =
new botan_pubkey_struct(std::move(kyber1024));
857#if defined(BOTAN_HAS_KYBER)
872#if defined(BOTAN_HAS_KYBER)
887#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
903 const std::string mce_params = std::to_string(n) +
"," + std::to_string(t);
915 BOTAN_UNUSED(mce_key_obj, aead, ct, ct_len, ad, ad_len, out, out_len);
928 BOTAN_UNUSED(mce_key_obj, rng_obj, aead, pt, pt_len, ad, ad_len, out, out_len);
virtual std::string algo_name() const =0
virtual const BigInt & get_int_field(std::string_view field) const
bool used_explicit_encoding() const
const EC_Group & domain() const
const EC_Point & public_point() const
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
struct botan_pubkey_struct * botan_pubkey_t
struct botan_privkey_struct * botan_privkey_t
int(* botan_view_bin_fn)(botan_view_ctx view_ctx, const uint8_t *data, size_t len)
#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
BOTAN_DLL int botan_privkey_create(botan_privkey_t *key, const char *algo_name, const char *algo_params, botan_rng_t rng)
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_privkey_view_kyber_raw_key(botan_privkey_t key, botan_view_ctx ctx, botan_view_bin_fn view)
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_pubkey_ecc_key_used_explicit_encoding(botan_pubkey_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_pubkey_view_ec_public_point(const botan_pubkey_t key, botan_view_ctx ctx, botan_view_bin_fn view)
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_pubkey_load_kyber(botan_pubkey_t *key, const uint8_t pubkey[], size_t key_len)
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_privkey_load_kyber(botan_privkey_t *key, const uint8_t privkey[], size_t key_len)
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)
int botan_pubkey_view_kyber_raw_key(botan_pubkey_t key, botan_view_ctx ctx, botan_view_bin_fn view)
#define BOTAN_FFI_VISIT(obj, lambda)
std::string encode(const uint8_t der[], size_t length, std::string_view label, size_t width)
int write_str_output(uint8_t out[], size_t *out_len, std::string_view str)
T & safe_get(botan_struct< T, M > *p)
int invoke_view_callback(botan_view_bin_fn view, botan_view_ctx ctx, const std::vector< uint8_t, Alloc > &buf)
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)
std::vector< uint8_t > sm2_compute_za(HashFunction &hash, std::string_view user_id, const EC_Group &domain, const EC_Point &pubkey)
BOTAN_DIAGNOSTIC_POP typedef Curve25519_PublicKey X25519_PublicKey
constexpr void copy_mem(T *out, const T *in, size_t n)
std::vector< T, secure_allocator< T > > secure_vector