From: Pauli Date: Wed, 4 Jun 2025 04:24:31 +0000 (+1000) Subject: ml-dsa: update to use TRIE decoder X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=3991ade5a5b57c0b81375e47e1ac502671177635;p=thirdparty%2Fopenssl.git ml-dsa: update to use TRIE decoder For get params and from data calls. Reviewed-by: Shane Lontis Reviewed-by: Viktor Dukhovni (Merged from https://github.com/openssl/openssl/pull/27756) --- diff --git a/providers/implementations/keymgmt/ml_dsa_kmgmt.c.in b/providers/implementations/keymgmt/ml_dsa_kmgmt.c.in index 33b0ab860be..5ab8fb741fc 100644 --- a/providers/implementations/keymgmt/ml_dsa_kmgmt.c.in +++ b/providers/implementations/keymgmt/ml_dsa_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_list); +-} #include #include @@ -16,6 +19,7 @@ #include "crypto/ml_dsa.h" #include "internal/fips.h" #include "internal/param_build_set.h" +#include "internal/param_names.h" #include "prov/implementations.h" #include "prov/providercommon.h" #include "prov/provider_ctx.h" @@ -179,6 +183,15 @@ static int ml_dsa_validate(const void *key_data, int selection, int check_type) return 1; } +/* Machine generated by util/perl/OpenSSL/paramnames.pm */ +{- produce_param_list('static', 'ml_dsa_key_types', + 'static', 'ml_dsa_key_types_find_pidx', + (['PKEY_PARAM_ML_DSA_SEED', 'octet_string'], + ['PKEY_PARAM_PUB_KEY', 'octet_string'], + ['PKEY_PARAM_PRIV_KEY', 'octet_string'], + )); -} +/* End of machine generated */ + /** * @brief Load a ML_DSA key from raw data. * @@ -196,37 +209,49 @@ static int ml_dsa_key_fromdata(ML_DSA_KEY *key, const OSSL_PARAM params[], const uint8_t *pk = NULL, *sk = NULL, *seed = NULL; size_t pk_len = 0, sk_len = 0, seed_len = 0; - p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY); - if (p != NULL - && !OSSL_PARAM_get_octet_string_ptr(p, (const void **)&pk, &pk_len)) - return 0; - if (pk != NULL && pk_len != key_params->pk_len) { - ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH, - "Invalid %s public key length", key_params->alg); - return 0; - } - - /* Private key is optional */ - if (include_private) { - p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ML_DSA_SEED); - if (p != NULL - && !OSSL_PARAM_get_octet_string_ptr(p, (const void **)&seed, - &seed_len)) - return 0; - if (seed != NULL && seed_len != ML_DSA_SEED_BYTES) { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SEED_LENGTH); - return 0; + for (p = params; p->key != NULL; p++) + switch (ml_dsa_key_types_find_pidx(p->key)) { + default: + break; + + case PIDX_PKEY_PARAM_PUB_KEY: + if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&pk, &pk_len)) + return 0; + if (pk != NULL && pk_len != key_params->pk_len) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH, + "Invalid %s public key length", key_params->alg); + return 0; + } + break; + + /* Private key seed is optional */ + case PIDX_PKEY_PARAM_ML_DSA_SEED: + if (include_private) { + if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&seed, + &seed_len)) + return 0; + if (seed != NULL && seed_len != ML_DSA_SEED_BYTES) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SEED_LENGTH); + return 0; + } + } + break; + + /* Private key is optional */ + case PIDX_PKEY_PARAM_PRIV_KEY: + if (include_private) { + if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&sk, + &sk_len)) + return 0; + if (sk != NULL && sk_len != key_params->sk_len) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH, + "Invalid %s private key length", + key_params->alg); + return 0; + } + } + break; } - p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); - if (p != NULL - && !OSSL_PARAM_get_octet_string_ptr(p, (const void **)&sk, &sk_len)) - return 0; - if (sk != NULL && sk_len != key_params->sk_len) { - ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH, - "Invalid %s private key length", key_params->alg); - return 0; - } - } /* The caller MUST specify at least one of seed, private or public keys. */ if (seed_len == 0 && pk_len == 0 && sk_len == 0) { @@ -278,15 +303,6 @@ static int ml_dsa_import(void *keydata, int selection, const OSSL_PARAM params[] return ml_dsa_key_fromdata(key, params, include_priv); } -#define ML_DSA_IMEXPORTABLE_PARAMETERS \ - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ML_DSA_SEED, NULL, 0), \ - 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 ml_dsa_key_types[] = { - ML_DSA_IMEXPORTABLE_PARAMETERS, - OSSL_PARAM_END -}; static const OSSL_PARAM *ml_dsa_imexport_types(int selection) { if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) @@ -294,15 +310,20 @@ static const OSSL_PARAM *ml_dsa_imexport_types(int selection) return ml_dsa_key_types; } -static const OSSL_PARAM ml_dsa_params[] = { - 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), - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0), - ML_DSA_IMEXPORTABLE_PARAMETERS, - OSSL_PARAM_END -}; +/* Machine generated by util/perl/OpenSSL/paramnames.pm */ +{- produce_param_list('static', 'ml_dsa_params', + 'static', 'ml_dsa_get_params_find_pidx', + (['PKEY_PARAM_BITS', 'int'], + ['PKEY_PARAM_SECURITY_BITS', 'int'], + ['PKEY_PARAM_MAX_SIZE', 'int'], + ['PKEY_PARAM_SECURITY_CATEGORY', 'int'], + ['PKEY_PARAM_MANDATORY_DIGEST', 'utf8_string'], + ['PKEY_PARAM_ML_DSA_SEED', 'octet_string'], + ['PKEY_PARAM_PUB_KEY', 'octet_string'], + ['PKEY_PARAM_PRIV_KEY', 'octet_string'], + )); -} +/* End of machine generated */ + static const OSSL_PARAM *ml_dsa_gettable_params(void *provctx) { return ml_dsa_params; @@ -312,47 +333,67 @@ static int ml_dsa_get_params(void *keydata, OSSL_PARAM params[]) { ML_DSA_KEY *key = keydata; OSSL_PARAM *p; - const uint8_t *pub, *priv, *seed; - - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL - && !OSSL_PARAM_set_int(p, 8 * ossl_ml_dsa_key_get_pub_len(key))) - return 0; - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL - && !OSSL_PARAM_set_int(p, ossl_ml_dsa_key_get_collision_strength_bits(key))) - return 0; - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL - && !OSSL_PARAM_set_int(p, ossl_ml_dsa_key_get_sig_len(key))) - return 0; - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_CATEGORY)) != NULL - && !OSSL_PARAM_set_int(p, ossl_ml_dsa_key_get_security_category(key))) - return 0; - - pub = ossl_ml_dsa_key_get_pub(key); - priv = ossl_ml_dsa_key_get_priv(key); - seed = ossl_ml_dsa_key_get_seed(key); - - if (seed != NULL - && (p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_ML_DSA_SEED)) != NULL - && !OSSL_PARAM_set_octet_string(p, seed, ML_DSA_SEED_BYTES)) - return 0; - if (priv != NULL - && (p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PRIV_KEY)) != NULL - && !OSSL_PARAM_set_octet_string(p, priv, - ossl_ml_dsa_key_get_priv_len(key))) - return 0; - if (pub != NULL - && (p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY)) != NULL - && !OSSL_PARAM_set_octet_string(p, pub, - ossl_ml_dsa_key_get_pub_len(key))) - return 0; - /* - * This allows apps to use an empty digest, so that the old API - * for digest signing can be used. - */ - p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MANDATORY_DIGEST); - if (p != NULL && !OSSL_PARAM_set_utf8_string(p, "")) - return 0; - + const uint8_t *d; + size_t len; + + for (p = params; p->key != NULL; p++) + switch (ml_dsa_get_params_find_pidx(p->key)) { + default: + break; + + case PIDX_PKEY_PARAM_BITS: + if (!OSSL_PARAM_set_int(p, 8 * ossl_ml_dsa_key_get_pub_len(key))) + return 0; + break; + + case PIDX_PKEY_PARAM_SECURITY_BITS: + if (!OSSL_PARAM_set_int(p, ossl_ml_dsa_key_get_collision_strength_bits(key))) + return 0; + break; + + case PIDX_PKEY_PARAM_MAX_SIZE: + if (!OSSL_PARAM_set_int(p, ossl_ml_dsa_key_get_sig_len(key))) + return 0; + break; + + case PIDX_PKEY_PARAM_SECURITY_CATEGORY: + if (!OSSL_PARAM_set_int(p, ossl_ml_dsa_key_get_security_category(key))) + return 0; + break; + + case PIDX_PKEY_PARAM_ML_DSA_SEED: + d = ossl_ml_dsa_key_get_seed(key); + if (d != NULL && !OSSL_PARAM_set_octet_string(p, d, ML_DSA_SEED_BYTES)) + return 0; + break; + + case PIDX_PKEY_PARAM_PRIV_KEY: + d = ossl_ml_dsa_key_get_priv(key); + if (d != NULL) { + len = ossl_ml_dsa_key_get_priv_len(key); + if (!OSSL_PARAM_set_octet_string(p, d, len)) + return 0; + } + break; + + case PIDX_PKEY_PARAM_PUB_KEY: + d = ossl_ml_dsa_key_get_pub(key); + if (d != NULL) { + len = ossl_ml_dsa_key_get_pub_len(key); + if (!OSSL_PARAM_set_octet_string(p, d, len)) + return 0; + } + break; + + /* + * This allows apps to use an empty digest, so that the old API + * for digest signing can be used. + */ + case PIDX_PKEY_PARAM_MANDATORY_DIGEST: + if (!OSSL_PARAM_set_utf8_string(p, "")) + return 0; + break; + } return 1; }