diff options
author | pohsingwu <pohsingwu@synology.com> | 2024-07-17 15:19:51 +0800 |
---|---|---|
committer | Pauli <ppzgs1@gmail.com> | 2024-07-24 13:16:08 +1000 |
commit | 14e46600c68ece74970462a60ad20703221747a1 (patch) | |
tree | 3a7a382ffed5d9f235b619119ddfd3f466215586 /providers | |
parent | 5e25b8afc0f964a3f178549d00fbe6a9295188e8 (diff) | |
download | openssl-master.tar.gz |
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.c | 146 | ||||
-rw-r--r-- | providers/implementations/kdfs/sshkdf.c | 28 | ||||
-rw-r--r-- | providers/implementations/kdfs/sskdf.c | 202 | ||||
-rw-r--r-- | providers/implementations/kdfs/tls1_prf.c | 39 |
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) { |