From: Pauli Date: Mon, 5 Aug 2024 06:07:43 +0000 (+1000) Subject: fips: add kbkdf key length check as per SP 800-131a revision 2 X-Git-Tag: openssl-3.4.0-alpha1~183 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ae87c488956c84795fd35cb9cc8024d620cf06c6;p=thirdparty%2Fopenssl.git fips: add kbkdf key length check as per SP 800-131a revision 2 Reviewed-by: Tomas Mraz Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/25095) --- diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index 3ef42796aaf..796ff106498 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -101,6 +101,7 @@ typedef struct fips_global_st { FIPS_OPTION fips_rsa_pkcs15_padding_disabled; FIPS_OPTION fips_rsa_sign_x931_disallowed; FIPS_OPTION fips_hkdf_key_check; + FIPS_OPTION fips_kbkdf_key_check; FIPS_OPTION fips_tls13_kdf_key_check; FIPS_OPTION fips_tls1_prf_key_check; FIPS_OPTION fips_sshkdf_key_check; @@ -137,6 +138,7 @@ void *ossl_fips_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx) init_fips_option(&fgbl->fips_rsa_pkcs15_padding_disabled, 0); init_fips_option(&fgbl->fips_rsa_sign_x931_disallowed, 0); init_fips_option(&fgbl->fips_hkdf_key_check, 0); + init_fips_option(&fgbl->fips_kbkdf_key_check, 0); init_fips_option(&fgbl->fips_tls13_kdf_key_check, 0); init_fips_option(&fgbl->fips_tls1_prf_key_check, 0); init_fips_option(&fgbl->fips_sshkdf_key_check, 0); @@ -206,7 +208,7 @@ static int fips_get_params_from_core(FIPS_GLOBAL *fgbl) * OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS and * OSSL_PROV_FIPS_PARAM_TLS1_PRF_EMS_CHECK are not self test parameters. */ - OSSL_PARAM core_params[29], *p = core_params; + OSSL_PARAM core_params[30], *p = core_params; *p++ = OSSL_PARAM_construct_utf8_ptr( OSSL_PROV_PARAM_CORE_MODULE_FILENAME, @@ -271,6 +273,8 @@ static int fips_get_params_from_core(FIPS_GLOBAL *fgbl) fips_rsa_sign_x931_disallowed); FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_HKDF_KEY_CHECK, fips_hkdf_key_check); + FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_KBKDF_KEY_CHECK, + fips_kbkdf_key_check); FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_TLS13_KDF_KEY_CHECK, fips_tls13_kdf_key_check); FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_TLS1_PRF_KEY_CHECK, @@ -356,6 +360,8 @@ static int fips_get_params(void *provctx, OSSL_PARAM params[]) fips_rsa_sign_x931_disallowed); FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_HKDF_KEY_CHECK, fips_hkdf_key_check); + FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_KBKDF_KEY_CHECK, + fips_kbkdf_key_check); FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_TLS13_KDF_KEY_CHECK, fips_tls13_kdf_key_check); FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_TLS1_PRF_KEY_CHECK, @@ -915,6 +921,7 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle, FIPS_SET_OPTION(fgbl, fips_rsa_pkcs15_padding_disabled); FIPS_SET_OPTION(fgbl, fips_rsa_sign_x931_disallowed); FIPS_SET_OPTION(fgbl, fips_hkdf_key_check); + FIPS_SET_OPTION(fgbl, fips_kbkdf_key_check); FIPS_SET_OPTION(fgbl, fips_tls13_kdf_key_check); FIPS_SET_OPTION(fgbl, fips_tls1_prf_key_check); FIPS_SET_OPTION(fgbl, fips_sshkdf_key_check); @@ -1137,6 +1144,7 @@ FIPS_FEATURE_CHECK(FIPS_rsa_pkcs15_padding_disabled, FIPS_FEATURE_CHECK(FIPS_rsa_sign_x931_disallowed, fips_rsa_sign_x931_disallowed) FIPS_FEATURE_CHECK(FIPS_hkdf_key_check, fips_hkdf_key_check) +FIPS_FEATURE_CHECK(FIPS_kbkdf_key_check, fips_kbkdf_key_check) FIPS_FEATURE_CHECK(FIPS_tls13_kdf_key_check, fips_tls13_kdf_key_check) FIPS_FEATURE_CHECK(FIPS_tls1_prf_key_check, fips_tls1_prf_key_check) FIPS_FEATURE_CHECK(FIPS_sshkdf_key_check, fips_sshkdf_key_check) diff --git a/providers/implementations/kdfs/kbkdf.c b/providers/implementations/kdfs/kbkdf.c index cee68d063d5..4dd8fe6f873 100644 --- a/providers/implementations/kdfs/kbkdf.c +++ b/providers/implementations/kdfs/kbkdf.c @@ -43,6 +43,9 @@ #include "prov/provider_ctx.h" #include "prov/provider_util.h" #include "prov/providercommon.h" +#include "prov/securitycheck.h" +#include "prov/fipscommon.h" +#include "prov/fipsindicator.h" #include "internal/e_os.h" #include "internal/params.h" @@ -73,6 +76,7 @@ typedef struct { int use_l; int is_kmac; int use_separator; + OSSL_FIPS_IND_DECLARE } KBKDF; /* Definitions needed for typechecking. */ @@ -122,6 +126,7 @@ static void *kbkdf_new(void *provctx) return NULL; ctx->provctx = provctx; + OSSL_FIPS_IND_INIT(ctx) init(ctx); return ctx; } @@ -174,6 +179,7 @@ static void *kbkdf_dup(void *vctx) dest->use_l = src->use_l; dest->use_separator = src->use_separator; dest->is_kmac = src->is_kmac; + OSSL_FIPS_IND_COPY(dest, src) } return dest; @@ -182,6 +188,24 @@ static void *kbkdf_dup(void *vctx) return NULL; } +#ifdef FIPS_MODULE +static int fips_kbkdf_key_check_passed(KBKDF *ctx) +{ + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); + int key_approved = ossl_kdf_check_key_size(ctx->ki_len); + + if (!key_approved) { + if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0, + libctx, "KBKDF", "Key size", + FIPS_kbkdf_key_check)) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + return 0; + } + } + return 1; +} +#endif + /* SP800-108 section 5.1 or section 5.2 depending on mode. */ static int derive(EVP_MAC_CTX *ctx_init, kbkdf_mode mode, unsigned char *iv, size_t iv_len, unsigned char *label, size_t label_len, @@ -351,6 +375,10 @@ static int kbkdf_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_KEY_CHECK)) + return 0; + if (!ossl_prov_macctx_load_from_params(&ctx->ctx_init, params, NULL, NULL, NULL, libctx)) return 0; @@ -382,9 +410,16 @@ static int kbkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 0; } - if (ossl_param_get1_octet_string(params, OSSL_KDF_PARAM_KEY, - &ctx->ki, &ctx->ki_len) == 0) + p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY); + if (p != NULL) { + if (ossl_param_get1_octet_string(p, OSSL_KDF_PARAM_KEY, + &ctx->ki, &ctx->ki_len) == 0) + return 0; +#ifdef FIPS_MODULE + if (!fips_kbkdf_key_check_passed(ctx)) return 0; +#endif + } if (ossl_param_get1_octet_string(params, OSSL_KDF_PARAM_SALT, &ctx->label, &ctx->label_len) == 0) @@ -443,6 +478,7 @@ static const OSSL_PARAM *kbkdf_settable_ctx_params(ossl_unused void *ctx, OSSL_PARAM_int(OSSL_KDF_PARAM_KBKDF_USE_L, NULL), OSSL_PARAM_int(OSSL_KDF_PARAM_KBKDF_USE_SEPARATOR, NULL), OSSL_PARAM_int(OSSL_KDF_PARAM_KBKDF_R, NULL), + OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_KEY_CHECK) OSSL_PARAM_END, }; return known_settable_ctx_params; @@ -450,21 +486,28 @@ static const OSSL_PARAM *kbkdf_settable_ctx_params(ossl_unused void *ctx, static int kbkdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) { +#ifdef FIPS_MODULE + KBKDF *ctx = (KBKDF *)vctx; +#endif OSSL_PARAM *p; + /* KBKDF can produce results as large as you like. */ p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE); - if (p == NULL) - return -2; + if (p != NULL && !OSSL_PARAM_set_size_t(p, SIZE_MAX)) + return 0; - /* KBKDF can produce results as large as you like. */ - return OSSL_PARAM_set_size_t(p, SIZE_MAX); + if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params)) + return 0; + return 1; } static const OSSL_PARAM *kbkdf_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_END + OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), + OSSL_FIPS_IND_GETTABLE_CTX_PARAM() + OSSL_PARAM_END }; return known_gettable_ctx_params; }