Restrict digest algorithm used in KDFs

Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23889)
This commit is contained in:
pohsingwu 2024-06-02 19:32:59 +08:00 committed by Pauli
parent 4f619ca622
commit 6d47e819f2
26 changed files with 686 additions and 42 deletions

View File

@ -40,6 +40,12 @@ typedef enum OPTION_choice {
OPT_NO_SECURITY_CHECKS,
OPT_TLS_PRF_EMS_CHECK,
OPT_DISALLOW_DRGB_TRUNC_DIGEST,
OPT_HKDF_DIGEST_CHECK,
OPT_TLS13_KDF_DIGEST_CHECK,
OPT_TLS1_PRF_DIGEST_CHECK,
OPT_SSHKDF_DIGEST_CHECK,
OPT_SSKDF_DIGEST_CHECK,
OPT_X963KDF_DIGEST_CHECK,
OPT_SELF_TEST_ONLOAD, OPT_SELF_TEST_ONINSTALL
} OPTION_CHOICE;
@ -66,6 +72,18 @@ const OPTIONS fipsinstall_options[] = {
"Enable the run-time FIPS check for EMS during TLS1_PRF"},
{"no_drbg_truncated_digests", OPT_DISALLOW_DRGB_TRUNC_DIGEST, '-',
"Disallow truncated digests with Hash and HMAC DRBGs"},
{"hkdf_digest_check", OPT_HKDF_DIGEST_CHECK, '-',
"Enable digest check for HKDF"},
{"tls13_kdf_digest_check", OPT_TLS13_KDF_DIGEST_CHECK, '-',
"Enable digest check for TLS13-KDF"},
{"tls1_prf_digest_check", OPT_TLS1_PRF_DIGEST_CHECK, '-',
"Enable digest check for TLS1-PRF"},
{"sshkdf_digest_check", OPT_SSHKDF_DIGEST_CHECK, '-',
"Enable digest check for SSHKDF"},
{"sskdf_digest_check", OPT_SSKDF_DIGEST_CHECK, '-',
"Enable digest check for SSKDF"},
{"x963kdf_digest_check", OPT_X963KDF_DIGEST_CHECK, '-',
"Enable digest check for X963KDF"},
OPT_SECTION("Input"),
{"in", OPT_IN, '<', "Input config file, used when verifying"},
@ -88,6 +106,12 @@ typedef struct {
unsigned int security_checks : 1;
unsigned int tls_prf_ems_check : 1;
unsigned int drgb_no_trunc_dgst : 1;
unsigned int hkdf_digest_check : 1;
unsigned int tls13_kdf_digest_check : 1;
unsigned int tls1_prf_digest_check : 1;
unsigned int sshkdf_digest_check : 1;
unsigned int sskdf_digest_check : 1;
unsigned int x963kdf_digest_check : 1;
} FIPS_OPTS;
/* Pedantic FIPS compliance */
@ -97,6 +121,12 @@ static const FIPS_OPTS pedantic_opts = {
1, /* security_checks */
1, /* tls_prf_ems_check */
1, /* drgb_no_trunc_dgst */
1, /* hkdf_digest_check */
1, /* tls13_kdf_digest_check */
1, /* tls1_prf_digest_check */
1, /* sshkdf_digest_check */
1, /* sskdf_digest_check */
1, /* x963kdf_digest_check */
};
/* Default FIPS settings for backward compatibility */
@ -106,6 +136,12 @@ static FIPS_OPTS fips_opts = {
1, /* security_checks */
0, /* tls_prf_ems_check */
0, /* drgb_no_trunc_dgst */
0, /* hkdf_digest_check */
0, /* tls13_kdf_digest_check */
0, /* tls1_prf_digest_check */
0, /* sshkdf_digest_check */
0, /* sskdf_digest_check */
0, /* x963kdf_digest_check */
};
static int check_non_pedantic_fips(int pedantic, const char *name)
@ -229,6 +265,22 @@ static int write_config_fips_section(BIO *out, const char *section,
opts->tls_prf_ems_check ? "1" : "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_DRBG_TRUNC_DIGEST,
opts->drgb_no_trunc_dgst ? "1" : "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_HKDF_DIGEST_CHECK,
opts->hkdf_digest_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n",
OSSL_PROV_FIPS_PARAM_TLS13_KDF_DIGEST_CHECK,
opts->tls13_kdf_digest_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n",
OSSL_PROV_FIPS_PARAM_TLS1_PRF_DIGEST_CHECK,
opts->tls1_prf_digest_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n",
OSSL_PROV_FIPS_PARAM_SSHKDF_DIGEST_CHECK,
opts->sshkdf_digest_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_SSKDF_DIGEST_CHECK,
opts->sskdf_digest_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n",
OSSL_PROV_FIPS_PARAM_X963KDF_DIGEST_CHECK,
opts->x963kdf_digest_check ? "1": "0") <= 0
|| !print_mac(out, OSSL_PROV_FIPS_PARAM_MODULE_MAC, module_mac,
module_mac_len))
goto end;
@ -415,6 +467,24 @@ opthelp:
case OPT_DISALLOW_DRGB_TRUNC_DIGEST:
fips_opts.drgb_no_trunc_dgst = 1;
break;
case OPT_HKDF_DIGEST_CHECK:
fips_opts.hkdf_digest_check = 1;
break;
case OPT_TLS13_KDF_DIGEST_CHECK:
fips_opts.tls13_kdf_digest_check = 1;
break;
case OPT_TLS1_PRF_DIGEST_CHECK:
fips_opts.tls1_prf_digest_check = 1;
break;
case OPT_SSHKDF_DIGEST_CHECK:
fips_opts.sshkdf_digest_check = 1;
break;
case OPT_SSKDF_DIGEST_CHECK:
fips_opts.sskdf_digest_check = 1;
break;
case OPT_X963KDF_DIGEST_CHECK:
fips_opts.x963kdf_digest_check = 1;
break;
case OPT_QUIET:
quiet = 1;
/* FALLTHROUGH */

View File

@ -24,6 +24,12 @@ B<openssl fipsinstall>
[B<-no_security_checks>]
[B<-ems_check>]
[B<-no_drbg_truncated_digests>]
[B<-hkdf_digest_check>]
[B<-tls13_kdf_digest_check>]
[B<-tls1_prf_digest_check>]
[B<-sshkdf_digest_check>]
[B<-sskdf_digest_check>]
[B<-x963kdf_digest_check>]
[B<-self_test_onload>]
[B<-self_test_oninstall>]
[B<-corrupt_desc> I<selftest_description>]
@ -190,6 +196,42 @@ See RFC 7627 for information related to EMS.
Configure the module to not allow truncated digests to be used with Hash and
HMAC DRBGs. See FIPS 140-3 IG D.R for details.
=item B<-hkdf_digest_check>
Configure the module to enable a run-time digest check when deriving a key by
HKDF.
See NIST SP 800-56Cr2 for details.
=item B<-tls13_kdf_digest_check>
Configure the module to enable a run-time digest check when deriving a key by
TLS13 KDF.
See RFC 8446 for details.
=item B<-tls1_prf_digest_check>
Configure the module to enable a run-time digest check when deriving a key by
TLS_PRF.
See NIST SP 800-135r1 for details.
=item B<-sshkdf_digest_check>
Configure the module to enable a run-time digest check when deriving a key by
SSHKDF.
See NIST SP 800-135r1 for details.
=item B<-sskdf_digest_check>
Configure the module to enable a run-time digest check when deriving a key by
SSKDF.
See NIST SP 800-56Cr2 for details.
=item B<-x963kdf_digest_check>
Configure the module to enable a run-time digest check when deriving a key by
X963KDF.
See NIST SP 800-131Ar2 for details.
=item B<-self_test_onload>
Do not write the two fields related to the "test status indicator" and

View File

@ -61,6 +61,22 @@ This parameter set the shared secret that is used for key derivation.
This parameter sets an optional value for fixedinfo, also known as otherinfo.
=item "fips-indicator" (B<OSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR>) <int>
A getter that returns 1 if the operation is FIPS approved, or 0 otherwise.
This may be used after calling EVP_KDF_derive. It returns 0 if any "***_check"
related parameter is set to 0 and the check fails.
This option is used by the OpenSSL FIPS provider.
=item "digest-check" (B<OSSL_KDF_PARAM_FIPS_DIGEST_CHECK>) <int>
The default value of 1 causes an error during EVP_KDF_derive() if
used digest is not approved.
Setting this to zero will ignore the error and set the approved
"fips-indicator" to 0.
This option is used by the OpenSSL FIPS provider, and breaks FIPS compliance if
set to 0.
=back
=head1 NOTES

View File

@ -80,6 +80,25 @@ A single char of value 70 (ASCII char 'F').
=back
=item "fips-indicator" (B<OSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR>) <int>
A getter that returns 1 if the operation is FIPS approved, or 0 otherwise.
This may be used after calling EVP_KDF_derive. It returns 0 if any "***_check"
related parameter is set to 0 and the check fails.
This option is used by the OpenSSL FIPS provider.
=item "digest-check" (B<OSSL_KDF_PARAM_FIPS_DIGEST_CHECK>) <int>
The default value of 1 causes an error during EVP_KDF_derive() if
used digest is not approved.
Setting this to zero will ignore the error and set the approved
"fips-indicator" to 0.
This option is used by the OpenSSL FIPS provider, and breaks FIPS compliance if
set to 0.
According to SP 800-135r1, the following are approved digest algorithms: SHA-1,
SHA2-224, SHA2-256, SHA2-384, SHA2-512.
=back
=head1 NOTES

View File

@ -54,6 +54,25 @@ Refer to RFC 8446 section 7.1 "Key Schedule" for details.
This parameter sets the mode for the TLS 1.3 KDF operation.
There are two modes that are currently defined:
=item "fips-indicator" (B<OSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR>) <int>
A getter that returns 1 if the operation is FIPS approved, or 0 otherwise.
This may be used after calling EVP_KDF_derive. It returns 0 if any "***_check"
related parameter is set to 0 and the check fails.
This option is used by the OpenSSL FIPS provider.
=item "digest-check" (B<OSSL_KDF_PARAM_FIPS_DIGEST_CHECK>) <int>
The default value of 1 causes an error during EVP_KDF_derive() if
used digest is not approved.
Setting this to zero will ignore the error and set the approved
"fips-indicator" to 0.
This option is used by the OpenSSL FIPS provider, and breaks FIPS compliance if
set to 0.
According to RFC 8446, the following are approved digest algorithms: SHA2-256,
SHA2-384.
=over 4
=item "EXTRACT_ONLY" or B<EVP_KDF_HKDF_MODE_EXTRACT_ONLY>

View File

@ -47,8 +47,8 @@ this should be more than enough for any normal use of the TLS PRF.
=item "fips-indicator" (B<OSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR>) <integer>
A getter that returns 1 if the operation is FIPS approved, or 0 otherwise.
This may be used after calling EVP_KDF_derive. It returns 0 if the "ems_check"
is set to 0 and the "extended master secret" test fails.
This may be used after calling EVP_KDF_derive. It returns 0 if any "***_check"
related parameter is set to 0 and the check fails.
This option is used by the OpenSSL FIPS provider.
=item "ems_check" (B<OSSL_KDF_PARAM_FIPS_EMS_CHECK>) <integer>
@ -59,6 +59,17 @@ will ignore the error and set the approved "fips-indicator" to 0.
This option is used by the OpenSSL FIPS provider, and breaks FIPS compliance if
set to 0.
=item "digest-check" (B<OSSL_KDF_PARAM_FIPS_DIGEST_CHECK>) <int>
The default value of 1 causes an error during EVP_KDF_derive() if
used digest is not approved.
Setting this to zero will ignore the error and set the approved
"fips-indicator" to 0.
This option is used by the OpenSSL FIPS provider, and breaks FIPS compliance if
set to 0.
According to SP 800-135r1, the following are approved digest algorithms:
SHA2-256, SHA2-384, SHA2-512.
=back

View File

@ -36,6 +36,26 @@ This parameter sets the secret.
This parameter specifies an optional value for shared info.
=item "fips-indicator" (B<OSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR>) <int>
A getter that returns 1 if the operation is FIPS approved, or 0 otherwise.
This may be used after calling EVP_KDF_derive. It returns 0 if any "***_check"
related parameter is set to 0 and the check fails.
This option is used by the OpenSSL FIPS provider.
=item "digest-check" (B<OSSL_KDF_PARAM_FIPS_DIGEST_CHECK>) <int>
The default value of 1 causes an error during EVP_KDF_derive() if
used digest is not approved.
Setting this to zero will ignore the error and set the approved
"fips-indicator" to 0.
This option is used by the OpenSSL FIPS provider, and breaks FIPS compliance if
set to 0.
According to ANSI X9.63-2001, the following are approved digest algorithms:
SHA2-224, SHA2-256, SHA2-384, SHA2-512, SHA2-512/224, SHA2-512/256, SHA3-224,
SHA3-256, SHA3-384, SHA3-512.
=back
=head1 NOTES

View File

@ -68,7 +68,55 @@ extern "C" {
* This is disabled by default.
* Type: OSSL_PARAM_UTF8_STRING
*/
# define OSSL_PROV_FIPS_PARAM_DRBG_TRUNC_DIGEST "drbg-no-trunc-md"
# define OSSL_PROV_FIPS_PARAM_DRBG_TRUNC_DIGEST "drbg-no-trunc-md"
/*
* A boolean that determines if the runtime FIPS digest check for HKDF is
* performed.
* This is disabled by default.
* Type: OSSL_PARAM_UTF8_STRING
*/
# define OSSL_PROV_FIPS_PARAM_HKDF_DIGEST_CHECK "hkdf-digest-check"
/*
* A boolean that determines if the runtime FIPS digest check for TLS13 KDF is
* performed.
* This is disabled by default.
* Type: OSSL_PARAM_UTF8_STRING
*/
# define OSSL_PROV_FIPS_PARAM_TLS13_KDF_DIGEST_CHECK "tls13-kdf-digest-check"
/*
* A boolean that determines if the runtime FIPS digest check for TLS1_PRF is
* performed.
* This is disabled by default.
* Type: OSSL_PARAM_UTF8_STRING
*/
# define OSSL_PROV_FIPS_PARAM_TLS1_PRF_DIGEST_CHECK "tls1-prf-digest-check"
/*
* A boolean that determines if the runtime FIPS digest check for SSHKDF is
* performed.
* This is disabled by default.
* Type: OSSL_PARAM_UTF8_STRING
*/
# define OSSL_PROV_FIPS_PARAM_SSHKDF_DIGEST_CHECK "sshkdf-digest-check"
/*
* A boolean that determines if the runtime FIPS digest check for SSKDF is
* performed.
* This is disabled by default.
* Type: OSSL_PARAM_UTF8_STRING
*/
# define OSSL_PROV_FIPS_PARAM_SSKDF_DIGEST_CHECK "sskdf-digest-check"
/*
* A boolean that determines if the runtime FIPS digest check for X963KDF is
* performed.
* This is disabled by default.
* Type: OSSL_PARAM_UTF8_STRING
*/
# define OSSL_PROV_FIPS_PARAM_X963KDF_DIGEST_CHECK "x963kdf-digest-check"
# ifdef __cplusplus
}

View File

@ -13,5 +13,11 @@
int FIPS_security_check_enabled(OSSL_LIB_CTX *libctx);
int FIPS_tls_prf_ems_check(OSSL_LIB_CTX *libctx);
int FIPS_restricted_drbg_digests_enabled(OSSL_LIB_CTX *libctx);
int FIPS_hkdf_digest_check(OSSL_LIB_CTX *libctx);
int FIPS_tls13_kdf_digest_check(OSSL_LIB_CTX *libctx);
int FIPS_tls1_prf_digest_check(OSSL_LIB_CTX *libctx);
int FIPS_sshkdf_digest_check(OSSL_LIB_CTX *libctx);
int FIPS_sskdf_digest_check(OSSL_LIB_CTX *libctx);
int FIPS_x963kdf_digest_check(OSSL_LIB_CTX *libctx);
#endif

View File

@ -19,8 +19,13 @@ int ossl_ec_check_curve_allowed(const EC_GROUP *group);
int ossl_ec_check_security_strength(const EC_GROUP *group, int protect);
#endif
#ifndef OPENSSL_NO_DSA
int ossl_dsa_check_key(const DSA *dsa, int sign);
#endif
#ifndef OPENSSL_NO_DH
int ossl_dh_check_key(const DH *dh);
#endif
int ossl_digest_md_to_nid(const EVP_MD *md, const OSSL_ITEM *it, size_t it_len);
int ossl_digest_get_approved_nid(const EVP_MD *md);
@ -28,4 +33,3 @@ int ossl_digest_get_approved_nid(const EVP_MD *md);
/* Functions that have different implementations for the FIPS_MODULE */
int ossl_digest_rsa_sign_get_md_nid(const EVP_MD *md);
int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx);
int ossl_tls1_prf_ems_check_enabled(OSSL_LIB_CTX *libctx);

View File

@ -22,12 +22,6 @@ int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx)
return 0;
}
/* Disable the ems check in the default provider */
int ossl_tls1_prf_ems_check_enabled(OSSL_LIB_CTX *libctx)
{
return 0;
}
int ossl_digest_rsa_sign_get_md_nid(const EVP_MD *md)
{
int mdnid;

View File

@ -30,11 +30,6 @@ int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx)
#endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */
}
int ossl_tls1_prf_ems_check_enabled(OSSL_LIB_CTX *libctx)
{
return FIPS_tls_prf_ems_check(libctx);
}
int ossl_digest_rsa_sign_get_md_nid(const EVP_MD *md)
{
return ossl_digest_get_approved_nid(md);

View File

@ -91,6 +91,12 @@ typedef struct fips_global_st {
FIPS_OPTION fips_security_checks;
FIPS_OPTION fips_tls1_prf_ems_check;
FIPS_OPTION fips_restricted_drgb_digests;
FIPS_OPTION fips_hkdf_digest_check;
FIPS_OPTION fips_tls13_kdf_digest_check;
FIPS_OPTION fips_tls1_prf_digest_check;
FIPS_OPTION fips_sshkdf_digest_check;
FIPS_OPTION fips_sskdf_digest_check;
FIPS_OPTION fips_x963kdf_digest_check;
} FIPS_GLOBAL;
static void init_fips_option(FIPS_OPTION *opt, int enabled)
@ -108,6 +114,12 @@ void *ossl_fips_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx)
init_fips_option(&fgbl->fips_security_checks, 1);
init_fips_option(&fgbl->fips_tls1_prf_ems_check, 0); /* Disabled by default */
init_fips_option(&fgbl->fips_restricted_drgb_digests, 0);
init_fips_option(&fgbl->fips_hkdf_digest_check, 0);
init_fips_option(&fgbl->fips_tls13_kdf_digest_check, 0);
init_fips_option(&fgbl->fips_tls1_prf_digest_check, 0);
init_fips_option(&fgbl->fips_sshkdf_digest_check, 0);
init_fips_option(&fgbl->fips_sskdf_digest_check, 0);
init_fips_option(&fgbl->fips_x963kdf_digest_check, 0);
return fgbl;
}
@ -125,6 +137,18 @@ static const OSSL_PARAM fips_param_types[] = {
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_SECURITY_CHECKS, OSSL_PARAM_INTEGER, NULL, 0),
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK, OSSL_PARAM_INTEGER, NULL, 0),
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_DRBG_TRUNC_DIGEST, OSSL_PARAM_INTEGER, NULL, 0),
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_HKDF_DIGEST_CHECK, OSSL_PARAM_INTEGER, NULL,
0),
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_TLS13_KDF_DIGEST_CHECK, OSSL_PARAM_INTEGER,
NULL, 0),
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_TLS1_PRF_DIGEST_CHECK, OSSL_PARAM_INTEGER,
NULL, 0),
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_SSHKDF_DIGEST_CHECK, OSSL_PARAM_INTEGER,
NULL, 0),
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_SSKDF_DIGEST_CHECK, OSSL_PARAM_INTEGER,
NULL, 0),
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_X963KDF_DIGEST_CHECK, OSSL_PARAM_INTEGER,
NULL, 0),
OSSL_PARAM_END
};
@ -138,7 +162,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[10], *p = core_params;
OSSL_PARAM core_params[16], *p = core_params;
*p++ = OSSL_PARAM_construct_utf8_ptr(
OSSL_PROV_PARAM_CORE_MODULE_FILENAME,
@ -177,6 +201,18 @@ static int fips_get_params_from_core(FIPS_GLOBAL *fgbl)
fips_tls1_prf_ems_check);
FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_DRBG_TRUNC_DIGEST,
fips_restricted_drgb_digests);
FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_HKDF_DIGEST_CHECK,
fips_hkdf_digest_check);
FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_TLS13_KDF_DIGEST_CHECK,
fips_tls13_kdf_digest_check);
FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_TLS1_PRF_DIGEST_CHECK,
fips_tls1_prf_digest_check);
FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_SSHKDF_DIGEST_CHECK,
fips_sshkdf_digest_check);
FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_SSKDF_DIGEST_CHECK,
fips_sskdf_digest_check);
FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_X963KDF_DIGEST_CHECK,
fips_x963kdf_digest_check);
#undef FIPS_FEATURE_OPTION
*p = OSSL_PARAM_construct_end();
@ -224,6 +260,18 @@ static int fips_get_params(void *provctx, OSSL_PARAM params[])
fips_tls1_prf_ems_check);
FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_DRBG_TRUNC_DIGEST,
fips_restricted_drgb_digests);
FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_HKDF_DIGEST_CHECK,
fips_hkdf_digest_check);
FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_TLS13_KDF_DIGEST_CHECK,
fips_tls13_kdf_digest_check);
FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_TLS1_PRF_DIGEST_CHECK,
fips_tls1_prf_digest_check);
FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_SSHKDF_DIGEST_CHECK,
fips_sshkdf_digest_check);
FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_SSKDF_DIGEST_CHECK,
fips_sskdf_digest_check);
FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_X963KDF_DIGEST_CHECK,
fips_x963kdf_digest_check);
#undef FIPS_FEATURE_GET
return 1;
}
@ -758,6 +806,12 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle,
FIPS_SET_OPTION(fgbl, fips_security_checks);
FIPS_SET_OPTION(fgbl, fips_tls1_prf_ems_check);
FIPS_SET_OPTION(fgbl, fips_restricted_drgb_digests);
FIPS_SET_OPTION(fgbl, fips_hkdf_digest_check);
FIPS_SET_OPTION(fgbl, fips_tls13_kdf_digest_check);
FIPS_SET_OPTION(fgbl, fips_tls1_prf_digest_check);
FIPS_SET_OPTION(fgbl, fips_sshkdf_digest_check);
FIPS_SET_OPTION(fgbl, fips_sskdf_digest_check);
FIPS_SET_OPTION(fgbl, fips_x963kdf_digest_check);
#undef FIPS_SET_OPTION
ossl_prov_cache_exported_algorithms(fips_ciphers, exported_fips_ciphers);
@ -959,6 +1013,12 @@ FIPS_FEATURE_CHECK(FIPS_security_check_enabled, fips_security_checks)
FIPS_FEATURE_CHECK(FIPS_tls_prf_ems_check, fips_tls1_prf_ems_check)
FIPS_FEATURE_CHECK(FIPS_restricted_drbg_digests_enabled,
fips_restricted_drgb_digests)
FIPS_FEATURE_CHECK(FIPS_hkdf_digest_check, fips_hkdf_digest_check)
FIPS_FEATURE_CHECK(FIPS_tls13_kdf_digest_check, fips_tls13_kdf_digest_check)
FIPS_FEATURE_CHECK(FIPS_tls1_prf_digest_check, fips_tls1_prf_digest_check)
FIPS_FEATURE_CHECK(FIPS_sshkdf_digest_check, fips_sshkdf_digest_check)
FIPS_FEATURE_CHECK(FIPS_sskdf_digest_check, fips_sskdf_digest_check)
FIPS_FEATURE_CHECK(FIPS_x963kdf_digest_check, fips_x963kdf_digest_check)
#undef FIPS_FEATURE_CHECK

View File

@ -29,6 +29,9 @@
#include "prov/providercommon.h"
#include "prov/implementations.h"
#include "prov/provider_util.h"
#include "prov/securitycheck.h"
#include "prov/fipscommon.h"
#include "prov/fipsindicator.h"
#include "internal/e_os.h"
#include "internal/params.h"
@ -87,6 +90,7 @@ typedef struct {
size_t data_len;
unsigned char *info;
size_t info_len;
OSSL_FIPS_IND_DECLARE
} KDF_HKDF;
static void *kdf_hkdf_new(void *provctx)
@ -96,8 +100,10 @@ static void *kdf_hkdf_new(void *provctx)
if (!ossl_prov_is_running())
return NULL;
if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) != NULL)
if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) != NULL) {
ctx->provctx = provctx;
OSSL_FIPS_IND_INIT(ctx)
}
return ctx;
}
@ -153,6 +159,7 @@ static void *kdf_hkdf_dup(void *vctx)
|| !ossl_prov_digest_copy(&dest->digest, &src->digest))
goto err;
dest->mode = src->mode;
OSSL_FIPS_IND_COPY(dest, src)
}
return dest;
@ -180,6 +187,33 @@ 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[])
{
@ -204,6 +238,11 @@ 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:
@ -286,6 +325,10 @@ 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;
@ -303,6 +346,7 @@ 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;
@ -318,16 +362,18 @@ static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
if (sz == 0)
return 0;
return OSSL_PARAM_set_size_t(p, sz);
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) {
if (ctx->info == NULL || ctx->info_len == 0)
p->return_size = 0;
return 1;
}
return OSSL_PARAM_set_octet_string(p, ctx->info, ctx->info_len);
else if (!OSSL_PARAM_set_octet_string(p, ctx->info, ctx->info_len))
return 0;
}
return -2;
if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))
return 0;
return 1;
}
static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(ossl_unused void *ctx,
@ -336,6 +382,7 @@ static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(ossl_unused void *ctx,
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()
OSSL_PARAM_END
};
return known_gettable_ctx_params;
@ -666,6 +713,33 @@ static int prov_tls13_hkdf_generate_secret(OSSL_LIB_CTX *libctx,
return ret;
}
#ifdef FIPS_MODULE
static int fips_tls1_3_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
*
* According to RFC 8446 appendix B.4, the valid hash functions are
* specified in FIPS 180-4. However, it only lists SHA2-256 and SHA2-384 in
* the table. ACVP also only lists the same set of hash functions.
*/
int digest_unapproved = !EVP_MD_is_a(md, SN_sha256)
&& !EVP_MD_is_a(md, SN_sha384);
if (digest_unapproved) {
if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
libctx, "TLS13 KDF", "Digest",
FIPS_tls13_kdf_digest_check)) {
ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED);
return 0;
}
}
return 1;
}
#endif
static int kdf_tls1_3_derive(void *vctx, unsigned char *key, size_t keylen,
const OSSL_PARAM params[])
{
@ -681,6 +755,11 @@ 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;
@ -711,6 +790,10 @@ static int kdf_tls1_3_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;
@ -752,6 +835,7 @@ static const OSSL_PARAM *kdf_tls1_3_settable_ctx_params(ossl_unused void *ctx,
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PREFIX, NULL, 0),
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_LABEL, NULL, 0),
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_DATA, NULL, 0),
OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_DIGEST_CHECK)
OSSL_PARAM_END
};
return known_settable_ctx_params;

View File

@ -21,6 +21,9 @@
#include "prov/providercommon.h"
#include "prov/implementations.h"
#include "prov/provider_util.h"
#include "prov/securitycheck.h"
#include "prov/fipscommon.h"
#include "prov/fipsindicator.h"
/* See RFC 4253, Section 7.2 */
static OSSL_FUNC_kdf_newctx_fn kdf_sshkdf_new;
@ -49,6 +52,7 @@ typedef struct {
char type; /* X */
unsigned char *session_id;
size_t session_id_len;
OSSL_FIPS_IND_DECLARE
} KDF_SSHKDF;
static void *kdf_sshkdf_new(void *provctx)
@ -58,8 +62,10 @@ static void *kdf_sshkdf_new(void *provctx)
if (!ossl_prov_is_running())
return NULL;
if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) != NULL)
if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) != NULL) {
ctx->provctx = provctx;
OSSL_FIPS_IND_INIT(ctx)
}
return ctx;
}
@ -102,6 +108,7 @@ static void *kdf_sshkdf_dup(void *vctx)
|| !ossl_prov_digest_copy(&dest->digest, &src->digest))
goto err;
dest->type = src->type;
OSSL_FIPS_IND_COPY(dest, src)
}
return dest;
@ -119,6 +126,36 @@ static int sshkdf_set_membuf(unsigned char **dst, size_t *dst_len,
return OSSL_PARAM_get_octet_string(p, (void **)dst, 0, dst_len);
}
#ifdef FIPS_MODULE
static int fips_digest_check_passed(KDF_SSHKDF *ctx)
{
OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
/*
* Perform digest check
*
* According to NIST SP 800-135r1 section 5.2, the valid hash functions are
* specified in FIPS 180-3. ACVP also only lists the same set of hash
* functions.
*/
int digest_unapproved = !EVP_MD_is_a(md, SN_sha1)
&& !EVP_MD_is_a(md, SN_sha224)
&& !EVP_MD_is_a(md, SN_sha256)
&& !EVP_MD_is_a(md, SN_sha384)
&& !EVP_MD_is_a(md, SN_sha512);
if (digest_unapproved) {
if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
libctx, "SSHKDF", "Digest",
FIPS_sshkdf_digest_check)) {
ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED);
return 0;
}
}
return 1;
}
#endif
static int kdf_sshkdf_derive(void *vctx, unsigned char *key, size_t keylen,
const OSSL_PARAM params[])
{
@ -149,6 +186,12 @@ static int kdf_sshkdf_derive(void *vctx, unsigned char *key, size_t keylen,
ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_TYPE);
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,
@ -164,6 +207,10 @@ static int kdf_sshkdf_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 (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx))
return 0;
@ -209,6 +256,7 @@ static const OSSL_PARAM *kdf_sshkdf_settable_ctx_params(ossl_unused void *ctx,
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SSHKDF_XCGHASH, NULL, 0),
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SSHKDF_SESSION_ID, NULL, 0),
OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_SSHKDF_TYPE, NULL, 0),
OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_DIGEST_CHECK)
OSSL_PARAM_END
};
return known_settable_ctx_params;
@ -218,9 +266,13 @@ static int kdf_sshkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
{
OSSL_PARAM *p;
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
return OSSL_PARAM_set_size_t(p, SIZE_MAX);
return -2;
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) {
if (!OSSL_PARAM_set_size_t(p, SIZE_MAX))
return 0;
}
if (!OSSL_FIPS_IND_GET_CTX_PARAM(((KDF_SSHKDF *)vctx), params))
return 0;
return 1;
}
static const OSSL_PARAM *kdf_sshkdf_gettable_ctx_params(ossl_unused void *ctx,
@ -228,6 +280,7 @@ static const OSSL_PARAM *kdf_sshkdf_gettable_ctx_params(ossl_unused void *ctx,
{
static const OSSL_PARAM known_gettable_ctx_params[] = {
OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
OSSL_PARAM_END
};
return known_gettable_ctx_params;

View File

@ -50,6 +50,9 @@
#include "prov/providercommon.h"
#include "prov/implementations.h"
#include "prov/provider_util.h"
#include "prov/securitycheck.h"
#include "prov/fipscommon.h"
#include "prov/fipsindicator.h"
#include "internal/params.h"
typedef struct {
@ -64,6 +67,7 @@ typedef struct {
size_t salt_len;
size_t out_len; /* optional KMAC parameter */
int is_kmac;
OSSL_FIPS_IND_DECLARE
} KDF_SSKDF;
#define SSKDF_MAX_INLEN (1<<30)
@ -292,8 +296,10 @@ static void *sskdf_new(void *provctx)
if (!ossl_prov_is_running())
return NULL;
if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) != NULL)
if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) != NULL) {
ctx->provctx = provctx;
OSSL_FIPS_IND_INIT(ctx)
}
return ctx;
}
@ -343,6 +349,7 @@ static void *sskdf_dup(void *vctx)
goto err;
dest->out_len = src->out_len;
dest->is_kmac = src->is_kmac;
OSSL_FIPS_IND_COPY(dest, src)
}
return dest;
@ -368,6 +375,35 @@ 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[])
{
@ -380,6 +416,12 @@ static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen,
ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET);
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) {
@ -435,6 +477,34 @@ 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)
{
OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
/*
* Perform digest check
*
* X963KDF is a KDF defined in ANSI-X9.63. According to ACVP specification
* 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));
if (digest_unapproved) {
if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
libctx, "X963KDF", "Digest",
FIPS_x963kdf_digest_check)) {
ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED);
return 0;
}
}
return 1;
}
#endif
static int x963kdf_derive(void *vctx, unsigned char *key, size_t keylen,
const OSSL_PARAM params[])
{
@ -461,6 +531,11 @@ 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);
}
@ -476,6 +551,10 @@ static int sskdf_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 (!ossl_prov_macctx_load_from_params(&ctx->macctx, params,
NULL, NULL, NULL, libctx))
return 0;
@ -528,6 +607,7 @@ static const OSSL_PARAM *sskdf_settable_ctx_params(ossl_unused void *ctx,
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)
OSSL_PARAM_END
};
return known_settable_ctx_params;
@ -538,9 +618,13 @@ static int sskdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
KDF_SSKDF *ctx = (KDF_SSKDF *)vctx;
OSSL_PARAM *p;
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
return OSSL_PARAM_set_size_t(p, sskdf_size(ctx));
return -2;
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 0;
return 1;
}
static const OSSL_PARAM *sskdf_gettable_ctx_params(ossl_unused void *ctx,
@ -548,6 +632,7 @@ static const OSSL_PARAM *sskdf_gettable_ctx_params(ossl_unused void *ctx,
{
static const OSSL_PARAM known_gettable_ctx_params[] = {
OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
OSSL_PARAM_END
};
return known_gettable_ctx_params;

View File

@ -68,6 +68,7 @@
#include "prov/implementations.h"
#include "prov/provider_util.h"
#include "prov/securitycheck.h"
#include "prov/fipscommon.h"
#include "prov/fipsindicator.h"
#include "internal/e_os.h"
#include "internal/safe_math.h"
@ -107,6 +108,11 @@ typedef struct {
/* Concatenated seed data */
unsigned char *seed;
size_t seedlen;
#ifdef FIPS_MODULE
PROV_DIGEST digest;
#endif
OSSL_FIPS_IND_DECLARE
} TLS1_PRF;
@ -139,6 +145,9 @@ 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);
@ -165,6 +174,10 @@ 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;
@ -194,13 +207,40 @@ static int fips_ems_check_passed(TLS1_PRF *ctx)
if (!ems_approved) {
if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
libctx, "TLS_PRF", "EMS",
ossl_tls1_prf_ems_check_enabled)) {
FIPS_tls_prf_ems_check)) {
ERR_raise(ERR_LIB_PROV, PROV_R_EMS_NOT_ENABLED);
return 0;
}
}
return 1;
}
static int fips_digest_check_passed(TLS1_PRF *ctx)
{
OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
/*
* Perform digest check
*
* According to NIST SP 800-135r1 section 5.2, the valid hash functions are
* 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)
&& !EVP_MD_is_a(md, SN_sha384)
&& !EVP_MD_is_a(md, SN_sha512);
if (digest_unapproved) {
if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE1,
libctx, "TLS_PRF", "Digest",
FIPS_tls1_prf_digest_check)) {
ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED);
return 0;
}
}
return 1;
}
#endif
static int kdf_tls1_prf_derive(void *vctx, unsigned char *key, size_t keylen,
@ -231,6 +271,8 @@ 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,
@ -250,7 +292,10 @@ static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,
OSSL_KDF_PARAM_FIPS_EMS_CHECK))
return 0;
return 0;
if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE1, params,
OSSL_KDF_PARAM_FIPS_DIGEST_CHECK))
return 0;
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_DIGEST)) != NULL) {
if (OPENSSL_strcasecmp(p->data, SN_md5_sha1) == 0) {
@ -268,6 +313,11 @@ static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
NULL, NULL, libctx))
return 0;
}
#ifdef FIPS_MODULE
if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx))
return 0;
#endif
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET)) != NULL) {
@ -317,6 +367,7 @@ static const OSSL_PARAM *kdf_tls1_prf_settable_ctx_params(
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0),
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SEED, NULL, 0),
OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_EMS_CHECK)
OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_DIGEST_CHECK)
OSSL_PARAM_END
};
return known_settable_ctx_params;
@ -326,8 +377,10 @@ static int kdf_tls1_prf_get_ctx_params(void *vctx, OSSL_PARAM params[])
{
OSSL_PARAM *p;
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
return OSSL_PARAM_set_size_t(p, SIZE_MAX);
if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) {
if (!OSSL_PARAM_set_size_t(p, SIZE_MAX))
return 0;
}
if (!OSSL_FIPS_IND_GET_CTX_PARAM(((TLS1_PRF *)vctx), params))
return 0;
return 1;

View File

@ -273,9 +273,9 @@ static int do_kdf_hkdf_gettables(int expand_only, int has_digest)
goto err;
}
/* Get params returns -2 if an unsupported parameter is requested */
/* Get params returns 1 if an unsupported parameter is requested */
params_get[0] = OSSL_PARAM_construct_end();
if (!TEST_int_eq(EVP_KDF_CTX_get_params(kctx, params_get), -2))
if (!TEST_int_eq(EVP_KDF_CTX_get_params(kctx, params_get), 1))
goto err;
ret = 1;
err:

View File

@ -221,3 +221,14 @@ Ctrl.IKM = hexkey:1a2d
Ctrl.salt = hexsalt:000000000000000000000000000000000000000000000000000000000000000000
Ctrl.info = info:
Output = 62f99231760bedd72319cc6cad
Title = HKDF bad digest test
Availablein = fips
FIPSversion = >=3.4.0
KDF = HKDF
Ctrl.digest = digest:SHAKE-256
Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
Ctrl.salt = hexsalt:000102030405060708090a0b0c
Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9
Result = KDF_DERIVE_ERROR

View File

@ -1131,3 +1131,13 @@ Ctrl.hexinfo = hexinfo:0553552e5345a11a3018a003020101a111300f1b066b72627467741b
Ctrl.hexinfo = hexinfo:0553552e5345a22404223020a003020110a10c040aaaaaaaaaaaaaaa
Ctrl.hexinfo = hexinfo:aaaaaaa20b0409bbbbbbbbbbbbbbbbbb
Output = d3c78b78d75313e9a926f75dfb012363fa17fa01db
Title = SSKDF bad digest test
Availablein = fips
FIPSversion = >=3.4.0
KDF = SSKDF
Ctrl.digest = digest:SHAKE-256
Ctrl.hexsecret = hexsecret:d09a6b1a472f930db4f5e6b967900744
Ctrl.hexinfo = hexinfo:b117255ab5f1b6b96fc434b0
Result = KDF_DERIVE_ERROR

View File

@ -4865,3 +4865,13 @@ Ctrl.hexsession_id = hexsession_id:a4ebd45934f56792b5112dcd75a1075fdc889245
Ctrl.type = type:A
Output = FF
Result = KDF_MISMATCH
Availablein = fips
FIPSversion = >=3.4.0
KDF = SSHKDF
Ctrl.digest = digest:SHA512-256
Ctrl.hexkey = hexkey:0000008055bae931c07fd824bf10add1902b6fbc7c665347383498a686929ff5a25f8e40cb6645ea814fb1a5e0a11f852f86255641e5ed986e83a78bc8269480eac0b0dfd770cab92e7a28dd87ff452466d6ae867cead63b366b1c286e6c4811a9f14c27aea14c5171d49b78c06e3735d36e6a3be321dd5fc82308f34ee1cb17fba94a59
Ctrl.hexxcghash = hexxcghash:a4ebd45934f56792b5112dcd75a1075fdc889245
Ctrl.hexsession_id = hexsession_id:a4ebd45934f56792b5112dcd75a1075fdc889245
Ctrl.type = type:A
Result = KDF_DERIVE_ERROR

View File

@ -4935,3 +4935,12 @@ Ctrl.mode = mode:EXTRACT_AND_EXPAND
Ctrl.digest = digest:SHA256
Result = KDF_CTRL_ERROR
Title = TLS13-KDF bad digest test
Availablein = fips
FIPSversion = >=3.4.0
KDF = TLS13-KDF
Ctrl.mode = mode:EXTRACT_ONLY
Ctrl.digest = digest:SHA3-256
Ctrl.key = hexkey:f8af6aea2d397baf2948a25b2834200692cff17eee9165e4e27babee9edefd05
Result = KDF_DERIVE_ERROR

View File

@ -17,6 +17,7 @@
Title = X963 KDF tests (from NIST test vectors)
FIPSversion = <3.4.0
KDF = X963KDF
Ctrl.digest = digest:SHA1
Ctrl.hexsecret = hexsecret:fd17198b89ab39c4ab5d7cca363b82f9fd7e23c3984dc8a2
@ -119,3 +120,13 @@ Ctrl.hexsecret = hexsecret:0096172bf47d06d544ae98471490cf9e52ee59ea7a2208b33b26c
Ctrl.hexinfo = hexinfo:cf3a74ba86
Ctrl.hexinfo = hexinfo:af42f1ae85477ead645583
Output = 995d1ab8557dfeafcb347f8182583fa0ac5e6cb3912393592590989f38a0214f6cf7d6fbe23917b0966c6a870876de2a2c13a45fa7aa1715be137ed332e1ffc204ce4dcce33ece6dec7f3da61fa049780040e44142cc8a1e5121cf56b386f65b7c261a192f05e5fefae4221a602bc51c41ef175dc45fb7eab8642421b4f7e3e7
Title = X963KDF bad digest test
Availablein = fips
FIPSversion = >=3.4.0
KDF = X963KDF
Ctrl.digest = digest:SHA1
Ctrl.hexsecret = hexsecret:fd17198b89ab39c4ab5d7cca363b82f9fd7e23c3984dc8a2
Ctrl.hexinfo = hexinfo:856a53f3e36a26bbc5792879f307cce2
Result = KDF_DERIVE_ERROR

View File

@ -607,17 +607,17 @@ my @smime_cms_param_tests = (
],
[ "enveloped content test streaming S/MIME format, ECDH, AES-128-CBC, SHA256 KDF",
[ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
[ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
"-stream", "-out", "{output}.cms",
"-recip", catfile($smdir, "smec1.pem"), "-aes128",
"-keyopt", "ecdh_kdf_md:sha256" ],
[ "{cmd2}", @prov, "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
[ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
"-in", "{output}.cms", "-out", "{output}.txt" ],
\&final_compare
],
[ "enveloped content test streaming S/MIME format, ECDH, AES-128-GCM cipher, SHA256 KDF",
[ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
[ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
"-stream", "-out", "{output}.cms",
"-recip", catfile($smdir, "smec1.pem"), "-aes-128-gcm", "-keyopt", "ecdh_kdf_md:sha256" ],
[ "{cmd2}", "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
@ -626,11 +626,11 @@ my @smime_cms_param_tests = (
],
[ "enveloped content test streaming S/MIME format, ECDH, K-283, cofactor DH",
[ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
[ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
"-stream", "-out", "{output}.cms",
"-recip", catfile($smdir, "smec2.pem"), "-aes128",
"-keyopt", "ecdh_kdf_md:sha256", "-keyopt", "ecdh_cofactor_mode:1" ],
[ "{cmd2}", @prov, "-decrypt", "-recip", catfile($smdir, "smec2.pem"),
[ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smec2.pem"),
"-in", "{output}.cms", "-out", "{output}.txt" ],
\&final_compare
],

View File

@ -14,6 +14,7 @@ my $conditional_errors = 1;
my $security_checks = 1;
my $ems_check = 1;
my $drgb_no_trunc_dgst = 1;
my $kdf_digest_check = 1;
my $activate = 1;
my $mac_key;
@ -48,4 +49,10 @@ security-checks = $security_checks
tls1-prf-ems-check = $ems_check
drbg-no-trunc-md = $drgb_no_trunc_dgst
module-mac = $module_mac
hkdf-digest-check = $kdf_digest_check
tls13-kdf-digest-check = $kd_digest_check
tls1-prf-digest-check = $kdf_digest_check
sshkdf-digest-check = $k_digest_check
sskdf-digest-check = $kd_digest_check
x963kdf-digest-check = $kdf__digest_check
_____

View File

@ -33,6 +33,12 @@ my %params = (
'PROV_PARAM_SECURITY_CHECKS' => "security-checks", # uint
'PROV_PARAM_TLS1_PRF_EMS_CHECK' => "tls1-prf-ems-check", # uint
'PROV_PARAM_DRBG_TRUNC_DIGEST' => "drbg-no-trunc-md", # uint
'PROV_PARAM_HKDF_DIGEST_CHECK' => "hkdf-digest-check", # uint
'PROV_PARAM_TLS13_KDF_DIGEST_CHECK' => "tls13-kdf-digest-check", # uint
'PROV_PARAM_TLS1_PRF_DIGEST_CHECK' => "tls1-prf-digest-check", # uint
'PROV_PARAM_SSHKDF_DIGEST_CHECK' => "sshkdf-digest-check", # uint
'PROV_PARAM_SSKDF_DIGEST_CHECK' => "sskdf-digest-check", # uint
'PROV_PARAM_X963KDF_DIGEST_CHECK' => "x963kdf-digest-check", # uint
# Self test callback parameters
'PROV_PARAM_SELF_TEST_PHASE' => "st-phase",# utf8_string
@ -193,6 +199,7 @@ my %params = (
'KDF_PARAM_ARGON2_MEMCOST' => "memcost", # uint32_t
'KDF_PARAM_ARGON2_VERSION' => "version", # uint32_t
'KDF_PARAM_FIPS_EMS_CHECK' => "ems_check", # int
'KDF_PARAM_FIPS_DIGEST_CHECK' => '*PKEY_PARAM_FIPS_DIGEST_CHECK',
'KDF_PARAM_FIPS_APPROVED_INDICATOR' => '*ALG_PARAM_FIPS_APPROVED_INDICATOR',
# Known RAND names