From: slontis Date: Tue, 1 Oct 2024 06:17:05 +0000 (+1000) Subject: Add LMS to the fips provider. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=48af66aef72d482d41beafaf919b71e1dcb491b8;p=thirdparty%2Fopenssl.git Add LMS to the fips provider. This required the LMS keymanager to have an export function. The self test will be provided by HSS, which covers the LMS case. Reviewed-by: Viktor Dukhovni Reviewed-by: Matt Caswell Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/27885) --- diff --git a/crypto/lms/build.info b/crypto/lms/build.info index 068f3d7d85a..f34366a6311 100644 --- a/crypto/lms/build.info +++ b/crypto/lms/build.info @@ -5,4 +5,5 @@ $COMMON=lms_params.c lms_pubkey_decode.c lms_key.c lm_ots_params.c \ IF[{- !$disabled{'lms'} -}] SOURCE[../../libcrypto]=$COMMON +SOURCE[../../providers/libfips.a]=$COMMON ENDIF diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index 15467a3deae..e99eb368c1f 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -271,21 +271,21 @@ static int fips_self_test(void *provctx) */ #define FIPS_DIGESTS_COMMON() \ -{ PROV_NAMES_SHA1, FIPS_DEFAULT_PROPERTIES, ossl_sha1_functions }, \ -{ PROV_NAMES_SHA2_224, FIPS_DEFAULT_PROPERTIES, ossl_sha224_functions }, \ -{ PROV_NAMES_SHA2_256, FIPS_DEFAULT_PROPERTIES, ossl_sha256_functions }, \ -{ PROV_NAMES_SHA2_384, FIPS_DEFAULT_PROPERTIES, ossl_sha384_functions }, \ -{ PROV_NAMES_SHA2_512, FIPS_DEFAULT_PROPERTIES, ossl_sha512_functions }, \ -{ PROV_NAMES_SHA2_512_224, FIPS_DEFAULT_PROPERTIES, \ - ossl_sha512_224_functions }, \ -{ PROV_NAMES_SHA2_512_256, FIPS_DEFAULT_PROPERTIES, \ - ossl_sha512_256_functions }, \ -{ PROV_NAMES_SHA3_224, FIPS_DEFAULT_PROPERTIES, ossl_sha3_224_functions }, \ -{ PROV_NAMES_SHA3_256, FIPS_DEFAULT_PROPERTIES, ossl_sha3_256_functions }, \ -{ PROV_NAMES_SHA3_384, FIPS_DEFAULT_PROPERTIES, ossl_sha3_384_functions }, \ -{ PROV_NAMES_SHA3_512, FIPS_DEFAULT_PROPERTIES, ossl_sha3_512_functions }, \ -{ PROV_NAMES_SHAKE_128, FIPS_DEFAULT_PROPERTIES, ossl_shake_128_functions }, \ -{ PROV_NAMES_SHAKE_256, FIPS_DEFAULT_PROPERTIES, ossl_shake_256_functions } + { PROV_NAMES_SHA1, FIPS_DEFAULT_PROPERTIES, ossl_sha1_functions }, \ + { PROV_NAMES_SHA2_224, FIPS_DEFAULT_PROPERTIES, ossl_sha224_functions }, \ + { PROV_NAMES_SHA2_256, FIPS_DEFAULT_PROPERTIES, ossl_sha256_functions }, \ + { PROV_NAMES_SHA2_384, FIPS_DEFAULT_PROPERTIES, ossl_sha384_functions }, \ + { PROV_NAMES_SHA2_512, FIPS_DEFAULT_PROPERTIES, ossl_sha512_functions }, \ + { PROV_NAMES_SHA2_512_224, FIPS_DEFAULT_PROPERTIES, \ + ossl_sha512_224_functions }, \ + { PROV_NAMES_SHA2_512_256, FIPS_DEFAULT_PROPERTIES, \ + ossl_sha512_256_functions }, \ + { PROV_NAMES_SHA3_224, FIPS_DEFAULT_PROPERTIES, ossl_sha3_224_functions }, \ + { PROV_NAMES_SHA3_256, FIPS_DEFAULT_PROPERTIES, ossl_sha3_256_functions }, \ + { PROV_NAMES_SHA3_384, FIPS_DEFAULT_PROPERTIES, ossl_sha3_384_functions }, \ + { PROV_NAMES_SHA3_512, FIPS_DEFAULT_PROPERTIES, ossl_sha3_512_functions }, \ + { PROV_NAMES_SHAKE_128, FIPS_DEFAULT_PROPERTIES, ossl_shake_128_functions }, \ + { PROV_NAMES_SHAKE_256, FIPS_DEFAULT_PROPERTIES, ossl_shake_256_functions } static const OSSL_ALGORITHM fips_digests[] = { FIPS_DIGESTS_COMMON(), @@ -528,6 +528,9 @@ static const OSSL_ALGORITHM fips_signature[] = { { PROV_NAMES_CMAC, FIPS_DEFAULT_PROPERTIES, ossl_mac_legacy_cmac_signature_functions }, #endif +#ifndef OPENSSL_NO_LMS + { PROV_NAMES_LMS, FIPS_DEFAULT_PROPERTIES, ossl_lms_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 }, @@ -627,6 +630,10 @@ static const OSSL_ALGORITHM fips_keymgmt[] = { { PROV_NAMES_CMAC, FIPS_DEFAULT_PROPERTIES, ossl_cmac_legacy_keymgmt_functions, PROV_DESCS_CMAC_SIGN }, #endif +#ifndef OPENSSL_NO_LMS + { PROV_NAMES_LMS, FIPS_DEFAULT_PROPERTIES, ossl_lms_keymgmt_functions, + PROV_DESCS_LMS }, +#endif #ifndef OPENSSL_NO_ML_KEM { PROV_NAMES_ML_KEM_512, FIPS_DEFAULT_PROPERTIES, ossl_ml_kem_512_keymgmt_functions, PROV_DESCS_ML_KEM_512 }, diff --git a/providers/implementations/keymgmt/build.info b/providers/implementations/keymgmt/build.info index 2f7e78ce3be..f5ae1ece886 100644 --- a/providers/implementations/keymgmt/build.info +++ b/providers/implementations/keymgmt/build.info @@ -8,7 +8,7 @@ $ECX_GOAL=../../libdefault.a ../../libfips.a $KDF_GOAL=../../libdefault.a ../../libfips.a $MAC_GOAL=../../libdefault.a ../../libfips.a $RSA_GOAL=../../libdefault.a ../../libfips.a -$LMS_GOAL=../../libdefault.a +$LMS_GOAL=../../libdefault.a ../../libfips.a $TEMPLATE_GOAL=../../libtemplate.a $ML_DSA_GOAL=../../libdefault.a ../../libfips.a $ML_KEM_GOAL=../../libdefault.a ../../libfips.a diff --git a/providers/implementations/keymgmt/lms_kmgmt.c b/providers/implementations/keymgmt/lms_kmgmt.c index 6623e30183a..72cffbc5e80 100644 --- a/providers/implementations/keymgmt/lms_kmgmt.c +++ b/providers/implementations/keymgmt/lms_kmgmt.c @@ -11,6 +11,7 @@ #include #include #include "crypto/lms.h" +#include "internal/param_build_set.h" #include "prov/implementations.h" #include "prov/providercommon.h" #include "prov/provider_ctx.h" @@ -21,7 +22,9 @@ static OSSL_FUNC_keymgmt_has_fn lms_has; static OSSL_FUNC_keymgmt_match_fn lms_match; static OSSL_FUNC_keymgmt_validate_fn lms_validate; static OSSL_FUNC_keymgmt_import_fn lms_import; +static OSSL_FUNC_keymgmt_export_fn lms_export; static OSSL_FUNC_keymgmt_import_types_fn lms_imexport_types; +static OSSL_FUNC_keymgmt_export_types_fn lms_imexport_types; static OSSL_FUNC_keymgmt_load_fn lms_load; #define LMS_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_PUBLIC_KEY) @@ -87,6 +90,41 @@ static const OSSL_PARAM *lms_imexport_types(int selection) return NULL; } +static int lms_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, + void *cbarg) +{ + LMS_KEY *lmskey = keydata; + OSSL_PARAM_BLD *tmpl; + OSSL_PARAM *params = NULL; + int ret = 0; + + if (!ossl_prov_is_running() || lmskey == NULL) + return 0; + + if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0) + return 0; + + tmpl = OSSL_PARAM_BLD_new(); + if (tmpl == NULL) + return 0; + + if (!ossl_param_build_set_octet_string(tmpl, params, + OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, + lmskey->pub.encoded, + lmskey->pub.encodedlen)) + 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 int lms_validate(const void *keydata, int selection, int checktype) { const LMS_KEY *lmskey = keydata; @@ -122,6 +160,8 @@ const OSSL_DISPATCH ossl_lms_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))lms_validate }, { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))lms_import }, { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))lms_imexport_types }, + { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))lms_export }, + { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))lms_imexport_types }, { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))lms_load }, OSSL_DISPATCH_END }; diff --git a/providers/implementations/signature/build.info b/providers/implementations/signature/build.info index 87270d7dab0..579045f2c58 100644 --- a/providers/implementations/signature/build.info +++ b/providers/implementations/signature/build.info @@ -6,7 +6,7 @@ $EC_GOAL=../../libdefault.a ../../libfips.a $MAC_GOAL=../../libdefault.a ../../libfips.a $RSA_GOAL=../../libdefault.a ../../libfips.a $SM2_GOAL=../../libdefault.a -$LMS_GOAL=../../libdefault.a +$LMS_GOAL=../../libdefault.a ../../libfips.a $ML_DSA_GOAL=../../libdefault.a ../../libfips.a $SLH_DSA_GOAL=../../libdefault.a ../../libfips.a @@ -38,7 +38,7 @@ DEPEND[sm2_sig.o]=../../common/include/prov/der_sm2.h SOURCE[$MAC_GOAL]=mac_legacy_sig.c IF[{- !$disabled{lms} -}] - SOURCE[$LMS_GOAL]=lms_sig.c + SOURCE[$LMS_GOAL]=lms_signature.c ENDIF IF[{- !$disabled{'ml-dsa'} -}] diff --git a/providers/implementations/signature/lms_sig.c b/providers/implementations/signature/lms_signature.c similarity index 98% rename from providers/implementations/signature/lms_sig.c rename to providers/implementations/signature/lms_signature.c index 1e641a70847..d4864105ccc 100644 --- a/providers/implementations/signature/lms_sig.c +++ b/providers/implementations/signature/lms_signature.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 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 diff --git a/test/lms_test.c b/test/lms_test.c index ef6ab7d0dac..430363c4ec6 100644 --- a/test/lms_test.c +++ b/test/lms_test.c @@ -15,7 +15,17 @@ #include "testutil.h" #include "lms.inc" +typedef enum OPTION_choice { + OPT_ERR = -1, + OPT_EOF = 0, + OPT_CONFIG_FILE, + OPT_TEST_ENUM +} OPTION_CHOICE; + static OSSL_LIB_CTX *libctx = NULL; +static char *propq = NULL; +static OSSL_PROVIDER *nullprov = NULL; +static OSSL_PROVIDER *libprov = NULL; static EVP_PKEY *lms_pubkey_from_data(const unsigned char *data, size_t datalen) { @@ -27,7 +37,7 @@ static EVP_PKEY *lms_pubkey_from_data(const unsigned char *data, size_t datalen) params[0] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, (unsigned char *)data, datalen); params[1] = OSSL_PARAM_construct_end(); - ret = TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "LMS", NULL)) + ret = TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "LMS", propq)) && TEST_int_eq(EVP_PKEY_fromdata_init(ctx), 1) && (EVP_PKEY_fromdata(ctx, &key, EVP_PKEY_PUBLIC_KEY, params) == 1); if (ret == 0) { @@ -187,13 +197,17 @@ err: static int lms_key_eq_test(void) { int ret = 0; - EVP_PKEY *key[4] = { NULL, NULL, NULL }; + EVP_PKEY *key[4]; LMS_ACVP_TEST_DATA *td1 = &lms_testdata[0]; LMS_ACVP_TEST_DATA *td2 = &lms_testdata[1]; + size_t i; #ifndef OPENSSL_NO_EC EVP_PKEY *eckey = NULL; #endif + for (i = 0; i < OSSL_NELEM(key); i++) + key[i] = NULL; + if (!TEST_ptr(key[0] = lms_pubkey_from_data(td1->pub, td1->publen)) || !TEST_ptr(key[1] = lms_pubkey_from_data(td1->pub, td1->publen)) || !TEST_ptr(key[2] = lms_pubkey_from_data(td2->pub, td2->publen)) @@ -461,8 +475,41 @@ end: 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) { + OPTION_CHOICE o; + char *config_file = NULL; + + /* Swap the libctx to test non-default context only */ + propq = "provider=default"; + + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_CONFIG_FILE: + config_file = opt_arg(); + propq = ""; + break; + case OPT_TEST_CASES: + break; + default: + case OPT_ERR: + return 0; + } + } + if (!test_get_libctx(&libctx, &nullprov, config_file, &libprov, NULL)) + return 0; + ADD_TEST(lms_bad_pub_len_test); ADD_TEST(lms_key_validate_test); ADD_TEST(lms_key_eq_test); @@ -478,3 +525,10 @@ int setup_tests(void) return 1; } + +void cleanup_tests(void) +{ + OSSL_PROVIDER_unload(nullprov); + OSSL_PROVIDER_unload(libprov); + OSSL_LIB_CTX_free(libctx); +} diff --git a/test/recipes/30-test_lms.t b/test/recipes/30-test_lms.t index 09b8c54c31d..c23214ea340 100644 --- a/test/recipes/30-test_lms.t +++ b/test/recipes/30-test_lms.t @@ -9,18 +9,25 @@ use strict; use warnings; -use OpenSSL::Test qw(:DEFAULT srctop_dir bldtop_dir); +use OpenSSL::Test qw(:DEFAULT srctop_file srctop_dir bldtop_dir); use OpenSSL::Test::Utils; BEGIN { setup("test_lms"); } +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 => 'LMS is not supported in this build' if disabled('lms'); -plan tests => 1; +plan tests => 1 + + ($no_fips ? 0 : 1); ok(run(test(["lms_test"])), "running lms_test"); +unless ($no_fips) { + ok(run(test(["lms_test", "-config", $provconf])), + "running lms_test with fips"); +}