From: slontis Date: Thu, 20 Feb 2025 21:54:36 +0000 (+1100) Subject: SLH-DSA - restrict keygen seed length to exact value of 3*n X-Git-Tag: openssl-3.5.0-alpha1~102 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6e770d38c72e15ab7d0f7ee0a5dd8deb88116571;p=thirdparty%2Fopenssl.git SLH-DSA - restrict keygen seed length to exact value of 3*n It was allowing the seed to be larger, and then just ignoring the trailing bytes. Reviewed-by: Paul Dale Reviewed-by: Tim Hudson (Merged from https://github.com/openssl/openssl/pull/26858) --- diff --git a/crypto/slh_dsa/slh_dsa_key.c b/crypto/slh_dsa/slh_dsa_key.c index 93d77dfd123..e57a4295c63 100644 --- a/crypto/slh_dsa/slh_dsa_key.c +++ b/crypto/slh_dsa/slh_dsa_key.c @@ -357,7 +357,7 @@ int ossl_slh_dsa_generate_key(SLH_DSA_HASH_CTX *ctx, SLH_DSA_KEY *out, uint8_t *pub = SLH_DSA_PUB(out); if (entropy != NULL && entropy_len != 0) { - if (entropy_len < entropy_len_expected) + if (entropy_len != entropy_len_expected) goto err; memcpy(priv, entropy, entropy_len_expected); } else { diff --git a/include/crypto/slh_dsa.h b/include/crypto/slh_dsa.h index 002427e1ab0..a43ef814bed 100644 --- a/include/crypto/slh_dsa.h +++ b/include/crypto/slh_dsa.h @@ -18,6 +18,7 @@ # include "crypto/types.h" # define SLH_DSA_MAX_CONTEXT_STRING_LEN 255 +# define SLH_DSA_MAX_N 32 typedef struct slh_dsa_hash_ctx_st SLH_DSA_HASH_CTX; typedef struct slh_dsa_key_st SLH_DSA_KEY; diff --git a/providers/implementations/keymgmt/slh_dsa_kmgmt.c b/providers/implementations/keymgmt/slh_dsa_kmgmt.c index 04fe5d9485a..fea538e2de9 100644 --- a/providers/implementations/keymgmt/slh_dsa_kmgmt.c +++ b/providers/implementations/keymgmt/slh_dsa_kmgmt.c @@ -41,7 +41,7 @@ struct slh_dsa_gen_ctx { SLH_DSA_HASH_CTX *ctx; OSSL_LIB_CTX *libctx; char *propq; - uint8_t entropy[32 * 3]; + uint8_t entropy[SLH_DSA_MAX_N * 3]; size_t entropy_len; }; diff --git a/providers/implementations/signature/slh_dsa_sig.c b/providers/implementations/signature/slh_dsa_sig.c index f8c07f4236c..40fc6846e2a 100644 --- a/providers/implementations/signature/slh_dsa_sig.c +++ b/providers/implementations/signature/slh_dsa_sig.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,9 +7,6 @@ * https://www.openssl.org/source/license.html */ -#include "internal/deprecated.h" - -#include #include #include #include @@ -284,7 +281,6 @@ static int slh_dsa_set_ctx_params(void *vctx, const OSSL_PARAM params[]) void *vp = pctx->add_random; size_t n = ossl_slh_dsa_key_get_n(pctx->key); - assert(n <= sizeof(pctx->add_random)); if (!OSSL_PARAM_get_octet_string(p, &vp, n, &(pctx->add_random_len)) || pctx->add_random_len != n) { pctx->add_random_len = 0; diff --git a/test/slh_dsa_test.c b/test/slh_dsa_test.c index 0efee5daccc..9deb672baee 100644 --- a/test/slh_dsa_test.c +++ b/test/slh_dsa_test.c @@ -570,6 +570,51 @@ err: return ret; } +static int slh_dsa_keygen_invalid_test(void) +{ + int ret = 0; + const SLH_DSA_KEYGEN_TEST_DATA *tst = &slh_dsa_keygen_testdata[0]; + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; + OSSL_PARAM params[2], *p = params; + size_t key_len = tst->priv_len; + size_t n = key_len / 4; + uint8_t seed[128] = {0}; + + if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(lib_ctx, tst->name, NULL)) + || !TEST_int_eq(EVP_PKEY_keygen_init(ctx), 1)) + goto err; + + /* Test the set fails if the seed is larger than the internal buffer */ + p[0] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_SLH_DSA_SEED, + seed, 97); + p[1] = OSSL_PARAM_construct_end(); + if (!TEST_int_eq(EVP_PKEY_CTX_set_params(ctx, params), 0)) + goto err; + + /* Test the generate fails if the seed is not the correct size */ + p[0] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_SLH_DSA_SEED, + seed, n * 3 - 1); + p[1] = OSSL_PARAM_construct_end(); + + if (!TEST_int_eq(EVP_PKEY_CTX_set_params(ctx, params), 1) + || !TEST_int_eq(EVP_PKEY_generate(ctx, &pkey), 0)) + goto err; + + /* Test the generate fails if the seed is not the correct size */ + p[0] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_SLH_DSA_SEED, + seed, n * 3 + 1); + p[1] = OSSL_PARAM_construct_end(); + if (!TEST_int_eq(EVP_PKEY_CTX_set_params(ctx, params), 1) + || !TEST_int_eq(EVP_PKEY_generate(ctx, &pkey), 0)) + goto err; + ret = 1; +err: + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); + return ret; +} + const OPTIONS *test_get_options(void) { static const OPTIONS options[] = { @@ -610,6 +655,7 @@ int setup_tests(void) 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_digest_sign_verify_test); + ADD_TEST(slh_dsa_keygen_invalid_test); return 1; }