summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/ec/ecx_backend.c48
-rw-r--r--crypto/ec/ecx_meth.c22
-rw-r--r--include/crypto/ecx.h1
-rw-r--r--providers/implementations/keymgmt/ecx_kmgmt.c5
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;
}