From: slontis Date: Thu, 7 Nov 2024 06:43:19 +0000 (+1100) Subject: Add SLH_DSA to the FIPS provider. X-Git-Tag: openssl-3.5.0-alpha1~194 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5901ca87baf59ae966ee6cc4bee17b652b359898;p=thirdparty%2Fopenssl.git Add SLH_DSA to the FIPS provider. 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 Reviewed-by: Viktor Dukhovni Reviewed-by: Tim Hudson (Merged from https://github.com/openssl/openssl/pull/25882) --- diff --git a/crypto/slh_dsa/build.info b/crypto/slh_dsa/build.info index 4f698d692a5..6f93bd41b00 100644 --- a/crypto/slh_dsa/build.info +++ b/crypto/slh_dsa/build.info @@ -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 diff --git a/crypto/slh_dsa/slh_dsa.c b/crypto/slh_dsa/slh_dsa.c index 498586fb9d7..8a51354ae1f 100644 --- a/crypto/slh_dsa/slh_dsa.c +++ b/crypto/slh_dsa/slh_dsa.c @@ -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; diff --git a/crypto/slh_dsa/slh_dsa_key.c b/crypto/slh_dsa/slh_dsa_key.c index 8756010504f..f7dbb0f785d 100644 --- a/crypto/slh_dsa/slh_dsa_key.c +++ b/crypto/slh_dsa/slh_dsa_key.c @@ -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; diff --git a/crypto/slh_dsa/slh_xmss.c b/crypto/slh_dsa/slh_xmss.c index 682315791d5..c2501e23c8d 100644 --- a/crypto/slh_dsa/slh_xmss.c +++ b/crypto/slh_dsa/slh_xmss.c @@ -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; diff --git a/include/crypto/slh_dsa.h b/include/crypto/slh_dsa.h index e652196e291..ab9903a4916 100644 --- a/include/crypto/slh_dsa.h +++ b/include/crypto/slh_dsa.h @@ -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); diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index 2cdfd4f5e55..0527135e535 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -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 } }; diff --git a/providers/implementations/keymgmt/build.info b/providers/implementations/keymgmt/build.info index cd6c51a65a4..908a32f3555 100644 --- a/providers/implementations/keymgmt/build.info +++ b/providers/implementations/keymgmt/build.info @@ -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 diff --git a/providers/implementations/keymgmt/slh_dsa_kmgmt.c b/providers/implementations/keymgmt/slh_dsa_kmgmt.c index 0d58543f0e8..f833f588ea6 100644 --- a/providers/implementations/keymgmt/slh_dsa_kmgmt.c +++ b/providers/implementations/keymgmt/slh_dsa_kmgmt.c @@ -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 }, \ diff --git a/providers/implementations/signature/build.info b/providers/implementations/signature/build.info index 8cb173b5b59..c01e69f84ea 100644 --- a/providers/implementations/signature/build.info +++ b/providers/implementations/signature/build.info @@ -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 diff --git a/test/recipes/30-test_slh_dsa.t b/test/recipes/30-test_slh_dsa.t index d8179c66dd6..e0ade7cfe8f 100644 --- a/test/recipes/30-test_slh_dsa.t +++ b/test/recipes/30-test_slh_dsa.t @@ -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"); +} diff --git a/test/slh_dsa_test.c b/test/slh_dsa_test.c index 307791cfd49..81b3733931b 100644 --- a/test/slh_dsa_test.c +++ b/test/slh_dsa_test.c @@ -16,35 +16,16 @@ #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); } diff --git a/util/perl/OpenSSL/paramnames.pm b/util/perl/OpenSSL/paramnames.pm index b90132d7a92..fa34e137e90 100644 --- a/util/perl/OpenSSL/paramnames.pm +++ b/util/perl/OpenSSL/paramnames.pm @@ -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",