]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add LMS to the fips provider.
authorslontis <shane.lontis@oracle.com>
Tue, 1 Oct 2024 06:17:05 +0000 (16:17 +1000)
committerPauli <ppzgs1@gmail.com>
Thu, 10 Jul 2025 09:03:46 +0000 (19:03 +1000)
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 <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/27885)

crypto/lms/build.info
providers/fips/fipsprov.c
providers/implementations/keymgmt/build.info
providers/implementations/keymgmt/lms_kmgmt.c
providers/implementations/signature/build.info
providers/implementations/signature/lms_signature.c [moved from providers/implementations/signature/lms_sig.c with 98% similarity]
test/lms_test.c
test/recipes/30-test_lms.t

index 068f3d7d85aab170d8cbe0c7fda273eecfe6a857..f34366a6311e68b8588b4adc1eea6d956381556f 100644 (file)
@@ -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
index 15467a3deae2f5ec274f01d2431bb7d28bfb9ecc..e99eb368c1fc44a3a9a3ac7ad6240f15bda66be1 100644 (file)
@@ -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 },
index 2f7e78ce3beaaa118d11901491720d4de814817d..f5ae1ece8869cff202481adec961bed665b5f4fd 100644 (file)
@@ -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
index 6623e30183aab5716e649846310f75d4abc7543a..72cffbc5e807245da78bf54752714840ef3762e3 100644 (file)
@@ -11,6 +11,7 @@
 #include <openssl/core_names.h>
 #include <openssl/param_build.h>
 #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
 };
index 87270d7dab083f86751c2df5bbb1cb6ea758f71d..579045f2c58a26b12b8c7b9e0a5f181a1d166146 100644 (file)
@@ -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'} -}]
similarity index 98%
rename from providers/implementations/signature/lms_sig.c
rename to providers/implementations/signature/lms_signature.c
index 1e641a708478d9f62de36e4058dddf17e1918ffb..d4864105ccc50bad2982f7327ea2fb5f898a2022 100644 (file)
@@ -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
index ef6ab7d0dac52b5a97cae06d50bf33b0a02e7354..430363c4ec67ad0410e4eb6b7288873acc1cb0ce 100644 (file)
 #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);
+}
index 09b8c54c31d68392b59601205440d0236b4b4f21..c23214ea340042a7e735a770043595f6b2e1752a 100644 (file)
@@ -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");
+}