]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add SLH_DSA to the FIPS provider.
authorslontis <shane.lontis@oracle.com>
Thu, 7 Nov 2024 06:43:19 +0000 (17:43 +1100)
committerTomas Mraz <tomas@openssl.org>
Tue, 18 Feb 2025 09:13:53 +0000 (10:13 +0100)
The keygen tests required "entropy" to be added via an additional
parameter for ACVP testing. This is required because TEST_RAND cant be
used to pass entropy to the FIPS provider, due to it not knowing the
lib ctx of the FIPS provider.

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)

12 files changed:
crypto/slh_dsa/build.info
crypto/slh_dsa/slh_dsa.c
crypto/slh_dsa/slh_dsa_key.c
crypto/slh_dsa/slh_xmss.c
include/crypto/slh_dsa.h
providers/fips/fipsprov.c
providers/implementations/keymgmt/build.info
providers/implementations/keymgmt/slh_dsa_kmgmt.c
providers/implementations/signature/build.info
test/recipes/30-test_slh_dsa.t
test/slh_dsa_test.c
util/perl/OpenSSL/paramnames.pm

index 4f698d692a582f31b0a65f8d6baee189f1dcee3a..6f93bd41b006584b4fba49c9bba9721962480a71 100644 (file)
@@ -5,4 +5,5 @@ $COMMON=slh_adrs.c slh_dsa.c slh_dsa_ctx.c slh_dsa_key.c slh_fors.c slh_hash.c \
 
 IF[{- !$disabled{'slh_dsa'} -}]
   SOURCE[../../libcrypto]=$COMMON
+  SOURCE[../../providers/libfips.a]=$COMMON
 ENDIF
index 498586fb9d7f0f7c8f68a2b4822d97e20df907df..8a51354ae1fdef4de5c8597f72fb9144fdfe965b 100644 (file)
@@ -54,9 +54,9 @@ static int slh_sign_internal(SLH_DSA_CTX *ctx, const SLH_DSA_KEY *priv,
     size_t sig_len_expected = r_len + sig_fors_len + sig_ht_len;
     SLH_HASH_FUNC_DECLARE(ctx, hashf, hctx);
     SLH_ADRS_FUNC_DECLARE(ctx, adrsf);
+    SLH_ADRS_DECLARE(adrs);
     uint64_t tree_id;
     uint32_t leaf_id;
-    uint8_t adrs[SLH_ADRS_SIZE_MAX];
     uint8_t pk_fors[SLH_MAX_N];
     uint8_t m_digest[SLH_MAX_M];
     uint8_t *r = sig;
index 8756010504ff377528005c72db7b7cbdb9806276..f7dbb0f785d2a4c30b0737021d2d98d22f8ac470 100644 (file)
@@ -245,10 +245,14 @@ static int slh_dsa_compute_pk_root(SLH_DSA_CTX *ctx, SLH_DSA_KEY *out)
  *
  * @param ctx Contains SLH_DSA algorithm functions and constants.
  * @param lib_ctx A library context for fetching RAND algorithms
+ * @param entropy Optional entropy to use instead of using a DRBG.
+ *        Required for ACVP testing. It may be NULL.
+ * @param entropy_len the size of |entropy|. If set it must be at least 3 * |n|.
  * @param out An SLH_DSA key to write keypair data to.
  * @returns 1 if the key is generated or 0 otherwise.
  */
 int ossl_slh_dsa_generate_key(SLH_DSA_CTX *ctx, OSSL_LIB_CTX *lib_ctx,
+                              const uint8_t *entropy, size_t entropy_len,
                               SLH_DSA_KEY *out)
 {
     size_t n = ctx->params->n;
@@ -256,9 +260,17 @@ int ossl_slh_dsa_generate_key(SLH_DSA_CTX *ctx, OSSL_LIB_CTX *lib_ctx,
 
     assert(ctx->params == out->params);
 
-    if (RAND_priv_bytes_ex(lib_ctx, out->priv, key_len, 0) <= 0
-            || RAND_bytes_ex(lib_ctx, out->pub, n, 0) <= 0
-            || !slh_dsa_compute_pk_root(ctx, out))
+    if (entropy != NULL && entropy_len != 0) {
+        if (entropy_len < (key_len + n))
+            goto err;
+        memcpy(out->priv, entropy, key_len);
+        memcpy(out->pub, entropy + key_len, n);
+    } else {
+        if (RAND_priv_bytes_ex(lib_ctx, out->priv, key_len, 0) <= 0
+                || RAND_bytes_ex(lib_ctx, out->pub, n, 0) <= 0)
+            goto err;
+    }
+    if (!slh_dsa_compute_pk_root(ctx, out))
         goto err;
     out->key_len = key_len;
     out->has_priv = 1;
index 682315791d50fc3552abb7ff430bc9d762f1deb8..c2501e23c8d6765186572e6cb6ef1bc7caa59cc4 100644 (file)
@@ -90,6 +90,7 @@ void ossl_slh_xmss_sign(SLH_DSA_CTX *ctx, const uint8_t *msg,
     size_t auth_sig_len = n * hm;
     assert(sig_len == (wots_sig_len + auth_sig_len));
 */
+
     for (h = 0; h < hm; ++h) {
         ossl_slh_xmss_node(ctx, sk_seed, id ^ 1, h, pk_seed, adrs, auth_path);
         id >>= 1;
index e652196e291c1e2bf88aa7c5178c2ad9a38ca01d..ab9903a4916d265c6845b6303b08e539ff52a050 100644 (file)
@@ -30,6 +30,7 @@ int ossl_slh_dsa_key_has(const SLH_DSA_KEY *key, int selection);
 int ossl_slh_dsa_key_fromdata(SLH_DSA_KEY *key, const OSSL_PARAM *params,
                               int include_private);
 int ossl_slh_dsa_generate_key(SLH_DSA_CTX *ctx, OSSL_LIB_CTX *libctx,
+                              const uint8_t *entropy, size_t entropy_len,
                               SLH_DSA_KEY *out);
 int ossl_slh_dsa_key_is_private(const SLH_DSA_KEY *key);
 const uint8_t *ossl_slh_dsa_key_get_pub(const SLH_DSA_KEY *key);
index 2cdfd4f5e554fff04a40868470018b19ee8987b9..0527135e53518a0d6bc906280b2501b4b3d1ad78 100644 (file)
@@ -500,6 +500,32 @@ static const OSSL_ALGORITHM fips_signature[] = {
     { PROV_NAMES_CMAC, FIPS_DEFAULT_PROPERTIES,
       ossl_mac_legacy_cmac_signature_functions },
 #endif
+#ifndef OPENSSL_NO_SLH_DSA
+    { PROV_NAMES_SLH_DSA_SHA2_128S, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_sha2_128s_signature_functions, PROV_DESCS_SLH_DSA_SHA2_128S },
+    { PROV_NAMES_SLH_DSA_SHA2_128F, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_sha2_128f_signature_functions, PROV_DESCS_SLH_DSA_SHA2_128F },
+    { PROV_NAMES_SLH_DSA_SHA2_192S, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_sha2_192s_signature_functions, PROV_DESCS_SLH_DSA_SHA2_192S },
+    { PROV_NAMES_SLH_DSA_SHA2_192F, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_sha2_192f_signature_functions, PROV_DESCS_SLH_DSA_SHA2_192F },
+    { PROV_NAMES_SLH_DSA_SHA2_256S, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_sha2_256s_signature_functions, PROV_DESCS_SLH_DSA_SHA2_256S },
+    { PROV_NAMES_SLH_DSA_SHA2_256F, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_sha2_256f_signature_functions, PROV_DESCS_SLH_DSA_SHA2_256F },
+    { PROV_NAMES_SLH_DSA_SHAKE_128S, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_shake_128s_signature_functions, PROV_DESCS_SLH_DSA_SHAKE_128S },
+    { PROV_NAMES_SLH_DSA_SHAKE_128F, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_shake_128f_signature_functions, PROV_DESCS_SLH_DSA_SHAKE_128F },
+    { PROV_NAMES_SLH_DSA_SHAKE_192S, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_shake_192s_signature_functions, PROV_DESCS_SLH_DSA_SHAKE_192S },
+    { PROV_NAMES_SLH_DSA_SHAKE_192F, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_shake_192f_signature_functions, PROV_DESCS_SLH_DSA_SHAKE_192F },
+    { PROV_NAMES_SLH_DSA_SHAKE_256S, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_shake_256s_signature_functions, PROV_DESCS_SLH_DSA_SHAKE_256S },
+    { PROV_NAMES_SLH_DSA_SHAKE_256F, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_shake_256f_signature_functions, PROV_DESCS_SLH_DSA_SHAKE_256F },
+#endif /* OPENSSL_NO_SLH_DSA */
     { NULL, NULL, NULL }
 };
 
@@ -593,6 +619,32 @@ static const OSSL_ALGORITHM fips_keymgmt[] = {
       PROV_DESCS_SecP384r1MLKEM1024 },
 # endif
 #endif
+#ifndef OPENSSL_NO_SLH_DSA
+    { PROV_NAMES_SLH_DSA_SHA2_128S, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_sha2_128s_keymgmt_functions, PROV_DESCS_SLH_DSA_SHA2_128S },
+    { PROV_NAMES_SLH_DSA_SHA2_128F, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_sha2_128f_keymgmt_functions, PROV_DESCS_SLH_DSA_SHA2_128F },
+    { PROV_NAMES_SLH_DSA_SHA2_192S, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_sha2_192s_keymgmt_functions, PROV_DESCS_SLH_DSA_SHA2_192S },
+    { PROV_NAMES_SLH_DSA_SHA2_192F, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_sha2_192f_keymgmt_functions, PROV_DESCS_SLH_DSA_SHA2_192F },
+    { PROV_NAMES_SLH_DSA_SHA2_256S, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_sha2_256s_keymgmt_functions, PROV_DESCS_SLH_DSA_SHA2_256S },
+    { PROV_NAMES_SLH_DSA_SHA2_256F, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_sha2_256f_keymgmt_functions, PROV_DESCS_SLH_DSA_SHA2_256F },
+    { PROV_NAMES_SLH_DSA_SHAKE_128S, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_shake_128s_keymgmt_functions, PROV_DESCS_SLH_DSA_SHAKE_128S },
+    { PROV_NAMES_SLH_DSA_SHAKE_128F, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_shake_128f_keymgmt_functions, PROV_DESCS_SLH_DSA_SHAKE_128F },
+    { PROV_NAMES_SLH_DSA_SHAKE_192S, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_shake_192s_keymgmt_functions, PROV_DESCS_SLH_DSA_SHAKE_192S },
+    { PROV_NAMES_SLH_DSA_SHAKE_192F, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_shake_192f_keymgmt_functions, PROV_DESCS_SLH_DSA_SHAKE_192F },
+    { PROV_NAMES_SLH_DSA_SHAKE_256S, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_shake_256s_keymgmt_functions, PROV_DESCS_SLH_DSA_SHAKE_256S },
+    { PROV_NAMES_SLH_DSA_SHAKE_256F, FIPS_DEFAULT_PROPERTIES,
+      ossl_slh_dsa_shake_256f_keymgmt_functions, PROV_DESCS_SLH_DSA_SHAKE_256F },
+#endif /* OPENSSL_NO_SLH_DSA */
     { NULL, NULL, NULL }
 };
 
index cd6c51a65a4a43c7394fb7e1a2c91b2e95222e39..908a32f3555e17d257a8c43ed2121aad6e13ff55 100644 (file)
@@ -12,7 +12,7 @@ $TEMPLATE_GOAL=../../libtemplate.a
 $ML_DSA_GOAL=../../libdefault.a ../../libfips.a
 $ML_KEM_GOAL=../../libdefault.a ../../libfips.a
 $TLS_ML_KEM_HYBRID_GOAL=../../libdefault.a ../../libfips.a
-$SLH_DSA_GOAL=../../libdefault.a
+$SLH_DSA_GOAL=../../libdefault.a ../../libfips.a
 
 IF[{- !$disabled{dh} -}]
   SOURCE[$DH_GOAL]=dh_kmgmt.c
index 0d58543f0e8aee1934d86d5b939d22b3adec449b..f833f588ea60a5b7b767ca26731a7b0ce3c39aee 100644 (file)
@@ -20,7 +20,10 @@ static OSSL_FUNC_keymgmt_free_fn slh_dsa_free_key;
 static OSSL_FUNC_keymgmt_has_fn slh_dsa_has;
 static OSSL_FUNC_keymgmt_match_fn slh_dsa_match;
 static OSSL_FUNC_keymgmt_import_fn slh_dsa_import;
+static OSSL_FUNC_keymgmt_export_fn slh_dsa_export;
 static OSSL_FUNC_keymgmt_import_types_fn slh_dsa_imexport_types;
+static OSSL_FUNC_keymgmt_export_types_fn slh_dsa_imexport_types;
+static OSSL_FUNC_keymgmt_load_fn slh_dsa_load;
 static OSSL_FUNC_keymgmt_get_params_fn slh_dsa_get_params;
 static OSSL_FUNC_keymgmt_gettable_params_fn slh_dsa_gettable_params;
 static OSSL_FUNC_keymgmt_gen_init_fn slh_dsa_gen_init;
@@ -31,9 +34,11 @@ static OSSL_FUNC_keymgmt_gen_settable_params_fn slh_dsa_gen_settable_params;
 #define SLH_DSA_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR)
 
 struct slh_dsa_gen_ctx {
+    SLH_DSA_CTX *ctx;
     OSSL_LIB_CTX *libctx;
     char *propq;
-    SLH_DSA_CTX *ctx;
+    uint8_t entropy[32 * 3];
+    size_t entropy_len;
 };
 
 static void *slh_dsa_new_key(void *provctx, const char *alg)
@@ -136,6 +141,56 @@ static int slh_dsa_get_params(void *keydata, OSSL_PARAM params[])
     return key_to_params(key, NULL, params, 1);
 }
 
+static int slh_dsa_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
+                      void *cbarg)
+{
+    SLH_DSA_KEY *key = keydata;
+    OSSL_PARAM_BLD *tmpl;
+    OSSL_PARAM *params = NULL;
+    int ret = 0, include_private;
+
+    if (!ossl_prov_is_running() || key == NULL)
+        return 0;
+
+    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
+        return 0;
+    /* The public key is required for private keys */
+    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0)
+        return 0;
+
+    tmpl = OSSL_PARAM_BLD_new();
+    if (tmpl == NULL)
+        return 0;
+
+    include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
+    if (!key_to_params(key, tmpl, NULL, include_private))
+        goto err;
+
+    params = OSSL_PARAM_BLD_to_param(tmpl);
+    if (params == NULL)
+        goto err;
+
+    ret = param_cb(params, cbarg);
+    OSSL_PARAM_free(params);
+err:
+    OSSL_PARAM_BLD_free(tmpl);
+    return ret;
+}
+
+static void *slh_dsa_load(const void *reference, size_t reference_sz)
+{
+    SLH_DSA_KEY *key = NULL;
+
+    if (ossl_prov_is_running() && reference_sz == sizeof(key)) {
+        /* The contents of the reference is the address to our object */
+        key = *(SLH_DSA_KEY **)reference;
+        /* We grabbed, so we detach it */
+        *(SLH_DSA_KEY **)reference = NULL;
+        return key;
+    }
+    return NULL;
+}
+
 static void *slh_dsa_gen_init(void *provctx, int selection,
                               const OSSL_PARAM params[])
 {
@@ -169,7 +224,8 @@ static void *slh_dsa_gen(void *genctx, const char *alg)
     key = ossl_slh_dsa_key_new(gctx->libctx, alg);
     if (key == NULL)
         return NULL;
-    if (!ossl_slh_dsa_generate_key(ctx, gctx->libctx, key))
+    if (!ossl_slh_dsa_generate_key(ctx, gctx->libctx,
+                                   gctx->entropy, gctx->entropy_len, key))
         goto err;
     ossl_slh_dsa_ctx_free(ctx);
     return key;
@@ -187,7 +243,18 @@ static int slh_dsa_gen_set_params(void *genctx, const OSSL_PARAM params[])
     if (gctx == NULL)
         return 0;
 
-    p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_PROPERTIES);
+    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_SLH_DSA_ENTROPY);
+    if (p != NULL) {
+        void *vp = gctx->entropy;
+        size_t len = sizeof(gctx->entropy);
+
+        if (!OSSL_PARAM_get_octet_string(p, &vp, len, &(gctx->entropy_len))) {
+            gctx->entropy_len = 0;
+            return 0;
+        }
+    }
+
+    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PROPERTIES);
     if (p != NULL) {
         if (p->data_type != OSSL_PARAM_UTF8_STRING)
             return 0;
@@ -203,7 +270,8 @@ static const OSSL_PARAM *slh_dsa_gen_settable_params(ossl_unused void *genctx,
                                                      ossl_unused void *provctx)
 {
     static OSSL_PARAM settable[] = {
-        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
+        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_SLH_DSA_ENTROPY, NULL, 0),
         OSSL_PARAM_END
     };
     return settable;
@@ -213,6 +281,7 @@ static void slh_dsa_gen_cleanup(void *genctx)
 {
     struct slh_dsa_gen_ctx *gctx = genctx;
 
+    OPENSSL_cleanse(gctx->entropy, gctx->entropy_len);
     OPENSSL_free(gctx->propq);
     OPENSSL_free(gctx);
 }
@@ -235,6 +304,9 @@ const OSSL_DISPATCH ossl_slh_dsa_##fn##_keymgmt_functions[] = {                \
     { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))slh_dsa_match },                \
     { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))slh_dsa_import },              \
     { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))slh_dsa_imexport_types },\
+    { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))slh_dsa_export },              \
+    { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))slh_dsa_imexport_types },\
+    { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))slh_dsa_load },                  \
     { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))slh_dsa_get_params },     \
     { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))slh_dsa_gettable_params }, \
     { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))slh_dsa_gen_init },          \
index 8cb173b5b59e0245e146adb2e9f16b6afc5e8ed0..c01e69f84ea8e0feb0e02f189f03db81004a4096 100644 (file)
@@ -7,7 +7,7 @@ $MAC_GOAL=../../libdefault.a ../../libfips.a
 $RSA_GOAL=../../libdefault.a ../../libfips.a
 $SM2_GOAL=../../libdefault.a
 $ML_DSA_GOAL=../../libdefault.a ../../libfips.a
-$SLH_DSA_GOAL=../../libdefault.a
+$SLH_DSA_GOAL=../../libdefault.a ../../libfips.a
 
 IF[{- !$disabled{dsa} -}]
   SOURCE[$DSA_GOAL]=dsa_sig.c
index d8179c66dd6441c2df93bfa5e5dbbd4387a9b37f..e0ade7cfe8f7cc145ec0fb985039927b80a986b9 100644 (file)
@@ -9,17 +9,25 @@
 use strict;
 use warnings;
 
-use OpenSSL::Test qw(:DEFAULT srctop_dir bldtop_dir);
+use OpenSSL::Test qw(:DEFAULT srctop_dir bldtop_dir srctop_file);
 use OpenSSL::Test::Utils;
 
 BEGIN {
     setup("test_slh_dsa");
 }
 
+my $provconf = srctop_file("test", "fips-and-base.cnf");
+my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
+
 use lib srctop_dir('Configurations');
 use lib bldtop_dir('.');
 
 plan skip_all => 'SLH-DSA is not supported in this build' if disabled('slh-dsa');
-plan tests => 1;
+plan tests => ($no_fips ? 0 : 1) + 1;
 
 ok(run(test(["slh_dsa_test"])), "running slh_dsa_test");
+
+unless ($no_fips) {
+    ok(run(test(["slh_dsa_test", "-config",  $provconf])),
+           "running slh_dsa_test with FIPS");
+}
index 307791cfd4998873f693d087fb675cad7902045c..81b3733931b1d05ea2f23a91da41530770af373c 100644 (file)
 #include "testutil.h"
 #include "slh_dsa.inc"
 
-static OSSL_LIB_CTX *libctx = NULL;
-static OSSL_PROVIDER *fake_rand = NULL;
+typedef enum OPTION_choice {
+    OPT_ERR = -1,
+    OPT_EOF = 0,
+    OPT_CONFIG_FILE,
+    OPT_TEST_ENUM
+} OPTION_CHOICE;
 
-static size_t entropy_pos = 0;
-static size_t entropy_sz = 0;
-static uint8_t entropy[128];
-
-static int set_entropy(const uint8_t *ent1, size_t ent1_len,
-                       const uint8_t *ent2, size_t ent2_len)
-{
-    if ((ent1_len + ent2_len) > sizeof(entropy))
-        return 0;
-    entropy_pos = 0;
-    entropy_sz += (ent1_len + ent2_len);
-    memcpy(entropy, ent1, ent1_len);
-    if (ent2 != NULL)
-        memcpy(entropy + ent1_len, ent2, ent2_len);
-    return 1;
-}
-
-static int fake_rand_cb(unsigned char *buf, size_t num,
-                        ossl_unused const char *name, EVP_RAND_CTX *ctx)
-{
-    if ((entropy_pos + num) > entropy_sz)
-        return 0;
-    memcpy(buf, entropy + entropy_pos, num);
-    entropy_pos += num;
-    return 1;
-}
+static OSSL_LIB_CTX *lib_ctx = NULL;
+static OSSL_PROVIDER *null_prov = NULL;
+static OSSL_PROVIDER *lib_prov = NULL;
 
 static EVP_PKEY *slh_dsa_pubkey_from_data(const char *alg,
                                           const unsigned char *data, size_t datalen)
@@ -57,7 +38,7 @@ static EVP_PKEY *slh_dsa_pubkey_from_data(const char *alg,
     params[0] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
                                                   (unsigned char *)data, datalen);
     params[1] = OSSL_PARAM_construct_end();
-    ret = TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, alg, NULL))
+    ret = TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(lib_ctx, alg, NULL))
         && TEST_int_eq(EVP_PKEY_fromdata_init(ctx), 1)
         && (EVP_PKEY_fromdata(ctx, &key, EVP_PKEY_PUBLIC_KEY, params) == 1);
     if (ret == 0) {
@@ -89,7 +70,7 @@ static int slh_dsa_create_keypair(EVP_PKEY **pkey, const char *name,
                                                            pub_name,
                                                            pub, pub_len) > 0)
             || !TEST_ptr(params = OSSL_PARAM_BLD_to_param(bld))
-            || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, name, NULL))
+            || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(lib_ctx, name, NULL))
             || !TEST_int_eq(EVP_PKEY_fromdata_init(ctx), 1)
             || !TEST_int_eq(EVP_PKEY_fromdata(ctx, pkey, EVP_PKEY_KEYPAIR,
                                               params), 1))
@@ -152,7 +133,7 @@ static int slh_dsa_key_eq_test(void)
         goto end;
 
 #ifndef OPENSSL_NO_EC
-    if (!TEST_ptr(eckey = EVP_PKEY_Q_keygen(libctx, NULL, "EC", "P-256")))
+    if (!TEST_ptr(eckey = EVP_PKEY_Q_keygen(lib_ctx, NULL, "EC", "P-256")))
         goto end;
     ret = TEST_int_ne(EVP_PKEY_eq(key[0], eckey), 1);
     EVP_PKEY_free(eckey);
@@ -173,7 +154,7 @@ static int slh_dsa_key_validate_test(void)
 
     if (!TEST_ptr(key = slh_dsa_pubkey_from_data(td->alg, td->pub, td->pub_len)))
         return 0;
-    if (!TEST_ptr(vctx = EVP_PKEY_CTX_new_from_pkey(libctx, key, NULL)))
+    if (!TEST_ptr(vctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key, NULL)))
         goto end;
     ret = TEST_int_eq(EVP_PKEY_check(vctx), 1);
     EVP_PKEY_CTX_free(vctx);
@@ -203,9 +184,9 @@ static int do_slh_dsa_verify(const SLH_DSA_SIG_TEST_DATA *td,
 
     if (!TEST_ptr(key = slh_dsa_pubkey_from_data(td->alg, td->pub, td->pub_len)))
         return 0;
-    if (!TEST_ptr(vctx = EVP_PKEY_CTX_new_from_pkey(libctx, key, NULL)))
+    if (!TEST_ptr(vctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key, NULL)))
         goto err;
-    if (!TEST_ptr(sig_alg = EVP_SIGNATURE_fetch(libctx, td->alg, NULL)))
+    if (!TEST_ptr(sig_alg = EVP_SIGNATURE_fetch(lib_ctx, td->alg, NULL)))
         goto err;
     if (!TEST_int_eq(EVP_PKEY_verify_init_ex2(vctx, sig_alg, params), 1)
             || !TEST_int_eq(EVP_PKEY_verify(vctx, sig, sig_len,
@@ -249,16 +230,16 @@ static int slh_dsa_sign_verify_test(int tst_id)
                                 td->pub, td->pub_len))
         goto err;
 
-    if (!TEST_ptr(sctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, NULL)))
+    if (!TEST_ptr(sctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, pkey, NULL)))
         goto err;
-    if (!TEST_ptr(sig_alg = EVP_SIGNATURE_fetch(libctx, td->alg, NULL)))
+    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,
                                           td->msg, td->msg_len), 1))
         goto err;
 
-    if (!TEST_int_eq(EVP_Q_digest(libctx, "SHA256", NULL, sig, sig_len,
+    if (!TEST_int_eq(EVP_Q_digest(lib_ctx, "SHA256", NULL, sig, sig_len,
                                   digest, &digest_len), 1))
         goto err;
     if (!TEST_mem_eq(digest, digest_len, td->sig_digest, td->sig_digest_len))
@@ -273,6 +254,28 @@ err:
     return ret;
 }
 
+static EVP_PKEY *do_gen_key(const char *alg,
+                            const uint8_t *entropy, size_t entropy_len)
+{
+    EVP_PKEY *pkey = NULL;
+    EVP_PKEY_CTX *ctx = NULL;
+    OSSL_PARAM params[2], *p = params;
+
+    if (entropy_len != 0)
+        *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_SLH_DSA_ENTROPY,
+                                                 (char *)entropy, entropy_len);
+    *p = OSSL_PARAM_construct_end();
+
+    if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(lib_ctx, alg, NULL))
+            || !TEST_int_eq(EVP_PKEY_keygen_init(ctx), 1)
+            || !TEST_int_eq(EVP_PKEY_CTX_set_params(ctx, params), 1)
+            || !TEST_int_eq(EVP_PKEY_generate(ctx, &pkey), 1))
+        goto err;
+err:
+    EVP_PKEY_CTX_free(ctx);
+    return pkey;
+}
+
 static int slh_dsa_keygen_test(int tst_id)
 {
     int ret = 0;
@@ -283,15 +286,9 @@ static int slh_dsa_keygen_test(int tst_id)
     size_t key_len = tst->priv_len / 2;
     size_t n = key_len / 2;
 
-    if (!TEST_true(set_entropy(tst->priv, key_len,
-                               tst->priv + key_len, n)))
+    if (!TEST_ptr(pkey = do_gen_key(tst->name, tst->priv, key_len + n)))
         goto err;
 
-    fake_rand_set_callback(RAND_get0_private(NULL), &fake_rand_cb);
-    fake_rand_set_callback(RAND_get0_public(NULL), &fake_rand_cb);
-
-    if (!TEST_ptr(pkey = EVP_PKEY_Q_keygen(libctx, NULL, tst->name)))
-        goto err;
     if (!TEST_true(EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY,
                                                    priv, sizeof(priv), &priv_len)))
         goto err;
@@ -305,8 +302,6 @@ static int slh_dsa_keygen_test(int tst_id)
         goto err;
     ret = 1;
 err:
-    fake_rand_set_callback(RAND_get0_public(NULL), NULL);
-    fake_rand_set_callback(RAND_get0_private(NULL), NULL);
     EVP_PKEY_free(pkey);
     return ret;
 }
@@ -344,10 +339,35 @@ err:
     return ret;
 }
 
+const OPTIONS *test_get_options(void)
+{
+    static const OPTIONS options[] = {
+        OPT_TEST_OPTIONS_DEFAULT_USAGE,
+        { "config", OPT_CONFIG_FILE, '<',
+          "The configuration file to use for the libctx" },
+        { NULL }
+    };
+    return options;
+}
+
 int setup_tests(void)
 {
-    fake_rand = fake_rand_start(NULL);
-    if (fake_rand == NULL)
+    OPTION_CHOICE o;
+    char *config_file = NULL;
+
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_CONFIG_FILE:
+            config_file = opt_arg();
+            break;
+        case OPT_TEST_CASES:
+            break;
+        default:
+        case OPT_ERR:
+            return 0;
+        }
+    }
+    if (!test_get_libctx(&lib_ctx, &null_prov, config_file, &lib_prov, NULL))
         return 0;
 
     ADD_TEST(slh_dsa_bad_pub_len_test);
@@ -361,5 +381,7 @@ int setup_tests(void)
 
 void cleanup_tests(void)
 {
-    fake_rand_finish(fake_rand);
+    OSSL_PROVIDER_unload(null_prov);
+    OSSL_PROVIDER_unload(lib_prov);
+    OSSL_LIB_CTX_free(lib_ctx);
 }
index b90132d7a92099ff3895d563b4c12fd778f60e95..fa34e137e90831b40ef2702199aa7133dcc23c58 100644 (file)
@@ -444,6 +444,10 @@ my %params = (
     'PKEY_PARAM_ML_DSA_PREFER_SEED' =>      "ml-dsa.prefer_seed",
     'PKEY_PARAM_ML_DSA_INPUT_FORMATS' =>    "ml-dsa.input_formats",
     'PKEY_PARAM_ML_DSA_OUTPUT_FORMATS' =>   "ml-dsa.output_formats",
+
+# SLH_DSA Key generation parameters
+    'PKEY_PARAM_SLH_DSA_ENTROPY' =>         "entropy",
+    
 # SLH_DSA parameters
     'PKEY_PARAM_SLH_DSA_PUB_SEED' => "pk-seed",