EVP_MAC_up_ref(src->hmac);
}
+/**
+ * @brief Return the libctx associated with a SLH_DSA_KEY object
+ *
+ * @param key A SLH_DSA_KEY to extract the libctx from.
+ * @returns The new OSSL_LIB_CTX object on success, or NULL failure
+ */
+OSSL_LIB_CTX *ossl_slh_dsa_key_get0_libctx(const SLH_DSA_KEY *key)
+{
+ return key != NULL ? key->libctx : NULL;
+}
+
/**
* @brief Create a new SLH_DSA_KEY object
*
return ret;
}
+void ossl_slh_dsa_key_reset(SLH_DSA_KEY *key)
+{
+ key->pub = NULL;
+ if (key->has_priv) {
+ key->has_priv = 0;
+ OPENSSL_cleanse(key->priv, sizeof(key->priv));
+ }
+}
+
/**
* @brief Load a SLH_DSA key from raw data.
*
key->pub = p;
return 1;
err:
- key->pub = NULL;
- key->has_priv = 0;
- OPENSSL_cleanse(key->priv, priv_len);
+ ossl_slh_dsa_key_reset(key);
return 0;
}
#include <openssl/core_names.h>
#include <openssl/param_build.h>
#include <openssl/self_test.h>
+#include <openssl/proverr.h>
#include "crypto/slh_dsa.h"
#include "internal/fips.h"
#include "internal/param_build_set.h"
#include "prov/providercommon.h"
#include "prov/provider_ctx.h"
+#ifdef FIPS_MODULE
+static int slh_dsa_fips140_pairwise_test(const SLH_DSA_KEY *key,
+ SLH_DSA_HASH_CTX *ctx);
+#endif /* FIPS_MODULE */
+
static OSSL_FUNC_keymgmt_free_fn slh_dsa_free_key;
static OSSL_FUNC_keymgmt_has_fn slh_dsa_has;
static OSSL_FUNC_keymgmt_match_fn slh_dsa_match;
static int slh_dsa_import(void *keydata, int selection, const OSSL_PARAM params[])
{
SLH_DSA_KEY *key = keydata;
- int include_priv;
+ int include_priv, res;
if (!ossl_prov_is_running() || key == NULL)
return 0;
return 0;
include_priv = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
- return ossl_slh_dsa_key_fromdata(key, params, include_priv);
+ res = ossl_slh_dsa_key_fromdata(key, params, include_priv);
+#ifdef FIPS_MODULE
+ /*
+ * FIPS 140-3 IG 10.3.A additional comment 1 mandates that a pairwise
+ * consistency check be undertaken on key import. The required test
+ * is described in SP 800-56Ar3 5.6.2.1.4.
+ */
+ if (res > 0 && ossl_slh_dsa_key_has(key, OSSL_KEYMGMT_SELECT_KEYPAIR) > 0)
+ if (!slh_dsa_fips140_pairwise_test(key, NULL)) {
+ ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY,
+ "explicit %s public key does not match private",
+ ossl_slh_dsa_key_get_name(key));
+ ossl_slh_dsa_key_reset(key);
+ res = 0;
+ }
+#endif /* FIPS_MODULE */
+ return res;
}
#define SLH_DSA_IMEXPORTABLE_PARAMETERS \
* Refer to FIPS 140-3 IG 10.3.A Additional Comment 1
* Perform a pairwise test for SLH_DSA by signing and verifying a signature.
*/
-static int slh_dsa_fips140_pairwise_test(SLH_DSA_HASH_CTX *ctx,
- const SLH_DSA_KEY *key,
- OSSL_LIB_CTX *lib_ctx)
+static int slh_dsa_fips140_pairwise_test(const SLH_DSA_KEY *key,
+ SLH_DSA_HASH_CTX *ctx)
{
int ret = 0;
OSSL_SELF_TEST *st = NULL;
size_t msg_len = sizeof(msg);
uint8_t *sig = NULL;
size_t sig_len;
+ OSSL_LIB_CTX *lib_ctx;
+ int alloc_ctx = 0;
/* During self test, it is a waste to do this test */
if (ossl_fips_self_testing())
return 1;
+ if (ctx == NULL) {
+ ctx = ossl_slh_dsa_hash_ctx_new(key);
+ if (ctx == NULL)
+ return 0;
+ alloc_ctx = 1;
+ }
+ lib_ctx = ossl_slh_dsa_key_get0_libctx(key);
+
OSSL_SELF_TEST_get_callback(lib_ctx, &cb, &cb_arg);
st = OSSL_SELF_TEST_new(cb, cb_arg);
if (st == NULL)
- return 0;
+ goto err;
OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
OSSL_SELF_TEST_DESC_PCT_SLH_DSA);
ret = 1;
err:
+ if (alloc_ctx)
+ ossl_slh_dsa_hash_ctx_free(ctx);
OPENSSL_free(sig);
OSSL_SELF_TEST_onend(st, ret);
OSSL_SELF_TEST_free(st);
return NULL;
ctx = ossl_slh_dsa_hash_ctx_new(key);
if (ctx == NULL)
- return NULL;
+ goto err;
if (!ossl_slh_dsa_generate_key(ctx, key, gctx->libctx,
gctx->entropy, gctx->entropy_len))
goto err;
#ifdef FIPS_MODULE
- if (!slh_dsa_fips140_pairwise_test(ctx, key, gctx->libctx)) {
+ if (!slh_dsa_fips140_pairwise_test(key, ctx)) {
ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
goto err;
}
* 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;
+ 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);
+ if (OSSL_PROVIDER_available(lib_ctx, "fips")
+ && fips_provider_version_match(lib_ctx, ">3.5.2")) {
+ /* The new pairwise test should fail in fips mode */
+ if (!TEST_ptr_null(key))
+ goto end;
+ } else {
+ if (!TEST_ptr(key))
+ goto end;
+ 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);