]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Added return code checks to SLH_DSA Hash functions and propogated the
authorslontis <shane.lontis@oracle.com>
Thu, 7 Nov 2024 08:01:16 +0000 (19:01 +1100)
committerTomas Mraz <tomas@openssl.org>
Tue, 18 Feb 2025 09:13:53 +0000 (10:13 +0100)
values thru the calling functions.

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)

12 files changed:
crypto/slh_dsa/slh_dsa.c
crypto/slh_dsa/slh_dsa_key.c
crypto/slh_dsa/slh_dsa_local.h
crypto/slh_dsa/slh_fors.c
crypto/slh_dsa/slh_hash.c
crypto/slh_dsa/slh_hash.h
crypto/slh_dsa/slh_hypertree.c
crypto/slh_dsa/slh_wots.c
crypto/slh_dsa/slh_xmss.c
include/crypto/slh_dsa.h
test/recipes/30-test_slh_dsa.t
test/slh_dsa_test.c

index 8a51354ae1fdef4de5c8597f72fb9144fdfe965b..8f6736b91b871e81868667c6142cdcf0f3d71ac0 100644 (file)
@@ -82,11 +82,11 @@ static int slh_sign_internal(SLH_DSA_CTX *ctx, const SLH_DSA_KEY *priv,
 
     adrsf->zero(adrs);
     /* calculate Randomness value r, and output to the signature */
-    hashf->PRF_MSG(hctx, SLH_DSA_SK_PRF(priv), opt_rand, msg, msg_len, r);
-
-    /* generate a digest of size |params->m| bytes where m is (30..49) */
-    hashf->H_MSG(hctx, r, pk_seed, SLH_DSA_PK_ROOT(priv), msg, msg_len,
-                 m_digest);
+    if (!hashf->PRF_MSG(hctx, SLH_DSA_SK_PRF(priv), opt_rand, msg, msg_len, r)
+            /* generate a digest of size |params->m| bytes where m is (30..49) */
+            || !hashf->H_MSG(hctx, r, pk_seed, SLH_DSA_PK_ROOT(priv), msg, msg_len,
+                             m_digest))
+        return 0;
     /* Grab selected bytes from the digest to select tree and leaf id's */
     get_tree_ids(m_digest, params, &tree_id, &leaf_id);
 
@@ -96,13 +96,11 @@ static int slh_sign_internal(SLH_DSA_CTX *ctx, const SLH_DSA_KEY *priv,
 
     /* generate the FORS signature and append it to the signature */
     md = m_digest;
-    ossl_slh_fors_sign(ctx, md, sk_seed, pk_seed, adrs, sig_fors, sig_fors_len);
-    /* Calculate the FORS public key */
-    ossl_slh_fors_pk_from_sig(ctx, sig_fors, md, pk_seed, adrs, pk_fors);
-
-    ossl_slh_ht_sign(ctx, pk_fors, sk_seed, pk_seed, tree_id, leaf_id,
-                     sig_ht, sig_ht_len);
-    return 1;
+    return ossl_slh_fors_sign(ctx, md, sk_seed, pk_seed, adrs, sig_fors, sig_fors_len)
+        /* Calculate the FORS public key */
+        && ossl_slh_fors_pk_from_sig(ctx, sig_fors, md, pk_seed, adrs, pk_fors)
+        && ossl_slh_ht_sign(ctx, pk_fors, sk_seed, pk_seed, tree_id, leaf_id,
+                            sig_ht, sig_ht_len);
 }
 
 /**
@@ -155,15 +153,17 @@ static int slh_verify_internal(SLH_DSA_CTX *ctx, const SLH_DSA_KEY *pub,
     pk_seed = SLH_DSA_PK_SEED(pub);
     pk_root = SLH_DSA_PK_ROOT(pub);
 
-    hashf->H_MSG(hctx, r, pk_seed, pk_root, msg, msg_len, mdigest);
+    if (!hashf->H_MSG(hctx, r, pk_seed, pk_root, msg, msg_len, mdigest))
+        return 0;
     md = mdigest;
     get_tree_ids(mdigest, params, &tree_id, &leaf_id);
 
     adrsf->set_tree_address(adrs, tree_id);
     adrsf->set_type_and_clear(adrs, SLH_ADRS_TYPE_FORS_TREE);
     adrsf->set_keypair_address(adrs, leaf_id);
-    ossl_slh_fors_pk_from_sig(ctx, sig_fors, md, pk_seed, adrs, pk_fors);
-    return ossl_slh_ht_verify(ctx, pk_fors, sig_ht, pk_seed, tree_id, leaf_id, pk_root);
+    return ossl_slh_fors_pk_from_sig(ctx, sig_fors, md, pk_seed, adrs, pk_fors)
+        && ossl_slh_ht_verify(ctx, pk_fors, sig_ht, pk_seed,
+                              tree_id, leaf_id, pk_root);
 }
 
 /**
@@ -221,6 +221,7 @@ static uint8_t *msg_encode(const uint8_t *msg, size_t msg_len,
 
 /**
  * See FIPS 205 Section 10.2.1 Algorithm 22
+ * @returns 1 on success, or 0 on error.
  */
 int ossl_slh_dsa_sign(SLH_DSA_CTX *slh_ctx, const SLH_DSA_KEY *priv,
                       const uint8_t *msg, size_t msg_len,
@@ -246,6 +247,7 @@ int ossl_slh_dsa_sign(SLH_DSA_CTX *slh_ctx, const SLH_DSA_KEY *priv,
 
 /**
  * See FIPS 205 Section 10.3 Algorithm 24
+ * @returns 1 on success, or 0 on error.
  */
 int ossl_slh_dsa_verify(SLH_DSA_CTX *slh_ctx, const SLH_DSA_KEY *pub,
                         const uint8_t *msg, size_t msg_len,
index f7dbb0f785d2a4c30b0737021d2d98d22f8ac470..922d1650846d2f765bb9e7d0a3911d1950e00b3a 100644 (file)
@@ -219,7 +219,7 @@ 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.
+ * @returns 1 if the root key is generated, or 0 on error.
  */
 static int slh_dsa_compute_pk_root(SLH_DSA_CTX *ctx, SLH_DSA_KEY *out)
 {
@@ -232,9 +232,8 @@ static int slh_dsa_compute_pk_root(SLH_DSA_CTX *ctx, SLH_DSA_KEY *out)
     adrsf->zero(adrs);
     adrsf->set_layer_address(adrs, params->d - 1);
     /* Generate the ROOT public key */
-    ossl_slh_xmss_node(ctx, SLH_DSA_SK_SEED(out), 0, params->hm,
-                       SLH_DSA_PK_SEED(out), adrs, SLH_DSA_PK_ROOT(out));
-    return 1;
+    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));
 }
 
 /**
index 77bf6a410a2a0486aa9ba715c31153f3d99d6a33..59c5fb605d58d92294c7103c2778020598d8f6be 100644 (file)
@@ -46,40 +46,42 @@ struct slh_dsa_ctx_st {
     SLH_HASH_CTX hash_ctx;
 };
 
-void ossl_slh_wots_pk_gen(SLH_DSA_CTX *ctx,
-                          const uint8_t *sk_seed, const uint8_t *pk_seed,
-                          SLH_ADRS adrs, uint8_t *pk_out);
-void ossl_slh_wots_sign(SLH_DSA_CTX *ctx, const uint8_t *msg,
-                        const uint8_t *sk_seed, const uint8_t *pk_seed,
-                        SLH_ADRS adrs, uint8_t *sig, size_t sig_len);
-void ossl_slh_wots_pk_from_sig(SLH_DSA_CTX *ctx,
-                               const uint8_t *sig, const uint8_t *msg,
-                               const uint8_t *pk_seed, uint8_t *adrs,
-                               uint8_t *pk_out);
+__owur int ossl_slh_wots_pk_gen(SLH_DSA_CTX *ctx,
+                                const uint8_t *sk_seed, const uint8_t *pk_seed,
+                                SLH_ADRS adrs, uint8_t *pk_out);
+__owur int ossl_slh_wots_sign(SLH_DSA_CTX *ctx, const uint8_t *msg,
+                             const uint8_t *sk_seed, const uint8_t *pk_seed,
+                             SLH_ADRS adrs, uint8_t *sig, size_t sig_len);
+__owur int ossl_slh_wots_pk_from_sig(SLH_DSA_CTX *ctx,
+                                     const uint8_t *sig, const uint8_t *msg,
+                                     const uint8_t *pk_seed, uint8_t *adrs,
+                                     uint8_t *pk_out);
 
-void ossl_slh_xmss_node(SLH_DSA_CTX *ctx, const uint8_t *sk_seed,
-                        uint32_t node_id, uint32_t height,
-                        const uint8_t *pk_seed, SLH_ADRS adrs, uint8_t *pk_out);
-void ossl_slh_xmss_sign(SLH_DSA_CTX *ctx, const uint8_t *msg,
-                        const uint8_t *sk_seed, uint32_t node_id,
-                        const uint8_t *pk_seed, SLH_ADRS adrs,
-                        uint8_t *sig, size_t sig_len);
-void ossl_slh_xmss_pk_from_sig(SLH_DSA_CTX *ctx, uint32_t node_id,
-                               const uint8_t *sig, const uint8_t *msg,
-                               const uint8_t *pk_seed, SLH_ADRS adrs,
-                               uint8_t *pk_out);
+__owur int ossl_slh_xmss_node(SLH_DSA_CTX *ctx, const uint8_t *sk_seed,
+                              uint32_t node_id, uint32_t height,
+                              const uint8_t *pk_seed, SLH_ADRS adrs,
+                              uint8_t *pk_out);
+__owur int ossl_slh_xmss_sign(SLH_DSA_CTX *ctx, const uint8_t *msg,
+                              const uint8_t *sk_seed, uint32_t node_id,
+                              const uint8_t *pk_seed, SLH_ADRS adrs,
+                              uint8_t *sig, size_t sig_len);
+__owur int ossl_slh_xmss_pk_from_sig(SLH_DSA_CTX *ctx, uint32_t node_id,
+                                     const uint8_t *sig, const uint8_t *msg,
+                                     const uint8_t *pk_seed, SLH_ADRS adrs,
+                                     uint8_t *pk_out);
 
-void ossl_slh_ht_sign(SLH_DSA_CTX *ctx, const uint8_t *msg,
-                      const uint8_t *sk_seed, const uint8_t *pk_seed,
-                      uint64_t tree_id, uint32_t leaf_id,
-                      uint8_t *sig_out, size_t sig_out_len);
-int ossl_slh_ht_verify(SLH_DSA_CTX *ctx, const uint8_t *msg, const uint8_t *sig,
-                       const uint8_t *pk_seed, uint64_t tree_id, uint32_t leaf_id,
-                       const uint8_t *pk_root);
+__owur int ossl_slh_ht_sign(SLH_DSA_CTX *ctx, const uint8_t *msg,
+                            const uint8_t *sk_seed, const uint8_t *pk_seed,
+                            uint64_t tree_id, uint32_t leaf_id,
+                            uint8_t *sig_out, size_t sig_out_len);
+__owur int ossl_slh_ht_verify(SLH_DSA_CTX *ctx, const uint8_t *msg,
+                              const uint8_t *sig, const uint8_t *pk_seed,
+                              uint64_t tree_id, uint32_t leaf_id,
+                              const uint8_t *pk_root);
 
-void ossl_slh_fors_sign(SLH_DSA_CTX *ctx, const uint8_t *md,
-                        const uint8_t *sk_seed, const uint8_t *pk_seed,
-                        SLH_ADRS adrs, uint8_t *sig, size_t sig_len);
-void ossl_slh_fors_pk_from_sig(SLH_DSA_CTX *ctx, const uint8_t *sig,
-                               const uint8_t *md, const uint8_t *pk_seed,
-                               SLH_ADRS adrs, uint8_t *pk_out);
+__owur int ossl_slh_fors_sign(SLH_DSA_CTX *ctx, const uint8_t *md,
+                              const uint8_t *sk_seed, const uint8_t *pk_seed,
+                              SLH_ADRS adrs, uint8_t *sig, size_t sig_len);
+__owur int ossl_slh_fors_pk_from_sig(SLH_DSA_CTX *ctx, const uint8_t *sig,
+                                     const uint8_t *md, const uint8_t *pk_seed,
+                                     SLH_ADRS adrs, uint8_t *pk_out);
index baa7f9053569b738963edbbb328eeea866546d37..7eb12b071723e71400576abb9b812e2c7e05a94b 100644 (file)
@@ -34,10 +34,11 @@ static void slh_base_2b(const uint8_t *in, uint32_t b, uint32_t *out, size_t out
  * @param id The index of the FORS secret value within the sets of FORS trees.
  *               (which must be < 2^(hm - height)
  * @param pk_out The generated FORS secret value of size |n|
+ * @returns 1 on success, or 0 on error.
  */
-static void slh_fors_sk_gen(SLH_DSA_CTX *ctx, const uint8_t *sk_seed,
-                            const uint8_t *pk_seed, SLH_ADRS adrs, uint32_t id,
-                            uint8_t *sk_out)
+static int slh_fors_sk_gen(SLH_DSA_CTX *ctx, const uint8_t *sk_seed,
+                           const uint8_t *pk_seed, SLH_ADRS adrs, uint32_t id,
+                           uint8_t *sk_out)
 {
     SLH_ADRS_DECLARE(sk_adrs);
     SLH_ADRS_FUNC_DECLARE(ctx, adrsf);
@@ -46,7 +47,7 @@ static void slh_fors_sk_gen(SLH_DSA_CTX *ctx, const uint8_t *sk_seed,
     adrsf->set_type_and_clear(sk_adrs, SLH_ADRS_TYPE_FORS_PRF);
     adrsf->copy_keypair_address(sk_adrs, adrs);
     adrsf->set_tree_index(sk_adrs, id);
-    ctx->hash_func->PRF(&ctx->hash_ctx, pk_seed, sk_seed, sk_adrs, sk_out);
+    return ctx->hash_func->PRF(&ctx->hash_ctx, pk_seed, sk_seed, sk_adrs, sk_out);
 }
 
 /**
@@ -67,29 +68,35 @@ static void slh_fors_sk_gen(SLH_DSA_CTX *ctx, const uint8_t *sk_seed,
  * @param node_id The target node index
  * @param height The target node height
  * @param node The returned hash for a node of size|n|
+ * @returns 1 on success, or 0 on error.
  */
-static void slh_fors_node(SLH_DSA_CTX *ctx, const uint8_t *sk_seed,
-                          const uint8_t *pk_seed, SLH_ADRS adrs, uint32_t node_id,
-                          uint32_t height, uint8_t *node)
+static int slh_fors_node(SLH_DSA_CTX *ctx, const uint8_t *sk_seed,
+                         const uint8_t *pk_seed, SLH_ADRS adrs, uint32_t node_id,
+                         uint32_t height, uint8_t *node)
 {
     SLH_ADRS_FUNC_DECLARE(ctx, adrsf);
     uint8_t sk[SLH_MAX_N], lnode[SLH_MAX_N], rnode[SLH_MAX_N];
     uint32_t n = ctx->params->n;
 
     if (height == 0) {
-        slh_fors_sk_gen(ctx, sk_seed, pk_seed, adrs, node_id, sk);
+        if (!slh_fors_sk_gen(ctx, sk_seed, pk_seed, adrs, node_id, sk))
+            return 0;
         adrsf->set_tree_height(adrs, 0);
         adrsf->set_tree_index(adrs, node_id);
-        ctx->hash_func->F(&ctx->hash_ctx, pk_seed, adrs, sk, n, node);
+        if (!ctx->hash_func->F(&ctx->hash_ctx, pk_seed, adrs, sk, n, node))
+            return 0;
     } else {
-        slh_fors_node(ctx, sk_seed, pk_seed, adrs, 2 * node_id, height - 1,
-                      lnode);
-        slh_fors_node(ctx, sk_seed, pk_seed, adrs, 2 * node_id + 1, height - 1,
-                      rnode);
+        if (!slh_fors_node(ctx, sk_seed, pk_seed, adrs, 2 * node_id, height - 1,
+                           lnode)
+                || !slh_fors_node(ctx, sk_seed, pk_seed, adrs, 2 * node_id + 1,
+                                  height - 1, rnode))
+            return 0;
         adrsf->set_tree_height(adrs, height);
         adrsf->set_tree_index(adrs, node_id);
-        ctx->hash_func->H(&ctx->hash_ctx, pk_seed, adrs, lnode, rnode, node);
+        if (!ctx->hash_func->H(&ctx->hash_ctx, pk_seed, adrs, lnode, rnode, node))
+            return 0;
     }
+    return 1;
 }
 
 /**
@@ -107,10 +114,11 @@ static void slh_fors_node(SLH_DSA_CTX *ctx, const uint8_t *sk_seed,
  * @param sig_out The generated XMSS signature which consists of a WOTS+
  *                signature and authentication path
  * @param sig_len  The size of |sig| which is (2 * n + 3) * n + tree_height * n.
+ * @returns 1 on success, or 0 on error.
  */
-void ossl_slh_fors_sign(SLH_DSA_CTX *ctx, const uint8_t *md,
-                        const uint8_t *sk_seed, const uint8_t *pk_seed,
-                        SLH_ADRS adrs, uint8_t *sig, size_t sig_len)
+int ossl_slh_fors_sign(SLH_DSA_CTX *ctx, const uint8_t *md,
+                       const uint8_t *sk_seed, const uint8_t *pk_seed,
+                       SLH_ADRS adrs, uint8_t *sig, size_t sig_len)
 {
     uint32_t i, j, s;
     uint32_t ids[SLH_MAX_K];
@@ -131,20 +139,23 @@ void ossl_slh_fors_sign(SLH_DSA_CTX *ctx, const uint8_t *md,
     for (i = 0; i < k; ++i) {
         uint32_t id = ids[i]; /* |id| = |a| bits */
 
-        slh_fors_sk_gen(ctx, sk_seed, pk_seed, adrs,
-                        id + t_times_i, psig);
+        if (!slh_fors_sk_gen(ctx, sk_seed, pk_seed, adrs,
+                             id + t_times_i, psig))
+            return 0;
         psig += n;
 
         for (j = 0; j < a; ++j) {
             s = id ^ 1;
-            slh_fors_node(ctx, sk_seed, pk_seed, adrs, s + i * (1 << (a - j)),
-                          j, psig);
+            if (!slh_fors_node(ctx, sk_seed, pk_seed, adrs, s + i * (1 << (a - j)),
+                               j, psig))
+                return 0;
             id >>= 1;
             psig += n;
         }
         t_times_i += t;
     }
     assert((size_t)(psig - sig) == sig_len);
+    return 1;
 }
 
 /**
@@ -160,10 +171,11 @@ void ossl_slh_fors_sign(SLH_DSA_CTX *ctx, const uint8_t *md,
  *             the type set to FORS_TREE, and the keypair address set to the
  *             index of the WOTS+ key that signs the FORS key.
  * @param pk_out The returned candidate FORS public key of size |n|
+ * @returns 1 on success, or 0 on error.
  */
-void ossl_slh_fors_pk_from_sig(SLH_DSA_CTX *ctx, const uint8_t *sig,
-                               const uint8_t *md, const uint8_t *pk_seed,
-                               SLH_ADRS adrs, uint8_t *pk_out)
+int ossl_slh_fors_pk_from_sig(SLH_DSA_CTX *ctx, const uint8_t *sig,
+                              const uint8_t *md, const uint8_t *pk_seed,
+                              SLH_ADRS adrs, uint8_t *pk_out)
 {
     SLH_ADRS_DECLARE(pk_adrs);
     SLH_ADRS_FUNC_DECLARE(ctx, adrsf);
@@ -191,7 +203,8 @@ void ossl_slh_fors_pk_from_sig(SLH_DSA_CTX *ctx, const uint8_t *sig,
 
         set_tree_height(adrs, 0);
         set_tree_index(adrs, node_id);
-        F(hctx, pk_seed, adrs, sig, n, node);
+        if (!F(hctx, pk_seed, adrs, sig, n, node))
+            return 0;
         sig += n;
 
         for (j = 0; j < a; ++j) {
@@ -199,11 +212,13 @@ void ossl_slh_fors_pk_from_sig(SLH_DSA_CTX *ctx, const uint8_t *sig,
             if ((id & 1) == 0) {
                 node_id >>= 1;
                 set_tree_index(adrs, node_id);
-                H(hctx, pk_seed, adrs, node, sig, node);
+                if (!H(hctx, pk_seed, adrs, node, sig, node))
+                    return 0;
             } else {
                 node_id = (node_id - 1) >> 1;
                 set_tree_index(adrs, node_id);
-                H(hctx, pk_seed, adrs, sig, node, node);
+                if (!H(hctx, pk_seed, adrs, sig, node, node))
+                    return 0;
             }
             id >>= 1;
             sig += n;
@@ -217,7 +232,7 @@ void ossl_slh_fors_pk_from_sig(SLH_DSA_CTX *ctx, const uint8_t *sig,
     adrsf->copy(pk_adrs, adrs);
     adrsf->set_type_and_clear(pk_adrs, SLH_ADRS_TYPE_FORS_ROOTS);
     adrsf->copy_keypair_address(pk_adrs, adrs);
-    hashf->T(hctx, pk_seed, pk_adrs, roots, node - roots, pk_out);
+    return hashf->T(hctx, pk_seed, pk_adrs, roots, node - roots, pk_out);
 }
 
 /**
index d0f2d29da4b0f5df16ff82f7acdc9c0de93ef896..9eafb42002dcafdf8888297b806646cc1b582c38 100644 (file)
@@ -157,7 +157,7 @@ static ossl_inline int xof_digest_4(EVP_MD_CTX *ctx,
 }
 
 /* See FIPS 205 Section 11.1 */
-static void
+static int
 slh_hmsg_shake(SLH_HASH_CTX *hctx, const uint8_t *r, const uint8_t *pk_seed,
                const uint8_t *pk_root, const uint8_t *msg, size_t msg_len,
                uint8_t *out)
@@ -165,53 +165,59 @@ slh_hmsg_shake(SLH_HASH_CTX *hctx, const uint8_t *r, const uint8_t *pk_seed,
     size_t m = hctx->m;
     size_t n = hctx->n;
 
-    xof_digest_4(hctx->md_ctx, r, n, pk_seed, n, pk_root, n, msg, msg_len, out, m);
+    return xof_digest_4(hctx->md_ctx, r, n, pk_seed, n, pk_root, n,
+                        msg, msg_len, out, m);
 }
 
-static void
+static int
 slh_prf_shake(SLH_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *sk_seed,
               const SLH_ADRS adrs, uint8_t *out)
 {
     size_t n = hctx->n;
 
-    xof_digest_3(hctx->md_ctx, pk_seed, n, adrs, SLH_ADRS_SIZE, sk_seed, n, out, n);
+    return xof_digest_3(hctx->md_ctx, pk_seed, n, adrs, SLH_ADRS_SIZE,
+                        sk_seed, n, out, n);
 }
 
-static void
+static int
 slh_prf_msg_shake(SLH_HASH_CTX *hctx, const uint8_t *sk_prf,
                   const uint8_t *opt_rand, const uint8_t *msg, size_t msg_len,
                   uint8_t *out)
 {
     size_t n = hctx->n;
 
-    xof_digest_3(hctx->md_ctx, sk_prf, n, opt_rand, n, msg, msg_len, out, n);
+    return xof_digest_3(hctx->md_ctx, sk_prf, n, opt_rand, n,
+                        msg, msg_len, out, n);
 }
 
-static void
+static int
 slh_f_shake(SLH_HASH_CTX *hctx, const uint8_t *pk_seed, const SLH_ADRS adrs,
             const uint8_t *m1, size_t m1_len, uint8_t *out)
 {
     size_t n = hctx->n;
 
-    xof_digest_3(hctx->md_ctx, pk_seed, n, adrs, SLH_ADRS_SIZE, m1, m1_len, out, n);
+    return xof_digest_3(hctx->md_ctx, pk_seed, n, adrs, SLH_ADRS_SIZE,
+                        m1, m1_len, out, n);
 }
 
-static void
+static int
 slh_h_shake(SLH_HASH_CTX *hctx, const uint8_t *pk_seed, const SLH_ADRS adrs,
             const uint8_t *m1, const uint8_t *m2, uint8_t *out)
 {
     size_t n = hctx->n;
 
-    xof_digest_4(hctx->md_ctx, pk_seed, n, adrs, SLH_ADRS_SIZE, m1, n, m2, n, out, n);
+    return xof_digest_4(hctx->md_ctx, pk_seed, n, adrs, SLH_ADRS_SIZE,
+                        m1, n, m2, n, out, n);
 }
 
-static void
+static int
 slh_t_shake(SLH_HASH_CTX *hctx, const uint8_t *pk_seed, const SLH_ADRS adrs,
             const uint8_t *ml, size_t ml_len, uint8_t *out)
 {
     size_t n = hctx->n;
 
-    xof_digest_3(hctx->md_ctx, pk_seed, n, adrs, SLH_ADRS_SIZE, ml, ml_len, out, n);
+    return xof_digest_3(hctx->md_ctx, pk_seed, n, adrs, SLH_ADRS_SIZE,
+                        ml, ml_len, out, n);
 }
 
 static ossl_inline int
@@ -230,7 +236,7 @@ digest_4(EVP_MD_CTX *ctx,
 
 /* FIPS 205 Section 11.2.1 and 11.2.2 */
 
-static void
+static int
 slh_hmsg_sha2(SLH_HASH_CTX *hctx, const uint8_t *r, const uint8_t *pk_seed,
               const uint8_t *pk_root, const uint8_t *msg, size_t msg_len,
               uint8_t *out)
@@ -245,19 +251,20 @@ slh_hmsg_sha2(SLH_HASH_CTX *hctx, const uint8_t *r, const uint8_t *pk_seed,
 
     memcpy(seed, r, n);
     memcpy(seed + n, pk_seed, n);
-    digest_4(hctx->md_big_ctx, r, n, pk_seed, n, pk_root, n, msg, msg_len,
-             seed + 2 * n);
-    PKCS1_MGF1(out, hctx->m, seed, seed_len, hctx->md);
+    return digest_4(hctx->md_big_ctx, r, n, pk_seed, n, pk_root, n, msg, msg_len,
+                    seed + 2 * n)
+        && (PKCS1_MGF1(out, hctx->m, seed, seed_len, hctx->md) == 0);
 }
 
-static void
+static int
 slh_prf_msg_sha2(SLH_HASH_CTX *hctx,
                  const uint8_t *sk_prf, const uint8_t *opt_rand,
                  const uint8_t *msg, size_t msg_len, uint8_t *out)
 {
+    int ret;
     EVP_MAC_CTX *mctx = hctx->hmac_ctx;
     size_t n = hctx->n;
-    uint8_t mac[MAX_DIGEST_SIZE];
+    uint8_t mac[MAX_DIGEST_SIZE] = {0};
     OSSL_PARAM *p = NULL;
     OSSL_PARAM params[3];
 
@@ -278,47 +285,50 @@ slh_prf_msg_sha2(SLH_HASH_CTX *hctx,
         hctx->hmac_digest = NULL;
     }
 
-    EVP_MAC_init(mctx, sk_prf, n, p);
-    EVP_MAC_update(mctx, opt_rand, n);
-    EVP_MAC_update(mctx, msg, msg_len);
-    EVP_MAC_final(mctx, mac, NULL, sizeof(mac));
+    ret = EVP_MAC_init(mctx, sk_prf, n, p) == 1
+        && EVP_MAC_update(mctx, opt_rand, n) == 1
+        && EVP_MAC_update(mctx, msg, msg_len) == 1
+        && EVP_MAC_final(mctx, mac, NULL, sizeof(mac)) == 1;
     memcpy(out, mac, n); /* Truncate output to n bytes */
+    return ret;
 }
 
-static ossl_inline void
+static ossl_inline int
 do_hash(EVP_MD_CTX *ctx, size_t n, const uint8_t *pk_seed, const SLH_ADRS adrs,
         const uint8_t *m, size_t m_len, size_t b, uint8_t *out)
 {
+    int ret;
     uint8_t zeros[128] = { 0 };
     uint8_t digest[MAX_DIGEST_SIZE];
 
     assert(b - n < sizeof(zeros));
 
-    digest_4(ctx, pk_seed, n, zeros, b - n, adrs, SLH_ADRSC_SIZE, m, m_len,
-             digest);
+    ret = digest_4(ctx, pk_seed, n, zeros, b - n, adrs, SLH_ADRSC_SIZE,
+                   m, m_len, digest);
     /* Truncated returned value is n = 16 bytes */
     memcpy(out, digest, n);
+    return ret;
 }
 
-static void
+static int
 slh_prf_sha2(SLH_HASH_CTX *hctx, const uint8_t *pk_seed,
              const uint8_t *sk_seed, const SLH_ADRS adrs, uint8_t *out)
 {
     size_t n = hctx->n;
 
-    do_hash(hctx->md_ctx, n, pk_seed, adrs, sk_seed, n,
-            SHA2_NUM_ZEROS_BOUND1, out);
+    return do_hash(hctx->md_ctx, n, pk_seed, adrs, sk_seed, n,
+                   SHA2_NUM_ZEROS_BOUND1, out);
 }
 
-static void
+static int
 slh_f_sha2(SLH_HASH_CTX *hctx, const uint8_t *pk_seed, const SLH_ADRS adrs,
            const uint8_t *m1, size_t m1_len, uint8_t *out)
 {
-    do_hash(hctx->md_ctx, hctx->n, pk_seed, adrs, m1, m1_len,
-            SHA2_NUM_ZEROS_BOUND1, out);
+    return do_hash(hctx->md_ctx, hctx->n, pk_seed, adrs, m1, m1_len,
+                   SHA2_NUM_ZEROS_BOUND1, out);
 }
 
-static void
+static int
 slh_h_sha2(SLH_HASH_CTX *hctx, const uint8_t *pk_seed, const SLH_ADRS adrs,
            const uint8_t *m1, const uint8_t *m2, uint8_t *out)
 {
@@ -327,16 +337,16 @@ slh_h_sha2(SLH_HASH_CTX *hctx, const uint8_t *pk_seed, const SLH_ADRS adrs,
 
     memcpy(m, m1, n);
     memcpy(m + n, m2, n);
-    do_hash(hctx->md_big_ctx, n, pk_seed, adrs, m, 2 * n,
-            hctx->sha2_h_and_t_bound, out);
+    return do_hash(hctx->md_big_ctx, n, pk_seed, adrs, m, 2 * n,
+                   hctx->sha2_h_and_t_bound, out);
 }
 
-static void
+static int
 slh_t_sha2(SLH_HASH_CTX *hctx, const uint8_t *pk_seed, const SLH_ADRS adrs,
            const uint8_t *ml, size_t ml_len, uint8_t *out)
 {
-    do_hash(hctx->md_big_ctx, hctx->n, pk_seed, adrs, ml, ml_len,
-            hctx->sha2_h_and_t_bound, out);
+    return do_hash(hctx->md_big_ctx, hctx->n, pk_seed, adrs, ml, ml_len,
+                   hctx->sha2_h_and_t_bound, out);
 }
 
 const SLH_HASH_FUNC *ossl_slh_get_hash_fn(int is_shake)
index e226db73cca5604fee1f1b2ac303194de993dc31..b6e3de77dba13c974dbdef65d1fd475fe8cb33d4 100644 (file)
@@ -38,23 +38,23 @@ typedef struct slh_hash_ctx_st {
 /*
  * @params out is |m| bytes which ranges from (30..49) bytes
  */
-typedef void (OSSL_SLH_HASHFUNC_H_MSG)(SLH_HASH_CTX *ctx, const uint8_t *r,
+typedef int (OSSL_SLH_HASHFUNC_H_MSG)(SLH_HASH_CTX *ctx, const uint8_t *r,
     const uint8_t *pk_seed, const uint8_t *pk_root,
     const uint8_t *msg, size_t msg_len, uint8_t *out);
 
-typedef void (OSSL_SLH_HASHFUNC_PRF)(SLH_HASH_CTX *ctx, const uint8_t *pk_seed,
+typedef int (OSSL_SLH_HASHFUNC_PRF)(SLH_HASH_CTX *ctx, const uint8_t *pk_seed,
     const uint8_t *sk_seed, const SLH_ADRS adrs, uint8_t *out);
 
-typedef void (OSSL_SLH_HASHFUNC_PRF_MSG)(SLH_HASH_CTX *ctx, const uint8_t *sk_prf,
+typedef int (OSSL_SLH_HASHFUNC_PRF_MSG)(SLH_HASH_CTX *ctx, const uint8_t *sk_prf,
     const uint8_t *opt_rand, const uint8_t *msg, size_t msg_len, uint8_t *out);
 
-typedef void (OSSL_SLH_HASHFUNC_F)(SLH_HASH_CTX *ctx, const uint8_t *pk_seed,
+typedef int (OSSL_SLH_HASHFUNC_F)(SLH_HASH_CTX *ctx, const uint8_t *pk_seed,
     const SLH_ADRS adrs, const uint8_t *m1, size_t m1_len, uint8_t *out);
 
-typedef void (OSSL_SLH_HASHFUNC_H)(SLH_HASH_CTX *ctx, const uint8_t *pk_seed,
+typedef int (OSSL_SLH_HASHFUNC_H)(SLH_HASH_CTX *ctx, const uint8_t *pk_seed,
     const SLH_ADRS adrs, const uint8_t *m1, const uint8_t *m2, uint8_t *out);
 
-typedef void (OSSL_SLH_HASHFUNC_T)(SLH_HASH_CTX *ctx, const uint8_t *pk_seed,
+typedef int (OSSL_SLH_HASHFUNC_T)(SLH_HASH_CTX *ctx, const uint8_t *pk_seed,
     const SLH_ADRS adrs, const uint8_t *m1, size_t m1_len, uint8_t *out);
 
 typedef struct slh_hash_func_st {
@@ -68,9 +68,9 @@ typedef struct slh_hash_func_st {
 
 const SLH_HASH_FUNC *ossl_slh_get_hash_fn(int is_shake);
 
-int ossl_slh_hash_ctx_init(SLH_HASH_CTX *ctx, OSSL_LIB_CTX *libctx,
-                           const char *propq, int is_shake,
-                           int security_category, size_t n, size_t m);
+__owur int ossl_slh_hash_ctx_init(SLH_HASH_CTX *ctx, OSSL_LIB_CTX *libctx,
+                                  const char *propq, int is_shake,
+                                  int security_category, size_t n, size_t m);
 void ossl_slh_hash_ctx_cleanup(SLH_HASH_CTX *ctx);
 
 #endif
index a0be9d38c594ef1a4fa7fd5d9b1e59b42b00ab71..fa16d45b77ff69b7b4e4de622e7e0434cbe3d0f4 100644 (file)
  * @param leaf_id Index of the WOTS+ key within the XMSS tree that will signed the message
  * @param sig The returned Hypertree Signature (which is |d| XMSS signatures)
  * @param sig_len The size of |sig| which is (|h| + |d| * |len|) * |n|)
+ * @returns 1 on success, or 0 on error.
  */
-void ossl_slh_ht_sign(SLH_DSA_CTX *ctx,
-                      const uint8_t *msg, const uint8_t *sk_seed,
-                      const uint8_t *pk_seed,
-                      uint64_t tree_id, uint32_t leaf_id,
-                      uint8_t *sig, size_t sig_len)
+int ossl_slh_ht_sign(SLH_DSA_CTX *ctx,
+                     const uint8_t *msg, const uint8_t *sk_seed,
+                     const uint8_t *pk_seed,
+                     uint64_t tree_id, uint32_t leaf_id,
+                     uint8_t *sig, size_t sig_len)
 {
     SLH_ADRS_FUNC_DECLARE(ctx, adrsf);
     SLH_ADRS_DECLARE(adrs);
@@ -50,15 +51,20 @@ void ossl_slh_ht_sign(SLH_DSA_CTX *ctx,
     for (layer = 0; layer < d; ++layer) {
         adrsf->set_layer_address(adrs, layer);
         adrsf->set_tree_address(adrs, tree_id);
-        ossl_slh_xmss_sign(ctx, root, sk_seed, leaf_id, pk_seed, adrs,
-                           psig, xmss_sig_len);
-        if (layer < d - 1)
-            ossl_slh_xmss_pk_from_sig(ctx, leaf_id, psig, root, pk_seed, adrs, root);
+        if (!ossl_slh_xmss_sign(ctx, root, sk_seed, leaf_id, pk_seed, adrs,
+                                psig, xmss_sig_len))
+            return 0;
+        if (layer < d - 1) {
+            if (!ossl_slh_xmss_pk_from_sig(ctx, leaf_id, psig, root,
+                                           pk_seed, adrs, root))
+                return 0;
+        }
         psig += xmss_sig_len;
         leaf_id = tree_id & mask;
         tree_id >>= hm;
     }
     assert((size_t)(psig - sig) == sig_len);
+    return 1;
 }
 
 /**
@@ -97,7 +103,9 @@ int ossl_slh_ht_verify(SLH_DSA_CTX *ctx, const uint8_t *msg, const uint8_t *sig,
     for (layer = 0; layer < d; ++layer) {
         adrsf->set_layer_address(adrs, layer);
         adrsf->set_tree_address(adrs, tree_id);
-        ossl_slh_xmss_pk_from_sig(ctx, leaf_id, sig, node, pk_seed, adrs, node);
+        if (!ossl_slh_xmss_pk_from_sig(ctx, leaf_id, sig, node,
+                                       pk_seed, adrs, node))
+            return 0;
         sig += len;
         leaf_id = tree_id & mask;
         tree_id >>= tree_height;
index 1c7c26b60b705c54a0f44dc8b7eb74d18c5238aa..9d3912623a970140cf66dbfa9bd65a79af2cc9c8 100644 (file)
@@ -89,10 +89,11 @@ static ossl_inline void compute_checksum_nibbles(const uint8_t *in, size_t in_le
  * @param adrs An ADRS object which has a type of WOTS_HASH, and has a layer
  *             address, tree address, key pair address and chain address
  * @param pk_seed A public key seed (which is added to the hash)
+ * @returns 1 on success, or 0 on error.
  */
-static void slh_wots_chain(SLH_DSA_CTX *ctx, const uint8_t *in,
-                           uint8_t start_index, uint8_t steps,
-                           const uint8_t *pk_seed, uint8_t *adrs, uint8_t *out)
+static int slh_wots_chain(SLH_DSA_CTX *ctx, const uint8_t *in,
+                          uint8_t start_index, uint8_t steps,
+                          const uint8_t *pk_seed, uint8_t *adrs, uint8_t *out)
 {
     SLH_HASH_FUNC_DECLARE(ctx, hashf, hctx);
     SLH_ADRS_FUNC_DECLARE(ctx, adrsf);
@@ -105,8 +106,10 @@ static void slh_wots_chain(SLH_DSA_CTX *ctx, const uint8_t *in,
 
     for (j = start_index; j < end_index; ++j) {
         set_hash_address(adrs, j);
-        F(hctx, pk_seed, adrs, out, n, out);
+        if (!F(hctx, pk_seed, adrs, out, n, out))
+            return 0;
     }
+    return 1;
 }
 
 /**
@@ -119,10 +122,11 @@ static void slh_wots_chain(SLH_DSA_CTX *ctx, const uint8_t *in,
  * @param adrs An ADRS object containing the layer address, tree address and
  *             keypair address of the WOTS+ public key to generate.
  * @param pk_out The generated public key of size |n|
+ * @returns 1 on success, or 0 on error.
  */
-void ossl_slh_wots_pk_gen(SLH_DSA_CTX *ctx,
-                          const uint8_t *sk_seed, const uint8_t *pk_seed,
-                          SLH_ADRS adrs, uint8_t *pk_out)
+int ossl_slh_wots_pk_gen(SLH_DSA_CTX *ctx,
+                         const uint8_t *sk_seed, const uint8_t *pk_seed,
+                         SLH_ADRS adrs, uint8_t *pk_out)
 {
     SLH_HASH_FUNC_DECLARE(ctx, hashf, hctx);
     SLH_ADRS_FUNC_DECLARE(ctx, adrsf);
@@ -142,10 +146,12 @@ void ossl_slh_wots_pk_gen(SLH_DSA_CTX *ctx,
     len = SLH_WOTS_LEN(n); /* See Section 5 intro */
     for (i = 0; i < len; ++i) {
         set_chain_address(sk_adrs, i);
-        PRF(hctx, pk_seed, sk_seed, sk_adrs, sk);
+        if (!PRF(hctx, pk_seed, sk_seed, sk_adrs, sk))
+            return 0;
 
         set_chain_address(adrs, i);
-        slh_wots_chain(ctx, sk, 0, NIBBLE_MASK, pk_seed, adrs, ptmp);
+        if (!slh_wots_chain(ctx, sk, 0, NIBBLE_MASK, pk_seed, adrs, ptmp))
+            return 0;
         ptmp += n;
     }
 
@@ -153,7 +159,7 @@ void ossl_slh_wots_pk_gen(SLH_DSA_CTX *ctx,
     adrsf->copy(wots_pk_adrs, adrs);
     adrsf->set_type_and_clear(wots_pk_adrs, SLH_ADRS_TYPE_WOTS_PK);
     adrsf->copy_keypair_address(wots_pk_adrs, adrs);
-    hashf->T(hctx, pk_seed, wots_pk_adrs, tmp, len, pk_out);
+    return hashf->T(hctx, pk_seed, wots_pk_adrs, tmp, len, pk_out);
 }
 
 /**
@@ -170,10 +176,11 @@ void ossl_slh_wots_pk_gen(SLH_DSA_CTX *ctx,
  * @param sig The returned signature.
  * @param sig_len The size of |sig| which should be len * |n| bytes.
  *                (where len = 2 * |n| + 3)
+ * @returns 1 on success, or 0 on error.
  */
-void ossl_slh_wots_sign(SLH_DSA_CTX *ctx, const uint8_t *msg,
-                        const uint8_t *sk_seed, const uint8_t *pk_seed,
-                        SLH_ADRS adrs, uint8_t *sig, size_t sig_len)
+int ossl_slh_wots_sign(SLH_DSA_CTX *ctx, const uint8_t *msg,
+                       const uint8_t *sk_seed, const uint8_t *pk_seed,
+                       SLH_ADRS adrs, uint8_t *sig, size_t sig_len)
 {
     SLH_HASH_FUNC_DECLARE(ctx, hashf, hctx);
     SLH_ADRS_FUNC_DECLARE(ctx, adrsf);
@@ -204,13 +211,17 @@ void ossl_slh_wots_sign(SLH_DSA_CTX *ctx, const uint8_t *msg,
     for (i = 0; i < len; ++i) {
         set_chain_address(sk_adrs, i);
         /* compute chain i secret */
-        PRF(hctx, pk_seed, sk_seed, sk_adrs, sk);
+        if (!PRF(hctx, pk_seed, sk_seed, sk_adrs, sk))
+            return 0;
         set_chain_address(adrs, i);
         /* compute chain i signature */
-        slh_wots_chain(ctx, sk, 0, msg_and_csum_nibbles[i], pk_seed, adrs, psig);
+        if (!slh_wots_chain(ctx, sk, 0, msg_and_csum_nibbles[i],
+                            pk_seed, adrs, psig))
+            return 0;
         psig += n;
     }
     assert(sig_len == (size_t)(psig - sig));
+    return 1;
 }
 
 /**
@@ -224,11 +235,12 @@ void ossl_slh_wots_sign(SLH_DSA_CTX *ctx, const uint8_t *msg,
  * @param adrs An ADRS object containing the layer address, tree address and
  *             key pair address that of the WOTS+ key used to sign the message.
  * @param pk_out The returned public key candidate of size |n|
+ * @returns 1 on success, or 0 on error.
  */
-void ossl_slh_wots_pk_from_sig(SLH_DSA_CTX *ctx,
-                               const uint8_t *sig, const uint8_t *msg,
-                               const uint8_t *pk_seed, uint8_t *adrs,
-                               uint8_t *pk_out)
+int ossl_slh_wots_pk_from_sig(SLH_DSA_CTX *ctx,
+                              const uint8_t *sig, const uint8_t *msg,
+                              const uint8_t *pk_seed, uint8_t *adrs,
+                              uint8_t *pk_out)
 {
     SLH_HASH_FUNC_DECLARE(ctx, hashf, hctx);
     SLH_ADRS_FUNC_DECLARE(ctx, adrsf);
@@ -247,9 +259,10 @@ void ossl_slh_wots_pk_from_sig(SLH_DSA_CTX *ctx,
     /* Compute the end nodes for each of the chains */
     for (i = 0; i < len; ++i) {
         set_chain_address(adrs, i);
-        slh_wots_chain(ctx, sig, msg_and_csum_nibbles[i],
-                       NIBBLE_MASK - msg_and_csum_nibbles[i],
-                       pk_seed, adrs, ptmp);
+        if (!slh_wots_chain(ctx, sig, msg_and_csum_nibbles[i],
+                            NIBBLE_MASK - msg_and_csum_nibbles[i],
+                            pk_seed, adrs, ptmp))
+            return 0;
         sig += n;
         ptmp += n;
     }
@@ -257,5 +270,5 @@ void ossl_slh_wots_pk_from_sig(SLH_DSA_CTX *ctx,
     adrsf->copy(wots_pk_adrs, adrs);
     adrsf->set_type_and_clear(wots_pk_adrs, SLH_ADRS_TYPE_WOTS_PK);
     adrsf->copy_keypair_address(wots_pk_adrs, adrs);
-    hashf->T(hctx, pk_seed, wots_pk_adrs, tmp, ptmp - tmp, pk_out);
+    return hashf->T(hctx, pk_seed, wots_pk_adrs, tmp, ptmp - tmp, pk_out);
 }
index c2501e23c8d6765186572e6cb6ef1bc7caa59cc4..08f112f0d2f2dff8ea40c5707fa575552010b738 100644 (file)
  * This is a recursive function that starts at an leaf index, that calculates
  * the hash of each parent using 2 child nodes.
  *
- * @param sk_seed A private key seed
- * @param pk_seed A public key seed
- * @param n The size of |sk_seed|, |pk_seed| and |pk_out|
- * @param adrs An ADRS object containing the layer address and tree address set
- *             to the XMSS tree within which the XMSS tree is being computed.
+ * @param ctx Contains SLH_DSA algorithm functions and constants.
+ * @param sk_seed A private key seed of size |n|
  * @param nodeid The index of the target node being computed
  *               (which must be < 2^(hm - height)
- * @param height The height within the tree of the node being computed.
- *               (which must be <= hm) (hm is one of 3, 4, 8 or 9)
- *               At height=0 There are 2^hm leaf nodes,
- *               and the root node is at height = hm)
+ * @param h The height within the tree of the node being computed.
+ *          (which must be <= hm) (hm is one of 3, 4, 8 or 9)
+ *          At height=0 There are 2^hm leaf nodes,
+ *          and the root node is at height = hm)
+ * @param pk_seed A public key seed of size |n|
+ * @param adrs An ADRS object containing the layer address and tree address set
+ *             to the XMSS tree within which the XMSS tree is being computed.
  * @param pk_out The generated public key of size |n|
+ * @returns 1 on success, or 0 on error.
  */
-void ossl_slh_xmss_node(SLH_DSA_CTX *ctx,
-                        const uint8_t *sk_seed,
-                        uint32_t node_id,
-                        uint32_t h,
-                        const uint8_t *pk_seed,
-                        SLH_ADRS adrs,
-                        uint8_t *pk_out)
+int ossl_slh_xmss_node(SLH_DSA_CTX *ctx, const uint8_t *sk_seed,
+                        uint32_t node_id, uint32_t h,
+                        const uint8_t *pk_seed, SLH_ADRS adrs, uint8_t *pk_out)
 {
     SLH_ADRS_FUNC_DECLARE(ctx, adrsf);
 
@@ -44,41 +41,46 @@ void ossl_slh_xmss_node(SLH_DSA_CTX *ctx,
         /* For leaf nodes generate the public key */
         adrsf->set_type_and_clear(adrs, SLH_ADRS_TYPE_WOTS_HASH);
         adrsf->set_keypair_address(adrs, node_id);
-        ossl_slh_wots_pk_gen(ctx, sk_seed, pk_seed, adrs, pk_out);
+        if (!ossl_slh_wots_pk_gen(ctx, sk_seed, pk_seed, adrs, pk_out))
+            return 0;
     } else {
         uint8_t lnode[SLH_MAX_N], rnode[SLH_MAX_N];
 
-        ossl_slh_xmss_node(ctx, sk_seed, 2 * node_id, h - 1, pk_seed, adrs,
-                           lnode);
-        ossl_slh_xmss_node(ctx, sk_seed, 2 * node_id + 1, h - 1, pk_seed, adrs,
-                           rnode);
+        if (!ossl_slh_xmss_node(ctx, sk_seed, 2 * node_id, h - 1, pk_seed, adrs,
+                                lnode)
+                || !ossl_slh_xmss_node(ctx, sk_seed, 2 * node_id + 1, h - 1,
+                                       pk_seed, adrs, rnode))
+            return 0;
         adrsf->set_type_and_clear(adrs, SLH_ADRS_TYPE_TREE);
         adrsf->set_tree_height(adrs, h);
         adrsf->set_tree_index(adrs, node_id);
-        ctx->hash_func->H(&ctx->hash_ctx, pk_seed, adrs, lnode, rnode, pk_out);
+        if (!ctx->hash_func->H(&ctx->hash_ctx, pk_seed, adrs, lnode, rnode, pk_out))
+            return 0;
     }
+    return 1;
 }
 
 /**
  * @brief Generate an XMSS signature using a message and key.
  * See FIPS 205 Section 6.2 Algorithm 10
  *
+ * @param ctx Contains SLH_DSA algorithm functions and constants.
  * @param msg A message of size |n| bytes to sign
- * @param sk_seed A private key seed
- * @param pk_seed A public key seed
- * @param n The size of |msg|, |sk_seed| and |pk_seed|
+ * @param sk_seed A private key seed of size |n|
+ * @param node_id The index of a WOTS+ key within the XMSS tree to use for signing.
+ * @param pk_seed A public key seed f size |n|
  * @param adrs An ADRS object containing the layer address and tree address set
  *              to the XMSS key being used to sign the message.
- * @param node_id The index of a WOTS+ key within the XMSS tree to use for signing.
- * @param tree_height The height of the XMSS tree.
- * @param sig_out The generated XMSS signature which consists of a WOTS+
- *                 signature of size [2 * n + 3][n] followed by an authentication
- *                 path of size [tree_height[n].
+ * @param sig The generated XMSS signature.
+ * @param sig_len The size of |sig|. which consists of a WOTS+
+ *                signature of size [2 * n + 3][n] followed by an authentication
+ *                path of size [tree_height[n].
+ * @returns 1 on success, or 0 on error.
  */
-void ossl_slh_xmss_sign(SLH_DSA_CTX *ctx, const uint8_t *msg,
-                        const uint8_t *sk_seed, uint32_t node_id,
-                        const uint8_t *pk_seed, SLH_ADRS adrs,
-                        uint8_t *sig, size_t sig_len)
+int ossl_slh_xmss_sign(SLH_DSA_CTX *ctx, const uint8_t *msg,
+                       const uint8_t *sk_seed, uint32_t node_id,
+                       const uint8_t *pk_seed, SLH_ADRS adrs,
+                       uint8_t *sig, size_t sig_len)
 {
     SLH_ADRS_FUNC_DECLARE(ctx, adrsf);
     uint32_t h, id = node_id;
@@ -86,42 +88,39 @@ void ossl_slh_xmss_sign(SLH_DSA_CTX *ctx, const uint8_t *msg,
     uint32_t hm = ctx->params->hm;
     size_t wots_sig_len = n * SLH_WOTS_LEN(n);
     uint8_t *auth_path = sig + wots_sig_len;
-/*
-    size_t auth_sig_len = n * hm;
-    assert(sig_len == (wots_sig_len + auth_sig_len));
-*/
 
     for (h = 0; h < hm; ++h) {
-        ossl_slh_xmss_node(ctx, sk_seed, id ^ 1, h, pk_seed, adrs, auth_path);
+        if (!ossl_slh_xmss_node(ctx, sk_seed, id ^ 1, h, pk_seed, adrs, auth_path))
+            return 0;
         id >>= 1;
         auth_path += n;
     }
     adrsf->set_type_and_clear(adrs, SLH_ADRS_TYPE_WOTS_HASH);
     adrsf->set_keypair_address(adrs, node_id);
-    ossl_slh_wots_sign(ctx, msg, sk_seed, pk_seed, adrs, sig, wots_sig_len);
+    return ossl_slh_wots_sign(ctx, msg, sk_seed, pk_seed, adrs, sig, wots_sig_len);
 }
 
 /**
  * @brief Compute a candidate XMSS public key from a message and XMSS signature
  * See FIPS 205 Section 6.3 Algorithm 11
  *
+ * @param ctx Contains SLH_DSA algorithm functions and constants.
+ * @param node_id Must be set to the |node_id| used in xmss_sign().
  * @param sig A XMSS signature which consists of a WOTS+ signature of
  *            [2 * n + 3][n] bytes followed by an authentication path of
  *            [hm][n] bytes (where hm is the height of the XMSS tree).
  * @param msg A message of size |n| bytes
- * @param sk_seed A private key seed
- * @param pk_seed A public key seed
- * @param n The hash size size if the size of |msg|, |sk_seed| and |pk_seed|
- * @param adrs An ADRS object containing a layer address and tress address of an
+ * @param sk_seed A private key seed of size |n|
+ * @param pk_seed A public key seed of size |n|
+ * @param adrs An ADRS object containing a layer address and tree address of an
  *             XMSS key used for signing the message.
- * @param node_id Must be set to the |node_id| used in xmss_sign().
- * @param tree_height The height of the XMSS tree.
  * @param pk_out The returned candidate XMSS public key of size |n|.
+ * @returns 1 on success, or 0 on error.
  */
-void ossl_slh_xmss_pk_from_sig(SLH_DSA_CTX *ctx, uint32_t node_id,
-                               const uint8_t *sig, const uint8_t *msg,
-                               const uint8_t *pk_seed, SLH_ADRS adrs,
-                               uint8_t *pk_out)
+int ossl_slh_xmss_pk_from_sig(SLH_DSA_CTX *ctx, uint32_t node_id,
+                              const uint8_t *sig, const uint8_t *msg,
+                              const uint8_t *pk_seed, SLH_ADRS adrs,
+                              uint8_t *pk_out)
 {
     SLH_HASH_FUNC_DECLARE(ctx, hashf, hctx);
     SLH_HASH_FN_DECLARE(hashf, H);
@@ -137,7 +136,8 @@ void ossl_slh_xmss_pk_from_sig(SLH_DSA_CTX *ctx, uint32_t node_id,
 
     adrsf->set_type_and_clear(adrs, SLH_ADRS_TYPE_WOTS_HASH);
     adrsf->set_keypair_address(adrs, node_id);
-    ossl_slh_wots_pk_from_sig(ctx, sig, msg, pk_seed, adrs, node);
+    if (!ossl_slh_wots_pk_from_sig(ctx, sig, msg, pk_seed, adrs, node))
+        return 0;
 
     adrsf->set_type_and_clear(adrs, SLH_ADRS_TYPE_TREE);
 
@@ -146,12 +146,15 @@ void ossl_slh_xmss_pk_from_sig(SLH_DSA_CTX *ctx, uint32_t node_id,
         if ((node_id & 1) == 0) { /* even */
             node_id >>= 1;
             set_tree_index(adrs, node_id);
-            H(hctx, pk_seed, adrs, node, auth_path, node);
+            if (!H(hctx, pk_seed, adrs, node, auth_path, node))
+                return 0;
         } else { /* odd */
             node_id = (node_id - 1) >> 1;
             set_tree_index(adrs, node_id);
-            H(hctx, pk_seed, adrs, auth_path, node, node);
+            if (!H(hctx, pk_seed, adrs, auth_path, node, node))
+                return 0;
         }
         auth_path += n;
     }
+    return 1;
 }
index ab9903a4916d265c6845b6303b08e539ff52a050..14139508b4cf81e38864b3048b0f2dfbd2a1cbfd 100644 (file)
 
 typedef struct slh_dsa_ctx_st SLH_DSA_CTX;
 
-SLH_DSA_KEY *ossl_slh_dsa_key_new(OSSL_LIB_CTX *libctx, const char *alg);
+__owur SLH_DSA_KEY *ossl_slh_dsa_key_new(OSSL_LIB_CTX *libctx, const char *alg);
 void ossl_slh_dsa_key_free(SLH_DSA_KEY *key);
-int ossl_slh_dsa_key_up_ref(SLH_DSA_KEY *key);
-int ossl_slh_dsa_key_equal(const SLH_DSA_KEY *key1, const SLH_DSA_KEY *key2,
-                           int selection);
-int ossl_slh_dsa_key_has(const SLH_DSA_KEY *key, int selection);
-int ossl_slh_dsa_key_fromdata(SLH_DSA_KEY *key, const OSSL_PARAM *params,
-                              int include_private);
-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);
-int ossl_slh_dsa_key_is_private(const SLH_DSA_KEY *key);
-const uint8_t *ossl_slh_dsa_key_get_pub(const SLH_DSA_KEY *key);
-const uint8_t *ossl_slh_dsa_key_get_priv(const SLH_DSA_KEY *key);
-size_t ossl_slh_dsa_key_get_len(const SLH_DSA_KEY *key);
-size_t ossl_slh_dsa_key_get_n(const SLH_DSA_KEY *key);
-int ossl_slh_dsa_key_type_matches(SLH_DSA_CTX *ctx, const SLH_DSA_KEY *key);
-
-SLH_DSA_CTX *ossl_slh_dsa_ctx_new(const char *alg,
-                                  OSSL_LIB_CTX *lib_ctx, const char *propq);
+__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_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_is_private(const SLH_DSA_KEY *key);
+__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_len(const SLH_DSA_KEY *key);
+__owur size_t ossl_slh_dsa_key_get_n(const SLH_DSA_KEY *key);
+__owur int ossl_slh_dsa_key_type_matches(SLH_DSA_CTX *ctx, const SLH_DSA_KEY *key);
+
+__owur SLH_DSA_CTX *ossl_slh_dsa_ctx_new(const char *alg,
+                                         OSSL_LIB_CTX *lib_ctx, const char *propq);
 void ossl_slh_dsa_ctx_free(SLH_DSA_CTX *ctx);
 
-int ossl_slh_dsa_sign(SLH_DSA_CTX *slh_ctx, const SLH_DSA_KEY *priv,
-                      const uint8_t *msg, size_t msg_len,
-                      const uint8_t *ctx, size_t ctx_len,
-                      const uint8_t *add_rand, int encode,
-                      unsigned char *sig, size_t *siglen, size_t sigsize);
-int ossl_slh_dsa_verify(SLH_DSA_CTX *slh_ctx, const SLH_DSA_KEY *pub,
-                        const uint8_t *msg, size_t msg_len,
-                        const uint8_t *ctx, size_t ctx_len, int encode,
-                        const uint8_t *sig, size_t sig_len);
+__owur int ossl_slh_dsa_sign(SLH_DSA_CTX *slh_ctx, const SLH_DSA_KEY *priv,
+                             const uint8_t *msg, size_t msg_len,
+                             const uint8_t *ctx, size_t ctx_len,
+                             const uint8_t *add_rand, int encode,
+                             unsigned char *sig, size_t *siglen, size_t sigsize);
+__owur int ossl_slh_dsa_verify(SLH_DSA_CTX *slh_ctx, const SLH_DSA_KEY *pub,
+                               const uint8_t *msg, size_t msg_len,
+                               const uint8_t *ctx, size_t ctx_len, int encode,
+                               const uint8_t *sig, size_t sig_len);
 
 #endif /* OSSL_CRYPTO_SLH_DSA_H */
index e0ade7cfe8f7cc145ec0fb985039927b80a986b9..6d61f5b050bdafd1d70b27b06fdd34abd6b0240b 100644 (file)
@@ -23,11 +23,20 @@ use lib srctop_dir('Configurations');
 use lib bldtop_dir('.');
 
 plan skip_all => 'SLH-DSA is not supported in this build' if disabled('slh-dsa');
-plan tests => ($no_fips ? 0 : 1) + 1;
+plan tests => 2;
 
 ok(run(test(["slh_dsa_test"])), "running slh_dsa_test");
 
-unless ($no_fips) {
+SKIP: {
+    skip "Skipping FIPS tests", 1
+        if $no_fips;
+
+    # SLH-DSA is only present after OpenSSL 3.5
+    run(test(["fips_version_test", "-config", $provconf, ">=3.5.0"]),
+             capture => 1, statusvar => \my $exit);
+    skip "FIPS provider version is too old for SLH_DSA test", 1
+        if !$exit;
+
     ok(run(test(["slh_dsa_test", "-config",  $provconf])),
            "running slh_dsa_test with FIPS");
 }
index 81b3733931b1d05ea2f23a91da41530770af373c..15cdf8bea0bb3c956cc83223426d645ccd52ef6f 100644 (file)
@@ -137,6 +137,8 @@ static int slh_dsa_key_eq_test(void)
         goto end;
     ret = TEST_int_ne(EVP_PKEY_eq(key[0], eckey), 1);
     EVP_PKEY_free(eckey);
+#else
+    ret = 1;
 #endif
 end:
     EVP_PKEY_free(key[2]);