]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add SLH_DSA key validation.
authorslontis <shane.lontis@oracle.com>
Thu, 21 Nov 2024 05:09:18 +0000 (16:09 +1100)
committerTomas Mraz <tomas@openssl.org>
Tue, 18 Feb 2025 09:17:29 +0000 (10:17 +0100)
The pairwise test requires that the computed PK_ROOT key matches the
keys PK_ROOT value. The public and private key tests just require the
key elements to exist.

Reviewed-by: Paul Dale <ppzgs1@gmail.com>
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Tim Hudson <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/25882)

14 files changed:
crypto/slh_dsa/slh_dsa_backend.c
crypto/slh_dsa/slh_dsa_key.c
crypto/slh_dsa/slh_dsa_local.h
crypto/slh_dsa/slh_dsa_meth.c
crypto/x509/x_pubkey.c
doc/designs/slh-dsa.md
include/crypto/evp.h
include/crypto/slh_dsa.h
providers/implementations/encode_decode/decode_der2key.c
providers/implementations/encode_decode/encode_key2any.c
providers/implementations/encode_decode/encode_key2text.c
providers/implementations/keymgmt/slh_dsa_kmgmt.c
test/endecode_test.c
test/slh_dsa_test.c

index 870b78f35937b804a27ed0335b1b3399f942cfd6..8cf089de16e2a6826405ae0dee02c37084a112ec 100644 (file)
@@ -29,7 +29,7 @@ SLH_DSA_KEY *ossl_slh_dsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8_info,
 
     X509_ALGOR_get0(NULL, &alg_param_type, NULL, alg);
     if (alg_param_type != V_ASN1_UNDEF)
-         return 0;
+        return 0;
 
     oct = d2i_ASN1_OCTET_STRING(NULL, &p, p_len);
     if (oct == NULL) {
index be531ca554aeb0b79580a3f65a0f7606cb474c9c..a454fb27a703f13857217e528f44854d6f10d458 100644 (file)
 #include <openssl/rand.h>
 #include "slh_dsa_local.h"
 #include "slh_dsa_key.h"
+#include "internal/encoder.h"
 
-static int slh_dsa_compute_pk_root(SLH_DSA_CTX *ctx, SLH_DSA_KEY *out);
+static int slh_dsa_compute_pk_root(SLH_DSA_CTX *ctx, SLH_DSA_KEY *out,
+                                   int verify);
 
 /**
  * @brief Create a new SLH_DSA_KEY object
@@ -142,6 +144,22 @@ int ossl_slh_dsa_key_has(const SLH_DSA_KEY *key, int selection)
     return 0;
 }
 
+int ossl_slh_dsa_key_pairwise_check(const SLH_DSA_KEY *key)
+{
+    int ret;
+    SLH_DSA_CTX *ctx = NULL;
+
+    if (key->pub == NULL || key->has_priv == 0)
+        return 0;
+
+    ctx = ossl_slh_dsa_ctx_new(key->params->alg, key->libctx, key->propq);
+    if (ctx == NULL)
+        return 0;
+    ret = slh_dsa_compute_pk_root(ctx, (SLH_DSA_KEY *)key, 1);
+    ossl_slh_dsa_ctx_free(ctx);
+    return ret;
+}
+
 /**
  * @brief Load a SLH_DSA key from raw data.
  *
@@ -213,20 +231,28 @@ int ossl_slh_dsa_key_fromdata(SLH_DSA_KEY *key, const OSSL_PARAM params[],
  * @param ctx Contains SLH_DSA algorithm functions and constants.
  * @param out A SLH_DSA key containing the private key (seed and prf) and public key seed.
  *            The public root key is written to this key.
- * @returns 1 if the root key is generated, or 0 on error.
+ * @param validate If set to 1 the computed public key is not written to the key,
+ *                 but will be compared to the existing value.
+ * @returns 1 if the root key is generated or compared successfully, or 0 on error.
  */
-static int slh_dsa_compute_pk_root(SLH_DSA_CTX *ctx, SLH_DSA_KEY *out)
+static int slh_dsa_compute_pk_root(SLH_DSA_CTX *ctx, SLH_DSA_KEY *out,
+                                   int validate)
 {
     SLH_ADRS_FUNC_DECLARE(ctx, adrsf);
     SLH_ADRS_DECLARE(adrs);
     const SLH_DSA_PARAMS *params = out->params;
+    size_t n = params->n;
+    uint8_t pk_root[SLH_DSA_MAX_N], *dst;
 
     adrsf->zero(adrs);
     adrsf->set_layer_address(adrs, params->d - 1);
+
+    dst = validate ? pk_root : SLH_DSA_PK_ROOT(out);
+
     /* Generate the ROOT public key */
     return ossl_slh_xmss_node(ctx, SLH_DSA_SK_SEED(out), 0, params->hm,
-                              SLH_DSA_PK_SEED(out), adrs,
-                              SLH_DSA_PK_ROOT(out), params->n);
+                              SLH_DSA_PK_SEED(out), adrs, dst, n)
+        && (validate == 0 || memcmp(dst, SLH_DSA_PK_ROOT(out), n) == 0);
 }
 
 /**
@@ -265,7 +291,7 @@ int ossl_slh_dsa_generate_key(SLH_DSA_CTX *ctx, OSSL_LIB_CTX *lib_ctx,
                 || RAND_bytes_ex(lib_ctx, pub, pk_seed_len, 0) <= 0)
             goto err;
     }
-    if (!slh_dsa_compute_pk_root(ctx, out))
+    if (!slh_dsa_compute_pk_root(ctx, out, 0))
         goto err;
     out->pub = pub;
     out->has_priv = 1;
@@ -358,3 +384,40 @@ int ossl_slh_dsa_set_pub(SLH_DSA_KEY *key, const uint8_t *pub, size_t pub_len)
     key->has_priv = 0;
     return 1;
 }
+
+int ossl_slh_dsa_key_to_text(BIO *out, const SLH_DSA_KEY *key, int selection)
+{
+    const char *name;
+
+    if (out == NULL || key == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    if (ossl_slh_dsa_key_get_pub(key) == NULL) {
+        /* Regardless of the |selection|, there must be a public key */
+        ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
+        return 0;
+    }
+
+    name = ossl_slh_dsa_key_get_name(key);
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+        if (ossl_slh_dsa_key_get_priv(key) == NULL) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
+            return 0;
+        }
+        if (BIO_printf(out, "%s Private-Key:\n", name) <= 0)
+            return 0;
+        if (!ossl_bio_print_labeled_buf(out, "priv:", ossl_slh_dsa_key_get_priv(key),
+                                        ossl_slh_dsa_key_get_priv_len(key)))
+            return 0;
+    } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+        if (BIO_printf(out, "%s Public-Key:\n", name) <= 0)
+            return 0;
+    }
+
+    if (!ossl_bio_print_labeled_buf(out, "pub:", ossl_slh_dsa_key_get_pub(key),
+                                    ossl_slh_dsa_key_get_pub_len(key)))
+        return 0;
+
+    return 1;
+}
index d48952e55bba98de7238198a9bac0411489906d0..288de32f37794aeacba2f0b4882c14eb2398220c 100644 (file)
  * It is the size used by WOTS+ public and private key elements as well as
  * signature elements.
  */
-#define SLH_MAX_N                   32
+#define SLH_MAX_N 32
 /*
  * For the given standard w=16 for all parameter sets.
  * A n byte message is converted into 2 * n base 16 Integers followed
  * by 3 Integers for the checksum of these values.
  */
-#define SLH_WOTS_LEN(n)             (2 * (n) + 3)
+#define SLH_WOTS_LEN(n) (2 * (n) + 3)
 
 /*
  * FIPS 205 SLH_DSA algorithms have many different parameters which includes:
index 0e0aca49df1951e6b561ce066b83c46f7a51775c..0bad7cca2c77d52c23a9632dfadfb2cecec4e499 100644 (file)
 #include "crypto/x509.h"
 #include "crypto/slh_dsa.h"
 
+/* Minimal ASN1 method table to support PUB_KEY decoding */
+#define IMPLEMENT_PKEY_ASN1_METHOD(alg, name, PKEY_NAME)                       \
+    const EVP_PKEY_ASN1_METHOD ossl_slh_dsa_##name##_asn1_meth =               \
+    {                                                                          \
+        EVP_PKEY_SLH_DSA_##PKEY_NAME, EVP_PKEY_SLH_DSA_##PKEY_NAME,            \
+        0,                                                                     \
+        alg,                                                                   \
+        "OpenSSL " alg " algorithm",                                           \
+        slh_dsa_pub_decode, NULL, NULL, NULL,                                  \
+        NULL, NULL, NULL,                                                      \
+        NULL, NULL, NULL,                                                      \
+        NULL, NULL, NULL, NULL, NULL, NULL,                                    \
+        NULL,                                                                  \
+        slh_dsa_free,                                                          \
+    }
+
 static SLH_DSA_KEY *ossl_slh_dsa_key_create(const X509_ALGOR *palg,
                                             const unsigned char *p, int p_len,
                                             int id, int public,
@@ -83,21 +99,6 @@ static void slh_dsa_free(EVP_PKEY *pkey)
     ossl_slh_dsa_key_free(pkey->pkey.slh_dsa);
 }
 
-/* Minimal ASN1 method table to support PUB_KEY decoding */
-#define IMPLEMENT_PKEY_ASN1_METHOD(alg, name, PKEY_NAME)                       \
-const EVP_PKEY_ASN1_METHOD ossl_slh_dsa_##name##_asn1_meth = {                 \
-    EVP_PKEY_SLH_DSA_##PKEY_NAME, EVP_PKEY_SLH_DSA_##PKEY_NAME,                \
-    0,                                                                         \
-    alg,                                                                       \
-    "OpenSSL " alg " algorithm",                                               \
-    slh_dsa_pub_decode, NULL, NULL, NULL,                                      \
-    NULL, NULL, NULL,                                                          \
-    NULL, NULL, NULL,                                                          \
-    NULL, NULL, NULL, NULL, NULL, NULL,                                        \
-    NULL,                                                                      \
-    slh_dsa_free,                                                              \
-}
-
 IMPLEMENT_PKEY_ASN1_METHOD("SLH-DSA-SHA2-128s", sha2_128s, SHA2_128S);
 IMPLEMENT_PKEY_ASN1_METHOD("SLH-DSA-SHA2-128f", sha2_128f, SHA2_128F);
 IMPLEMENT_PKEY_ASN1_METHOD("SLH-DSA-SHA2-192s", sha2_192s, SHA2_192S);
index 8c6e994d0b776218e988475cb3125788f7ddbed1..4f0c785a783b54b30d610f00fef6150d36f73699 100644 (file)
@@ -1054,17 +1054,17 @@ static int i2d_SLH_DSA_PUBKEY(const SLH_DSA_KEY *a, unsigned char **pp,
     return ret;
 }
 
-#define IMPLEMENT_SLH_DSA_PUBKEY_D2I_I2D(alg)                                  \
-int ossl_i2d_SLH_DSA_##alg##_PUBKEY(const SLH_DSA_KEY *a, unsigned char **pp)  \
-{                                                                              \
-    return i2d_SLH_DSA_PUBKEY(a, pp, EVP_PKEY_SLH_DSA_##alg);                  \
-}                                                                              \
-SLH_DSA_KEY *ossl_d2i_SLH_DSA_##alg##_PUBKEY(SLH_DSA_KEY **a,                  \
-                                             const unsigned char **pp,         \
-                                             long length)                      \
-{                                                                              \
-    return d2i_SLH_DSA_PUBKEY(a, pp, length, EVP_PKEY_SLH_DSA_##alg);          \
-}
+# define IMPLEMENT_SLH_DSA_PUBKEY_D2I_I2D(alg)                                 \
+    int ossl_i2d_SLH_DSA_##alg##_PUBKEY(const SLH_DSA_KEY *a, unsigned char **pp)\
+    {                                                                          \
+        return i2d_SLH_DSA_PUBKEY(a, pp, EVP_PKEY_SLH_DSA_##alg);              \
+    }                                                                          \
+    SLH_DSA_KEY *ossl_d2i_SLH_DSA_##alg##_PUBKEY(SLH_DSA_KEY **a,              \
+                                                 const unsigned char **pp,     \
+                                                 long length)                  \
+    {                                                                          \
+        return d2i_SLH_DSA_PUBKEY(a, pp, length, EVP_PKEY_SLH_DSA_##alg);      \
+    }
 
 IMPLEMENT_SLH_DSA_PUBKEY_D2I_I2D(SHA2_128S)
 IMPLEMENT_SLH_DSA_PUBKEY_D2I_I2D(SHA2_128F)
index 4cca1f2b5726914492f83f0ab127734404a7ae11..7926cd56056f2e793cd129ec17576c3291de45a5 100644 (file)
@@ -60,7 +60,7 @@ The fields 'key_len' and 'has_priv' are used to determine if a key has loaded
 the public and private key elements.
 The 'params' field is the parameter set which is resolved via the algorithm name.
 
-The FIPS 205 the SLH_DSA private key contains the public key.
+In FIPS 205 the SLH_DSA private key contains the public key.
 In OpenSSL these components are stored separately, so there must always be a
 public key in order for the key to be valid.
 
index a87f14a01296b8b74ecd8a1d1ca1851f4a783606..5e2f8a148ec1af6b13ea937fec76a49871e1051b 100644 (file)
@@ -663,9 +663,9 @@ union legacy_pkey_st {
 #   ifndef OPENSSL_NO_ECX
     ECX_KEY *ecx;           /* X25519, X448, Ed25519, Ed448 */
 #   endif
-#   ifndef OPENSSL_NO_SLH_DSA
+#  endif
+#  ifndef OPENSSL_NO_SLH_DSA
     SLH_DSA_KEY *slh_dsa;  /* SLH_DSA_* */
-#   endif
 #  endif
 };
 
index 353daf04c9579e5aa347113548fde32beebbbd00..dc04df8061e942f03651fb349e9329681983da86 100644 (file)
@@ -27,11 +27,13 @@ __owur int ossl_slh_dsa_key_up_ref(SLH_DSA_KEY *key);
 __owur int ossl_slh_dsa_key_equal(const SLH_DSA_KEY *key1, const SLH_DSA_KEY *key2,
                                   int selection);
 __owur int ossl_slh_dsa_key_has(const SLH_DSA_KEY *key, int selection);
+__owur int ossl_slh_dsa_key_pairwise_check(const SLH_DSA_KEY *key);
 __owur int ossl_slh_dsa_key_fromdata(SLH_DSA_KEY *key, const OSSL_PARAM *params,
                                      int include_private);
 __owur 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);
+__owur int ossl_slh_dsa_key_to_text(BIO *out, const SLH_DSA_KEY *key, int selection);
 __owur const uint8_t *ossl_slh_dsa_key_get_pub(const SLH_DSA_KEY *key);
 __owur const uint8_t *ossl_slh_dsa_key_get_priv(const SLH_DSA_KEY *key);
 __owur size_t ossl_slh_dsa_key_get_pub_len(const SLH_DSA_KEY *key);
index aca35cdaa408e8fb073c7176fa20a583ae3285e4..85f6bfc5dc46cbd22d30faf2fb3d95c399052b86 100644 (file)
@@ -622,7 +622,7 @@ ml_kem_d2i_PUBKEY(const uint8_t **der, long der_len,
 #endif
 
 
-# ifndef OPENSSL_NO_SLH_DSA
+#ifndef OPENSSL_NO_SLH_DSA
 
 /* SLH_DSA only implements PKCS#8 and SubjectPublicKeyInfo */
 
@@ -638,128 +638,126 @@ static void slh_dsa_key_adjust(void *key, struct der2key_ctx_st *ctx)
     ossl_slh_dsa_key_set0_libctx(key, PROV_LIBCTX_OF(ctx->provctx));
 }
 
-#  define slh_dsa_sha2_128s_evp_type        EVP_PKEY_SLH_DSA_SHA2_128S
-#  define slh_dsa_sha2_128s_d2i_private_key NULL
-#  define slh_dsa_sha2_128s_d2i_public_key  NULL
-#  define slh_dsa_sha2_128s_d2i_key_params  NULL
-#  define slh_dsa_sha2_128s_d2i_PKCS8       slh_dsa_d2i_PKCS8
-#  define slh_dsa_sha2_128s_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHA2_128S_PUBKEY
-#  define slh_dsa_sha2_128s_free            (free_key_fn *)ossl_slh_dsa_key_free
-#  define slh_dsa_sha2_128s_check           NULL
-#  define slh_dsa_sha2_128s_adjust          slh_dsa_key_adjust
-
-#  define slh_dsa_sha2_128f_evp_type        EVP_PKEY_SLH_DSA_SHA2_128F
-#  define slh_dsa_sha2_128f_d2i_private_key NULL
-#  define slh_dsa_sha2_128f_d2i_public_key  NULL
-#  define slh_dsa_sha2_128f_d2i_key_params  NULL
-#  define slh_dsa_sha2_128f_d2i_PKCS8       slh_dsa_d2i_PKCS8
-#  define slh_dsa_sha2_128f_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHA2_128F_PUBKEY
-#  define slh_dsa_sha2_128f_free            (free_key_fn *)ossl_slh_dsa_key_free
-#  define slh_dsa_sha2_128f_check           NULL
-#  define slh_dsa_sha2_128f_adjust          slh_dsa_key_adjust
-
-#  define slh_dsa_sha2_192s_evp_type        EVP_PKEY_SLH_DSA_SHA2_192S
-#  define slh_dsa_sha2_192s_d2i_private_key NULL
-#  define slh_dsa_sha2_192s_d2i_public_key  NULL
-#  define slh_dsa_sha2_192s_d2i_key_params  NULL
-#  define slh_dsa_sha2_192s_d2i_PKCS8       slh_dsa_d2i_PKCS8
-#  define slh_dsa_sha2_192s_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHA2_192S_PUBKEY
-#  define slh_dsa_sha2_192s_free            (free_key_fn *)ossl_slh_dsa_key_free
-#  define slh_dsa_sha2_192s_check           NULL
-#  define slh_dsa_sha2_192s_adjust          slh_dsa_key_adjust
-
-#  define slh_dsa_sha2_192f_evp_type        EVP_PKEY_SLH_DSA_SHA2_192F
-#  define slh_dsa_sha2_192f_d2i_private_key NULL
-#  define slh_dsa_sha2_192f_d2i_public_key  NULL
-#  define slh_dsa_sha2_192f_d2i_key_params  NULL
-#  define slh_dsa_sha2_192f_d2i_PKCS8       slh_dsa_d2i_PKCS8
-#  define slh_dsa_sha2_192f_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHA2_192F_PUBKEY
-#  define slh_dsa_sha2_192f_free            (free_key_fn *)ossl_slh_dsa_key_free
-#  define slh_dsa_sha2_192f_check           NULL
-#  define slh_dsa_sha2_192f_adjust          slh_dsa_key_adjust
-
-#  define slh_dsa_sha2_256s_evp_type        EVP_PKEY_SLH_DSA_SHA2_256S
-#  define slh_dsa_sha2_256s_d2i_private_key NULL
-#  define slh_dsa_sha2_256s_d2i_public_key  NULL
-#  define slh_dsa_sha2_256s_d2i_key_params  NULL
-#  define slh_dsa_sha2_256s_d2i_PKCS8       slh_dsa_d2i_PKCS8
-#  define slh_dsa_sha2_256s_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHA2_256S_PUBKEY
-#  define slh_dsa_sha2_256s_free            (free_key_fn *)ossl_slh_dsa_key_free
-#  define slh_dsa_sha2_256s_check           NULL
-#  define slh_dsa_sha2_256s_adjust          slh_dsa_key_adjust
-
-#  define slh_dsa_sha2_256f_evp_type        EVP_PKEY_SLH_DSA_SHA2_256F
-#  define slh_dsa_sha2_256f_d2i_private_key NULL
-#  define slh_dsa_sha2_256f_d2i_public_key  NULL
-#  define slh_dsa_sha2_256f_d2i_key_params  NULL
-#  define slh_dsa_sha2_256f_d2i_PKCS8       slh_dsa_d2i_PKCS8
-#  define slh_dsa_sha2_256f_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHA2_256F_PUBKEY
-#  define slh_dsa_sha2_256f_free            (free_key_fn *)ossl_slh_dsa_key_free
-#  define slh_dsa_sha2_256f_check           NULL
-#  define slh_dsa_sha2_256f_adjust          slh_dsa_key_adjust
-
-#  define slh_dsa_shake_128s_evp_type        EVP_PKEY_SLH_DSA_SHAKE_128S
-#  define slh_dsa_shake_128s_d2i_private_key NULL
-#  define slh_dsa_shake_128s_d2i_public_key  NULL
-#  define slh_dsa_shake_128s_d2i_key_params  NULL
-#  define slh_dsa_shake_128s_d2i_PKCS8       slh_dsa_d2i_PKCS8
-#  define slh_dsa_shake_128s_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHAKE_128S_PUBKEY
-#  define slh_dsa_shake_128s_free            (free_key_fn *)ossl_slh_dsa_key_free
-#  define slh_dsa_shake_128s_check           NULL
-#  define slh_dsa_shake_128s_adjust          slh_dsa_key_adjust
-
-#  define slh_dsa_shake_128f_evp_type        EVP_PKEY_SLH_DSA_SHAKE_128F
-#  define slh_dsa_shake_128f_d2i_private_key NULL
-#  define slh_dsa_shake_128f_d2i_public_key  NULL
-#  define slh_dsa_shake_128f_d2i_key_params  NULL
-#  define slh_dsa_shake_128f_d2i_PKCS8       slh_dsa_d2i_PKCS8
-#  define slh_dsa_shake_128f_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHAKE_128F_PUBKEY
-#  define slh_dsa_shake_128f_free            (free_key_fn *)ossl_slh_dsa_key_free
-#  define slh_dsa_shake_128f_check           NULL
-#  define slh_dsa_shake_128f_adjust          slh_dsa_key_adjust
-
-#  define slh_dsa_shake_192s_evp_type        EVP_PKEY_SLH_DSA_SHAKE_192S
-#  define slh_dsa_shake_192s_d2i_private_key NULL
-#  define slh_dsa_shake_192s_d2i_public_key  NULL
-#  define slh_dsa_shake_192s_d2i_key_params  NULL
-#  define slh_dsa_shake_192s_d2i_PKCS8       slh_dsa_d2i_PKCS8
-#  define slh_dsa_shake_192s_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHAKE_192S_PUBKEY
-#  define slh_dsa_shake_192s_free            (free_key_fn *)ossl_slh_dsa_key_free
-#  define slh_dsa_shake_192s_check           NULL
-#  define slh_dsa_shake_192s_adjust          slh_dsa_key_adjust
-
-#  define slh_dsa_shake_192f_evp_type        EVP_PKEY_SLH_DSA_SHAKE_192F
-#  define slh_dsa_shake_192f_d2i_private_key NULL
-#  define slh_dsa_shake_192f_d2i_public_key  NULL
-#  define slh_dsa_shake_192f_d2i_key_params  NULL
-#  define slh_dsa_shake_192f_d2i_PKCS8       slh_dsa_d2i_PKCS8
-#  define slh_dsa_shake_192f_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHAKE_192F_PUBKEY
-#  define slh_dsa_shake_192f_free            (free_key_fn *)ossl_slh_dsa_key_free
-#  define slh_dsa_shake_192f_check           NULL
-#  define slh_dsa_shake_192f_adjust          slh_dsa_key_adjust
-
-#  define slh_dsa_shake_256s_evp_type        EVP_PKEY_SLH_DSA_SHAKE_256S
-#  define slh_dsa_shake_256s_d2i_private_key NULL
-#  define slh_dsa_shake_256s_d2i_public_key  NULL
-#  define slh_dsa_shake_256s_d2i_key_params  NULL
-#  define slh_dsa_shake_256s_d2i_PKCS8       slh_dsa_d2i_PKCS8
-#  define slh_dsa_shake_256s_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHAKE_256S_PUBKEY
-#  define slh_dsa_shake_256s_free            (free_key_fn *)ossl_slh_dsa_key_free
-#  define slh_dsa_shake_256s_check           NULL
-#  define slh_dsa_shake_256s_adjust          slh_dsa_key_adjust
-
-#  define slh_dsa_shake_256f_evp_type        EVP_PKEY_SLH_DSA_SHAKE_256F
-#  define slh_dsa_shake_256f_d2i_private_key NULL
-#  define slh_dsa_shake_256f_d2i_public_key  NULL
-#  define slh_dsa_shake_256f_d2i_key_params  NULL
-#  define slh_dsa_shake_256f_d2i_PKCS8       slh_dsa_d2i_PKCS8
-#  define slh_dsa_shake_256f_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHAKE_256F_PUBKEY
-#  define slh_dsa_shake_256f_free            (free_key_fn *)ossl_slh_dsa_key_free
-#  define slh_dsa_shake_256f_check           NULL
-#  define slh_dsa_shake_256f_adjust          slh_dsa_key_adjust
-
-
-# endif /* OPENSSL_NO_SLH_DSA */
+# define slh_dsa_sha2_128s_evp_type        EVP_PKEY_SLH_DSA_SHA2_128S
+# define slh_dsa_sha2_128s_d2i_private_key NULL
+# define slh_dsa_sha2_128s_d2i_public_key  NULL
+# define slh_dsa_sha2_128s_d2i_key_params  NULL
+# define slh_dsa_sha2_128s_d2i_PKCS8       slh_dsa_d2i_PKCS8
+# define slh_dsa_sha2_128s_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHA2_128S_PUBKEY
+# define slh_dsa_sha2_128s_free            (free_key_fn *)ossl_slh_dsa_key_free
+# define slh_dsa_sha2_128s_check           NULL
+# define slh_dsa_sha2_128s_adjust          slh_dsa_key_adjust
+
+# define slh_dsa_sha2_128f_evp_type        EVP_PKEY_SLH_DSA_SHA2_128F
+# define slh_dsa_sha2_128f_d2i_private_key NULL
+# define slh_dsa_sha2_128f_d2i_public_key  NULL
+# define slh_dsa_sha2_128f_d2i_key_params  NULL
+# define slh_dsa_sha2_128f_d2i_PKCS8       slh_dsa_d2i_PKCS8
+# define slh_dsa_sha2_128f_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHA2_128F_PUBKEY
+# define slh_dsa_sha2_128f_free            (free_key_fn *)ossl_slh_dsa_key_free
+# define slh_dsa_sha2_128f_check           NULL
+# define slh_dsa_sha2_128f_adjust          slh_dsa_key_adjust
+
+# define slh_dsa_sha2_192s_evp_type        EVP_PKEY_SLH_DSA_SHA2_192S
+# define slh_dsa_sha2_192s_d2i_private_key NULL
+# define slh_dsa_sha2_192s_d2i_public_key  NULL
+# define slh_dsa_sha2_192s_d2i_key_params  NULL
+# define slh_dsa_sha2_192s_d2i_PKCS8       slh_dsa_d2i_PKCS8
+# define slh_dsa_sha2_192s_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHA2_192S_PUBKEY
+# define slh_dsa_sha2_192s_free            (free_key_fn *)ossl_slh_dsa_key_free
+# define slh_dsa_sha2_192s_check           NULL
+# define slh_dsa_sha2_192s_adjust          slh_dsa_key_adjust
+
+# define slh_dsa_sha2_192f_evp_type        EVP_PKEY_SLH_DSA_SHA2_192F
+# define slh_dsa_sha2_192f_d2i_private_key NULL
+# define slh_dsa_sha2_192f_d2i_public_key  NULL
+# define slh_dsa_sha2_192f_d2i_key_params  NULL
+# define slh_dsa_sha2_192f_d2i_PKCS8       slh_dsa_d2i_PKCS8
+# define slh_dsa_sha2_192f_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHA2_192F_PUBKEY
+# define slh_dsa_sha2_192f_free            (free_key_fn *)ossl_slh_dsa_key_free
+# define slh_dsa_sha2_192f_check           NULL
+# define slh_dsa_sha2_192f_adjust          slh_dsa_key_adjust
+
+# define slh_dsa_sha2_256s_evp_type        EVP_PKEY_SLH_DSA_SHA2_256S
+# define slh_dsa_sha2_256s_d2i_private_key NULL
+# define slh_dsa_sha2_256s_d2i_public_key  NULL
+# define slh_dsa_sha2_256s_d2i_key_params  NULL
+# define slh_dsa_sha2_256s_d2i_PKCS8       slh_dsa_d2i_PKCS8
+# define slh_dsa_sha2_256s_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHA2_256S_PUBKEY
+# define slh_dsa_sha2_256s_free            (free_key_fn *)ossl_slh_dsa_key_free
+# define slh_dsa_sha2_256s_check           NULL
+# define slh_dsa_sha2_256s_adjust          slh_dsa_key_adjust
+
+# define slh_dsa_sha2_256f_evp_type        EVP_PKEY_SLH_DSA_SHA2_256F
+# define slh_dsa_sha2_256f_d2i_private_key NULL
+# define slh_dsa_sha2_256f_d2i_public_key  NULL
+# define slh_dsa_sha2_256f_d2i_key_params  NULL
+# define slh_dsa_sha2_256f_d2i_PKCS8       slh_dsa_d2i_PKCS8
+# define slh_dsa_sha2_256f_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHA2_256F_PUBKEY
+# define slh_dsa_sha2_256f_free            (free_key_fn *)ossl_slh_dsa_key_free
+# define slh_dsa_sha2_256f_check           NULL
+# define slh_dsa_sha2_256f_adjust          slh_dsa_key_adjust
+
+# define slh_dsa_shake_128s_evp_type        EVP_PKEY_SLH_DSA_SHAKE_128S
+# define slh_dsa_shake_128s_d2i_private_key NULL
+# define slh_dsa_shake_128s_d2i_public_key  NULL
+# define slh_dsa_shake_128s_d2i_key_params  NULL
+# define slh_dsa_shake_128s_d2i_PKCS8       slh_dsa_d2i_PKCS8
+# define slh_dsa_shake_128s_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHAKE_128S_PUBKEY
+# define slh_dsa_shake_128s_free            (free_key_fn *)ossl_slh_dsa_key_free
+# define slh_dsa_shake_128s_check           NULL
+# define slh_dsa_shake_128s_adjust          slh_dsa_key_adjust
+
+# define slh_dsa_shake_128f_evp_type        EVP_PKEY_SLH_DSA_SHAKE_128F
+# define slh_dsa_shake_128f_d2i_private_key NULL
+# define slh_dsa_shake_128f_d2i_public_key  NULL
+# define slh_dsa_shake_128f_d2i_key_params  NULL
+# define slh_dsa_shake_128f_d2i_PKCS8       slh_dsa_d2i_PKCS8
+# define slh_dsa_shake_128f_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHAKE_128F_PUBKEY
+# define slh_dsa_shake_128f_free            (free_key_fn *)ossl_slh_dsa_key_free
+# define slh_dsa_shake_128f_check           NULL
+# define slh_dsa_shake_128f_adjust          slh_dsa_key_adjust
+
+# define slh_dsa_shake_192s_evp_type        EVP_PKEY_SLH_DSA_SHAKE_192S
+# define slh_dsa_shake_192s_d2i_private_key NULL
+# define slh_dsa_shake_192s_d2i_public_key  NULL
+# define slh_dsa_shake_192s_d2i_key_params  NULL
+# define slh_dsa_shake_192s_d2i_PKCS8       slh_dsa_d2i_PKCS8
+# define slh_dsa_shake_192s_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHAKE_192S_PUBKEY
+# define slh_dsa_shake_192s_free            (free_key_fn *)ossl_slh_dsa_key_free
+# define slh_dsa_shake_192s_check           NULL
+# define slh_dsa_shake_192s_adjust          slh_dsa_key_adjust
+
+# define slh_dsa_shake_192f_evp_type        EVP_PKEY_SLH_DSA_SHAKE_192F
+# define slh_dsa_shake_192f_d2i_private_key NULL
+# define slh_dsa_shake_192f_d2i_public_key  NULL
+# define slh_dsa_shake_192f_d2i_key_params  NULL
+# define slh_dsa_shake_192f_d2i_PKCS8       slh_dsa_d2i_PKCS8
+# define slh_dsa_shake_192f_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHAKE_192F_PUBKEY
+# define slh_dsa_shake_192f_free            (free_key_fn *)ossl_slh_dsa_key_free
+# define slh_dsa_shake_192f_check           NULL
+# define slh_dsa_shake_192f_adjust          slh_dsa_key_adjust
+
+# define slh_dsa_shake_256s_evp_type        EVP_PKEY_SLH_DSA_SHAKE_256S
+# define slh_dsa_shake_256s_d2i_private_key NULL
+# define slh_dsa_shake_256s_d2i_public_key  NULL
+# define slh_dsa_shake_256s_d2i_key_params  NULL
+# define slh_dsa_shake_256s_d2i_PKCS8       slh_dsa_d2i_PKCS8
+# define slh_dsa_shake_256s_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHAKE_256S_PUBKEY
+# define slh_dsa_shake_256s_free            (free_key_fn *)ossl_slh_dsa_key_free
+# define slh_dsa_shake_256s_check           NULL
+# define slh_dsa_shake_256s_adjust          slh_dsa_key_adjust
+
+# define slh_dsa_shake_256f_evp_type        EVP_PKEY_SLH_DSA_SHAKE_256F
+# define slh_dsa_shake_256f_d2i_private_key NULL
+# define slh_dsa_shake_256f_d2i_public_key  NULL
+# define slh_dsa_shake_256f_d2i_key_params  NULL
+# define slh_dsa_shake_256f_d2i_PKCS8       slh_dsa_d2i_PKCS8
+# define slh_dsa_shake_256f_d2i_PUBKEY      (d2i_of_void *)ossl_d2i_SLH_DSA_SHAKE_256F_PUBKEY
+# define slh_dsa_shake_256f_free            (free_key_fn *)ossl_slh_dsa_key_free
+# define slh_dsa_shake_256f_check           NULL
+# define slh_dsa_shake_256f_adjust          slh_dsa_key_adjust
+#endif /* OPENSSL_NO_SLH_DSA */
 
 /* ---------------------------------------------------------------------- */
 
index 4480746fd67122ae4b7e2cc9b49195533adf09e8..9c0f2176f4e140ad265584698042a91c86aad290 100644 (file)
@@ -1628,8 +1628,6 @@ MAKE_ENCODER(slh_dsa_shake_192s, slh_dsa, EVP_PKEY_SLH_DSA_SHAKE_192S, Encrypted
 MAKE_ENCODER(slh_dsa_shake_192f, slh_dsa, EVP_PKEY_SLH_DSA_SHAKE_192F, EncryptedPrivateKeyInfo, pem);
 MAKE_ENCODER(slh_dsa_shake_256s, slh_dsa, EVP_PKEY_SLH_DSA_SHAKE_256S, EncryptedPrivateKeyInfo, pem);
 MAKE_ENCODER(slh_dsa_shake_256f, slh_dsa, EVP_PKEY_SLH_DSA_SHAKE_256F, EncryptedPrivateKeyInfo, pem);
-
-
 MAKE_ENCODER(slh_dsa_sha2_128s, slh_dsa, EVP_PKEY_SLH_DSA_SHA2_128S, PrivateKeyInfo, der);
 MAKE_ENCODER(slh_dsa_sha2_128f, slh_dsa, EVP_PKEY_SLH_DSA_SHA2_128F, PrivateKeyInfo, der);
 MAKE_ENCODER(slh_dsa_sha2_192s, slh_dsa, EVP_PKEY_SLH_DSA_SHA2_192S, PrivateKeyInfo, der);
@@ -1654,7 +1652,6 @@ MAKE_ENCODER(slh_dsa_shake_192s, slh_dsa, EVP_PKEY_SLH_DSA_SHAKE_192S, PrivateKe
 MAKE_ENCODER(slh_dsa_shake_192f, slh_dsa, EVP_PKEY_SLH_DSA_SHAKE_192F, PrivateKeyInfo, pem);
 MAKE_ENCODER(slh_dsa_shake_256s, slh_dsa, EVP_PKEY_SLH_DSA_SHAKE_256S, PrivateKeyInfo, pem);
 MAKE_ENCODER(slh_dsa_shake_256f, slh_dsa, EVP_PKEY_SLH_DSA_SHAKE_256F, PrivateKeyInfo, pem);
-
 MAKE_ENCODER(slh_dsa_sha2_128s, slh_dsa, EVP_PKEY_SLH_DSA_SHA2_128S, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(slh_dsa_sha2_128f, slh_dsa, EVP_PKEY_SLH_DSA_SHA2_128F, SubjectPublicKeyInfo, der);
 MAKE_ENCODER(slh_dsa_sha2_192s, slh_dsa, EVP_PKEY_SLH_DSA_SHA2_192S, SubjectPublicKeyInfo, der);
index 56a5766432a5a7c121fbaf8ea5c9bb01880671db..a2fb47ef3c8b514135726a32bf61e4ddc5588fc3 100644 (file)
@@ -449,41 +449,8 @@ static int ml_kem_to_text(BIO *out, const void *vkey, int selection)
 #ifndef OPENSSL_NO_SLH_DSA
 static int slh_dsa_to_text(BIO *out, const void *key, int selection)
 {
-    const char *name;
-
-    if (out == NULL || key == NULL) {
-        ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
-        return 0;
-    }
-    if (ossl_slh_dsa_key_get_pub(key) == NULL) {
-        /* Regardless of the |selection|, there must be a public key */
-        ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
-        return 0;
-    }
-
-    name = ossl_slh_dsa_key_get_name(key);
-    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
-        if (ossl_slh_dsa_key_get_priv(key) == NULL) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
-            return 0;
-        }
-        if (BIO_printf(out, "%s Private-Key:\n", name) <= 0)
-            return 0;
-        if (!print_labeled_buf(out, "priv:", ossl_slh_dsa_key_get_priv(key),
-                               ossl_slh_dsa_key_get_priv_len(key)))
-            return 0;
-    } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
-        if (BIO_printf(out, "%s Public-Key:\n", name) <= 0)
-            return 0;
-    }
-
-    if (!print_labeled_buf(out, "pub:", ossl_slh_dsa_key_get_pub(key),
-                           ossl_slh_dsa_key_get_pub_len(key)))
-        return 0;
-
-    return 1;
+    return ossl_slh_dsa_key_to_text(out, (SLH_DSA_KEY *)key, selection);
 }
-
 #endif /* OPENSSL_NO_SLH_DSA */
 
 static int rsa_to_text(BIO *out, const void *key, int selection)
index 288f49390d39e662fae1aacaa13b8c1192700f0c..52b6858ebb1d7f5cda674385d241cd43c170630c 100644 (file)
@@ -27,6 +27,7 @@ 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_validate_fn slh_dsa_validate;
 static OSSL_FUNC_keymgmt_gen_init_fn slh_dsa_gen_init;
 static OSSL_FUNC_keymgmt_gen_cleanup_fn slh_dsa_gen_cleanup;
 static OSSL_FUNC_keymgmt_gen_set_params_fn slh_dsa_gen_set_params;
@@ -79,6 +80,18 @@ static int slh_dsa_match(const void *keydata1, const void *keydata2, int selecti
     return ossl_slh_dsa_key_equal(key1, key2, selection);
 }
 
+static int slh_dsa_validate(const void *key_data, int selection, int check_type)
+{
+    const SLH_DSA_KEY *key = key_data;
+
+    if (!slh_dsa_has(key, selection))
+        return 0;
+
+    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR)
+        return ossl_slh_dsa_key_pairwise_check(key);
+    return 1;
+}
+
 static int slh_dsa_import(void *keydata, int selection, const OSSL_PARAM params[])
 {
     SLH_DSA_KEY *key = keydata;
@@ -175,7 +188,7 @@ static int slh_dsa_get_params(void *keydata, OSSL_PARAM params[])
         if (pub == NULL
                 || !OSSL_PARAM_set_octet_string(p, pub,
                                                 ossl_slh_dsa_key_get_pub_len(key)))
-        return 0;
+            return 0;
     }
     return 1;
 }
@@ -279,7 +292,7 @@ static int slh_dsa_fips140_pairwise_test(SLH_DSA_CTX *ctx, const SLH_DSA_KEY *ke
     if (sig == NULL)
         goto err;
 
-    if (ossl_slh_dsa_sign(ctx, key, msg, msg_len, NULL, 0, NULL,  0,
+    if (ossl_slh_dsa_sign(ctx, key, msg, msg_len, NULL, 0, NULL, 0,
                           sig, &sig_len, sig_len) != 1)
         goto err;
 
@@ -400,6 +413,7 @@ static void slh_dsa_gen_cleanup(void *genctx)
         { 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_VALIDATE, (void (*)(void))slh_dsa_validate },      \
         { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))slh_dsa_gen_init },      \
         { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))slh_dsa_##fn##_gen },         \
         { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))slh_dsa_gen_cleanup },\
index 217fa0279537c9179224d09cedb06602cdf2b843..17752e7d17a38b94cfa4cd851fdb1f34fc77f0fe 100644 (file)
@@ -110,7 +110,8 @@ static EVP_PKEY *make_template(const char *type, OSSL_PARAM *genparams)
     !defined(OPENSSL_NO_DSA) || \
     !defined(OPENSSL_NO_EC) || \
     !defined(OPENSSL_NO_ML_DSA) || \
-    !defined(OPENSSL_NO_ML_KEM)
+    !defined(OPENSSL_NO_ML_KEM) || \
+    !defined(OPENSSL_NO_SLH_DSA)
 static EVP_PKEY *make_key(const char *type, EVP_PKEY *template,
                           OSSL_PARAM *genparams)
 {
@@ -1396,7 +1397,7 @@ int setup_tests(void)
 
     /* FIPS(3.0.0): provider imports explicit params but they won't work #17998 */
     is_fips_3_0_0 = is_fips && fips_provider_version_eq(testctx, 3, 0, 0);
-    /* FIPS(3.5.0) is the first to support ML-KEM and ML-DSA */
+    /* FIPS(3.5.0) is the first to support ML-DSA, ML-KEM and SLH-DSA */
     is_fips_lt_3_5 = is_fips && fips_provider_version_lt(testctx, 3, 5, 0);
 
 #ifdef STATIC_LEGACY
@@ -1480,18 +1481,20 @@ int setup_tests(void)
     }
 #endif
 #ifndef OPENSSL_NO_SLH_DSA
-    MAKE_KEYS(SLH_DSA_SHA2_128s, "SLH-DSA-SHA2-128s", NULL);
-    MAKE_KEYS(SLH_DSA_SHA2_128f, "SLH-DSA-SHA2-128f", NULL);
-    MAKE_KEYS(SLH_DSA_SHA2_192s, "SLH-DSA-SHA2-192s", NULL);
-    MAKE_KEYS(SLH_DSA_SHA2_192f, "SLH-DSA-SHA2-192f", NULL);
-    MAKE_KEYS(SLH_DSA_SHA2_256s, "SLH-DSA-SHA2-256s", NULL);
-    MAKE_KEYS(SLH_DSA_SHA2_256f, "SLH-DSA-SHA2-256f", NULL);
-    MAKE_KEYS(SLH_DSA_SHAKE_128s, "SLH-DSA-SHAKE-128s", NULL);
-    MAKE_KEYS(SLH_DSA_SHAKE_128f, "SLH-DSA-SHAKE-128f", NULL);
-    MAKE_KEYS(SLH_DSA_SHAKE_192s, "SLH-DSA-SHAKE-192s", NULL);
-    MAKE_KEYS(SLH_DSA_SHAKE_192f, "SLH-DSA-SHAKE-192f", NULL);
-    MAKE_KEYS(SLH_DSA_SHAKE_256s, "SLH-DSA-SHAKE-256s", NULL);
-    MAKE_KEYS(SLH_DSA_SHAKE_256f, "SLH-DSA-SHAKE-256f", NULL);
+    if (!is_fips_lt_3_5) {
+        MAKE_KEYS(SLH_DSA_SHA2_128s, "SLH-DSA-SHA2-128s", NULL);
+        MAKE_KEYS(SLH_DSA_SHA2_128f, "SLH-DSA-SHA2-128f", NULL);
+        MAKE_KEYS(SLH_DSA_SHA2_192s, "SLH-DSA-SHA2-192s", NULL);
+        MAKE_KEYS(SLH_DSA_SHA2_192f, "SLH-DSA-SHA2-192f", NULL);
+        MAKE_KEYS(SLH_DSA_SHA2_256s, "SLH-DSA-SHA2-256s", NULL);
+        MAKE_KEYS(SLH_DSA_SHA2_256f, "SLH-DSA-SHA2-256f", NULL);
+        MAKE_KEYS(SLH_DSA_SHAKE_128s, "SLH-DSA-SHAKE-128s", NULL);
+        MAKE_KEYS(SLH_DSA_SHAKE_128f, "SLH-DSA-SHAKE-128f", NULL);
+        MAKE_KEYS(SLH_DSA_SHAKE_192s, "SLH-DSA-SHAKE-192s", NULL);
+        MAKE_KEYS(SLH_DSA_SHAKE_192f, "SLH-DSA-SHAKE-192f", NULL);
+        MAKE_KEYS(SLH_DSA_SHAKE_256s, "SLH-DSA-SHAKE-256s", NULL);
+        MAKE_KEYS(SLH_DSA_SHAKE_256f, "SLH-DSA-SHAKE-256f", NULL);
+    }
 #endif /* OPENSSL_NO_SLH_DSA */
 
     TEST_info("Loading RSA key...");
@@ -1581,18 +1584,20 @@ int setup_tests(void)
 #endif /* OPENSSL_NO_ML_DSA */
 
 #ifndef OPENSSL_NO_SLH_DSA
-        ADD_TEST_SUITE(SLH_DSA_SHA2_128s);
-        ADD_TEST_SUITE(SLH_DSA_SHA2_128f);
-        ADD_TEST_SUITE(SLH_DSA_SHA2_192s);
-        ADD_TEST_SUITE(SLH_DSA_SHA2_192f);
-        ADD_TEST_SUITE(SLH_DSA_SHA2_256s);
-        ADD_TEST_SUITE(SLH_DSA_SHA2_256f);
-        ADD_TEST_SUITE(SLH_DSA_SHAKE_128s);
-        ADD_TEST_SUITE(SLH_DSA_SHAKE_128f);
-        ADD_TEST_SUITE(SLH_DSA_SHAKE_192s);
-        ADD_TEST_SUITE(SLH_DSA_SHAKE_192f);
-        ADD_TEST_SUITE(SLH_DSA_SHAKE_256s);
-        ADD_TEST_SUITE(SLH_DSA_SHAKE_256f);
+        if (!is_fips_lt_3_5) {
+            ADD_TEST_SUITE(SLH_DSA_SHA2_128s);
+            ADD_TEST_SUITE(SLH_DSA_SHA2_128f);
+            ADD_TEST_SUITE(SLH_DSA_SHA2_192s);
+            ADD_TEST_SUITE(SLH_DSA_SHA2_192f);
+            ADD_TEST_SUITE(SLH_DSA_SHA2_256s);
+            ADD_TEST_SUITE(SLH_DSA_SHA2_256f);
+            ADD_TEST_SUITE(SLH_DSA_SHAKE_128s);
+            ADD_TEST_SUITE(SLH_DSA_SHAKE_128f);
+            ADD_TEST_SUITE(SLH_DSA_SHAKE_192s);
+            ADD_TEST_SUITE(SLH_DSA_SHAKE_192f);
+            ADD_TEST_SUITE(SLH_DSA_SHAKE_256s);
+            ADD_TEST_SUITE(SLH_DSA_SHAKE_256f);
+        }
 #endif /* OPENSSL_NO_SLH_DSA */
     }
 
@@ -1659,18 +1664,20 @@ void cleanup_tests(void)
 #endif /* OPENSSL_NO_ML_DSA */
 
 #ifndef OPENSSL_NO_SLH_DSA
-    FREE_KEYS(SLH_DSA_SHA2_128s);
-    FREE_KEYS(SLH_DSA_SHA2_128f);
-    FREE_KEYS(SLH_DSA_SHA2_192s);
-    FREE_KEYS(SLH_DSA_SHA2_192f);
-    FREE_KEYS(SLH_DSA_SHA2_256s);
-    FREE_KEYS(SLH_DSA_SHA2_256f);
-    FREE_KEYS(SLH_DSA_SHAKE_128s);
-    FREE_KEYS(SLH_DSA_SHAKE_128f);
-    FREE_KEYS(SLH_DSA_SHAKE_192s);
-    FREE_KEYS(SLH_DSA_SHAKE_192f);
-    FREE_KEYS(SLH_DSA_SHAKE_256s);
-    FREE_KEYS(SLH_DSA_SHAKE_256f);
+    if (!is_fips_lt_3_5) {
+        FREE_KEYS(SLH_DSA_SHA2_128s);
+        FREE_KEYS(SLH_DSA_SHA2_128f);
+        FREE_KEYS(SLH_DSA_SHA2_192s);
+        FREE_KEYS(SLH_DSA_SHA2_192f);
+        FREE_KEYS(SLH_DSA_SHA2_256s);
+        FREE_KEYS(SLH_DSA_SHA2_256f);
+        FREE_KEYS(SLH_DSA_SHAKE_128s);
+        FREE_KEYS(SLH_DSA_SHAKE_128f);
+        FREE_KEYS(SLH_DSA_SHAKE_192s);
+        FREE_KEYS(SLH_DSA_SHAKE_192f);
+        FREE_KEYS(SLH_DSA_SHAKE_256s);
+        FREE_KEYS(SLH_DSA_SHAKE_256f);
+    }
 #endif /* OPENSSL_NO_SLH_DSA */
 
     OSSL_PROVIDER_unload(nullprov);
index 7dc8d549aeac6756853e8709f489b653b32adb5b..c378eb8d1e9a454b0b3b5dbcb149f8050e381901 100644 (file)
@@ -28,20 +28,22 @@ 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)
+static EVP_PKEY *slh_dsa_key_from_data(const char *alg,
+                                       const unsigned char *data, size_t datalen,
+                                       int public)
 {
     int ret;
     EVP_PKEY_CTX *ctx = NULL;
     EVP_PKEY *key = NULL;
     OSSL_PARAM params[2];
+    const char *keytype = public ? OSSL_PKEY_PARAM_PUB_KEY : OSSL_PKEY_PARAM_PRIV_KEY;
+    int selection = public ? EVP_PKEY_PUBLIC_KEY : EVP_PKEY_KEYPAIR;
 
-    params[0] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
-                                                  (unsigned char *)data, datalen);
+    params[0] = OSSL_PARAM_construct_octet_string(keytype, (uint8_t *)data, datalen);
     params[1] = OSSL_PARAM_construct_end();
     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);
+        && (EVP_PKEY_fromdata(ctx, &key, selection, params) == 1);
     if (ret == 0) {
         EVP_PKEY_free(key);
         key = NULL;
@@ -96,10 +98,10 @@ static int slh_dsa_bad_pub_len_test(void)
     OPENSSL_cleanse(pubdata, sizeof(pubdata));
     memcpy(pubdata, td->pub, td->pub_len);
 
-    if (!TEST_ptr_null(pkey = slh_dsa_pubkey_from_data(td->alg, pubdata,
-                                                       td->pub_len - 1))
-            || !TEST_ptr_null(pkey = slh_dsa_pubkey_from_data(td->alg, pubdata,
-                                                              td->pub_len + 1)))
+    if (!TEST_ptr_null(pkey = slh_dsa_key_from_data(td->alg, pubdata,
+                                                    td->pub_len - 1, 1))
+            || !TEST_ptr_null(pkey = slh_dsa_key_from_data(td->alg, pubdata,
+                                                           td->pub_len + 1, 1)))
         goto end;
 
     ret = 1;
@@ -121,9 +123,9 @@ static int slh_dsa_key_eq_test(void)
     EVP_PKEY *eckey = NULL;
 #endif
 
-    if (!TEST_ptr(key[0] = slh_dsa_pubkey_from_data(td1->alg, td1->pub, td1->pub_len))
-            || !TEST_ptr(key[1] = slh_dsa_pubkey_from_data(td1->alg, td1->pub, td1->pub_len))
-            || !TEST_ptr(key[2] = slh_dsa_pubkey_from_data(td2->alg, td2->pub, td2->pub_len)))
+    if (!TEST_ptr(key[0] = slh_dsa_key_from_data(td1->alg, td1->pub, td1->pub_len, 1))
+            || !TEST_ptr(key[1] = slh_dsa_key_from_data(td1->alg, td1->pub, td1->pub_len, 1))
+            || !TEST_ptr(key[2] = slh_dsa_key_from_data(td2->alg, td2->pub, td2->pub_len, 1)))
         goto end;
 
     if (!TEST_int_eq(EVP_PKEY_eq(key[0], key[1]), 1)
@@ -152,13 +154,44 @@ static int slh_dsa_key_validate_test(void)
     EVP_PKEY_CTX *vctx = NULL;
     EVP_PKEY *key = NULL;
 
-    if (!TEST_ptr(key = slh_dsa_pubkey_from_data(td->alg, td->pub, td->pub_len)))
+    if (!TEST_ptr(key = slh_dsa_key_from_data(td->alg, td->pub, td->pub_len, 1)))
         return 0;
     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);
+    if (!TEST_int_eq(EVP_PKEY_public_check(vctx), 1))
+        goto end;
+    if (!TEST_int_eq(EVP_PKEY_private_check(vctx), 0))
+        goto end;
+    if (!TEST_int_eq(EVP_PKEY_pairwise_check(vctx), 0))
+        goto end;
+    ret = 1;
+end:
     EVP_PKEY_CTX_free(vctx);
+    EVP_PKEY_free(key);
+    return ret;
+}
+
+static int slh_dsa_key_validate_failure_test(void)
+{
+    int ret = 0;
+    EVP_PKEY_CTX *vctx = NULL;
+    EVP_PKEY *key = NULL;
+
+    /*
+     * Loading 128s private key data into a 128f algorithm will have an incorrect
+     * public key.
+     */
+    if (!TEST_ptr(key = slh_dsa_key_from_data("SLH-DSA-SHA2-128f",
+                                              slh_dsa_sha2_128s_0_keygen_priv,
+                                              sizeof(slh_dsa_sha2_128s_0_keygen_priv), 0)))
+        return 0;
+    if (!TEST_ptr(vctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key, NULL)))
+        goto end;
+    if (!TEST_int_eq(EVP_PKEY_pairwise_check(vctx), 0))
+        goto end;
+    ret = 1;
 end:
+    EVP_PKEY_CTX_free(vctx);
     EVP_PKEY_free(key);
     return ret;
 }
@@ -182,7 +215,7 @@ static int do_slh_dsa_verify(const SLH_DSA_SIG_TEST_DATA *td,
     *p++ = OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_MESSAGE_ENCODING, &encode);
     *p = OSSL_PARAM_construct_end();
 
-    if (!TEST_ptr(key = slh_dsa_pubkey_from_data(td->alg, td->pub, td->pub_len)))
+    if (!TEST_ptr(key = slh_dsa_key_from_data(td->alg, td->pub, td->pub_len, 1)))
         return 0;
     if (!TEST_ptr(vctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key, NULL)))
         goto err;
@@ -365,6 +398,10 @@ static int slh_dsa_usage_test(void)
             || !TEST_ptr(sig = OPENSSL_malloc(sig_len))
             || !TEST_int_eq(EVP_PKEY_sign(sctx, sig, &sig_len, msg, msg_len), 1))
         goto err;
+    if (!TEST_true(EVP_PKEY_pairwise_check(sctx))
+            || !TEST_true(EVP_PKEY_public_check(sctx))
+            || !TEST_true(EVP_PKEY_private_check(sctx)))
+        goto err;
     /* Read the public key and add to a verify ctx */
     if (!TEST_ptr(PEM_read_bio_PUBKEY_ex(pub_bio, &pub, NULL, NULL, lib_ctx, NULL))
             || !TEST_ptr(vctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, pub, NULL)))
@@ -373,6 +410,7 @@ static int slh_dsa_usage_test(void)
     if (!TEST_int_eq(EVP_PKEY_verify_message_init(vctx, sig_alg, NULL), 1)
             || !TEST_int_eq(EVP_PKEY_verify(vctx, sig, sig_len, msg, msg_len), 1))
         goto err;
+
     ret = 1;
 err:
     EVP_CIPHER_free(cipher);
@@ -495,6 +533,7 @@ int setup_tests(void)
 
     ADD_TEST(slh_dsa_bad_pub_len_test);
     ADD_TEST(slh_dsa_key_validate_test);
+    ADD_TEST(slh_dsa_key_validate_failure_test);
     ADD_TEST(slh_dsa_key_eq_test);
     ADD_TEST(slh_dsa_usage_test);
     ADD_TEST(slh_dsa_deterministic_usage_test);