From f553c0f0dd24f037f31d971a99a1ffe7a11f64e6 Mon Sep 17 00:00:00 2001 From: Pauli Date: Thu, 16 Mar 2023 14:12:09 +1100 Subject: DRBG: restrict the digests that can be used with HMAC and Hash DRBGs. According to FIP 140-3 IG D.R: https://csrc.nist.gov/CSRC/media/Projects/cryptographic-module-validation-program/documents/fips%20140-3/FIPS%20140-3%20IG.pdf Outside of FIPS, there remains no restriction other than not allowing XOF digests. Reviewed-by: Tomas Mraz Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/20521) --- providers/implementations/rands/drbg.c | 29 ++++++++++++++++++++++++++++ providers/implementations/rands/drbg_hash.c | 6 ++---- providers/implementations/rands/drbg_hmac.c | 13 +++---------- providers/implementations/rands/drbg_local.h | 3 +++ 4 files changed, 37 insertions(+), 14 deletions(-) (limited to 'providers') diff --git a/providers/implementations/rands/drbg.c b/providers/implementations/rands/drbg.c index de9b2a5a44..cae7718b84 100644 --- a/providers/implementations/rands/drbg.c +++ b/providers/implementations/rands/drbg.c @@ -922,3 +922,32 @@ int ossl_drbg_set_ctx_params(PROV_DRBG *drbg, const OSSL_PARAM params[]) return 0; return 1; } + +/* Confirm digest is allowed to be used with a DRBG */ +int ossl_drbg_verify_digest(ossl_unused OSSL_LIB_CTX *libctx, const EVP_MD *md) +{ +#ifdef FIPS_MODULE + /* FIPS 140-3 IG D.R limited DRBG digests to a specific set */ + static const char *const allowed_digests[] = { + "SHA1", /* SHA 1 allowed */ + "SHA2-256", "SHA2-512", /* non-truncated SHA2 allowed */ + "SHA3-256", "SHA3-512", /* non-truncated SHA3 allowed */ + }; + size_t i; + extern int FIPS_restricted_drbg_digests_enabled(OSSL_LIB_CTX *libctx); + + if (FIPS_restricted_drbg_digests_enabled(libctx)) { + for (i = 0; i < OSSL_NELEM(allowed_digests); i++) + if (EVP_MD_is_a(md, allowed_digests[i])) + return 1; + ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED); + return 0; + } +#endif + /* Outside of FIPS, any digests that are not XOF are allowed */ + if ((EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF) != 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED); + return 0; + } + return 1; +} diff --git a/providers/implementations/rands/drbg_hash.c b/providers/implementations/rands/drbg_hash.c index 12faa993d0..0761b403da 100644 --- a/providers/implementations/rands/drbg_hash.c +++ b/providers/implementations/rands/drbg_hash.c @@ -466,10 +466,8 @@ static int drbg_hash_set_ctx_params(void *vctx, const OSSL_PARAM params[]) md = ossl_prov_digest_md(&hash->digest); if (md != NULL) { - 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 (!ossl_drbg_verify_digest(libctx, md)) + return 0; /* Error already raised for us */ /* These are taken from SP 800-90 10.1 Table 2 */ hash->blocklen = EVP_MD_get_size(md); diff --git a/providers/implementations/rands/drbg_hmac.c b/providers/implementations/rands/drbg_hmac.c index 44241223a6..f4b31a0f1b 100644 --- a/providers/implementations/rands/drbg_hmac.c +++ b/providers/implementations/rands/drbg_hmac.c @@ -366,22 +366,15 @@ static int drbg_hmac_set_ctx_params(void *vctx, const OSSL_PARAM params[]) if (!ossl_prov_digest_load_from_params(&hmac->digest, params, libctx)) return 0; - /* - * Confirm digest is allowed. We allow all digests that are not XOF - * (such as SHAKE). In FIPS mode, the fetch will fail for non-approved - * digests. - */ md = ossl_prov_digest_md(&hmac->digest); - if (md != NULL && (EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF) != 0) { - ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED); - return 0; - } + if (md != NULL && !ossl_drbg_verify_digest(libctx, md)) + return 0; /* Error already raised for us */ if (!ossl_prov_macctx_load_from_params(&hmac->ctx, params, NULL, NULL, NULL, libctx)) return 0; - if (hmac->ctx != NULL) { + if (md != NULL && hmac->ctx != NULL) { /* These are taken from SP 800-90 10.1 Table 2 */ hmac->blocklen = EVP_MD_get_size(md); /* See SP800-57 Part1 Rev4 5.6.1 Table 3 */ diff --git a/providers/implementations/rands/drbg_local.h b/providers/implementations/rands/drbg_local.h index d3b439d13e..776b44882c 100644 --- a/providers/implementations/rands/drbg_local.h +++ b/providers/implementations/rands/drbg_local.h @@ -251,4 +251,7 @@ size_t ossl_crngt_get_entropy(PROV_DRBG *drbg, void ossl_crngt_cleanup_entropy(PROV_DRBG *drbg, unsigned char *out, size_t outlen); +/* Confirm digest is allowed to be used with a DRBG */ +int ossl_drbg_verify_digest(ossl_unused OSSL_LIB_CTX *libctx, const EVP_MD *md); + #endif -- cgit v1.2.1