mirror of
https://github.com/openssl/openssl.git
synced 2025-04-06 20:20:50 +08:00
SLH-DSA clean ups
- Make slh_dsa_sign() return the siglen when sig is NULL. - Remove the ability in fromdata to generate the public key root given the private key and public key seed. This was messy and can be done by key generation instead. - Add common EVP_PKEY gettablesto SLH_DSA keys (OSSL_PKEY_PARAM_BITS, OSSL_PKEY_PARAM_SECURITY_BITS, and OSSL_PKEY_PARAM_MAX_SIZE). - Update tests based on the above changes. Reviewed-by: Paul Dale <ppzgs1@gmail.com> Reviewed-by: Viktor Dukhovni <viktor@openssl.org> Reviewed-by: Tim Hudson <tjh@openssl.org> (Merged from https://github.com/openssl/openssl/pull/25882)
This commit is contained in:
parent
ce3acbd07e
commit
5c2b404241
@ -64,12 +64,14 @@ static int slh_sign_internal(SLH_DSA_CTX *ctx, const SLH_DSA_KEY *priv,
|
||||
uint8_t *sig_ht = sig_fors + sig_fors_len;
|
||||
const uint8_t *md, *pk_seed, *sk_seed;
|
||||
|
||||
if (sig_size < sig_len_expected)
|
||||
return 0;
|
||||
if (sig_len != NULL)
|
||||
*sig_len = sig_len_expected;
|
||||
|
||||
if (sig == NULL)
|
||||
return 1;
|
||||
return (sig_len != NULL);
|
||||
|
||||
if (sig_size < sig_len_expected)
|
||||
return 0;
|
||||
/* Exit if private key is not set */
|
||||
if (priv->has_priv == 0)
|
||||
return 0;
|
||||
@ -229,16 +231,16 @@ int ossl_slh_dsa_sign(SLH_DSA_CTX *slh_ctx, const SLH_DSA_KEY *priv,
|
||||
const uint8_t *add_rand, int encode,
|
||||
unsigned char *sig, size_t *siglen, size_t sigsize)
|
||||
{
|
||||
uint8_t *m;
|
||||
size_t m_len;
|
||||
uint8_t m_tmp[1024];
|
||||
uint8_t m_tmp[1024], *m = m_tmp;
|
||||
size_t m_len = 0;
|
||||
int ret = 0;
|
||||
|
||||
m = msg_encode(msg, msg_len, ctx, ctx_len, encode, m_tmp, sizeof(m_tmp),
|
||||
&m_len);
|
||||
if (m == NULL)
|
||||
return 0;
|
||||
|
||||
if (sig != NULL) {
|
||||
m = msg_encode(msg, msg_len, ctx, ctx_len, encode, m_tmp, sizeof(m_tmp),
|
||||
&m_len);
|
||||
if (m == NULL)
|
||||
return 0;
|
||||
}
|
||||
ret = slh_sign_internal(slh_ctx, priv, m, m_len, sig, siglen, sigsize, add_rand);
|
||||
if (m != msg && m != m_tmp)
|
||||
OPENSSL_free(m);
|
||||
|
@ -137,9 +137,8 @@ int ossl_slh_dsa_key_fromdata(SLH_DSA_KEY *key, const OSSL_PARAM params[],
|
||||
int include_private)
|
||||
{
|
||||
size_t n, key_len, len = 0;
|
||||
const OSSL_PARAM *param_priv = NULL, *param_pub, *param_pk_seed = NULL;
|
||||
const OSSL_PARAM *param_priv = NULL, *param_pub = NULL;
|
||||
void *p;
|
||||
SLH_DSA_CTX *dsa_ctx = NULL;
|
||||
|
||||
if (key == NULL)
|
||||
return 0;
|
||||
@ -158,24 +157,20 @@ int ossl_slh_dsa_key_fromdata(SLH_DSA_KEY *key, const OSSL_PARAM params[],
|
||||
/*
|
||||
* There must always be a public key, since the private key cannot exist
|
||||
* without the public key elements.
|
||||
* If there is only the public seed then the private key MUST be present in
|
||||
* order to compute the pk_root element.
|
||||
*/
|
||||
param_pub = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
|
||||
if (param_pub == NULL) {
|
||||
param_pk_seed = OSSL_PARAM_locate_const(params,
|
||||
OSSL_PKEY_PARAM_SLH_DSA_PUB_SEED);
|
||||
if (param_pk_seed == NULL || param_priv == NULL)
|
||||
return 0;
|
||||
}
|
||||
if (param_pub == NULL)
|
||||
return 0;
|
||||
|
||||
if (param_pub != NULL) {
|
||||
p = key->pub;
|
||||
if (!OSSL_PARAM_get_octet_string(param_pub, &p, key_len, &len))
|
||||
return 0;
|
||||
if (len != key_len)
|
||||
return 0;
|
||||
}
|
||||
p = key->pub;
|
||||
if (!OSSL_PARAM_get_octet_string(param_pub, &p, key_len, &len))
|
||||
return 0;
|
||||
/*
|
||||
* This does not allow you to pass in just the PK SEED, this can be done
|
||||
* via key generation
|
||||
*/
|
||||
if (len != key_len)
|
||||
return 0;
|
||||
if (param_priv != NULL) {
|
||||
p = key->priv;
|
||||
if (!OSSL_PARAM_get_octet_string(param_priv, &p, key_len, &len))
|
||||
@ -185,29 +180,11 @@ int ossl_slh_dsa_key_fromdata(SLH_DSA_KEY *key, const OSSL_PARAM params[],
|
||||
goto err;
|
||||
key->has_priv = 1;
|
||||
}
|
||||
if (param_pk_seed != NULL) {
|
||||
/*
|
||||
* In this case we need to generate the pk_root
|
||||
* which requires both the private key element(s) and the public key seed.
|
||||
*/
|
||||
p = SLH_DSA_PK_SEED(key);
|
||||
if (!OSSL_PARAM_get_octet_string(param_pk_seed, &p, n, &len))
|
||||
goto err;
|
||||
if (len != n)
|
||||
goto err;
|
||||
/* Compute the pk_root element */
|
||||
dsa_ctx = ossl_slh_dsa_ctx_new(key->params->alg, key->libctx, key->propq);
|
||||
if (dsa_ctx == NULL
|
||||
|| !slh_dsa_compute_pk_root(dsa_ctx, key))
|
||||
goto err;
|
||||
ossl_slh_dsa_ctx_free(dsa_ctx);
|
||||
}
|
||||
key->key_len = key_len; /* This indicates the public key is present */
|
||||
return 1;
|
||||
err:
|
||||
key->key_len = 0;
|
||||
key->has_priv = 0;
|
||||
ossl_slh_dsa_ctx_free(dsa_ctx);
|
||||
OPENSSL_cleanse(key->priv, key_len);
|
||||
return 0;
|
||||
}
|
||||
@ -324,3 +301,8 @@ size_t ossl_slh_dsa_key_get_n(const SLH_DSA_KEY *key)
|
||||
{
|
||||
return key->params->n;
|
||||
}
|
||||
|
||||
size_t ossl_slh_dsa_key_get_sig_len(const SLH_DSA_KEY *key)
|
||||
{
|
||||
return key->params->sig_len;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ __owur const uint8_t *ossl_slh_dsa_key_get_pub(const SLH_DSA_KEY *key);
|
||||
__owur const uint8_t *ossl_slh_dsa_key_get_priv(const SLH_DSA_KEY *key);
|
||||
__owur size_t ossl_slh_dsa_key_get_len(const SLH_DSA_KEY *key);
|
||||
__owur size_t ossl_slh_dsa_key_get_n(const SLH_DSA_KEY *key);
|
||||
__owur size_t ossl_slh_dsa_key_get_sig_len(const SLH_DSA_KEY *key);
|
||||
__owur int ossl_slh_dsa_key_type_matches(SLH_DSA_CTX *ctx, const SLH_DSA_KEY *key);
|
||||
|
||||
__owur SLH_DSA_CTX *ossl_slh_dsa_ctx_new(const char *alg,
|
||||
|
@ -93,12 +93,14 @@ static int slh_dsa_import(void *keydata, int selection, const OSSL_PARAM params[
|
||||
return ossl_slh_dsa_key_fromdata(key, params, include_priv);
|
||||
}
|
||||
|
||||
#define SLH_DSA_IMEXPORTABLE_PARAMETERS \
|
||||
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 slh_dsa_key_types[] = {
|
||||
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
|
||||
SLH_DSA_IMEXPORTABLE_PARAMETERS,
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
|
||||
static const OSSL_PARAM *slh_dsa_imexport_types(int selection)
|
||||
{
|
||||
if ((selection & SLH_DSA_POSSIBLE_SELECTIONS) == 0)
|
||||
@ -106,9 +108,16 @@ static const OSSL_PARAM *slh_dsa_imexport_types(int selection)
|
||||
return slh_dsa_key_types;
|
||||
}
|
||||
|
||||
static const OSSL_PARAM slh_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),
|
||||
SLH_DSA_IMEXPORTABLE_PARAMETERS,
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
static const OSSL_PARAM *slh_dsa_gettable_params(void *provctx)
|
||||
{
|
||||
return slh_dsa_key_types;
|
||||
return slh_dsa_params;
|
||||
}
|
||||
|
||||
static int key_to_params(SLH_DSA_KEY *key, OSSL_PARAM_BLD *tmpl,
|
||||
@ -137,6 +146,17 @@ static int key_to_params(SLH_DSA_KEY *key, OSSL_PARAM_BLD *tmpl,
|
||||
static int slh_dsa_get_params(void *keydata, OSSL_PARAM params[])
|
||||
{
|
||||
SLH_DSA_KEY *key = keydata;
|
||||
OSSL_PARAM *p;
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
|
||||
&& !OSSL_PARAM_set_int(p, 8 * ossl_slh_dsa_key_get_len(key)))
|
||||
return 0;
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
|
||||
&& !OSSL_PARAM_set_int(p, 8 * ossl_slh_dsa_key_get_n(key)))
|
||||
return 0;
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
|
||||
&& !OSSL_PARAM_set_int(p, ossl_slh_dsa_key_get_sig_len(key)))
|
||||
return 0;
|
||||
|
||||
return key_to_params(key, NULL, params, 1);
|
||||
}
|
||||
|
@ -127,13 +127,16 @@ static int slh_sign(void *vctx, unsigned char *sig, size_t *siglen,
|
||||
|
||||
if (!ossl_prov_is_running())
|
||||
return 0;
|
||||
if (ctx->add_random_len != 0) {
|
||||
opt_rand = ctx->add_random;
|
||||
} else if (ctx->deterministic == 0) {
|
||||
n = ossl_slh_dsa_key_get_n(ctx->key);
|
||||
if (RAND_priv_bytes_ex(ctx->libctx, add_rand, n, 0) <= 0)
|
||||
return 0;
|
||||
opt_rand = add_rand;
|
||||
|
||||
if (sig != NULL) {
|
||||
if (ctx->add_random_len != 0) {
|
||||
opt_rand = ctx->add_random;
|
||||
} else if (ctx->deterministic == 0) {
|
||||
n = ossl_slh_dsa_key_get_n(ctx->key);
|
||||
if (RAND_priv_bytes_ex(ctx->libctx, add_rand, n, 0) <= 0)
|
||||
return 0;
|
||||
opt_rand = add_rand;
|
||||
}
|
||||
}
|
||||
ret = ossl_slh_dsa_sign(ctx->ctx, ctx->key, msg, msg_len,
|
||||
ctx->context_string, ctx->context_string_len,
|
||||
|
@ -59,9 +59,6 @@ static int slh_dsa_create_keypair(EVP_PKEY **pkey, const char *name,
|
||||
OSSL_PARAM *params = NULL;
|
||||
const char *pub_name = OSSL_PKEY_PARAM_PUB_KEY;
|
||||
|
||||
if (pub_len != priv_len)
|
||||
pub_name = OSSL_PKEY_PARAM_SLH_DSA_PUB_SEED;
|
||||
|
||||
if (!TEST_ptr(bld = OSSL_PARAM_BLD_new())
|
||||
|| !TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
|
||||
OSSL_PKEY_PARAM_PRIV_KEY,
|
||||
@ -210,8 +207,8 @@ static int slh_dsa_sign_verify_test(int tst_id)
|
||||
EVP_PKEY *pkey = NULL;
|
||||
EVP_SIGNATURE *sig_alg = NULL;
|
||||
OSSL_PARAM params[4], *p = params;
|
||||
uint8_t sig[64 * 1024];
|
||||
size_t sig_len = sizeof(sig);
|
||||
uint8_t *psig = NULL;
|
||||
size_t psig_len = 0, sig_len2 = 0;
|
||||
uint8_t digest[32];
|
||||
size_t digest_len = sizeof(digest);
|
||||
int encode = 0, deterministic = 1;
|
||||
@ -237,22 +234,29 @@ static int slh_dsa_sign_verify_test(int tst_id)
|
||||
if (!TEST_ptr(sig_alg = EVP_SIGNATURE_fetch(lib_ctx, td->alg, NULL)))
|
||||
goto err;
|
||||
if (!TEST_int_eq(EVP_PKEY_sign_init_ex2(sctx, sig_alg, params), 1)
|
||||
|| !TEST_int_eq(EVP_PKEY_sign(sctx, sig, &sig_len,
|
||||
|| !TEST_int_eq(EVP_PKEY_sign(sctx, NULL, &psig_len,
|
||||
td->msg, td->msg_len), 1)
|
||||
|| !TEST_true(EVP_PKEY_get_size_t_param(pkey, OSSL_PKEY_PARAM_MAX_SIZE,
|
||||
&sig_len2))
|
||||
|| !TEST_int_eq(sig_len2, psig_len)
|
||||
|| !TEST_ptr(psig = OPENSSL_zalloc(psig_len))
|
||||
|| !TEST_int_eq(EVP_PKEY_sign(sctx, psig, &psig_len,
|
||||
td->msg, td->msg_len), 1))
|
||||
goto err;
|
||||
|
||||
if (!TEST_int_eq(EVP_Q_digest(lib_ctx, "SHA256", NULL, sig, sig_len,
|
||||
if (!TEST_int_eq(EVP_Q_digest(lib_ctx, "SHA256", NULL, psig, psig_len,
|
||||
digest, &digest_len), 1))
|
||||
goto err;
|
||||
if (!TEST_mem_eq(digest, digest_len, td->sig_digest, td->sig_digest_len))
|
||||
goto err;
|
||||
if (!do_slh_dsa_verify(td, sig, sig_len))
|
||||
if (!do_slh_dsa_verify(td, psig, psig_len))
|
||||
goto err;
|
||||
ret = 1;
|
||||
err:
|
||||
EVP_SIGNATURE_free(sig_alg);
|
||||
EVP_PKEY_free(pkey);
|
||||
EVP_PKEY_CTX_free(sctx);
|
||||
OPENSSL_free(psig);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -287,6 +291,7 @@ static int slh_dsa_keygen_test(int tst_id)
|
||||
size_t priv_len, pub_len;
|
||||
size_t key_len = tst->priv_len / 2;
|
||||
size_t n = key_len / 2;
|
||||
int bits = 0, sec_bits = 0, sig_len = 0;
|
||||
|
||||
if (!TEST_ptr(pkey = do_gen_key(tst->name, tst->priv, key_len + n)))
|
||||
goto err;
|
||||
@ -297,6 +302,17 @@ static int slh_dsa_keygen_test(int tst_id)
|
||||
if (!TEST_true(EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY,
|
||||
pub, sizeof(pub), &pub_len)))
|
||||
goto err;
|
||||
if (!TEST_true(EVP_PKEY_get_int_param(pkey, OSSL_PKEY_PARAM_BITS, &bits))
|
||||
|| !TEST_int_eq(bits, 8 * key_len)
|
||||
|| !TEST_true(EVP_PKEY_get_int_param(pkey, OSSL_PKEY_PARAM_SECURITY_BITS,
|
||||
&sec_bits))
|
||||
|| !TEST_int_eq(sec_bits, 8 * n)
|
||||
|| !TEST_true(EVP_PKEY_get_int_param(pkey, OSSL_PKEY_PARAM_MAX_SIZE,
|
||||
&sig_len))
|
||||
|| !TEST_int_ge(sig_len, 7856)
|
||||
|| !TEST_int_le(sig_len, 49856))
|
||||
goto err;
|
||||
|
||||
if (!TEST_size_t_eq(priv_len, key_len)
|
||||
|| !TEST_size_t_eq(pub_len, key_len))
|
||||
goto err;
|
||||
@ -308,39 +324,6 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given raw values for the private key + public key seed
|
||||
* generate the public root using from data.
|
||||
*/
|
||||
static int slh_dsa_pub_root_from_data_test(void)
|
||||
{
|
||||
int ret = 0;
|
||||
uint8_t priv[64], pub[64];
|
||||
size_t priv_len = 0, pub_len = 0;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
const SLH_DSA_KEYGEN_TEST_DATA *tst = &slh_dsa_keygen_testdata[0];
|
||||
size_t key_len = tst->priv_len / 2;
|
||||
size_t n = key_len / 2;
|
||||
|
||||
if (!slh_dsa_create_keypair(&pkey, tst->name, tst->priv, key_len,
|
||||
tst->priv + key_len, n))
|
||||
goto err;
|
||||
|
||||
if (!TEST_true(EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY,
|
||||
priv, sizeof(priv), &priv_len)))
|
||||
goto err;
|
||||
if (!TEST_true(EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY,
|
||||
pub, sizeof(pub), &pub_len)))
|
||||
goto err;
|
||||
if (!TEST_mem_eq(pub, pub_len, tst->priv + key_len, key_len))
|
||||
goto err;
|
||||
ret = 1;
|
||||
err:
|
||||
OPENSSL_cleanse(priv, priv_len);
|
||||
EVP_PKEY_free(pkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const OPTIONS *test_get_options(void)
|
||||
{
|
||||
static const OPTIONS options[] = {
|
||||
@ -377,7 +360,6 @@ int setup_tests(void)
|
||||
ADD_TEST(slh_dsa_key_eq_test);
|
||||
ADD_ALL_TESTS(slh_dsa_sign_verify_test, OSSL_NELEM(slh_dsa_sig_testdata));
|
||||
ADD_ALL_TESTS(slh_dsa_keygen_test, OSSL_NELEM(slh_dsa_keygen_testdata));
|
||||
ADD_TEST(slh_dsa_pub_root_from_data_test);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -447,9 +447,6 @@ my %params = (
|
||||
|
||||
# SLH_DSA Key generation parameters
|
||||
'PKEY_PARAM_SLH_DSA_ENTROPY' => "entropy",
|
||||
|
||||
# SLH_DSA parameters
|
||||
'PKEY_PARAM_SLH_DSA_PUB_SEED' => "pk-seed",
|
||||
|
||||
# Key Exchange parameters
|
||||
'EXCHANGE_PARAM_PAD' => "pad",# uint
|
||||
|
Loading…
x
Reference in New Issue
Block a user