diff options
-rw-r--r-- | crypto/ec/ecx_backend.c | 48 | ||||
-rw-r--r-- | crypto/ec/ecx_meth.c | 22 | ||||
-rw-r--r-- | include/crypto/ecx.h | 1 | ||||
-rw-r--r-- | providers/implementations/keymgmt/ecx_kmgmt.c | 5 |
4 files changed, 44 insertions, 32 deletions
diff --git a/crypto/ec/ecx_backend.c b/crypto/ec/ecx_backend.c index e613337029..042f9ca8da 100644 --- a/crypto/ec/ecx_backend.c +++ b/crypto/ec/ecx_backend.c @@ -9,6 +9,8 @@ #include <openssl/core_names.h> #include <openssl/params.h> +#include <openssl/ec.h> +#include <openssl/err.h> #include "crypto/ecx.h" #include "ecx_backend.h" @@ -18,10 +20,35 @@ * implementations alike. */ +int ecx_public_from_private(ECX_KEY *key) +{ + switch (key->type) { + case ECX_KEY_TYPE_X25519: + X25519_public_from_private(key->pubkey, key->privkey); + break; + case ECX_KEY_TYPE_ED25519: + if (!ED25519_public_from_private(key->libctx, key->pubkey, key->privkey)) { + ECerr(0, EC_R_FAILED_MAKING_PUBLIC_KEY); + return 0; + } + break; + case ECX_KEY_TYPE_X448: + X448_public_from_private(key->pubkey, key->privkey); + break; + case ECX_KEY_TYPE_ED448: + if (!ED448_public_from_private(key->libctx, key->pubkey, key->privkey)) { + ECerr(0, EC_R_FAILED_MAKING_PUBLIC_KEY); + return 0; + } + break; + } + return 1; +} + int ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[], int include_private) { - size_t privkeylen = 0, pubkeylen; + size_t privkeylen = 0, pubkeylen = 0; const OSSL_PARAM *param_priv_key = NULL, *param_pub_key; unsigned char *pubkey; @@ -32,11 +59,8 @@ int ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[], if (include_private) param_priv_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); - /* - * If a private key is present then a public key must also be present. - * Alternatively we've just got a public key. - */ - if (param_pub_key == NULL) + + if (param_pub_key == NULL && param_priv_key == NULL) return 0; if (param_priv_key != NULL @@ -46,15 +70,19 @@ int ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[], return 0; pubkey = ecx->pubkey; - if (!OSSL_PARAM_get_octet_string(param_pub_key, - (void **)&pubkey, - sizeof(ecx->pubkey), &pubkeylen)) + if (param_pub_key != NULL + && !OSSL_PARAM_get_octet_string(param_pub_key, + (void **)&pubkey, + sizeof(ecx->pubkey), &pubkeylen)) return 0; - if (pubkeylen != ecx->keylen + if ((param_pub_key != NULL && pubkeylen != ecx->keylen) || (param_priv_key != NULL && privkeylen != ecx->keylen)) return 0; + if (param_pub_key == NULL && !ecx_public_from_private(ecx)) + return 0; + ecx->haspubkey = 1; return 1; diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c index a9c71f33aa..b88d73a499 100644 --- a/crypto/ec/ecx_meth.c +++ b/crypto/ec/ecx_meth.c @@ -88,25 +88,9 @@ static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg, } else { memcpy(privkey, p, KEYLENID(id)); } - switch (id) { - case EVP_PKEY_X25519: - X25519_public_from_private(pubkey, privkey); - break; - case EVP_PKEY_ED25519: - if (!ED25519_public_from_private(libctx, pubkey, privkey)) { - ECerr(EC_F_ECX_KEY_OP, EC_R_FAILED_MAKING_PUBLIC_KEY); - goto err; - } - break; - case EVP_PKEY_X448: - X448_public_from_private(pubkey, privkey); - break; - case EVP_PKEY_ED448: - if (!ED448_public_from_private(libctx, pubkey, privkey)) { - ECerr(EC_F_ECX_KEY_OP, EC_R_FAILED_MAKING_PUBLIC_KEY); - goto err; - } - break; + if (!ecx_public_from_private(key)) { + ECerr(EC_F_ECX_KEY_OP, EC_R_FAILED_MAKING_PUBLIC_KEY); + goto err; } } diff --git a/include/crypto/ecx.h b/include/crypto/ecx.h index 5ee6b8ce7e..ef3bf0f3a8 100644 --- a/include/crypto/ecx.h +++ b/include/crypto/ecx.h @@ -109,6 +109,7 @@ void X448_public_from_private(uint8_t out_public_value[56], const uint8_t private_key[56]); /* Backend support */ +int ecx_public_from_private(ECX_KEY *key); int ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[], int include_private); diff --git a/providers/implementations/keymgmt/ecx_kmgmt.c b/providers/implementations/keymgmt/ecx_kmgmt.c index 2ba8f53e5a..5cc11406f6 100644 --- a/providers/implementations/keymgmt/ecx_kmgmt.c +++ b/providers/implementations/keymgmt/ecx_kmgmt.c @@ -113,12 +113,11 @@ static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[]) if (key == NULL) return 0; - if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0) + if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) return 0; include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0); - if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) - ok = ok && ecx_key_fromdata(key, params, include_private); + ok = ok && ecx_key_fromdata(key, params, include_private); return ok; } |