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)
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);
/* 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);
}
/**
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);
}
/**
/**
* 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,
/**
* 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,
* @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)
{
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));
}
/**
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);
* @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);
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);
}
/**
* @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;
}
/**
* @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];
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;
}
/**
* 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);
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) {
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;
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);
}
/**
}
/* 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)
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
/* 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)
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];
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)
{
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)
/*
* @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 {
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
* @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);
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;
}
/**
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;
* @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);
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;
}
/**
* @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);
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;
}
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);
}
/**
* @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);
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;
}
/**
* @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);
/* 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;
}
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);
}
* 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);
/* 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;
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);
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);
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;
}
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 */
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");
}
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]);