From 7c664b1f1b5f60bf896f5fdea5c08c401c541dfe Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Mon, 27 Jul 2020 18:40:05 +0200 Subject: DESERIALIZER: Add deserializers for the rest of our asymmetric key types To be able to implement this, there was a need for the standard EVP_PKEY_set1_, EVP_PKEY_get0_ and EVP_PKEY_get1_ functions for ED25519, ED448, X25519 and X448, as well as the corresponding EVP_PKEY_assign_ macros. There was also a need to extend the list of hard coded names that EVP_PKEY_is_a() recognise. Along with this, OSSL_FUNC_keymgmt_load() are implemented for all those key types. The deserializers for these key types are all implemented generically, in providers/implementations/serializers/deserializer_der2key.c. Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/12544) --- crypto/err/openssl.txt | 2 + crypto/evp/evp_err.c | 2 + crypto/evp/p_lib.c | 61 ++++ doc/man3/EVP_PKEY_set1_RSA.pod | 55 +++- include/openssl/evp.h | 21 ++ include/openssl/evperr.h | 2 + providers/deserializers.inc | 14 + .../implementations/include/prov/implementations.h | 7 + providers/implementations/keymgmt/dh_kmgmt.c | 16 + providers/implementations/keymgmt/dsa_kmgmt.c | 16 + providers/implementations/keymgmt/ec_kmgmt.c | 16 + providers/implementations/keymgmt/ecx_kmgmt.c | 16 + providers/implementations/serializers/build.info | 3 +- .../serializers/deserialize_der2key.c | 234 ++++++++++++++ .../serializers/deserialize_der2rsa.c | 241 -------------- test/serdes_test.c | 346 +++++++++++++-------- util/libcrypto.num | 12 + util/other.syms | 4 + 18 files changed, 684 insertions(+), 384 deletions(-) create mode 100644 providers/implementations/serializers/deserialize_der2key.c delete mode 100644 providers/implementations/serializers/deserialize_der2rsa.c diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 0124d1d3ae..1b4fca9b97 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -875,6 +875,7 @@ EVP_F_EVP_PKEY_ENCRYPT_INIT:139:EVP_PKEY_encrypt_init EVP_F_EVP_PKEY_ENCRYPT_OLD:152:EVP_PKEY_encrypt_old EVP_F_EVP_PKEY_GET0_DH:119:EVP_PKEY_get0_DH EVP_F_EVP_PKEY_GET0_DSA:120:EVP_PKEY_get0_DSA +EVP_F_EVP_PKEY_GET0_ECX_KEY:222: EVP_F_EVP_PKEY_GET0_EC_KEY:131:EVP_PKEY_get0_EC_KEY EVP_F_EVP_PKEY_GET0_HMAC:183:EVP_PKEY_get0_hmac EVP_F_EVP_PKEY_GET0_POLY1305:184:EVP_PKEY_get0_poly1305 @@ -2532,6 +2533,7 @@ EVP_R_EXPECTING_AN_HMAC_KEY:174:expecting an hmac key EVP_R_EXPECTING_AN_RSA_KEY:127:expecting an rsa key EVP_R_EXPECTING_A_DH_KEY:128:expecting a dh key EVP_R_EXPECTING_A_DSA_KEY:129:expecting a dsa key +EVP_R_EXPECTING_A_ECX_KEY:219:expecting a ecx key EVP_R_EXPECTING_A_EC_KEY:142:expecting a ec key EVP_R_EXPECTING_A_POLY1305_KEY:164:expecting a poly1305 key EVP_R_EXPECTING_A_SIPHASH_KEY:175:expecting a siphash key diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index 239efaa51a..d13cd05faa 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -61,6 +61,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_DH_KEY), "expecting a dh key"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_DSA_KEY), "expecting a dsa key"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_ECX_KEY), + "expecting a ecx key"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_EC_KEY), "expecting a ec key"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_POLY1305_KEY), "expecting a poly1305 key"}, diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index a7fd687dd0..3e3f2118a2 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -34,6 +34,7 @@ #include "crypto/asn1.h" #include "crypto/evp.h" +#include "crypto/ecx.h" #include "internal/evp.h" #include "internal/provider.h" #include "evp_local.h" @@ -855,6 +856,54 @@ EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) EC_KEY_up_ref(ret); return ret; } + +static int EVP_PKEY_set1_ECX_KEY(EVP_PKEY *pkey, int type, ECX_KEY *key) +{ + int ret = EVP_PKEY_assign(pkey, type, key); + if (ret) + ecx_key_up_ref(key); + return ret; +} + +static ECX_KEY *EVP_PKEY_get0_ECX_KEY(const EVP_PKEY *pkey, int type) +{ + if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY); + return NULL; + } + if (EVP_PKEY_base_id(pkey) != type) { + ERR_raise(ERR_LIB_EVP, EVP_R_EXPECTING_A_ECX_KEY); + return NULL; + } + return pkey->pkey.ecx; +} + +static ECX_KEY *EVP_PKEY_get1_ECX_KEY(EVP_PKEY *pkey, int type) +{ + ECX_KEY *ret = EVP_PKEY_get0_ECX_KEY(pkey, type); + if (ret != NULL) + ecx_key_up_ref(ret); + return ret; +} + +# define IMPLEMENT_ECX_VARIANT(NAME) \ + int EVP_PKEY_set1_##NAME(EVP_PKEY *pkey, ECX_KEY *key) \ + { \ + return EVP_PKEY_set1_ECX_KEY(pkey, EVP_PKEY_##NAME, key); \ + } \ + ECX_KEY *EVP_PKEY_get0_##NAME(const EVP_PKEY *pkey) \ + { \ + return EVP_PKEY_get0_ECX_KEY(pkey, EVP_PKEY_##NAME); \ + } \ + ECX_KEY *EVP_PKEY_get1_##NAME(EVP_PKEY *pkey) \ + { \ + return EVP_PKEY_get1_ECX_KEY(pkey, EVP_PKEY_##NAME); \ + } +IMPLEMENT_ECX_VARIANT(X25519) +IMPLEMENT_ECX_VARIANT(X448) +IMPLEMENT_ECX_VARIANT(ED25519) +IMPLEMENT_ECX_VARIANT(ED448) + # endif # ifndef OPENSSL_NO_DH @@ -940,6 +989,18 @@ int EVP_PKEY_is_a(const EVP_PKEY *pkey, const char *name) #ifndef OPENSSL_NO_EC else if (strcasecmp(name, "EC") == 0) type = EVP_PKEY_EC; + else if (strcasecmp(name, "ED25519") == 0) + type = EVP_PKEY_ED25519; + else if (strcasecmp(name, "ED448") == 0) + type = EVP_PKEY_ED448; + else if (strcasecmp(name, "X25519") == 0) + type = EVP_PKEY_X25519; + else if (strcasecmp(name, "X448") == 0) + type = EVP_PKEY_X448; +#endif +#ifndef OPENSSL_NO_DH + else if (strcasecmp(name, "DH") == 0) + type = EVP_PKEY_DH; #endif #ifndef OPENSSL_NO_DSA else if (strcasecmp(name, "DSA") == 0) diff --git a/doc/man3/EVP_PKEY_set1_RSA.pod b/doc/man3/EVP_PKEY_set1_RSA.pod index 10a8e94661..89737a3c8c 100644 --- a/doc/man3/EVP_PKEY_set1_RSA.pod +++ b/doc/man3/EVP_PKEY_set1_RSA.pod @@ -3,10 +3,18 @@ =head1 NAME EVP_PKEY_set1_RSA, EVP_PKEY_set1_DSA, EVP_PKEY_set1_DH, EVP_PKEY_set1_EC_KEY, +EVP_PKEY_set1_ED25519, EVP_PKEY_set1_ED448, +EVP_PKEY_set1_X25519, EVP_PKEY_set1_X448, EVP_PKEY_get1_RSA, EVP_PKEY_get1_DSA, EVP_PKEY_get1_DH, EVP_PKEY_get1_EC_KEY, +EVP_PKEY_get1_ED25519, EVP_PKEY_get1_ED448, +EVP_PKEY_get1_X25519, EVP_PKEY_get1_X448, EVP_PKEY_get0_RSA, EVP_PKEY_get0_DSA, EVP_PKEY_get0_DH, EVP_PKEY_get0_EC_KEY, +EVP_PKEY_get0_ED25519, EVP_PKEY_get0_ED448, +EVP_PKEY_get0_X25519, EVP_PKEY_get0_X448, EVP_PKEY_assign_RSA, EVP_PKEY_assign_DSA, EVP_PKEY_assign_DH, EVP_PKEY_assign_EC_KEY, EVP_PKEY_assign_POLY1305, EVP_PKEY_assign_SIPHASH, +EVP_PKEY_assign_ED25519, EVP_PKEY_assign_ED448, +EVP_PKEY_assign_X25519, EVP_PKEY_assign_X448, EVP_PKEY_get0_hmac, EVP_PKEY_get0_poly1305, EVP_PKEY_get0_siphash, EVP_PKEY_type, EVP_PKEY_id, EVP_PKEY_base_id, EVP_PKEY_set_alias_type, EVP_PKEY_set1_engine, EVP_PKEY_get0_engine - EVP_PKEY assignment functions @@ -19,11 +27,19 @@ EVP_PKEY_set1_engine, EVP_PKEY_get0_engine - EVP_PKEY assignment functions int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key); int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key); int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key); + int EVP_PKEY_set1_ED25519(EVP_PKEY *pkey, ECX_KEY *key); + int EVP_PKEY_set1_ED448(EVP_PKEY *pkey, ECX_KEY *key); + int EVP_PKEY_set1_X25519(EVP_PKEY *pkey, ECX_KEY *key); + int EVP_PKEY_set1_X448(EVP_PKEY *pkey, ECX_KEY *key); RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey); DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey); DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey); EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); + ECX_KEY *EVP_PKEY_get1_ED25519(EVP_PKEY *pkey); + ECX_KEY *EVP_PKEY_get1_ED448(EVP_PKEY *pkey); + ECX_KEY *EVP_PKEY_get1_X25519(EVP_PKEY *pkey); + ECX_KEY *EVP_PKEY_get1_X448(EVP_PKEY *pkey); const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len); const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len); @@ -32,11 +48,19 @@ EVP_PKEY_set1_engine, EVP_PKEY_get0_engine - EVP_PKEY assignment functions DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey); DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey); EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey); + ECX_KEY *EVP_PKEY_get0_ED25519(EVP_PKEY *pkey); + ECX_KEY *EVP_PKEY_get0_ED448(EVP_PKEY *pkey); + ECX_KEY *EVP_PKEY_get0_X25519(EVP_PKEY *pkey); + ECX_KEY *EVP_PKEY_get0_X448(EVP_PKEY *pkey); int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key); int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key); int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key); int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key); + int EVP_PKEY_assign_ED25519(EVP_PKEY *pkey, ECX_KEY *key); + int EVP_PKEY_assign_ED448(EVP_PKEY *pkey, ECX_KEY *key); + int EVP_PKEY_assign_X25519(EVP_PKEY *pkey, ECX_KEY *key); + int EVP_PKEY_assign_X448(EVP_PKEY *pkey, ECX_KEY *key); int EVP_PKEY_assign_POLY1305(EVP_PKEY *pkey, ASN1_OCTET_STRING *key); int EVP_PKEY_assign_SIPHASH(EVP_PKEY *pkey, ASN1_OCTET_STRING *key); @@ -50,24 +74,31 @@ EVP_PKEY_set1_engine, EVP_PKEY_get0_engine - EVP_PKEY assignment functions =head1 DESCRIPTION -EVP_PKEY_set1_RSA(), EVP_PKEY_set1_DSA(), EVP_PKEY_set1_DH() and -EVP_PKEY_set1_EC_KEY() set the key referenced by I to I. +EVP_PKEY_set1_RSA(), EVP_PKEY_set1_DSA(), EVP_PKEY_set1_DH(), +EVP_PKEY_set1_EC_KEY(), EVP_PKEY_set1_ED25519(), EVP_PKEY_set1_ED448(), +EVP_PKEY_set1_X25519() and EVP_PKEY_set1_X448() set the key referenced by +I to I. EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH() and -EVP_PKEY_get1_EC_KEY() return the referenced key in I or -NULL if the key is not of the correct type. +EVP_PKEY_get1_EC_KEY(), EVP_PKEY_get1_ED25519(), EVP_PKEY_get1_ED448(), +EVP_PKEY_get1_X25519() and EVP_PKEY_get1_X448() return the referenced key in +I or NULL if the key is not of the correct type. The returned key must +be freed after use. EVP_PKEY_get0_hmac(), EVP_PKEY_get0_poly1305(), EVP_PKEY_get0_siphash(), -EVP_PKEY_get0_RSA(), EVP_PKEY_get0_DSA(), EVP_PKEY_get0_DH() -and EVP_PKEY_get0_EC_KEY() also return the referenced key in I or NULL -if the key is not of the correct type but the reference count of the -returned key is B incremented and so must not be freed up after use. +EVP_PKEY_get0_RSA(), EVP_PKEY_get0_DSA(), EVP_PKEY_get0_DH(), +EVP_PKEY_get0_EC_KEY(), EVP_PKEY_get0_ED25519(), EVP_PKEY_get0_ED448(), +EVP_PKEY_get0_X25519() and EVP_PKEY_get0_X448() return the referenced +key in I or NULL if the key is not of the correct type but the +reference count of the returned key is B incremented and so must not be +freed after use. EVP_PKEY_assign_RSA(), EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH(), -EVP_PKEY_assign_EC_KEY(), EVP_PKEY_assign_POLY1305() and -EVP_PKEY_assign_SIPHASH() also set the referenced key to I -however these use the supplied I internally and so I -will be freed when the parent I is freed. +EVP_PKEY_assign_EC_KEY(), EVP_PKEY_assign_ED25519(), EVP_PKEY_assign_ED448(), +EVP_PKEY_assign_X25519(), EVP_PKEY_assign_X448(), EVP_PKEY_assign_POLY1305() and +EVP_PKEY_assign_SIPHASH() set the referenced key to I however these use +the supplied I internally and so I will be freed when the parent +I is freed. EVP_PKEY_base_id() returns the type of I. For example an RSA key will return B. diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 78771ca251..57b6ff1f7c 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -466,6 +466,14 @@ typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass, # ifndef OPENSSL_NO_EC # define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\ (eckey)) +# define EVP_PKEY_assign_X25519(pkey,ecxkey) EVP_PKEY_assign((pkey),EVP_PKEY_X25519,\ + (ecxkey)) +# define EVP_PKEY_assign_X448(pkey,ecxkey) EVP_PKEY_assign((pkey),EVP_PKEY_X448,\ + (ecxkey)) +# define EVP_PKEY_assign_ED25519(pkey,ecxkey) EVP_PKEY_assign((pkey),EVP_PKEY_ED25519,\ + (ecxkey)) +# define EVP_PKEY_assign_ED448(pkey,ecxkey) EVP_PKEY_assign((pkey),EVP_PKEY_ED448,\ + (ecxkey)) # endif # ifndef OPENSSL_NO_SIPHASH # define EVP_PKEY_assign_SIPHASH(pkey,shkey) EVP_PKEY_assign((pkey),\ @@ -1222,6 +1230,19 @@ struct ec_key_st; int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key); struct ec_key_st *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey); struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); +struct ecx_key_st; +int EVP_PKEY_set1_X25519(EVP_PKEY *pkey, struct ecx_key_st *key); +struct ecx_key_st *EVP_PKEY_get0_X25519(const EVP_PKEY *pkey); +struct ecx_key_st *EVP_PKEY_get1_X25519(EVP_PKEY *pkey); +int EVP_PKEY_set1_X448(EVP_PKEY *pkey, struct ecx_key_st *key); +struct ecx_key_st *EVP_PKEY_get0_X448(const EVP_PKEY *pkey); +struct ecx_key_st *EVP_PKEY_get1_X448(EVP_PKEY *pkey); +int EVP_PKEY_set1_ED25519(EVP_PKEY *pkey, struct ecx_key_st *key); +struct ecx_key_st *EVP_PKEY_get0_ED25519(const EVP_PKEY *pkey); +struct ecx_key_st *EVP_PKEY_get1_ED25519(EVP_PKEY *pkey); +int EVP_PKEY_set1_ED448(EVP_PKEY *pkey, struct ecx_key_st *key); +struct ecx_key_st *EVP_PKEY_get0_ED448(const EVP_PKEY *pkey); +struct ecx_key_st *EVP_PKEY_get1_ED448(EVP_PKEY *pkey); # endif EVP_PKEY *EVP_PKEY_new(void); diff --git a/include/openssl/evperr.h b/include/openssl/evperr.h index 6bc106812b..5aa002815a 100644 --- a/include/openssl/evperr.h +++ b/include/openssl/evperr.h @@ -102,6 +102,7 @@ int ERR_load_EVP_strings(void); # define EVP_F_EVP_PKEY_ENCRYPT_OLD 0 # define EVP_F_EVP_PKEY_GET0_DH 0 # define EVP_F_EVP_PKEY_GET0_DSA 0 +# define EVP_F_EVP_PKEY_GET0_ECX_KEY 0 # define EVP_F_EVP_PKEY_GET0_EC_KEY 0 # define EVP_F_EVP_PKEY_GET0_HMAC 0 # define EVP_F_EVP_PKEY_GET0_POLY1305 0 @@ -185,6 +186,7 @@ int ERR_load_EVP_strings(void); # define EVP_R_EXPECTING_AN_RSA_KEY 127 # define EVP_R_EXPECTING_A_DH_KEY 128 # define EVP_R_EXPECTING_A_DSA_KEY 129 +# define EVP_R_EXPECTING_A_ECX_KEY 219 # define EVP_R_EXPECTING_A_EC_KEY 142 # define EVP_R_EXPECTING_A_POLY1305_KEY 164 # define EVP_R_EXPECTING_A_SIPHASH_KEY 175 diff --git a/providers/deserializers.inc b/providers/deserializers.inc index bab709d31d..ead1c67878 100644 --- a/providers/deserializers.inc +++ b/providers/deserializers.inc @@ -11,6 +11,20 @@ # error Macro DESER undefined #endif +#ifndef OPENSSL_NO_DH + DESER("DH", "yes", "der", der_to_dh_deserializer_functions), +#endif +#ifndef OPENSSL_NO_DSA + DESER("DSA", "yes", "der", der_to_dsa_deserializer_functions), +#endif +#ifndef OPENSSL_NO_EC + DESER("EC", "yes", "der", der_to_ec_deserializer_functions), + DESER("ED25519", "yes", "der", der_to_ed25519_deserializer_functions), + DESER("ED448", "yes", "der", der_to_ed448_deserializer_functions), + DESER("X25519", "yes", "der", der_to_x25519_deserializer_functions), + DESER("X448", "yes", "der", der_to_x448_deserializer_functions), +#endif DESER("RSA", "yes", "der", der_to_rsa_deserializer_functions), DESER("RSA-PSS", "yes", "der", der_to_rsapss_deserializer_functions), + DESER("DER", "yes", "pem", pem_to_der_deserializer_functions), diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h index b02f0c6476..73d4a0225e 100644 --- a/providers/implementations/include/prov/implementations.h +++ b/providers/implementations/include/prov/implementations.h @@ -359,6 +359,13 @@ extern const OSSL_DISPATCH ec_priv_pem_serializer_functions[]; extern const OSSL_DISPATCH ec_pub_pem_serializer_functions[]; extern const OSSL_DISPATCH ec_param_pem_serializer_functions[]; +extern const OSSL_DISPATCH der_to_dh_deserializer_functions[]; +extern const OSSL_DISPATCH der_to_dsa_deserializer_functions[]; +extern const OSSL_DISPATCH der_to_ec_deserializer_functions[]; +extern const OSSL_DISPATCH der_to_x25519_deserializer_functions[]; +extern const OSSL_DISPATCH der_to_x448_deserializer_functions[]; +extern const OSSL_DISPATCH der_to_ed25519_deserializer_functions[]; +extern const OSSL_DISPATCH der_to_ed448_deserializer_functions[]; extern const OSSL_DISPATCH der_to_rsa_deserializer_functions[]; extern const OSSL_DISPATCH der_to_rsapss_deserializer_functions[]; extern const OSSL_DISPATCH pem_to_der_deserializer_functions[]; diff --git a/providers/implementations/keymgmt/dh_kmgmt.c b/providers/implementations/keymgmt/dh_kmgmt.c index aa4097766d..2a8b7f8521 100644 --- a/providers/implementations/keymgmt/dh_kmgmt.c +++ b/providers/implementations/keymgmt/dh_kmgmt.c @@ -34,6 +34,7 @@ static OSSL_FUNC_keymgmt_gen_set_params_fn dh_gen_set_params; static OSSL_FUNC_keymgmt_gen_settable_params_fn dh_gen_settable_params; static OSSL_FUNC_keymgmt_gen_fn dh_gen; static OSSL_FUNC_keymgmt_gen_cleanup_fn dh_gen_cleanup; +static OSSL_FUNC_keymgmt_load_fn dh_load; static OSSL_FUNC_keymgmt_get_params_fn dh_get_params; static OSSL_FUNC_keymgmt_gettable_params_fn dh_gettable_params; static OSSL_FUNC_keymgmt_set_params_fn dh_set_params; @@ -644,6 +645,20 @@ static void dh_gen_cleanup(void *genctx) OPENSSL_free(gctx); } +void *dh_load(const void *reference, size_t reference_sz) +{ + DH *dh = NULL; + + if (reference_sz == sizeof(dh)) { + /* The contents of the reference is the address to our object */ + dh = *(DH **)reference; + /* We grabbed, so we detach it */ + *(DH **)reference = NULL; + return dh; + } + return NULL; +} + const OSSL_DISPATCH dh_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dh_newdata }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))dh_gen_init }, @@ -653,6 +668,7 @@ const OSSL_DISPATCH dh_keymgmt_functions[] = { (void (*)(void))dh_gen_settable_params }, { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))dh_gen }, { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))dh_gen_cleanup }, + { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))dh_load }, { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))dh_freedata }, { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))dh_get_params }, { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))dh_gettable_params }, diff --git a/providers/implementations/keymgmt/dsa_kmgmt.c b/providers/implementations/keymgmt/dsa_kmgmt.c index 3d38fea44d..58e9fc564f 100644 --- a/providers/implementations/keymgmt/dsa_kmgmt.c +++ b/providers/implementations/keymgmt/dsa_kmgmt.c @@ -34,6 +34,7 @@ static OSSL_FUNC_keymgmt_gen_set_params_fn dsa_gen_set_params; static OSSL_FUNC_keymgmt_gen_settable_params_fn dsa_gen_settable_params; static OSSL_FUNC_keymgmt_gen_fn dsa_gen; static OSSL_FUNC_keymgmt_gen_cleanup_fn dsa_gen_cleanup; +static OSSL_FUNC_keymgmt_load_fn dsa_load; static OSSL_FUNC_keymgmt_get_params_fn dsa_get_params; static OSSL_FUNC_keymgmt_gettable_params_fn dsa_gettable_params; static OSSL_FUNC_keymgmt_has_fn dsa_has; @@ -557,6 +558,20 @@ static void dsa_gen_cleanup(void *genctx) OPENSSL_free(gctx); } +void *dsa_load(const void *reference, size_t reference_sz) +{ + DSA *dsa = NULL; + + if (reference_sz == sizeof(dsa)) { + /* The contents of the reference is the address to our object */ + dsa = *(DSA **)reference; + /* We grabbed, so we detach it */ + *(DSA **)reference = NULL; + return dsa; + } + return NULL; +} + const OSSL_DISPATCH dsa_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dsa_newdata }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))dsa_gen_init }, @@ -566,6 +581,7 @@ const OSSL_DISPATCH dsa_keymgmt_functions[] = { (void (*)(void))dsa_gen_settable_params }, { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))dsa_gen }, { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))dsa_gen_cleanup }, + { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))dsa_load }, { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))dsa_freedata }, { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))dsa_get_params }, { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))dsa_gettable_params }, diff --git a/providers/implementations/keymgmt/ec_kmgmt.c b/providers/implementations/keymgmt/ec_kmgmt.c index 792b2193e6..4d040a1902 100644 --- a/providers/implementations/keymgmt/ec_kmgmt.c +++ b/providers/implementations/keymgmt/ec_kmgmt.c @@ -33,6 +33,7 @@ static OSSL_FUNC_keymgmt_gen_set_params_fn ec_gen_set_params; static OSSL_FUNC_keymgmt_gen_settable_params_fn ec_gen_settable_params; static OSSL_FUNC_keymgmt_gen_fn ec_gen; static OSSL_FUNC_keymgmt_gen_cleanup_fn ec_gen_cleanup; +static OSSL_FUNC_keymgmt_load_fn ec_load; static OSSL_FUNC_keymgmt_free_fn ec_freedata; static OSSL_FUNC_keymgmt_get_params_fn ec_get_params; static OSSL_FUNC_keymgmt_gettable_params_fn ec_gettable_params; @@ -791,6 +792,20 @@ static void ec_gen_cleanup(void *genctx) OPENSSL_free(gctx); } +void *ec_load(const void *reference, size_t reference_sz) +{ + EC_KEY *ec = NULL; + + if (reference_sz == sizeof(ec)) { + /* The contents of the reference is the address to our object */ + ec = *(EC_KEY **)reference; + /* We grabbed, so we detach it */ + *(EC_KEY **)reference = NULL; + return ec; + } + return NULL; +} + const OSSL_DISPATCH ec_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))ec_newdata }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))ec_gen_init }, @@ -801,6 +816,7 @@ const OSSL_DISPATCH ec_keymgmt_functions[] = { (void (*)(void))ec_gen_settable_params }, { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))ec_gen }, { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ec_gen_cleanup }, + { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ec_load }, { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ec_freedata }, { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))ec_get_params }, { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))ec_gettable_params }, diff --git a/providers/implementations/keymgmt/ecx_kmgmt.c b/providers/implementations/keymgmt/ecx_kmgmt.c index 542592666e..a1e1edbf5a 100644 --- a/providers/implementations/keymgmt/ecx_kmgmt.c +++ b/providers/implementations/keymgmt/ecx_kmgmt.c @@ -41,6 +41,7 @@ static OSSL_FUNC_keymgmt_gen_fn x448_gen; static OSSL_FUNC_keymgmt_gen_fn ed25519_gen; static OSSL_FUNC_keymgmt_gen_fn ed448_gen; static OSSL_FUNC_keymgmt_gen_cleanup_fn ecx_gen_cleanup; +static OSSL_FUNC_keymgmt_load_fn ecx_load; static OSSL_FUNC_keymgmt_get_params_fn x25519_get_params; static OSSL_FUNC_keymgmt_get_params_fn x448_get_params; static OSSL_FUNC_keymgmt_get_params_fn ed25519_get_params; @@ -589,6 +590,20 @@ static void ecx_gen_cleanup(void *genctx) OPENSSL_free(gctx); } +void *ecx_load(const void *reference, size_t reference_sz) +{ + ECX_KEY *key = NULL; + + if (reference_sz == sizeof(key)) { + /* The contents of the reference is the address to our object */ + key = *(ECX_KEY **)reference; + /* We grabbed, so we detach it */ + *(ECX_KEY **)reference = NULL; + return key; + } + return NULL; +} + #define MAKE_KEYMGMT_FUNCTIONS(alg) \ const OSSL_DISPATCH alg##_keymgmt_functions[] = { \ { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \ @@ -609,6 +624,7 @@ static void ecx_gen_cleanup(void *genctx) (void (*)(void))ecx_gen_settable_params }, \ { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen }, \ { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \ + { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ecx_load }, \ { 0, NULL } \ }; diff --git a/providers/implementations/serializers/build.info b/providers/implementations/serializers/build.info index bcfe9d4d4b..d660385163 100644 --- a/providers/implementations/serializers/build.info +++ b/providers/implementations/serializers/build.info @@ -2,6 +2,7 @@ # switch each to the Legacy provider when needed. $SERIALIZER_GOAL=../../libimplementations.a +$DESERIALIZER_GOAL=../../libimplementations.a $RSA_GOAL=../../libimplementations.a $FFC_GOAL=../../libimplementations.a $DH_GOAL=../../libimplementations.a @@ -11,7 +12,7 @@ $EC_GOAL=../../libimplementations.a SOURCE[$SERIALIZER_GOAL]=serializer_common.c deserialize_common.c -SOURCE[$RSA_GOAL]=deserialize_der2rsa.c deserialize_pem2der.c +SOURCE[$RSA_GOAL]=deserialize_der2key.c deserialize_pem2der.c SOURCE[$RSA_GOAL]=serializer_rsa.c serializer_rsa_priv.c serializer_rsa_pub.c DEPEND[serializer_rsa.o]=../../common/include/prov/der_rsa.h diff --git a/providers/implementations/serializers/deserialize_der2key.c b/providers/implementations/serializers/deserialize_der2key.c new file mode 100644 index 0000000000..a544d8522c --- /dev/null +++ b/providers/implementations/serializers/deserialize_der2key.c @@ -0,0 +1,234 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#include +#include +#include +#include +#include "prov/bio.h" +#include "prov/implementations.h" +#include "serializer_local.h" + +static OSSL_FUNC_deserializer_newctx_fn der2rsa_newctx; + +static OSSL_FUNC_deserializer_freectx_fn der2key_freectx; +static OSSL_FUNC_deserializer_gettable_params_fn der2key_gettable_params; +static OSSL_FUNC_deserializer_get_params_fn der2key_get_params; +static OSSL_FUNC_deserializer_deserialize_fn der2key_deserialize; +static OSSL_FUNC_deserializer_export_object_fn der2key_export_object; + +typedef void *(extract_key_fn)(EVP_PKEY *); +typedef void (free_key_fn)(void *); +struct keytype_desc_st { + int type; /* EVP key type */ + const char *name; /* Keytype */ + const OSSL_DISPATCH *fns; /* Keymgmt (to pilfer functions from) */ + + /* + * These must be the correct EVP_PKEY_get1_{TYPE}() and {TYPE}_free() + * function for the key. + */ + extract_key_fn *extract_key; + free_key_fn *free_key; +}; + +/* + * Context used for DER to key deserialization. + */ +struct der2key_ctx_st { + PROV_CTX *provctx; + const struct keytype_desc_st *desc; +}; + +static struct der2key_ctx_st * +der2key_newctx(void *provctx, const struct keytype_desc_st *desc) +{ + struct der2key_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); + + if (ctx != NULL) { + ctx->provctx = provctx; + ctx->desc = desc; + } + return ctx; +} + +static void der2key_freectx(void *vctx) +{ + struct der2key_ctx_st *ctx = vctx; + + OPENSSL_free(ctx); +} + +static const OSSL_PARAM *der2key_gettable_params(void) +{ + static const OSSL_PARAM gettables[] = { + { OSSL_DESERIALIZER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 }, + OSSL_PARAM_END, + }; + + return gettables; +} + +static int der2key_get_params(OSSL_PARAM params[]) +{ + OSSL_PARAM *p; + + p = OSSL_PARAM_locate(params, OSSL_DESERIALIZER_PARAM_INPUT_TYPE); + if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "DER")) + return 0; + + return 1; +} + +static int der2key_deserialize(void *vctx, OSSL_CORE_BIO *cin, + OSSL_CALLBACK *data_cb, void *data_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + struct der2key_ctx_st *ctx = vctx; + void *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx); + unsigned char *der = NULL; + const unsigned char *derp; + long der_len = 0; + unsigned char *new_der = NULL; + long new_der_len; + EVP_PKEY *pkey = NULL; + void *key = NULL; + int ok = 0; + + if (!ossl_prov_read_der(ctx->provctx, cin, &der, &der_len)) + return 0; + + /* + * Opportunistic attempt to decrypt. If it doesn't work, we try to + * decode our input unencrypted. + */ + if (ossl_prov_der_from_p8(&new_der, &new_der_len, der, der_len, + pw_cb, pw_cbarg)) { + OPENSSL_free(der); + der = new_der; + der_len = new_der_len; + } + + derp = der; + pkey = d2i_PrivateKey_ex(ctx->desc->type, NULL, &derp, der_len, + libctx, NULL); + if (pkey == NULL) { + derp = der; + pkey = d2i_PUBKEY(NULL, &derp, der_len); + } + + if (pkey != NULL) { + /* + * Tear out the low-level key pointer from the pkey, + * but only if it matches the expected key type. + * + * TODO(3.0): The check should be done with EVP_PKEY_is_a(), but + * as long as we still have #legacy internal keys, it's safer to + * use the type numbers in side the provider. + */ + if (EVP_PKEY_id(pkey) == ctx->desc->type) + key = ctx->desc->extract_key(pkey); + + /* + * ctx->desc->extract_key() is expected to have incremented |key|'s + * reference count, so it should be safe to free |pkey| now. + */ + EVP_PKEY_free(pkey); + } + + OPENSSL_free(der); + + if (key != NULL) { + OSSL_PARAM params[3]; + + params[0] = + OSSL_PARAM_construct_utf8_string(OSSL_DESERIALIZER_PARAM_DATA_TYPE, + (char *)ctx->desc->name, 0); + /* The address of the key becomes the octet string */ + params[1] = + OSSL_PARAM_construct_octet_string(OSSL_DESERIALIZER_PARAM_REFERENCE, + &key, sizeof(key)); + params[2] = OSSL_PARAM_construct_end(); + + ok = data_cb(params, data_cbarg); + } + ctx->desc->free_key(key); + + return ok; +} + +static int der2key_export_object(void *vctx, + const void *reference, size_t reference_sz, + OSSL_CALLBACK *export_cb, void *export_cbarg) +{ + struct der2key_ctx_st *ctx = vctx; + OSSL_FUNC_keymgmt_export_fn *export = + ossl_prov_get_keymgmt_export(ctx->desc->fns); + void *keydata; + + if (reference_sz == sizeof(keydata) && export != NULL) { + /* The contents of the reference is the address to our object */ + keydata = *(void **)reference; + + return export(keydata, OSSL_KEYMGMT_SELECT_ALL, + export_cb, export_cbarg); + } + return 0; +} + +#define IMPLEMENT_NEWCTX(KEYTYPEstr, KEYTYPE, keytype, extract, free) \ + static const struct keytype_desc_st keytype##_desc = \ + { EVP_PKEY_##KEYTYPE, KEYTYPEstr, keytype##_keymgmt_functions, \ + (extract_key_fn *)extract, \ + (free_key_fn *)free }; \ + static void *der2##keytype##_newctx(void *provctx) \ + { \ + return der2key_newctx(provctx, &keytype##_desc); \ + } \ + const OSSL_DISPATCH der_to_##keytype##_deserializer_functions[] = { \ + { OSSL_FUNC_DESERIALIZER_NEWCTX, \ + (void (*)(void))der2##keytype##_newctx }, \ + { OSSL_FUNC_DESERIALIZER_FREECTX, \ + (void (*)(void))der2key_freectx }, \ + { OSSL_FUNC_DESERIALIZER_GETTABLE_PARAMS, \ + (void (*)(void))der2key_gettable_params }, \ + { OSSL_FUNC_DESERIALIZER_GET_PARAMS, \ + (void (*)(void))der2key_get_params }, \ + { OSSL_FUNC_DESERIALIZER_DESERIALIZE, \ + (void (*)(void))der2key_deserialize }, \ + { OSSL_FUNC_DESERIALIZER_EXPORT_OBJECT, \ + (void (*)(void))der2key_export_object }, \ + { 0, NULL } \ + } + +#ifndef OPENSSL_NO_DH +IMPLEMENT_NEWCTX("DH", DH, dh, EVP_PKEY_get1_DH, DH_free); +#endif +#ifndef OPENSSL_NO_DSA +IMPLEMENT_NEWCTX("DSA", DSA, dsa, EVP_PKEY_get1_DSA, DSA_free); +#endif +#ifndef OPENSSL_NO_EC +IMPLEMENT_NEWCTX("EC", EC, ec, EVP_PKEY_get1_EC_KEY, EC_KEY_free); +IMPLEMENT_NEWCTX("X25519", X25519, x25519, + EVP_PKEY_get1_X25519, ecx_key_free); +IMPLEMENT_NEWCTX("X448", X448, x448, + EVP_PKEY_get1_X448, ecx_key_free); +IMPLEMENT_NEWCTX("ED25519", ED25519, ed25519, + EVP_PKEY_get1_ED25519, ecx_key_free); +IMPLEMENT_NEWCTX("ED448", ED448, ed448, EVP_PKEY_get1_ED448, ecx_key_free); +#endif +IMPLEMENT_NEWCTX("RSA", RSA, rsa, EVP_PKEY_get1_RSA, RSA_free); +IMPLEMENT_NEWCTX("RSA-PSS", RSA_PSS, rsapss, EVP_PKEY_get1_RSA, RSA_free); diff --git a/providers/implementations/serializers/deserialize_der2rsa.c b/providers/implementations/serializers/deserialize_der2rsa.c deleted file mode 100644 index 710fd2d1a8..0000000000 --- a/providers/implementations/serializers/deserialize_der2rsa.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * RSA low level APIs are deprecated for public use, but still ok for - * internal use. - */ -#include "internal/deprecated.h" - -#include -#include -#include -#include -#include -#include -#include "prov/bio.h" -#include "prov/implementations.h" -#include "prov/providercommonerr.h" -#include "serializer_local.h" - -static OSSL_FUNC_deserializer_newctx_fn der2rsa_newctx; -static OSSL_FUNC_deserializer_freectx_fn der2rsa_freectx; -static OSSL_FUNC_deserializer_gettable_params_fn der2rsa_gettable_params; -static OSSL_FUNC_deserializer_get_params_fn der2rsa_get_params; -static OSSL_FUNC_deserializer_deserialize_fn der2rsa_deserialize; -static OSSL_FUNC_deserializer_export_object_fn der2rsa_export_object; - -/* - * Context used for DER to RSA key deserialization. - */ -struct der2rsa_ctx_st { - PROV_CTX *provctx; - - int type; -}; - -static struct der2rsa_ctx_st *der2rsa_newctx_int(void *provctx) -{ - struct der2rsa_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); - - if (ctx != NULL) - ctx->provctx = provctx; - return ctx; -} - -static void *der2rsa_newctx(void *provctx) -{ - struct der2rsa_ctx_st *ctx = der2rsa_newctx_int(provctx); - - if (ctx != NULL) - ctx->type = EVP_PKEY_RSA; - return ctx; -} - -static void *der2rsapss_newctx(void *provctx) -{ - struct der2rsa_ctx_st *ctx = der2rsa_newctx_int(provctx); - - if (ctx != NULL) - ctx->type = EVP_PKEY_RSA_PSS; - return ctx; -} - -static void der2rsa_freectx(void *vctx) -{ - OPENSSL_free(vctx); -} - -static const OSSL_PARAM *der2rsa_gettable_params(void) -{ - static const OSSL_PARAM gettables[] = { - { OSSL_DESERIALIZER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 }, - OSSL_PARAM_END, - }; - - return gettables; -} - -static int der2rsa_get_params(OSSL_PARAM params[]) -{ - OSSL_PARAM *p; - - p = OSSL_PARAM_locate(params, OSSL_DESERIALIZER_PARAM_INPUT_TYPE); - if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "DER")) - return 0; - - return 1; -} - -static int der2rsa_deserialize(void *vctx, OSSL_CORE_BIO *cin, - OSSL_CALLBACK *data_cb, void *data_cbarg, - OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) -{ - struct der2rsa_ctx_st *ctx = vctx; - void *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx); - RSA *rsa = NULL; - unsigned char *der = NULL; - const unsigned char *derp; - long der_len = 0; - unsigned char *new_der = NULL; - long new_der_len; - EVP_PKEY *pkey = NULL; - int ok = 0; - - if (!ossl_prov_read_der(ctx->provctx, cin, &der, &der_len)) - return 0; - - /* - * Opportunistic attempt to decrypt. If it doesn't work, we try to - * decode our input unencrypted. - */ - if (ossl_prov_der_from_p8(&new_der, &new_der_len, der, der_len, - pw_cb, pw_cbarg)) { - OPENSSL_free(der); - der = new_der; - der_len = new_der_len; - } - - derp = der; - pkey = d2i_PrivateKey_ex(ctx->type, NULL, &derp, der_len, libctx, NULL); - if (pkey == NULL) { - derp = der; - pkey = d2i_PUBKEY(NULL, &derp, der_len); - } - - if (pkey != NULL) { - /* Tear out the RSA pointer from the pkey */ - rsa = EVP_PKEY_get1_RSA(pkey); - EVP_PKEY_free(pkey); - } - - OPENSSL_free(der); - - if (rsa != NULL) { - OSSL_PARAM params[3]; - char *object_type = NULL; - - switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) { - case RSA_FLAG_TYPE_RSA: - object_type = "RSA"; - break; - case RSA_FLAG_TYPE_RSASSAPSS: - object_type = "RSA-PSS"; - break; - default: - ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_RSA_KEY, - "Expected the RSA type to be %d or %d, but got %d", - RSA_FLAG_TYPE_RSA, RSA_FLAG_TYPE_RSASSAPSS, - RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)); - goto end; - } - - - params[0] = - OSSL_PARAM_construct_utf8_string(OSSL_DESERIALIZER_PARAM_DATA_TYPE, - object_type, 0); - /* The address of the key becomes the octet string */ - params[1] = - OSSL_PARAM_construct_octet_string(OSSL_DESERIALIZER_PARAM_REFERENCE, - &rsa, sizeof(rsa)); - params[2] = OSSL_PARAM_construct_end(); - - ok = data_cb(params, data_cbarg); - } - end: - RSA_free(rsa); - - return ok; -} - -static int der2rsa_export_object_int(void *vctx, - const void *reference, size_t reference_sz, - OSSL_FUNC_keymgmt_export_fn *rsa_export, - OSSL_CALLBACK *export_cb, - void *export_cbarg) -{ - void *keydata; - - if (reference_sz == sizeof(keydata) && rsa_export != NULL) { - /* The contents of the reference is the address to our object */ - keydata = *(RSA **)reference; - - return rsa_export(keydata, OSSL_KEYMGMT_SELECT_ALL, - export_cb, export_cbarg); - } - return 0; -} - -static int der2rsa_export_object(void *vctx, - const void *reference, size_t reference_sz, - OSSL_CALLBACK *export_cb, - void *export_cbarg) -{ - return der2rsa_export_object_int(vctx, reference, reference_sz, - ossl_prov_get_keymgmt_rsa_export(), - export_cb, export_cbarg); -} - -static int der2rsapss_export_object(void *vctx, - const void *reference, size_t reference_sz, - OSSL_CALLBACK *export_cb, - void *export_cbarg) -{ - return der2rsa_export_object_int(vctx, reference, reference_sz, - ossl_prov_get_keymgmt_rsapss_export(), - export_cb, export_cbarg); -} - -const OSSL_DISPATCH der_to_rsa_deserializer_functions[] = { - { OSSL_FUNC_DESERIALIZER_NEWCTX, (void (*)(void))der2rsa_newctx }, - { OSSL_FUNC_DESERIALIZER_FREECTX, (void (*)(void))der2rsa_freectx }, - { OSSL_FUNC_DESERIALIZER_GETTABLE_PARAMS, - (void (*)(void))der2rsa_gettable_params }, - { OSSL_FUNC_DESERIALIZER_GET_PARAMS, - (void (*)(void))der2rsa_get_params }, - { OSSL_FUNC_DESERIALIZER_DESERIALIZE, - (void (*)(void))der2rsa_deserialize }, - { OSSL_FUNC_DESERIALIZER_EXPORT_OBJECT, - (void (*)(void))der2rsa_export_object }, - { 0, NULL } -}; - -const OSSL_DISPATCH der_to_rsapss_deserializer_functions[] = { - { OSSL_FUNC_DESERIALIZER_NEWCTX, (void (*)(void))der2rsapss_newctx }, - { OSSL_FUNC_DESERIALIZER_FREECTX, (void (*)(void))der2rsa_freectx }, - { OSSL_FUNC_DESERIALIZER_GETTABLE_PARAMS, - (void (*)(void))der2rsa_gettable_params }, - { OSSL_FUNC_DESERIALIZER_GET_PARAMS, - (void (*)(void))der2rsa_get_params }, - { OSSL_FUNC_DESERIALIZER_DESERIALIZE, - (void (*)(void))der2rsa_deserialize }, - { OSSL_FUNC_DESERIALIZER_EXPORT_OBJECT, - (void (*)(void))der2rsapss_export_object }, - { 0, NULL } -}; diff --git a/test/serdes_test.c b/test/serdes_test.c index df6008a6f6..298d22e8b9 100644 --- a/test/serdes_test.c +++ b/test/serdes_test.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -27,22 +28,42 @@ * serializing/deserializing with "traditional" keys. */ -static EVP_PKEY *key_RSA = NULL; -static EVP_PKEY *legacy_key_RSA = NULL; -static EVP_PKEY *key_RSA_PSS = NULL; -static EVP_PKEY *legacy_key_RSA_PSS = NULL; +static EVP_PKEY *make_template(const char *type, OSSL_PARAM *genparams) +{ + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, type, NULL); + + /* + * No real need to check the errors other than for the cascade + * effect. |pkey| will simply remain NULL if something goes wrong. + */ + (void)(ctx != NULL + && EVP_PKEY_paramgen_init(ctx) > 0 + && (genparams == NULL + || EVP_PKEY_CTX_set_params(ctx, genparams) > 0) + && EVP_PKEY_gen(ctx, &pkey) > 0); + EVP_PKEY_CTX_free(ctx); + + return pkey; +} -static EVP_PKEY *make_RSA(const char *rsa_type, int make_legacy) +static EVP_PKEY *make_key(const char *type, EVP_PKEY *template, + OSSL_PARAM *genparams, int make_legacy) { EVP_PKEY *pkey = NULL; - EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, rsa_type, NULL); + EVP_PKEY_CTX *ctx = + template != NULL + ? EVP_PKEY_CTX_new(template, NULL) + : EVP_PKEY_CTX_new_from_name(NULL, type, NULL); /* * No real need to check the errors other than for the cascade - * effect. |pkey| will imply remain NULL if something goes wrong. + * effect. |pkey| will simply remain NULL if something goes wrong. */ (void)(ctx != NULL && EVP_PKEY_keygen_init(ctx) > 0 + && (genparams == NULL + || EVP_PKEY_CTX_set_params(ctx, genparams) > 0) && EVP_PKEY_keygen(ctx, &pkey) > 0); EVP_PKEY_CTX_free(ctx); if (make_legacy && EVP_PKEY_get0(pkey) == NULL) { @@ -53,6 +74,7 @@ static EVP_PKEY *make_RSA(const char *rsa_type, int make_legacy) return pkey; } + /* Main test driver */ /* @@ -256,19 +278,9 @@ static int check_unprotected_PKCS8_DER(const char *type, return ok; } -static int test_unprotected_RSA_via_DER(void) -{ - return test_serialize_deserialize("RSA", key_RSA, NULL, NULL, - serialize_EVP_PKEY_prov, - deserialize_EVP_PKEY_prov, - check_unprotected_PKCS8_DER, dump_der, - OSSL_SERIALIZER_PrivateKey_TO_DER_PQ, - 0); -} - -static int test_unprotected_RSA_PSS_via_DER(void) +static int test_unprotected_via_DER(const char *type, EVP_PKEY *key) { - return test_serialize_deserialize("RSA-PSS", key_RSA_PSS, NULL, NULL, + return test_serialize_deserialize(type, key, NULL, NULL, serialize_EVP_PKEY_prov, deserialize_EVP_PKEY_prov, check_unprotected_PKCS8_DER, dump_der, @@ -284,19 +296,9 @@ static int check_unprotected_PKCS8_PEM(const char *type, return TEST_strn_eq(data, pem_header, sizeof(pem_header) - 1); } -static int test_unprotected_RSA_via_PEM(void) +static int test_unprotected_via_PEM(const char *type, EVP_PKEY *key) { - return test_serialize_deserialize("RSA", key_RSA, NULL, NULL, - serialize_EVP_PKEY_prov, - deserialize_EVP_PKEY_prov, - check_unprotected_PKCS8_PEM, dump_pem, - OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ, - 0); -} - -static int test_unprotected_RSA_PSS_via_PEM(void) -{ - return test_serialize_deserialize("RSA-PSS", key_RSA_PSS, NULL, NULL, + return test_serialize_deserialize(type, key, NULL, NULL, serialize_EVP_PKEY_prov, deserialize_EVP_PKEY_prov, check_unprotected_PKCS8_PEM, dump_pem, @@ -315,18 +317,9 @@ static int check_unprotected_legacy_PEM(const char *type, && TEST_strn_eq(data, pem_header, strlen(pem_header)); } -static int test_unprotected_RSA_via_legacy_PEM(void) -{ - return test_serialize_deserialize("RSA", legacy_key_RSA, NULL, NULL, - serialize_EVP_PKEY_legacy_PEM, - deserialize_EVP_PKEY_prov, - check_unprotected_legacy_PEM, dump_pem, - NULL, 1); -} - -static int test_unprotected_RSA_PSS_via_legacy_PEM(void) +static int test_unprotected_via_legacy_PEM(const char *type, EVP_PKEY *key) { - return test_serialize_deserialize("RSA-PSS", legacy_key_RSA_PSS, NULL, NULL, + return test_serialize_deserialize(type, key, NULL, NULL, serialize_EVP_PKEY_legacy_PEM, deserialize_EVP_PKEY_prov, check_unprotected_legacy_PEM, dump_pem, @@ -347,19 +340,9 @@ static int check_protected_PKCS8_DER(const char *type, return ok; } -static int test_protected_RSA_via_DER(void) -{ - return test_serialize_deserialize("RSA", key_RSA, pass, pass_cipher, - serialize_EVP_PKEY_prov, - deserialize_EVP_PKEY_prov, - check_protected_PKCS8_DER, dump_der, - OSSL_SERIALIZER_PrivateKey_TO_DER_PQ, - 0); -} - -static int test_protected_RSA_PSS_via_DER(void) +static int test_protected_via_DER(const char *type, EVP_PKEY *key) { - return test_serialize_deserialize("RSA", key_RSA, pass, pass_cipher, + return test_serialize_deserialize(type, key, pass, pass_cipher, serialize_EVP_PKEY_prov, deserialize_EVP_PKEY_prov, check_protected_PKCS8_DER, dump_der, @@ -375,19 +358,9 @@ static int check_protected_PKCS8_PEM(const char *type, return TEST_strn_eq(data, pem_header, sizeof(pem_header) - 1); } -static int test_protected_RSA_via_PEM(void) +static int test_protected_via_PEM(const char *type, EVP_PKEY *key) { - return test_serialize_deserialize("RSA", key_RSA, pass, pass_cipher, - serialize_EVP_PKEY_prov, - deserialize_EVP_PKEY_prov, - check_protected_PKCS8_PEM, dump_pem, - OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ, - 0); -} - -static int test_protected_RSA_PSS_via_PEM(void) -{ - return test_serialize_deserialize("RSA-PSS", key_RSA_PSS, pass, pass_cipher, + return test_serialize_deserialize(type, key, pass, pass_cipher, serialize_EVP_PKEY_prov, deserialize_EVP_PKEY_prov, check_protected_PKCS8_PEM, dump_pem, @@ -407,38 +380,28 @@ static int check_protected_legacy_PEM(const char *type, && TEST_ptr(strstr(data, "\nDEK-Info: ")); } -static int test_protected_RSA_via_legacy_PEM(void) +static int test_protected_via_legacy_PEM(const char *type, EVP_PKEY *key) { - return test_serialize_deserialize("RSA", legacy_key_RSA, pass, pass_cipher, + return test_serialize_deserialize(type, key, pass, pass_cipher, serialize_EVP_PKEY_legacy_PEM, deserialize_EVP_PKEY_prov, check_protected_legacy_PEM, dump_pem, NULL, 1); } -static int test_protected_RSA_PSS_via_legacy_PEM(void) -{ - return test_serialize_deserialize("RSA-PSS", legacy_key_RSA_PSS, - pass, pass_cipher, - serialize_EVP_PKEY_legacy_PEM, - deserialize_EVP_PKEY_prov, - check_protected_legacy_PEM, dump_pem, - NULL, 1); -} - -static int check_public_DER(int type, const void *data, size_t data_len) +static int check_public_DER(const char *type, const void *data, size_t data_len) { const unsigned char *datap = data; EVP_PKEY *pkey = d2i_PUBKEY(NULL, &datap, data_len); - int ok = (TEST_ptr(pkey) && TEST_true(EVP_PKEY_is_a(pkey, "RSA"))); + int ok = (TEST_ptr(pkey) && TEST_true(EVP_PKEY_is_a(pkey, type))); EVP_PKEY_free(pkey); return ok; } -static int test_public_RSA_via_DER(void) +static int test_public_via_DER(const char *type, EVP_PKEY *key) { - return test_serialize_deserialize("RSA", NULL, NULL, + return test_serialize_deserialize(type, key, NULL, NULL, serialize_EVP_PKEY_prov, deserialize_EVP_PKEY_prov, check_public_DER, dump_der, @@ -446,17 +409,7 @@ static int test_public_RSA_via_DER(void) 0); } -static int test_public_RSA_PSS_via_DER(void) -{ - return test_serialize_deserialize("RSA-PSS", NULL, NULL, - serialize_EVP_PKEY_prov, - deserialize_EVP_PKEY_prov, - check_public_DER, dump_der, - OSSL_SERIALIZER_PUBKEY_TO_DER_PQ, - 0); -} - -static int check_public_PEM(int type, const void *data, size_t data_len) +static int check_public_PEM(const char *type, const void *data, size_t data_len) { static const char pem_header[] = "-----BEGIN " PEM_STRING_PUBLIC "-----"; @@ -464,9 +417,9 @@ static int check_public_PEM(int type, const void *data, size_t data_len) TEST_strn_eq(data, pem_header, sizeof(pem_header) - 1); } -static int test_public_RSA_via_PEM(void) +static int test_public_via_PEM(const char *type, EVP_PKEY *key) { - return test_serialize_deserialize("RSA", NULL, NULL, + return test_serialize_deserialize(type, key, NULL, NULL, serialize_EVP_PKEY_prov, deserialize_EVP_PKEY_prov, check_public_PEM, dump_pem, @@ -474,47 +427,180 @@ static int test_public_RSA_via_PEM(void) 0); } -static int test_public_RSA_PSS_via_PEM(void) -{ - return test_serialize_deserialize("RSA-PSS", NULL, NULL, - serialize_EVP_PKEY_prov, - deserialize_EVP_PKEY_prov, - check_public_PEM, dump_pem, - OSSL_SERIALIZER_PUBKEY_TO_PEM_PQ, - 0); -} +#define KEYS(KEYTYPE) \ + static EVP_PKEY *key_##KEYTYPE = NULL; \ + static EVP_PKEY *legacy_key_##KEYTYPE = NULL +#define MAKE_KEYS(KEYTYPE, KEYTYPEstr, params) \ + ok = ok \ + && TEST_ptr(key_##KEYTYPE = \ + make_key(KEYTYPEstr, NULL, params, 0)) \ + && TEST_ptr(legacy_key_##KEYTYPE = \ + make_key(KEYTYPEstr, NULL, params, 1)) +#define FREE_KEYS(KEYTYPE) \ + EVP_PKEY_free(key_##KEYTYPE); \ + EVP_PKEY_free(legacy_key_##KEYTYPE) + +#define DOMAIN_KEYS(KEYTYPE) \ + static EVP_PKEY *template_##KEYTYPE = NULL; \ + static EVP_PKEY *key_##KEYTYPE = NULL; \ + static EVP_PKEY *legacy_key_##KEYTYPE = NULL +#define MAKE_DOMAIN_KEYS(KEYTYPE, KEYTYPEstr, params) \ + ok = ok \ + && TEST_ptr(template_##KEYTYPE = \ + make_template(KEYTYPEstr, params)) \ + && TEST_ptr(key_##KEYTYPE = \ + make_key(KEYTYPEstr, template_##KEYTYPE, NULL, 0)) \ + && TEST_ptr(legacy_key_##KEYTYPE = \ + make_key(KEYTYPEstr, template_##KEYTYPE, NULL, 1)) +#define FREE_DOMAIN_KEYS(KEYTYPE) \ + EVP_PKEY_free(template_##KEYTYPE); \ + EVP_PKEY_free(key_##KEYTYPE); \ + EVP_PKEY_free(legacy_key_##KEYTYPE) + +#define IMPLEMENT_TEST_SUITE(KEYTYPE, KEYTYPEstr) \ + static int test_unprotected_##KEYTYPE##_via_DER(void) \ + { \ + return test_unprotected_via_DER(KEYTYPEstr, key_##KEYTYPE); \ + } \ + static int test_unprotected_##KEYTYPE##_via_PEM(void) \ + { \ + return test_unprotected_via_PEM(KEYTYPEstr, key_##KEYTYPE); \ + } \ + static int test_unprotected_##KEYTYPE##_via_legacy_PEM(void) \ + { \ + return test_unprotected_via_legacy_PEM(KEYTYPEstr, \ + legacy_key_##KEYTYPE); \ + } \ + static int test_protected_##KEYTYPE##_via_DER(void) \ + { \ + return test_protected_via_DER(KEYTYPEstr, key_##KEYTYPE); \ + } \ + static int test_protected_##KEYTYPE##_via_PEM(void) \ + { \ + return test_protected_via_PEM(KEYTYPEstr, key_##KEYTYPE); \ + } \ + static int test_protected_##KEYTYPE##_via_legacy_PEM(void) \ + { \ + return test_protected_via_legacy_PEM(KEYTYPEstr, \ + legacy_key_##KEYTYPE); \ + } \ + static int test_public_##KEYTYPE##_via_DER(void) \ + { \ + return test_public_via_DER(KEYTYPEstr, key_##KEYTYPE); \ + } \ + static int test_public_##KEYTYPE##_via_PEM(void) \ + { \ + return test_public_via_PEM(KEYTYPEstr, key_##KEYTYPE); \ + } + +#define ADD_TEST_SUITE(KEYTYPE) \ + ADD_TEST(test_unprotected_##KEYTYPE##_via_DER); \ + ADD_TEST(test_unprotected_##KEYTYPE##_via_PEM); \ + ADD_TEST(test_unprotected_##KEYTYPE##_via_legacy_PEM); \ + ADD_TEST(test_protected_##KEYTYPE##_via_DER); \ + ADD_TEST(test_protected_##KEYTYPE##_via_PEM); \ + ADD_TEST(test_protected_##KEYTYPE##_via_legacy_PEM); \ + ADD_TEST(test_public_##KEYTYPE##_via_DER); \ + ADD_TEST(test_public_##KEYTYPE##_via_PEM) + +#ifndef OPENSSL_NO_DH +DOMAIN_KEYS(DH); +IMPLEMENT_TEST_SUITE(DH, "DH") +#endif +#ifndef OPENSSL_NO_DSA +DOMAIN_KEYS(DSA); +IMPLEMENT_TEST_SUITE(DSA, "DSA") +#endif +#ifndef OPENSSL_NO_EC +DOMAIN_KEYS(EC); +IMPLEMENT_TEST_SUITE(EC, "EC") +KEYS(ED25519); +IMPLEMENT_TEST_SUITE(ED25519, "ED25519") +KEYS(ED448); +IMPLEMENT_TEST_SUITE(ED448, "ED448") +KEYS(X25519); +IMPLEMENT_TEST_SUITE(X25519, "X25519") +KEYS(X448); +IMPLEMENT_TEST_SUITE(X448, "X448") +#endif +KEYS(RSA); +IMPLEMENT_TEST_SUITE(RSA, "RSA") +KEYS(RSA_PSS); +IMPLEMENT_TEST_SUITE(RSA_PSS, "RSA-PSS") int setup_tests(void) { + int ok = 1; + +#ifndef OPENSSL_NO_EC + static char groupname[] = "prime256v1"; + OSSL_PARAM EC_params[] = { + OSSL_PARAM_utf8_string("group", groupname, sizeof(groupname) - 1), + OSSL_PARAM_END + }; +#endif + + /* 7 is the default magic number */ + static unsigned int rsapss_min_saltlen = 7; + OSSL_PARAM RSA_PSS_params[] = { + OSSL_PARAM_uint("saltlen", &rsapss_min_saltlen), + OSSL_PARAM_END + }; + TEST_info("Generating keys..."); - if (!TEST_ptr(key_RSA = make_RSA("RSA", 0)) - || !TEST_ptr(legacy_key_RSA = make_RSA("RSA", 1)) - || !TEST_ptr(key_RSA_PSS = make_RSA("RSA-PSS", 0)) - || !TEST_ptr(legacy_key_RSA_PSS = make_RSA("RSA-PSS", 1))) { - EVP_PKEY_free(key_RSA); - EVP_PKEY_free(legacy_key_RSA); - EVP_PKEY_free(key_RSA_PSS); - EVP_PKEY_free(legacy_key_RSA_PSS); - return 0; - } +#ifndef OPENSSL_NO_DH + MAKE_DOMAIN_KEYS(DH, "DH", NULL); +#endif +#ifndef OPENSSL_NO_DSA + MAKE_DOMAIN_KEYS(DSA, "DSA", NULL); +#endif +#ifndef OPENSSL_NO_EC + MAKE_DOMAIN_KEYS(EC, "EC", EC_params); + MAKE_KEYS(ED25519, "ED25519", NULL); + MAKE_KEYS(ED448, "ED448", NULL); + MAKE_KEYS(X25519, "X25519", NULL); + MAKE_KEYS(X448, "X448", NULL); +#endif + MAKE_KEYS(RSA, "RSA", NULL); + MAKE_KEYS(RSA_PSS, "RSA-PSS", RSA_PSS_params); TEST_info("Generating key... done"); - ADD_TEST(test_unprotected_RSA_via_DER); - ADD_TEST(test_unprotected_RSA_via_PEM); - ADD_TEST(test_unprotected_RSA_via_legacy_PEM); - ADD_TEST(test_protected_RSA_via_DER); - ADD_TEST(test_protected_RSA_via_PEM); - ADD_TEST(test_protected_RSA_via_legacy_PEM); - ADD_TEST(test_public_RSA_via_DER); - ADD_TEST(test_public_RSA_via_PEM); - ADD_TEST(test_unprotected_RSA_PSS_via_DER); - ADD_TEST(test_unprotected_RSA_PSS_via_PEM); - ADD_TEST(test_unprotected_RSA_PSS_via_legacy_PEM); - ADD_TEST(test_protected_RSA_PSS_via_DER); - ADD_TEST(test_protected_RSA_PSS_via_PEM); - ADD_TEST(test_protected_RSA_PSS_via_legacy_PEM); - ADD_TEST(test_public_RSA_PSS_via_DER); - ADD_TEST(test_public_RSA_PSS_via_PEM); + if (ok) { +#ifndef OPENSSL_NO_DH + ADD_TEST_SUITE(DH); +#endif +#ifndef OPENSSL_NO_DSA + ADD_TEST_SUITE(DSA); +#endif +#ifndef OPENSSL_NO_EC + ADD_TEST_SUITE(EC); + ADD_TEST_SUITE(ED25519); + ADD_TEST_SUITE(ED448); + ADD_TEST_SUITE(X25519); + ADD_TEST_SUITE(X448); +#endif + ADD_TEST_SUITE(RSA); + ADD_TEST_SUITE(RSA_PSS); + } return 1; } + +void cleanup_tests(void) +{ +#ifndef OPENSSL_NO_DH + FREE_DOMAIN_KEYS(DH); +#endif +#ifndef OPENSSL_NO_DSA + FREE_DOMAIN_KEYS(DSA); +#endif +#ifndef OPENSSL_NO_EC + FREE_DOMAIN_KEYS(EC); + FREE_KEYS(ED25519); + FREE_KEYS(ED448); + FREE_KEYS(X25519); + FREE_KEYS(X448); +#endif + FREE_KEYS(RSA); + FREE_KEYS(RSA_PSS); +} diff --git a/util/libcrypto.num b/util/libcrypto.num index 11f230ae1c..0c94a3e7dc 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5180,3 +5180,15 @@ ERR_load_OSSL_DESERIALIZER_strings ? 3_0_0 EXIST::FUNCTION: OSSL_DESERIALIZER_gettable_params ? 3_0_0 EXIST::FUNCTION: OSSL_DESERIALIZER_get_params ? 3_0_0 EXIST::FUNCTION: OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY ? 3_0_0 EXIST::FUNCTION: +EVP_PKEY_set1_X25519 ? 3_0_0 EXIST::FUNCTION:EC +EVP_PKEY_get0_X25519 ? 3_0_0 EXIST::FUNCTION:EC +EVP_PKEY_get1_X25519 ? 3_0_0 EXIST::FUNCTION:EC +EVP_PKEY_set1_X448 ? 3_0_0 EXIST::FUNCTION:EC +EVP_PKEY_get0_X448 ? 3_0_0 EXIST::FUNCTION:EC +EVP_PKEY_get1_X448 ? 3_0_0 EXIST::FUNCTION:EC +EVP_PKEY_set1_ED25519 ? 3_0_0 EXIST::FUNCTION:EC +EVP_PKEY_get0_ED25519 ? 3_0_0 EXIST::FUNCTION:EC +EVP_PKEY_get1_ED25519 ? 3_0_0 EXIST::FUNCTION:EC +EVP_PKEY_set1_ED448 ? 3_0_0 EXIST::FUNCTION:EC +EVP_PKEY_get0_ED448 ? 3_0_0 EXIST::FUNCTION:EC +EVP_PKEY_get1_ED448 ? 3_0_0 EXIST::FUNCTION:EC diff --git a/util/other.syms b/util/other.syms index 38ad3d3a33..a8eda47bde 100644 --- a/util/other.syms +++ b/util/other.syms @@ -305,6 +305,10 @@ EVP_PKEY_CTX_set_tls1_prf_md define EVP_PKEY_assign_DH define EVP_PKEY_assign_DSA define EVP_PKEY_assign_EC_KEY define +EVP_PKEY_assign_ED25519 define +EVP_PKEY_assign_ED448 define +EVP_PKEY_assign_X25519 define +EVP_PKEY_assign_X448 define EVP_PKEY_assign_POLY1305 define EVP_PKEY_assign_RSA define EVP_PKEY_assign_SIPHASH define -- cgit v1.2.3