summaryrefslogtreecommitdiff
path: root/providers
diff options
context:
space:
mode:
authorPauli <pauli@openssl.org>2023-03-16 14:12:09 +1100
committerPauli <pauli@openssl.org>2023-03-29 09:25:19 +1100
commitf553c0f0dd24f037f31d971a99a1ffe7a11f64e6 (patch)
tree1bbc151f1e2e9f56177a7999c65f99b63adee8e7 /providers
parent83ccf81b1dd8886d54c570354ef8c532af4c514f (diff)
downloadopenssl-new-f553c0f0dd24f037f31d971a99a1ffe7a11f64e6.tar.gz
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 <tomas@openssl.org> Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from https://github.com/openssl/openssl/pull/20521)
Diffstat (limited to 'providers')
-rw-r--r--providers/implementations/rands/drbg.c29
-rw-r--r--providers/implementations/rands/drbg_hash.c6
-rw-r--r--providers/implementations/rands/drbg_hmac.c13
-rw-r--r--providers/implementations/rands/drbg_local.h3
4 files changed, 37 insertions, 14 deletions
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