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/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=06937de11d302de72f3f88f4620592bceb32bec2;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: Hugo Landau Reviewed-by: Dmitry Belyavskiy Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/25598) --- 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 825eb329e16..268b15e249c 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -255,21 +255,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(), @@ -485,6 +485,9 @@ static const OSSL_ALGORITHM fips_signature[] = { #ifndef OPENSSL_NO_CMAC { 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 { NULL, NULL, NULL } }; @@ -537,6 +540,10 @@ static const OSSL_ALGORITHM fips_keymgmt[] = { #ifndef OPENSSL_NO_CMAC { 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 { NULL, NULL, NULL } }; diff --git a/providers/implementations/keymgmt/build.info b/providers/implementations/keymgmt/build.info index a4e03b4f6a1..0650e9391b7 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 IF[{- !$disabled{dh} -}] diff --git a/providers/implementations/keymgmt/lms_kmgmt.c b/providers/implementations/keymgmt/lms_kmgmt.c index 330528f91af..d8998d572cc 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 9903076f457..56a19412861 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 IF[{- !$disabled{dsa} -}] SOURCE[$DSA_GOAL]=dsa_sig.c @@ -34,5 +34,5 @@ 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 diff --git a/providers/implementations/signature/lms_sig.c b/providers/implementations/signature/lms_signature.c similarity index 100% rename from providers/implementations/signature/lms_sig.c rename to providers/implementations/signature/lms_signature.c diff --git a/test/lms_test.c b/test/lms_test.c index 346b1b9fb0f..4150aeae33a 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)) @@ -465,8 +479,41 @@ end: return ret == 1; } +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); @@ -482,3 +529,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 ada1ab01661..1f7b6803331 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"); +}