From accc7ce60eab53b1597375cd1f811e7f4dfa65ee Mon Sep 17 00:00:00 2001 From: Pauli Date: Wed, 6 Aug 2025 12:25:19 +1000 Subject: [PATCH] ecx: convert to using generated parameter decoding Reviewed-by: Tomas Mraz Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/28275) --- crypto/ec/ecx_backend.c | 12 +- crypto/ec/ecx_meth.c | 4 +- include/crypto/ecx.h | 3 +- providers/implementations/kem/ecx_kem.c.in | 9 +- .../implementations/keymgmt/ecx_kmgmt.c.in | 221 +++++++++--------- 5 files changed, 129 insertions(+), 120 deletions(-) diff --git a/crypto/ec/ecx_backend.c b/crypto/ec/ecx_backend.c index d21c037841a..43e120b0881 100644 --- a/crypto/ec/ecx_backend.c +++ b/crypto/ec/ecx_backend.c @@ -52,25 +52,20 @@ int ossl_ecx_public_from_private(ECX_KEY *key) return 1; } -int ossl_ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[], +int ossl_ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM *param_pub_key, + const OSSL_PARAM *param_priv_key, int include_private) { size_t privkeylen = 0, pubkeylen = 0; - const OSSL_PARAM *param_priv_key = NULL, *param_pub_key; unsigned char *pubkey; if (ecx == NULL) return 0; - param_pub_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY); - if (include_private) - param_priv_key = - OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); - if (param_pub_key == NULL && param_priv_key == NULL) return 0; - if (param_priv_key != NULL) { + if (include_private && param_priv_key != NULL) { if (!OSSL_PARAM_get_octet_string(param_priv_key, (void **)&ecx->privkey, ecx->keylen, &privkeylen)) @@ -87,7 +82,6 @@ int ossl_ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[], } } - pubkey = ecx->pubkey; if (param_pub_key != NULL && !OSSL_PARAM_get_octet_string(param_pub_key, diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c index 531ff1c3df4..71d2a05a7c7 100644 --- a/crypto/ec/ecx_meth.c +++ b/crypto/ec/ecx_meth.c @@ -388,13 +388,15 @@ static int ecx_generic_import_from(const OSSL_PARAM params[], void *vpctx, EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); ECX_KEY *ecx = ossl_ecx_key_new(pctx->libctx, KEYNID2TYPE(keytype), 0, pctx->propquery); + const OSSL_PARAM *pub = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY); + const OSSL_PARAM *priv = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); if (ecx == NULL) { ERR_raise(ERR_LIB_DH, ERR_R_EC_LIB); return 0; } - if (!ossl_ecx_key_fromdata(ecx, params, 1) + if (!ossl_ecx_key_fromdata(ecx, pub, priv, 1) || !EVP_PKEY_assign(pkey, keytype, ecx)) { ossl_ecx_key_free(ecx); return 0; diff --git a/include/crypto/ecx.h b/include/crypto/ecx.h index 0e8828e5466..4f96573cda8 100644 --- a/include/crypto/ecx.h +++ b/include/crypto/ecx.h @@ -150,7 +150,8 @@ ECX_KEY *ossl_ecx_key_op(const X509_ALGOR *palg, OSSL_LIB_CTX *libctx, const char *propq); int ossl_ecx_public_from_private(ECX_KEY *key); -int ossl_ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[], +int ossl_ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM *param_pub_key, + const OSSL_PARAM *param_priv_key, int include_private); ECX_KEY *ossl_ecx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, OSSL_LIB_CTX *libctx, const char *propq); diff --git a/providers/implementations/kem/ecx_kem.c.in b/providers/implementations/kem/ecx_kem.c.in index cc3bafe3bae..7458664e9a0 100644 --- a/providers/implementations/kem/ecx_kem.c.in +++ b/providers/implementations/kem/ecx_kem.c.in @@ -134,16 +134,15 @@ static ECX_KEY *ecxkey_pubfromdata(PROV_ECX_CTX *ctx, const unsigned char *pubbuf, size_t pubbuflen) { ECX_KEY *ecx = NULL; - OSSL_PARAM params[2], *p = params; + OSSL_PARAM pub; - *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY, - (char *)pubbuf, pubbuflen); - *p = OSSL_PARAM_construct_end(); + pub = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY, + (char *)pubbuf, pubbuflen); ecx = ossl_ecx_key_new(ctx->libctx, ctx->recipient_key->type, 1, ctx->propq); if (ecx == NULL) return NULL; - if (ossl_ecx_key_fromdata(ecx, params, 0) <= 0) { + if (ossl_ecx_key_fromdata(ecx, &pub, NULL, 0) <= 0) { ossl_ecx_key_free(ecx); ecx = NULL; } diff --git a/providers/implementations/keymgmt/ecx_kmgmt.c.in b/providers/implementations/keymgmt/ecx_kmgmt.c.in index 1223def69f6..b718c6b598a 100644 --- a/providers/implementations/keymgmt/ecx_kmgmt.c.in +++ b/providers/implementations/keymgmt/ecx_kmgmt.c.in @@ -6,6 +6,9 @@ * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ +{- +use OpenSSL::paramnames qw(produce_param_decoder); +-} #include #include @@ -203,20 +206,28 @@ static int ecx_match(const void *keydata1, const void *keydata2, int selection) return ok; } +{- produce_param_decoder('ecx_imexport_types', + (['PKEY_PARAM_PUB_KEY', 'pub', 'octet_string'], + ['PKEY_PARAM_PRIV_KEY', 'priv', 'octet_string'], + )); -} + static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[]) { ECX_KEY *key = keydata; int ok = 1; int include_private; + struct ecx_imexport_types_st p; - if (!ossl_prov_is_running() || key == NULL) + if (!ossl_prov_is_running() + || key == NULL + || !ecx_imexport_types_decoder(params, &p)) return 0; if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) return 0; include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0; - ok = ok && ossl_ecx_key_fromdata(key, params, include_private); + ok = ok && ossl_ecx_key_fromdata(key, p.pub, p.priv, include_private); #ifdef FIPS_MODULE if (ok > 0 && ecx_key_type_is_ed(key->type) && !ossl_fips_self_testing()) @@ -230,19 +241,19 @@ static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[]) } static int key_to_params(ECX_KEY *key, OSSL_PARAM_BLD *tmpl, - OSSL_PARAM params[], int include_private) + OSSL_PARAM *pub, OSSL_PARAM *priv, int include_private) { if (key == NULL) return 0; - if (!ossl_param_build_set_octet_string(tmpl, params, + if (!ossl_param_build_set_octet_string(tmpl, pub, OSSL_PKEY_PARAM_PUB_KEY, key->pubkey, key->keylen)) return 0; if (include_private && key->privkey != NULL - && !ossl_param_build_set_octet_string(tmpl, params, + && !ossl_param_build_set_octet_string(tmpl, priv, OSSL_PKEY_PARAM_PRIV_KEY, key->privkey, key->keylen)) return 0; @@ -271,7 +282,7 @@ static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { int include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0); - if (!key_to_params(key, tmpl, NULL, include_private)) + if (!key_to_params(key, tmpl, NULL, NULL, include_private)) goto err; } @@ -286,42 +297,66 @@ err: return ret; } -#define ECX_KEY_TYPES() \ -OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), \ -OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0) - -static const OSSL_PARAM ecx_key_types[] = { - ECX_KEY_TYPES(), - OSSL_PARAM_END -}; static const OSSL_PARAM *ecx_imexport_types(int selection) { if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) - return ecx_key_types; + return ecx_imexport_types_list; return NULL; } +struct ecx_ed_common_get_params_st { + OSSL_PARAM *bits; + OSSL_PARAM *secbits; + OSSL_PARAM *size; + OSSL_PARAM *seccat; + OSSL_PARAM *pub; + OSSL_PARAM *priv; + OSSL_PARAM *encpub; /* ECX only */ + OSSL_PARAM *ind; /* ECX only */ + OSSL_PARAM *digest; /* Ed only */ +}; + +#define ecx_get_params_st ecx_ed_common_get_params_st + +{- produce_param_decoder('ecx_get_params', + (['PKEY_PARAM_BITS', 'bits', 'int'], + ['PKEY_PARAM_SECURITY_BITS', 'secbits', 'int'], + ['PKEY_PARAM_MAX_SIZE', 'size', 'int'], + ['PKEY_PARAM_SECURITY_CATEGORY', 'seccat', 'int'], + ['PKEY_PARAM_PUB_KEY', 'pub', 'octet_string'], + ['PKEY_PARAM_PRIV_KEY', 'priv', 'octet_string'], + ['PKEY_PARAM_ENCODED_PUBLIC_KEY', 'encpub', 'octet_string'], + ['PKEY_PARAM_FIPS_APPROVED_INDICATOR', 'ind', 'int', 'fips'], + )); -} + +#define ed_get_params_st ecx_ed_common_get_params_st + +{- produce_param_decoder('ed_get_params', + (['PKEY_PARAM_BITS', 'bits', 'int'], + ['PKEY_PARAM_SECURITY_BITS', 'secbits', 'int'], + ['PKEY_PARAM_MAX_SIZE', 'size', 'int'], + ['PKEY_PARAM_SECURITY_CATEGORY', 'seccat', 'int'], + ['PKEY_PARAM_PUB_KEY', 'pub', 'octet_string'], + ['PKEY_PARAM_PRIV_KEY', 'priv', 'octet_string'], + ['PKEY_PARAM_MANDATORY_DIGEST', 'digest', 'utf8_string'], + )); -} + /* This getter is shared by ED25519, ED448, X25519 and X448 */ -static int ecx_ed_common_get_params(void *key, OSSL_PARAM params[], int bits, - int secbits, int size) +static int ecx_ed_common_get_params(void *key, + const struct ecx_ed_common_get_params_st *p, + int bits, int secbits, int size) { ECX_KEY *ecx = key; - OSSL_PARAM *p; - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL - && !OSSL_PARAM_set_int(p, bits)) + if (p->bits != NULL && !OSSL_PARAM_set_int(p->bits, bits)) return 0; - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL - && !OSSL_PARAM_set_int(p, secbits)) + if (p->secbits != NULL && !OSSL_PARAM_set_int(p->secbits, secbits)) return 0; - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL - && !OSSL_PARAM_set_int(p, size)) + if (p->size != NULL && !OSSL_PARAM_set_int(p->size, size)) return 0; - if ((p = OSSL_PARAM_locate(params, - OSSL_PKEY_PARAM_SECURITY_CATEGORY)) != NULL - && !OSSL_PARAM_set_int(p, 0)) + if (p->seccat != NULL && !OSSL_PARAM_set_int(p->seccat, 0)) return 0; - return key_to_params(ecx, NULL, params, 1); + return key_to_params(ecx, NULL, p->pub, p->priv, 1); } /* X25519/X448 getter */ @@ -329,37 +364,38 @@ static int ecx_get_params(void *key, OSSL_PARAM params[], int bits, int secbits, int size) { ECX_KEY *ecx = key; - OSSL_PARAM *p; + struct ecx_ed_common_get_params_st p; - p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY); - if (p != NULL - && !OSSL_PARAM_set_octet_string(p, ecx->pubkey, ecx->keylen)) + if (key == NULL || !ecx_get_params_decoder(params, &p)) + return 0; + + if (p.encpub != NULL + && !OSSL_PARAM_set_octet_string(p.encpub, ecx->pubkey, ecx->keylen)) return 0; #ifdef FIPS_MODULE { /* Currently X25519 and X448 are not approved */ int approved = 0; - p = OSSL_PARAM_locate(params, OSSL_ALG_PARAM_FIPS_APPROVED_INDICATOR); - if (p != NULL && !OSSL_PARAM_set_int(p, approved)) + if (p.ind != NULL && !OSSL_PARAM_set_int(p.ind, approved)) return 0; } #endif - return ecx_ed_common_get_params(key, params, bits, secbits, size); + return ecx_ed_common_get_params(key, &p, bits, secbits, size); } /* ED25519/ED448 getter */ static int ed_get_params(void *key, OSSL_PARAM params[], int bits, int secbits, int size) { - OSSL_PARAM *p; + struct ecx_ed_common_get_params_st p; - if ((p = OSSL_PARAM_locate(params, - OSSL_PKEY_PARAM_MANDATORY_DIGEST)) != NULL - && !OSSL_PARAM_set_utf8_string(p, "")) + if (key == NULL || !ed_get_params_decoder(params, &p)) return 0; - return ecx_ed_common_get_params(key, params, bits, secbits, size); + if (p.digest != NULL && !OSSL_PARAM_set_utf8_string(p.digest, "")) + return 0; + return ecx_ed_common_get_params(key, &p, bits, secbits, size); } static int x25519_get_params(void *key, OSSL_PARAM params[]) @@ -385,44 +421,24 @@ static int ed448_get_params(void *key, OSSL_PARAM params[]) ED448_SIGSIZE); } -#define GETTABLES_COMMON() \ - OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), \ - OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), \ - OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), \ - OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_CATEGORY, NULL), \ - ECX_KEY_TYPES() - -static const OSSL_PARAM ecx_gettable_params[] = { - GETTABLES_COMMON(), - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), - OSSL_FIPS_IND_GETTABLE_CTX_PARAM() - OSSL_PARAM_END -}; - -static const OSSL_PARAM ed_gettable_params[] = { - GETTABLES_COMMON(), - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0), - OSSL_PARAM_END -}; - static const OSSL_PARAM *x25519_gettable_params(void *provctx) { - return ecx_gettable_params; + return ecx_get_params_list; } static const OSSL_PARAM *x448_gettable_params(void *provctx) { - return ecx_gettable_params; + return ecx_get_params_list; } static const OSSL_PARAM *ed25519_gettable_params(void *provctx) { - return ed_gettable_params; + return ed_get_params_list; } static const OSSL_PARAM *ed448_gettable_params(void *provctx) { - return ed_gettable_params; + return ed_get_params_list; } static int set_property_query(ECX_KEY *ecxkey, const char *propq) @@ -437,30 +453,34 @@ static int set_property_query(ECX_KEY *ecxkey, const char *propq) return 1; } +{- produce_param_decoder('ecx_set_params', + (['PKEY_PARAM_ENCODED_PUBLIC_KEY', 'pub', 'octet_string'], + ['PKEY_PARAM_PROPERTIES', 'propq', 'utf8_string'], + )); -} + static int ecx_set_params(void *key, const OSSL_PARAM params[]) { ECX_KEY *ecxkey = key; - const OSSL_PARAM *p; + struct ecx_set_params_st p; - if (ossl_param_is_empty(params)) - return 1; + if (key == NULL || !ecx_set_params_decoder(params, &p)) + return 0; - p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY); - if (p != NULL) { + if (p.pub != NULL) { void *buf = ecxkey->pubkey; - if (p->data_size != ecxkey->keylen - || !OSSL_PARAM_get_octet_string(p, &buf, sizeof(ecxkey->pubkey), + if (p.pub->data_size != ecxkey->keylen + || !OSSL_PARAM_get_octet_string(p.pub, &buf, sizeof(ecxkey->pubkey), NULL)) return 0; OPENSSL_clear_free(ecxkey->privkey, ecxkey->keylen); ecxkey->privkey = NULL; ecxkey->haspubkey = 1; } - p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PROPERTIES); - if (p != NULL) { - if (p->data_type != OSSL_PARAM_UTF8_STRING - || !set_property_query(ecxkey, p->data)) + + if (p.propq != NULL) { + if (p.propq->data_type != OSSL_PARAM_UTF8_STRING + || !set_property_query(ecxkey, p.propq->data)) return 0; } @@ -487,24 +507,18 @@ static int ed448_set_params(void *key, const OSSL_PARAM params[]) return 1; } -static const OSSL_PARAM ecx_settable_params[] = { - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, NULL, 0), - OSSL_PARAM_END -}; - static const OSSL_PARAM ed_settable_params[] = { OSSL_PARAM_END }; static const OSSL_PARAM *x25519_settable_params(void *provctx) { - return ecx_settable_params; + return ecx_set_params_list; } static const OSSL_PARAM *x448_settable_params(void *provctx) { - return ecx_settable_params; + return ecx_set_params_list; } static const OSSL_PARAM *ed25519_settable_params(void *provctx) @@ -573,16 +587,21 @@ static void *ed448_gen_init(void *provctx, int selection, return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_ED448, NULL); } +{- produce_param_decoder('ecx_gen_set_params', + (['PKEY_PARAM_GROUP_NAME', 'group', 'utf8_string'], + ['KDF_PARAM_PROPERTIES', 'kdfpropq', 'utf8_string'], + ['PKEY_PARAM_DHKEM_IKM', 'ikm', 'octet_string'], + )); -} + static int ecx_gen_set_params(void *genctx, const OSSL_PARAM params[]) { struct ecx_gen_ctx *gctx = genctx; - const OSSL_PARAM *p; + struct ecx_gen_set_params_st p; - if (gctx == NULL) + if (gctx == NULL || !ecx_gen_set_params_decoder(params, &p)) return 0; - p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME); - if (p != NULL) { + if (p.group != NULL) { const char *groupname = NULL; /* @@ -601,28 +620,28 @@ static int ecx_gen_set_params(void *genctx, const OSSL_PARAM params[]) /* We only support this for key exchange at the moment */ break; } - if (p->data_type != OSSL_PARAM_UTF8_STRING + if (p.group->data_type != OSSL_PARAM_UTF8_STRING || groupname == NULL - || OPENSSL_strcasecmp(p->data, groupname) != 0) { + || OPENSSL_strcasecmp(p.group->data, groupname) != 0) { ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); return 0; } } - p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PROPERTIES); - if (p != NULL) { - if (p->data_type != OSSL_PARAM_UTF8_STRING) + + if (p.kdfpropq != NULL) { + if (p.kdfpropq->data_type != OSSL_PARAM_UTF8_STRING) return 0; OPENSSL_free(gctx->propq); - gctx->propq = OPENSSL_strdup(p->data); + gctx->propq = OPENSSL_strdup(p.kdfpropq->data); if (gctx->propq == NULL) return 0; } - p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DHKEM_IKM); - if (p != NULL) { - if (p->data_size != 0 && p->data != NULL) { + + if (p.ikm != NULL) { + if (p.ikm->data_size != 0 && p.ikm->data != NULL) { OPENSSL_free(gctx->dhkem_ikm); gctx->dhkem_ikm = NULL; - if (!OSSL_PARAM_get_octet_string(p, (void **)&gctx->dhkem_ikm, 0, + if (!OSSL_PARAM_get_octet_string(p.ikm, (void **)&gctx->dhkem_ikm, 0, &gctx->dhkem_ikmlen)) return 0; } @@ -634,13 +653,7 @@ static int ecx_gen_set_params(void *genctx, const OSSL_PARAM params[]) static const OSSL_PARAM *ecx_gen_settable_params(ossl_unused void *genctx, ossl_unused void *provctx) { - static OSSL_PARAM settable[] = { - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), - OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM, NULL, 0), - OSSL_PARAM_END - }; - return settable; + return ecx_gen_set_params_list; } #ifdef FIPS_MODULE -- 2.47.3