diff --git a/crypto/slh_dsa/slh_dsa.c b/crypto/slh_dsa/slh_dsa.c index 8f6736b91b..10b0b1f66b 100644 --- a/crypto/slh_dsa/slh_dsa.c +++ b/crypto/slh_dsa/slh_dsa.c @@ -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); diff --git a/crypto/slh_dsa/slh_dsa_key.c b/crypto/slh_dsa/slh_dsa_key.c index 922d165084..e189c8e55e 100644 --- a/crypto/slh_dsa/slh_dsa_key.c +++ b/crypto/slh_dsa/slh_dsa_key.c @@ -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; +} diff --git a/include/crypto/slh_dsa.h b/include/crypto/slh_dsa.h index 14139508b4..86ad4f96f8 100644 --- a/include/crypto/slh_dsa.h +++ b/include/crypto/slh_dsa.h @@ -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, diff --git a/providers/implementations/keymgmt/slh_dsa_kmgmt.c b/providers/implementations/keymgmt/slh_dsa_kmgmt.c index f833f588ea..7deb42b345 100644 --- a/providers/implementations/keymgmt/slh_dsa_kmgmt.c +++ b/providers/implementations/keymgmt/slh_dsa_kmgmt.c @@ -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); } diff --git a/providers/implementations/signature/slh_dsa_sig.c b/providers/implementations/signature/slh_dsa_sig.c index ddee41ca75..d279f1fbf7 100644 --- a/providers/implementations/signature/slh_dsa_sig.c +++ b/providers/implementations/signature/slh_dsa_sig.c @@ -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, diff --git a/test/slh_dsa_test.c b/test/slh_dsa_test.c index 15cdf8bea0..7e66e3a100 100644 --- a/test/slh_dsa_test.c +++ b/test/slh_dsa_test.c @@ -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; } diff --git a/util/perl/OpenSSL/paramnames.pm b/util/perl/OpenSSL/paramnames.pm index fa34e137e9..be5b8c027a 100644 --- a/util/perl/OpenSSL/paramnames.pm +++ b/util/perl/OpenSSL/paramnames.pm @@ -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