aboutsummaryrefslogtreecommitdiffstats
path: root/providers
diff options
context:
space:
mode:
authorpohsingwu <pohsingwu@synology.com>2024-07-17 15:19:51 +0800
committerPauli <ppzgs1@gmail.com>2024-07-24 13:16:08 +1000
commit14e46600c68ece74970462a60ad20703221747a1 (patch)
tree3a7a382ffed5d9f235b619119ddfd3f466215586 /providers
parent5e25b8afc0f964a3f178549d00fbe6a9295188e8 (diff)
downloadopenssl-master.tar.gz
Restrict digest in set_ctx_paramsHEADmaster
In this commit, we also return different error if the digest is XOF. Reviewed-by: Shane Lontis <shane.lontis@oracle.com> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/23889)
Diffstat (limited to 'providers')
-rw-r--r--providers/implementations/kdfs/hkdf.c146
-rw-r--r--providers/implementations/kdfs/sshkdf.c28
-rw-r--r--providers/implementations/kdfs/sskdf.c202
-rw-r--r--providers/implementations/kdfs/tls1_prf.c39
4 files changed, 255 insertions, 160 deletions
diff --git a/providers/implementations/kdfs/hkdf.c b/providers/implementations/kdfs/hkdf.c
index 3829ce1ee3..1efd1102bc 100644
--- a/providers/implementations/kdfs/hkdf.c
+++ b/providers/implementations/kdfs/hkdf.c
@@ -50,6 +50,8 @@ static OSSL_FUNC_kdf_get_ctx_params_fn kdf_hkdf_get_ctx_params;
static OSSL_FUNC_kdf_derive_fn kdf_tls1_3_derive;
static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_tls1_3_settable_ctx_params;
static OSSL_FUNC_kdf_set_ctx_params_fn kdf_tls1_3_set_ctx_params;
+static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_tls1_3_gettable_ctx_params;
+static OSSL_FUNC_kdf_get_ctx_params_fn kdf_tls1_3_get_ctx_params;
static int HKDF(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md,
const unsigned char *salt, size_t salt_len,
@@ -66,13 +68,18 @@ static int HKDF_Expand(const EVP_MD *evp_md,
unsigned char *okm, size_t okm_len);
/* Settable context parameters that are common across HKDF and the TLS KDF */
-#define HKDF_COMMON_SETTABLES \
- OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MODE, NULL, 0), \
- OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, NULL), \
- OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), \
- OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0), \
- OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0), \
- OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0)
+#define HKDF_COMMON_SETTABLES \
+ OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MODE, NULL, 0), \
+ OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, NULL), \
+ OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), \
+ OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0), \
+ OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0), \
+ OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0)
+
+/* Gettable context parameters that are common across HKDF and the TLS KDF */
+#define HKDF_COMMON_GETTABLES \
+ OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), \
+ OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0)
typedef struct {
void *provctx;
@@ -187,33 +194,6 @@ static size_t kdf_hkdf_size(KDF_HKDF *ctx)
return sz;
}
-#ifdef FIPS_MODULE
-static int fips_hkdf_digest_check_passed(KDF_HKDF *ctx)
-{
- OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
- const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
- /*
- * Perform digest check
- *
- * HKDF is a TwoStep KDF defined in SP 800-56Cr2. According to section 7,
- * the valid hash functions are specified in FIPS 180 and FIPS 202.
- * However, it only lists SHA-1, SHA-2 and SHA-3 in the table in section
- * 5.2. ACVP also only lists the same set of hash functions.
- */
- int digest_unapproved = ((EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF) != 0);
-
- if (digest_unapproved) {
- if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
- libctx, "HKDF", "Digest",
- FIPS_hkdf_digest_check)) {
- ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED);
- return 0;
- }
- }
- return 1;
-}
-#endif
-
static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen,
const OSSL_PARAM params[])
{
@@ -238,11 +218,6 @@ static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen,
return 0;
}
-#ifdef FIPS_MODULE
- if (!fips_hkdf_digest_check_passed(ctx))
- return 0;
-#endif
-
switch (ctx->mode) {
case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND:
default:
@@ -268,8 +243,18 @@ static int hkdf_common_set_ctx_params(KDF_HKDF *ctx, const OSSL_PARAM params[])
if (params == NULL)
return 1;
- if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx))
- return 0;
+ if (OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST) != NULL) {
+ const EVP_MD *md = NULL;
+
+ if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx))
+ return 0;
+
+ md = ossl_prov_digest_md(&ctx->digest);
+ if ((EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF) != 0) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED);
+ return 0;
+ }
+ }
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_MODE)) != NULL) {
if (p->data_type == OSSL_PARAM_UTF8_STRING) {
@@ -325,10 +310,6 @@ static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
if (params == NULL)
return 1;
- if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,
- OSSL_KDF_PARAM_FIPS_DIGEST_CHECK))
- return 0;
-
if (!hkdf_common_set_ctx_params(ctx, params))
return 0;
@@ -346,17 +327,18 @@ static const OSSL_PARAM *kdf_hkdf_settable_ctx_params(ossl_unused void *ctx,
static const OSSL_PARAM known_settable_ctx_params[] = {
HKDF_COMMON_SETTABLES,
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),
- OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_DIGEST_CHECK)
OSSL_PARAM_END
};
return known_settable_ctx_params;
}
-static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
+static int hkdf_common_get_ctx_params(KDF_HKDF *ctx, OSSL_PARAM params[])
{
- KDF_HKDF *ctx = (KDF_HKDF *)vctx;
OSSL_PARAM *p;
+ if (params == NULL)
+ return 1;
+
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) {
size_t sz = kdf_hkdf_size(ctx);
@@ -365,14 +347,27 @@ static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
if (!OSSL_PARAM_set_size_t(p, sz))
return 0;
}
+
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_INFO)) != NULL) {
if (ctx->info == NULL || ctx->info_len == 0)
p->return_size = 0;
else if (!OSSL_PARAM_set_octet_string(p, ctx->info, ctx->info_len))
return 0;
}
- if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))
+
+ return 1;
+}
+
+static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+ KDF_HKDF *ctx = (KDF_HKDF *)vctx;
+
+ if (params == NULL)
+ return 1;
+
+ if (!hkdf_common_get_ctx_params(ctx, params))
return 0;
+
return 1;
}
@@ -380,9 +375,7 @@ static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(ossl_unused void *ctx,
ossl_unused void *provctx)
{
static const OSSL_PARAM known_gettable_ctx_params[] = {
- OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
- OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),
- OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
+ HKDF_COMMON_GETTABLES,
OSSL_PARAM_END
};
return known_gettable_ctx_params;
@@ -714,10 +707,9 @@ static int prov_tls13_hkdf_generate_secret(OSSL_LIB_CTX *libctx,
}
#ifdef FIPS_MODULE
-static int fips_tls1_3_digest_check_passed(KDF_HKDF *ctx)
+static int fips_tls1_3_digest_check_passed(KDF_HKDF *ctx, const EVP_MD *md)
{
OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
- const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
/*
* Perform digest check
*
@@ -755,11 +747,6 @@ static int kdf_tls1_3_derive(void *vctx, unsigned char *key, size_t keylen,
return 0;
}
-#ifdef FIPS_MODULE
- if (!fips_tls1_3_digest_check_passed(ctx))
- return 0;
-#endif
-
switch (ctx->mode) {
default:
return 0;
@@ -824,6 +811,16 @@ static int kdf_tls1_3_set_ctx_params(void *vctx, const OSSL_PARAM params[])
&& !OSSL_PARAM_get_octet_string(p, (void **)&ctx->data, 0,
&ctx->data_len))
return 0;
+
+#ifdef FIPS_MODULE
+ if (OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST) != NULL) {
+ const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
+
+ if (!fips_tls1_3_digest_check_passed(ctx, md))
+ return 0;
+ }
+#endif
+
return 1;
}
@@ -841,6 +838,33 @@ static const OSSL_PARAM *kdf_tls1_3_settable_ctx_params(ossl_unused void *ctx,
return known_settable_ctx_params;
}
+static int kdf_tls1_3_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+ KDF_HKDF *ctx = (KDF_HKDF *)vctx;
+
+ if (params == NULL)
+ return 1;
+
+ if (!hkdf_common_get_ctx_params(ctx, params))
+ return 0;
+
+ if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))
+ return 0;
+
+ return 1;
+}
+
+static const OSSL_PARAM *kdf_tls1_3_gettable_ctx_params(ossl_unused void *ctx,
+ ossl_unused void *provctx)
+{
+ static const OSSL_PARAM known_gettable_ctx_params[] = {
+ HKDF_COMMON_GETTABLES,
+ OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
+ OSSL_PARAM_END
+ };
+ return known_gettable_ctx_params;
+}
+
const OSSL_DISPATCH ossl_kdf_tls1_3_kdf_functions[] = {
{ OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_hkdf_new },
{ OSSL_FUNC_KDF_DUPCTX, (void(*)(void))kdf_hkdf_dup },
@@ -851,7 +875,7 @@ const OSSL_DISPATCH ossl_kdf_tls1_3_kdf_functions[] = {
(void(*)(void))kdf_tls1_3_settable_ctx_params },
{ OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_tls1_3_set_ctx_params },
{ OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
- (void(*)(void))kdf_hkdf_gettable_ctx_params },
- { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_hkdf_get_ctx_params },
+ (void(*)(void))kdf_tls1_3_gettable_ctx_params },
+ { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_tls1_3_get_ctx_params },
OSSL_DISPATCH_END
};
diff --git a/providers/implementations/kdfs/sshkdf.c b/providers/implementations/kdfs/sshkdf.c
index 767066bb2c..d26047bee8 100644
--- a/providers/implementations/kdfs/sshkdf.c
+++ b/providers/implementations/kdfs/sshkdf.c
@@ -127,10 +127,9 @@ static int sshkdf_set_membuf(unsigned char **dst, size_t *dst_len,
}
#ifdef FIPS_MODULE
-static int fips_digest_check_passed(KDF_SSHKDF *ctx)
+static int fips_digest_check_passed(KDF_SSHKDF *ctx, const EVP_MD *md)
{
OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
- const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
/*
* Perform digest check
*
@@ -187,11 +186,6 @@ static int kdf_sshkdf_derive(void *vctx, unsigned char *key, size_t keylen,
return 0;
}
-#ifdef FIPS_MODULE
- if (!fips_digest_check_passed(ctx))
- return 0;
-#endif
-
return SSHKDF(md, ctx->key, ctx->key_len,
ctx->xcghash, ctx->xcghash_len,
ctx->session_id, ctx->session_id_len,
@@ -211,8 +205,23 @@ static int kdf_sshkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
OSSL_KDF_PARAM_FIPS_DIGEST_CHECK))
return 0;
- if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))
- return 0;
+ if (OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST) != NULL) {
+ const EVP_MD *md = NULL;
+
+ if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))
+ return 0;
+
+ md = ossl_prov_digest_md(&ctx->digest);
+ if ((EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF) != 0) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED);
+ return 0;
+ }
+
+#ifdef FIPS_MODULE
+ if (!fips_digest_check_passed(ctx, md))
+ return 0;
+#endif
+ }
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL)
if (!sshkdf_set_membuf(&ctx->key, &ctx->key_len, p))
@@ -376,4 +385,3 @@ out:
OPENSSL_cleanse(digest, EVP_MAX_MD_SIZE);
return ret;
}
-
diff --git a/providers/implementations/kdfs/sskdf.c b/providers/implementations/kdfs/sskdf.c
index f1edcda7ef..c603525e3a 100644
--- a/providers/implementations/kdfs/sskdf.c
+++ b/providers/implementations/kdfs/sskdf.c
@@ -82,11 +82,30 @@ static OSSL_FUNC_kdf_dupctx_fn sskdf_dup;
static OSSL_FUNC_kdf_freectx_fn sskdf_free;
static OSSL_FUNC_kdf_reset_fn sskdf_reset;
static OSSL_FUNC_kdf_derive_fn sskdf_derive;
-static OSSL_FUNC_kdf_derive_fn x963kdf_derive;
static OSSL_FUNC_kdf_settable_ctx_params_fn sskdf_settable_ctx_params;
static OSSL_FUNC_kdf_set_ctx_params_fn sskdf_set_ctx_params;
static OSSL_FUNC_kdf_gettable_ctx_params_fn sskdf_gettable_ctx_params;
static OSSL_FUNC_kdf_get_ctx_params_fn sskdf_get_ctx_params;
+static OSSL_FUNC_kdf_derive_fn x963kdf_derive;
+static OSSL_FUNC_kdf_settable_ctx_params_fn x963kdf_settable_ctx_params;
+static OSSL_FUNC_kdf_set_ctx_params_fn x963kdf_set_ctx_params;
+static OSSL_FUNC_kdf_gettable_ctx_params_fn x963kdf_gettable_ctx_params;
+static OSSL_FUNC_kdf_get_ctx_params_fn x963kdf_get_ctx_params;
+
+/* Settable context parameters that are common across SSKDF and X963 KDF */
+#define SSKDF_COMMON_SETTABLES \
+ OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0), \
+ OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0), \
+ OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0), \
+ OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), \
+ OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0), \
+ OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MAC, NULL, 0), \
+ OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0), \
+ OSSL_PARAM_size_t(OSSL_KDF_PARAM_MAC_SIZE, NULL)
+
+/* Gettable context parameters that are common across SSKDF and X963 KDF */
+#define SSKDF_COMMON_GETTABLES \
+ OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL)
/*
* Refer to https://csrc.nist.gov/publications/detail/sp/800-56c/rev-1/final
@@ -375,35 +394,6 @@ static size_t sskdf_size(KDF_SSKDF *ctx)
return (len <= 0) ? 0 : (size_t)len;
}
-#ifdef FIPS_MODULE
-static int fips_sskdf_digest_check_passed(KDF_SSKDF *ctx)
-{
- OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
- const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
- /*
- * Perform digest check
- *
- * SSKDF is a OneStep KDF defined in SP 800-56Cr2. According to section 7,
- * the valid hash functions are specified in FIPS 180 and FIPS 202.
- * However, it only lists SHA-1, SHA-2 and SHA-3 in the table in section
- * 4.2. ACVP also only lists the same set of hash functions.
- */
- int digest_unapproved = (ctx->is_kmac != 1)
- && (md != NULL)
- && ((EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF) != 0);
-
- if (digest_unapproved) {
- if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
- libctx, "SSKDF", "Digest",
- FIPS_sskdf_digest_check)) {
- ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED);
- return 0;
- }
- }
- return 1;
-}
-#endif
-
static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen,
const OSSL_PARAM params[])
{
@@ -417,11 +407,6 @@ static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen,
return 0;
}
-#ifdef FIPS_MODULE
- if (!fips_sskdf_digest_check_passed(ctx))
- return 0;
-#endif
-
md = ossl_prov_digest_md(&ctx->digest);
if (ctx->macctx != NULL) {
@@ -478,10 +463,9 @@ static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen,
}
#ifdef FIPS_MODULE
-static int fips_x963kdf_digest_check_passed(KDF_SSKDF *ctx)
+static int fips_x963kdf_digest_check_passed(KDF_SSKDF *ctx, const EVP_MD *md)
{
OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
- const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
/*
* Perform digest check
*
@@ -489,9 +473,7 @@ static int fips_x963kdf_digest_check_passed(KDF_SSKDF *ctx)
* section 7.3.1, only SHA-2 and SHA-3 can be regarded as valid hash
* functions.
*/
- int digest_unapproved = (ctx->is_kmac != 1)
- && (((EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF) != 0)
- || EVP_MD_is_a(md, SN_sha1));
+ int digest_unapproved = (ctx->is_kmac != 1) && EVP_MD_is_a(md, SN_sha1);
if (digest_unapproved) {
if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
@@ -511,7 +493,7 @@ static int x963kdf_derive(void *vctx, unsigned char *key, size_t keylen,
KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
const EVP_MD *md;
- if (!ossl_prov_is_running() || !sskdf_set_ctx_params(ctx, params))
+ if (!ossl_prov_is_running() || !x963kdf_set_ctx_params(ctx, params))
return 0;
if (ctx->secret == NULL) {
@@ -531,30 +513,21 @@ static int x963kdf_derive(void *vctx, unsigned char *key, size_t keylen,
return 0;
}
-#ifdef FIPS_MODULE
- if (!fips_x963kdf_digest_check_passed(ctx))
- return 0;
-#endif
-
return SSKDF_hash_kdm(md, ctx->secret, ctx->secret_len,
ctx->info, ctx->info_len, 1, key, keylen);
}
-static int sskdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+static int sskdf_common_set_ctx_params(KDF_SSKDF *ctx, const OSSL_PARAM params[])
{
const OSSL_PARAM *p;
- KDF_SSKDF *ctx = vctx;
OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
+ const EVP_MD *md = NULL;
size_t sz;
int r;
if (params == NULL)
return 1;
- if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,
- OSSL_KDF_PARAM_FIPS_DIGEST_CHECK))
- return 0;
-
if (!ossl_prov_macctx_load_from_params(&ctx->macctx, params,
NULL, NULL, NULL, libctx))
return 0;
@@ -567,8 +540,16 @@ static int sskdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
}
}
- if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx))
- return 0;
+ if (OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST) != NULL) {
+ if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx))
+ return 0;
+
+ md = ossl_prov_digest_md(&ctx->digest);
+ if ((EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF) != 0) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED);
+ return 0;
+ }
+ }
r = ossl_param_get1_octet_string(params, OSSL_KDF_PARAM_SECRET,
&ctx->secret, &ctx->secret_len);
@@ -595,35 +576,54 @@ static int sskdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
return 1;
}
+static int sskdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+ KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
+
+ if (params == NULL)
+ return 1;
+
+ if (!sskdf_common_set_ctx_params(ctx, params))
+ return 0;
+
+ return 1;
+}
+
static const OSSL_PARAM *sskdf_settable_ctx_params(ossl_unused void *ctx,
ossl_unused void *provctx)
{
static const OSSL_PARAM known_settable_ctx_params[] = {
- OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0),
- OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0),
- OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),
- OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
- OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0),
- OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MAC, NULL, 0),
- OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0),
- OSSL_PARAM_size_t(OSSL_KDF_PARAM_MAC_SIZE, NULL),
- OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_DIGEST_CHECK)
+ SSKDF_COMMON_SETTABLES,
OSSL_PARAM_END
};
return known_settable_ctx_params;
}
-static int sskdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
+static int sskdf_common_get_ctx_params(KDF_SSKDF *ctx, OSSL_PARAM params[])
{
- KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
OSSL_PARAM *p;
+ if (params == NULL)
+ return 1;
+
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) {
if (!OSSL_PARAM_set_size_t(p, sskdf_size(ctx)))
return 0;
}
- if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))
+
+ return 1;
+}
+
+static int sskdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+ KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
+
+ if (params == NULL)
+ return 1;
+
+ if (!sskdf_common_get_ctx_params(ctx, params))
return 0;
+
return 1;
}
@@ -631,7 +631,67 @@ static const OSSL_PARAM *sskdf_gettable_ctx_params(ossl_unused void *ctx,
ossl_unused void *provctx)
{
static const OSSL_PARAM known_gettable_ctx_params[] = {
- OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
+ SSKDF_COMMON_GETTABLES,
+ OSSL_PARAM_END
+ };
+ return known_gettable_ctx_params;
+}
+
+static int x963kdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+ KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
+
+ if (params == NULL)
+ return 1;
+
+ if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,
+ OSSL_KDF_PARAM_FIPS_DIGEST_CHECK))
+ return 0;
+
+ if (!sskdf_common_set_ctx_params(ctx, params))
+ return 0;
+
+#ifdef FIPS_MODULE
+ if (OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST) != NULL) {
+ const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
+
+ if (!fips_x963kdf_digest_check_passed(ctx, md))
+ return 0;
+ }
+#endif
+
+ return 1;
+}
+
+static const OSSL_PARAM *x963kdf_settable_ctx_params(ossl_unused void *ctx,
+ ossl_unused void *provctx)
+{
+ static const OSSL_PARAM known_settable_ctx_params[] = {
+ SSKDF_COMMON_SETTABLES,
+ OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_DIGEST_CHECK)
+ OSSL_PARAM_END
+ };
+ return known_settable_ctx_params;
+}
+
+static int x963kdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+ KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
+
+ if (!sskdf_common_get_ctx_params(ctx, params))
+ return 0;
+
+ if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))
+ return 0;
+
+ return 1;
+}
+
+static const OSSL_PARAM *x963kdf_gettable_ctx_params(ossl_unused void *ctx,
+ ossl_unused void *provctx)
+{
+ static const OSSL_PARAM known_gettable_ctx_params[] = {
+ SSKDF_COMMON_GETTABLES,
OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
OSSL_PARAM_END
};
@@ -660,10 +720,10 @@ const OSSL_DISPATCH ossl_kdf_x963_kdf_functions[] = {
{ OSSL_FUNC_KDF_RESET, (void(*)(void))sskdf_reset },
{ OSSL_FUNC_KDF_DERIVE, (void(*)(void))x963kdf_derive },
{ OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
- (void(*)(void))sskdf_settable_ctx_params },
- { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))sskdf_set_ctx_params },
+ (void(*)(void))x963kdf_settable_ctx_params },
+ { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))x963kdf_set_ctx_params },
{ OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
- (void(*)(void))sskdf_gettable_ctx_params },
- { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))sskdf_get_ctx_params },
+ (void(*)(void))x963kdf_gettable_ctx_params },
+ { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))x963kdf_get_ctx_params },
OSSL_DISPATCH_END
};
diff --git a/providers/implementations/kdfs/tls1_prf.c b/providers/implementations/kdfs/tls1_prf.c
index 72af2e329b..620b0c84c3 100644
--- a/providers/implementations/kdfs/tls1_prf.c
+++ b/providers/implementations/kdfs/tls1_prf.c
@@ -109,10 +109,6 @@ typedef struct {
unsigned char *seed;
size_t seedlen;
-#ifdef FIPS_MODULE
- PROV_DIGEST digest;
-#endif
-
OSSL_FIPS_IND_DECLARE
} TLS1_PRF;
@@ -145,9 +141,6 @@ static void kdf_tls1_prf_reset(void *vctx)
TLS1_PRF *ctx = (TLS1_PRF *)vctx;
void *provctx = ctx->provctx;
-#ifdef FIPS_MODULE
- ossl_prov_digest_reset(&ctx->digest);
-#endif
EVP_MAC_CTX_free(ctx->P_hash);
EVP_MAC_CTX_free(ctx->P_sha1);
OPENSSL_clear_free(ctx->sec, ctx->seclen);
@@ -174,10 +167,6 @@ static void *kdf_tls1_prf_dup(void *vctx)
if (!ossl_prov_memdup(src->seed, src->seedlen, &dest->seed,
&dest->seedlen))
goto err;
-#ifdef FIPS_MODULE
- if (!ossl_prov_digest_copy(&dest->digest, &src->digest))
- goto err;
-#endif
OSSL_FIPS_IND_COPY(dest, src)
}
return dest;
@@ -215,10 +204,9 @@ static int fips_ems_check_passed(TLS1_PRF *ctx)
return 1;
}
-static int fips_digest_check_passed(TLS1_PRF *ctx)
+static int fips_digest_check_passed(TLS1_PRF *ctx, const EVP_MD *md)
{
OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
- const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
/*
* Perform digest check
*
@@ -226,8 +214,7 @@ static int fips_digest_check_passed(TLS1_PRF *ctx)
* specified in FIPS 180-3. ACVP also only lists the same set of hash
* functions.
*/
- int digest_unapproved = (md != NULL)
- && !EVP_MD_is_a(md, SN_sha256)
+ int digest_unapproved = !EVP_MD_is_a(md, SN_sha256)
&& !EVP_MD_is_a(md, SN_sha384)
&& !EVP_MD_is_a(md, SN_sha512);
@@ -271,8 +258,6 @@ static int kdf_tls1_prf_derive(void *vctx, unsigned char *key, size_t keylen,
#ifdef FIPS_MODULE
if (!fips_ems_check_passed(ctx))
return 0;
- if (!fips_digest_check_passed(ctx))
- return 0;
#endif
return tls1_prf_alg(ctx->P_hash, ctx->P_sha1,
@@ -298,6 +283,9 @@ static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
return 0;
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_DIGEST)) != NULL) {
+ PROV_DIGEST digest;
+ const EVP_MD *md = NULL;
+
if (OPENSSL_strcasecmp(p->data, SN_md5_sha1) == 0) {
if (!ossl_prov_macctx_load_from_params(&ctx->P_hash, params,
OSSL_MAC_NAME_HMAC,
@@ -314,10 +302,25 @@ static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
return 0;
}
+ memset(&digest, 0, sizeof(digest));
+ if (!ossl_prov_digest_load_from_params(&digest, params, libctx))
+ return 0;
+
+ md = ossl_prov_digest_md(&digest);
+ if ((EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF) != 0) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED);
+ ossl_prov_digest_reset(&digest);
+ return 0;
+ }
+
#ifdef FIPS_MODULE
- if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx))
+ if (!fips_digest_check_passed(ctx, md)) {
+ ossl_prov_digest_reset(&digest);
return 0;
+ }
#endif
+
+ ossl_prov_digest_reset(&digest);
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET)) != NULL) {