]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
SLH-DSA - restrict keygen seed length to exact value of 3*n
authorslontis <shane.lontis@oracle.com>
Thu, 20 Feb 2025 21:54:36 +0000 (08:54 +1100)
committerslontis <shane.lontis@oracle.com>
Sat, 22 Feb 2025 11:46:44 +0000 (22:46 +1100)
It was allowing the seed to be larger, and then just ignoring the
trailing bytes.

Reviewed-by: Paul Dale <ppzgs1@gmail.com>
Reviewed-by: Tim Hudson <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26858)

crypto/slh_dsa/slh_dsa_key.c
include/crypto/slh_dsa.h
providers/implementations/keymgmt/slh_dsa_kmgmt.c
providers/implementations/signature/slh_dsa_sig.c
test/slh_dsa_test.c

index 93d77dfd123b5f0ecebbec4040081ee7bfa0a0c9..e57a4295c63db9d359281a20e3a318c692a27d1f 100644 (file)
@@ -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 {
index 002427e1ab0a9363e0520c0a63aac12fab022a0b..a43ef814bedb951e1e1d943ef5365381e1efd639 100644 (file)
@@ -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;
index 04fe5d9485af643cc6c9880f9fdec443945fc8f0..fea538e2de97af6738b06e83db3d4cfb17507e62 100644 (file)
@@ -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;
 };
 
index f8c07f4236cbb71a17d4a0b84bd6822613d8d287..40fc6846e2adc9cbbac9fb0ba4956b255cdcc15f 100644 (file)
@@ -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 <assert.h>
 #include <openssl/core_names.h>
 #include <openssl/err.h>
 #include <openssl/rand.h>
@@ -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;
index 0efee5daccc3a66e25ea847bdfca08abaa421c68..9deb672baee3c9dea805387b3ba22fac5ab35d3f 100644 (file)
@@ -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;
 }