]> 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>
Mon, 3 Feb 2025 21:29:22 +0000 (08:29 +1100)
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 <hlandau@devever.net>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/25598)

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 100% 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 825eb329e1671425fce5c6ce7dc049facd1a4984..268b15e249c29d45240cadb5deaf9e49b6088fc0 100644 (file)
@@ -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 }
 };
index a4e03b4f6a1c480ff60ad004bac3807599537b22..0650e9391b79b169524f3d54904e602ffcb64397 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
 
 IF[{- !$disabled{dh} -}]
index 330528f91af0cd902a75f4dbb3fc2f8157bd000c..d8998d572cc6c2463798764c0ef637ff6766b66e 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 9903076f457549d615ce29a3a87ecd44c572def7..56a19412861aade2e59a00af56e117c604034c20 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
 
 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
index 346b1b9fb0f94dc6533aa867345c7a431b038b40..4150aeae33a20e5cfdc5d8c91fcc448a3706af52 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))
@@ -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);
+}
index ada1ab01661481945334a3394f582e5a2137e2fe..1f7b68033311026612b45822f4bfaf7b1d3fdfbf 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");
+}