Make the ML-DSA seed gettable as documented

- Also fix the get_params keymgmt function to always return what's
  available.  Requested, but unavailable, parameters are simply left
  unmodified.  It is not an error to request more than is present.

Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/26674)
This commit is contained in:
Viktor Dukhovni 2025-02-09 13:07:39 +11:00 committed by Tomas Mraz
parent 5421423ef9
commit 3138976041
2 changed files with 23 additions and 19 deletions

View File

@ -263,6 +263,7 @@ static int ml_dsa_import(void *keydata, int selection, const OSSL_PARAM params[]
}
#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)
@ -294,7 +295,7 @@ static int ml_dsa_get_params(void *keydata, OSSL_PARAM params[])
{
ML_DSA_KEY *key = keydata;
OSSL_PARAM *p;
const uint8_t *pub, *priv;
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)))
@ -308,22 +309,22 @@ static int ml_dsa_get_params(void *keydata, OSSL_PARAM params[])
pub = ossl_ml_dsa_key_get_pub(key);
priv = ossl_ml_dsa_key_get_priv(key);
seed = ossl_ml_dsa_key_get_seed(key);
/* This just gets the private elements */
p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PRIV_KEY);
if (p != NULL) {
if (priv == NULL
|| !OSSL_PARAM_set_octet_string(p, priv,
ossl_ml_dsa_key_get_priv_len(key)))
return 0;
}
p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY);
if (p != NULL) {
if (pub == NULL
|| !OSSL_PARAM_set_octet_string(p, pub,
ossl_ml_dsa_key_get_pub_len(key)))
return 0;
}
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.

View File

@ -87,16 +87,19 @@ static int ml_dsa_keygen_test(int tst_id)
int ret = 0;
const ML_DSA_KEYGEN_TEST_DATA *tst = &ml_dsa_keygen_testdata[tst_id];
EVP_PKEY *pkey = NULL;
uint8_t priv[5 * 1024], pub[3 * 1024];
size_t priv_len, pub_len;
uint8_t priv[5 * 1024], pub[3 * 1024], seed[ML_DSA_SEED_BYTES];
size_t priv_len, pub_len, seed_len;
if (!TEST_ptr(pkey = do_gen_key(tst->name, tst->seed, tst->seed_len))
|| !TEST_true(EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ML_DSA_SEED,
seed, sizeof(seed), &seed_len))
|| !TEST_true(EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY,
priv, sizeof(priv), &priv_len))
|| !TEST_true(EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY,
pub, sizeof(pub), &pub_len))
|| !TEST_mem_eq(pub, pub_len, tst->pub, tst->pub_len)
|| !TEST_mem_eq(priv, priv_len, tst->priv, tst->priv_len))
|| !TEST_mem_eq(priv, priv_len, tst->priv, tst->priv_len)
|| !TEST_mem_eq(seed, seed_len, tst->seed, tst->seed_len))
goto err;
ret = 1;
err: