Add option to FIPS module to enforce EMS check during KDF TLS1_PRF.
Fixes #19989 Reviewed-by: Paul Dale <pauli@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/20241)
This commit is contained in:
parent
de13699370
commit
50ea5cdcb7
18 changed files with 281 additions and 38 deletions
|
@ -237,6 +237,13 @@ OpenSSL 3.1
|
|||
|
||||
### Changes between 3.0 and 3.1.0 [xx XXX xxxx]
|
||||
|
||||
* Add FIPS provider configuration option to enforce the
|
||||
Extended Master Secret (EMS) check during the TLS1_PRF KDF.
|
||||
The option '-ems-check' can optionally be supplied to
|
||||
'openssl fipsinstall'.
|
||||
|
||||
*Shane Lontis*
|
||||
|
||||
* The FIPS provider includes a few non-approved algorithms for
|
||||
backward compatibility purposes and the "fips=yes" property query
|
||||
must be used for all algorithm fetches to ensure FIPS compliance.
|
||||
|
|
|
@ -38,6 +38,7 @@ typedef enum OPTION_choice {
|
|||
OPT_NO_LOG, OPT_CORRUPT_DESC, OPT_CORRUPT_TYPE, OPT_QUIET, OPT_CONFIG,
|
||||
OPT_NO_CONDITIONAL_ERRORS,
|
||||
OPT_NO_SECURITY_CHECKS,
|
||||
OPT_TLS_PRF_EMS_CHECK,
|
||||
OPT_SELF_TEST_ONLOAD, OPT_SELF_TEST_ONINSTALL
|
||||
} OPTION_CHOICE;
|
||||
|
||||
|
@ -50,15 +51,17 @@ const OPTIONS fipsinstall_options[] = {
|
|||
{"provider_name", OPT_PROV_NAME, 's', "FIPS provider name"},
|
||||
{"section_name", OPT_SECTION_NAME, 's',
|
||||
"FIPS Provider config section name (optional)"},
|
||||
{"no_conditional_errors", OPT_NO_CONDITIONAL_ERRORS, '-',
|
||||
"Disable the ability of the fips module to enter an error state if"
|
||||
" any conditional self tests fail"},
|
||||
{"no_conditional_errors", OPT_NO_CONDITIONAL_ERRORS, '-',
|
||||
"Disable the ability of the fips module to enter an error state if"
|
||||
" any conditional self tests fail"},
|
||||
{"no_security_checks", OPT_NO_SECURITY_CHECKS, '-',
|
||||
"Disable the run-time FIPS security checks in the module"},
|
||||
{"self_test_onload", OPT_SELF_TEST_ONLOAD, '-',
|
||||
"Forces self tests to always run on module load"},
|
||||
{"self_test_oninstall", OPT_SELF_TEST_ONINSTALL, '-',
|
||||
"Forces self tests to run once on module installation"},
|
||||
{"ems_check", OPT_TLS_PRF_EMS_CHECK, '-',
|
||||
"Enable the run-time FIPS check for EMS during TLS1_PRF"},
|
||||
OPT_SECTION("Input"),
|
||||
{"in", OPT_IN, '<', "Input config file, used when verifying"},
|
||||
|
||||
|
@ -171,6 +174,7 @@ static int write_config_fips_section(BIO *out, const char *section,
|
|||
size_t module_mac_len,
|
||||
int conditional_errors,
|
||||
int security_checks,
|
||||
int ems_check,
|
||||
unsigned char *install_mac,
|
||||
size_t install_mac_len)
|
||||
{
|
||||
|
@ -184,6 +188,8 @@ static int write_config_fips_section(BIO *out, const char *section,
|
|||
conditional_errors ? "1" : "0") <= 0
|
||||
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS,
|
||||
security_checks ? "1" : "0") <= 0
|
||||
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_TLS1_PRF_EMS_CHECK,
|
||||
ems_check ? "1" : "0") <= 0
|
||||
|| !print_mac(out, OSSL_PROV_FIPS_PARAM_MODULE_MAC, module_mac,
|
||||
module_mac_len))
|
||||
goto end;
|
||||
|
@ -205,7 +211,8 @@ static CONF *generate_config_and_load(const char *prov_name,
|
|||
unsigned char *module_mac,
|
||||
size_t module_mac_len,
|
||||
int conditional_errors,
|
||||
int security_checks)
|
||||
int security_checks,
|
||||
int ems_check)
|
||||
{
|
||||
BIO *mem_bio = NULL;
|
||||
CONF *conf = NULL;
|
||||
|
@ -218,6 +225,7 @@ static CONF *generate_config_and_load(const char *prov_name,
|
|||
module_mac, module_mac_len,
|
||||
conditional_errors,
|
||||
security_checks,
|
||||
ems_check,
|
||||
NULL, 0))
|
||||
goto end;
|
||||
|
||||
|
@ -315,6 +323,7 @@ int fipsinstall_main(int argc, char **argv)
|
|||
{
|
||||
int ret = 1, verify = 0, gotkey = 0, gotdigest = 0, self_test_onload = 1;
|
||||
int enable_conditional_errors = 1, enable_security_checks = 1;
|
||||
int enable_tls_prf_ems_check = 0; /* This is off by default */
|
||||
const char *section_name = "fips_sect";
|
||||
const char *mac_name = "HMAC";
|
||||
const char *prov_name = "fips";
|
||||
|
@ -360,6 +369,9 @@ opthelp:
|
|||
case OPT_NO_SECURITY_CHECKS:
|
||||
enable_security_checks = 0;
|
||||
break;
|
||||
case OPT_TLS_PRF_EMS_CHECK:
|
||||
enable_tls_prf_ems_check = 1;
|
||||
break;
|
||||
case OPT_QUIET:
|
||||
quiet = 1;
|
||||
/* FALLTHROUGH */
|
||||
|
@ -523,7 +535,8 @@ opthelp:
|
|||
conf = generate_config_and_load(prov_name, section_name, module_mac,
|
||||
module_mac_len,
|
||||
enable_conditional_errors,
|
||||
enable_security_checks);
|
||||
enable_security_checks,
|
||||
enable_tls_prf_ems_check);
|
||||
if (conf == NULL)
|
||||
goto end;
|
||||
if (!load_fips_prov_and_run_self_test(prov_name))
|
||||
|
@ -540,6 +553,7 @@ opthelp:
|
|||
module_mac, module_mac_len,
|
||||
enable_conditional_errors,
|
||||
enable_security_checks,
|
||||
enable_tls_prf_ems_check,
|
||||
install_mac, install_mac_len))
|
||||
goto end;
|
||||
if (!quiet)
|
||||
|
|
|
@ -1006,6 +1006,7 @@ PROV_R_BN_ERROR:160:bn error
|
|||
PROV_R_CIPHER_OPERATION_FAILED:102:cipher operation failed
|
||||
PROV_R_DERIVATION_FUNCTION_INIT_FAILED:205:derivation function init failed
|
||||
PROV_R_DIGEST_NOT_ALLOWED:174:digest not allowed
|
||||
PROV_R_EMS_NOT_ENABLED:233:ems not enabled
|
||||
PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK:186:entropy source strength too weak
|
||||
PROV_R_ERROR_INSTANTIATING_DRBG:188:error instantiating drbg
|
||||
PROV_R_ERROR_RETRIEVING_ENTROPY:189:error retrieving entropy
|
||||
|
|
|
@ -21,6 +21,7 @@ B<openssl fipsinstall>
|
|||
[B<-quiet>]
|
||||
[B<-no_conditional_errors>]
|
||||
[B<-no_security_checks>]
|
||||
[B<-ems_check>]
|
||||
[B<-self_test_onload>]
|
||||
[B<-self_test_oninstall>]
|
||||
[B<-corrupt_desc> I<selftest_description>]
|
||||
|
@ -165,6 +166,15 @@ fails as described above.
|
|||
|
||||
Configure the module to not perform run-time security checks as described above.
|
||||
|
||||
Enabling the configuration option "no-fips-securitychecks" provides another way to
|
||||
turn off the check at compile time.
|
||||
|
||||
=item B<-ems_check>
|
||||
|
||||
Configure the module to enable a run-time Extended Master Secret (EMS) check
|
||||
when using the TLS1_PRF KDF algorithm. This check is disabled by default.
|
||||
See RFC 7627 for information related to EMS.
|
||||
|
||||
=item B<-self_test_onload>
|
||||
|
||||
Do not write the two fields related to the "test status indicator" and
|
||||
|
|
|
@ -41,6 +41,21 @@ query. Including C<provider=fips> in your property query guarantees
|
|||
that the OpenSSL FIPS provider is used for cryptographic operations
|
||||
rather than other FIPS capable providers.
|
||||
|
||||
=head2 Provider parameters
|
||||
|
||||
See L<provider-base(7)/Provider parameters> for a list of base parameters.
|
||||
Additionally the OpenSSL FIPS provider also supports the following gettable
|
||||
parameters:
|
||||
|
||||
=over 4
|
||||
|
||||
=item "security-checks" (B<OSSL_OSSL_PROV_PARAM_SECURITY_CHECKS>) <unsigned integer>
|
||||
|
||||
For further information refer to the L<openssl-fipsinstall(1)> option
|
||||
B<-no_security_checks>.
|
||||
|
||||
=back
|
||||
|
||||
=head1 OPERATIONS AND ALGORITHMS
|
||||
|
||||
The OpenSSL FIPS provider supports these operations and algorithms:
|
||||
|
|
|
@ -21,11 +21,12 @@ extern "C" {
|
|||
#define OSSL_PROV_PARAM_CORE_MODULE_FILENAME "module-filename" /* utf8_ptr */
|
||||
|
||||
/* Well known parameter names that Providers can define */
|
||||
#define OSSL_PROV_PARAM_NAME "name" /* utf8_ptr */
|
||||
#define OSSL_PROV_PARAM_VERSION "version" /* utf8_ptr */
|
||||
#define OSSL_PROV_PARAM_BUILDINFO "buildinfo" /* utf8_ptr */
|
||||
#define OSSL_PROV_PARAM_STATUS "status" /* uint */
|
||||
#define OSSL_PROV_PARAM_SECURITY_CHECKS "security-checks" /* uint */
|
||||
#define OSSL_PROV_PARAM_NAME "name" /* utf8_ptr */
|
||||
#define OSSL_PROV_PARAM_VERSION "version" /* utf8_ptr */
|
||||
#define OSSL_PROV_PARAM_BUILDINFO "buildinfo" /* utf8_ptr */
|
||||
#define OSSL_PROV_PARAM_STATUS "status" /* uint */
|
||||
#define OSSL_PROV_PARAM_SECURITY_CHECKS "security-checks" /* uint */
|
||||
#define OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK "tls1-prf-ems-check" /* uint */
|
||||
|
||||
/* Self test callback parameters */
|
||||
#define OSSL_PROV_PARAM_SELF_TEST_PHASE "st-phase" /* utf8_string */
|
||||
|
|
|
@ -53,6 +53,14 @@ extern "C" {
|
|||
*/
|
||||
# define OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS "security-checks"
|
||||
|
||||
/*
|
||||
* A boolean that determines if the runtime FIPS check for TLS1_PRF EMS is performed.
|
||||
* This is disabled by default.
|
||||
*
|
||||
* Type: OSSL_PARAM_UTF8_STRING
|
||||
*/
|
||||
# define OSSL_PROV_FIPS_PARAM_TLS1_PRF_EMS_CHECK "tls1-prf-ems-check"
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -32,6 +32,7 @@
|
|||
# define PROV_R_CIPHER_OPERATION_FAILED 102
|
||||
# define PROV_R_DERIVATION_FUNCTION_INIT_FAILED 205
|
||||
# define PROV_R_DIGEST_NOT_ALLOWED 174
|
||||
# define PROV_R_EMS_NOT_ENABLED 233
|
||||
# define PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK 186
|
||||
# define PROV_R_ERROR_INSTANTIATING_DRBG 188
|
||||
# define PROV_R_ERROR_RETRIEVING_ENTROPY 189
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
|
|
@ -28,3 +28,4 @@ int ossl_digest_get_approved_nid(const EVP_MD *md);
|
|||
int ossl_digest_rsa_sign_get_md_nid(OSSL_LIB_CTX *ctx, const EVP_MD *md,
|
||||
int sha1_allowed);
|
||||
int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx);
|
||||
int ossl_tls1_prf_ems_check_enabled(OSSL_LIB_CTX *libctx);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -33,6 +33,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
|
|||
"derivation function init failed"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_DIGEST_NOT_ALLOWED),
|
||||
"digest not allowed"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_EMS_NOT_ENABLED), "ems not enabled"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK),
|
||||
"entropy source strength too weak"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ERROR_INSTANTIATING_DRBG),
|
||||
|
|
|
@ -22,6 +22,12 @@ 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(OSSL_LIB_CTX *ctx, const EVP_MD *md,
|
||||
ossl_unused int sha1_allowed)
|
||||
{
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "prov/securitycheck.h"
|
||||
|
||||
int FIPS_security_check_enabled(OSSL_LIB_CTX *libctx);
|
||||
int FIPS_tls_prf_ems_check(OSSL_LIB_CTX *libctx);
|
||||
|
||||
int ossl_securitycheck_enabled(OSSL_LIB_CTX *libctx)
|
||||
{
|
||||
|
@ -30,6 +31,11 @@ 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(OSSL_LIB_CTX *ctx, const EVP_MD *md,
|
||||
int sha1_allowed)
|
||||
{
|
||||
|
|
|
@ -47,6 +47,7 @@ static OSSL_FUNC_provider_query_operation_fn fips_query;
|
|||
|
||||
extern OSSL_FUNC_core_thread_start_fn *c_thread_start;
|
||||
int FIPS_security_check_enabled(OSSL_LIB_CTX *libctx);
|
||||
int FIPS_tls_prf_ems_check(OSSL_LIB_CTX *libctx);
|
||||
|
||||
/*
|
||||
* Should these function pointers be stored in the provider side provctx? Could
|
||||
|
@ -82,7 +83,9 @@ typedef struct fips_global_st {
|
|||
const OSSL_CORE_HANDLE *handle;
|
||||
SELF_TEST_POST_PARAMS selftest_params;
|
||||
int fips_security_checks;
|
||||
int fips_tls1_prf_ems_check;
|
||||
const char *fips_security_check_option;
|
||||
const char *fips_tls1_prf_ems_check_option;
|
||||
} FIPS_GLOBAL;
|
||||
|
||||
void *ossl_fips_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx)
|
||||
|
@ -94,6 +97,9 @@ void *ossl_fips_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx)
|
|||
fgbl->fips_security_checks = 1;
|
||||
fgbl->fips_security_check_option = "1";
|
||||
|
||||
fgbl->fips_tls1_prf_ems_check = 0; /* Disabled by default */
|
||||
fgbl->fips_tls1_prf_ems_check_option = "0";
|
||||
|
||||
return fgbl;
|
||||
}
|
||||
|
||||
|
@ -109,6 +115,7 @@ static const OSSL_PARAM fips_param_types[] = {
|
|||
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_BUILDINFO, OSSL_PARAM_UTF8_PTR, NULL, 0),
|
||||
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_STATUS, OSSL_PARAM_INTEGER, NULL, 0),
|
||||
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_END
|
||||
};
|
||||
|
||||
|
@ -119,9 +126,10 @@ static int fips_get_params_from_core(FIPS_GLOBAL *fgbl)
|
|||
* NOTE: inside core_get_params() these will be loaded from config items
|
||||
* stored inside prov->parameters (except for
|
||||
* OSSL_PROV_PARAM_CORE_MODULE_FILENAME).
|
||||
* OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS is not a self test parameter.
|
||||
* OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS and
|
||||
* OSSL_PROV_FIPS_PARAM_TLS1_PRF_EMS_CHECK are not self test parameters.
|
||||
*/
|
||||
OSSL_PARAM core_params[8], *p = core_params;
|
||||
OSSL_PARAM core_params[9], *p = core_params;
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_ptr(
|
||||
OSSL_PROV_PARAM_CORE_MODULE_FILENAME,
|
||||
|
@ -151,6 +159,10 @@ static int fips_get_params_from_core(FIPS_GLOBAL *fgbl)
|
|||
OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS,
|
||||
(char **)&fgbl->fips_security_check_option,
|
||||
sizeof(fgbl->fips_security_check_option));
|
||||
*p++ = OSSL_PARAM_construct_utf8_ptr(
|
||||
OSSL_PROV_FIPS_PARAM_TLS1_PRF_EMS_CHECK,
|
||||
(char **)&fgbl->fips_tls1_prf_ems_check_option,
|
||||
sizeof(fgbl->fips_tls1_prf_ems_check_option));
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
|
||||
if (!c_get_params(fgbl->handle, core_params)) {
|
||||
|
@ -187,6 +199,9 @@ static int fips_get_params(void *provctx, OSSL_PARAM params[])
|
|||
p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_SECURITY_CHECKS);
|
||||
if (p != NULL && !OSSL_PARAM_set_int(p, fgbl->fips_security_checks))
|
||||
return 0;
|
||||
p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK);
|
||||
if (p != NULL && !OSSL_PARAM_set_int(p, fgbl->fips_tls1_prf_ems_check))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -698,6 +713,11 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle,
|
|||
&& strcmp(fgbl->fips_security_check_option, "0") == 0)
|
||||
fgbl->fips_security_checks = 0;
|
||||
|
||||
/* Enable the ems check if it's enabled in the fips config file. */
|
||||
if (fgbl->fips_tls1_prf_ems_check_option != NULL
|
||||
&& strcmp(fgbl->fips_tls1_prf_ems_check_option, "1") == 0)
|
||||
fgbl->fips_tls1_prf_ems_check = 1;
|
||||
|
||||
ossl_prov_cache_exported_algorithms(fips_ciphers, exported_fips_ciphers);
|
||||
|
||||
if (!SELF_TEST_post(&fgbl->selftest_params, 0)) {
|
||||
|
@ -893,6 +913,14 @@ int FIPS_security_check_enabled(OSSL_LIB_CTX *libctx)
|
|||
return fgbl->fips_security_checks;
|
||||
}
|
||||
|
||||
int FIPS_tls_prf_ems_check(OSSL_LIB_CTX *libctx)
|
||||
{
|
||||
FIPS_GLOBAL *fgbl = ossl_lib_ctx_get_data(libctx,
|
||||
OSSL_LIB_CTX_FIPS_PROV_INDEX);
|
||||
|
||||
return fgbl->fips_tls1_prf_ems_check;
|
||||
}
|
||||
|
||||
void OSSL_SELF_TEST_get_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK **cb,
|
||||
void **cbarg)
|
||||
{
|
||||
|
|
|
@ -45,6 +45,13 @@
|
|||
* A(0) = seed
|
||||
* A(i) = HMAC_<hash>(secret, A(i-1))
|
||||
*/
|
||||
|
||||
/*
|
||||
* Low level APIs (such as DH) are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
@ -60,6 +67,7 @@
|
|||
#include "prov/providercommon.h"
|
||||
#include "prov/implementations.h"
|
||||
#include "prov/provider_util.h"
|
||||
#include "prov/securitycheck.h"
|
||||
#include "internal/e_os.h"
|
||||
|
||||
static OSSL_FUNC_kdf_newctx_fn kdf_tls1_prf_new;
|
||||
|
@ -78,6 +86,8 @@ static int tls1_prf_alg(EVP_MAC_CTX *mdctx, EVP_MAC_CTX *sha1ctx,
|
|||
unsigned char *out, size_t olen);
|
||||
|
||||
#define TLS1_PRF_MAXBUF 1024
|
||||
#define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"
|
||||
#define TLS_MD_MASTER_SECRET_CONST_SIZE 13
|
||||
|
||||
/* TLS KDF kdf context structure */
|
||||
typedef struct {
|
||||
|
@ -160,6 +170,7 @@ static int kdf_tls1_prf_derive(void *vctx, unsigned char *key, size_t keylen,
|
|||
const OSSL_PARAM params[])
|
||||
{
|
||||
TLS1_PRF *ctx = (TLS1_PRF *)vctx;
|
||||
OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
|
||||
|
||||
if (!ossl_prov_is_running() || !kdf_tls1_prf_set_ctx_params(ctx, params))
|
||||
return 0;
|
||||
|
@ -181,6 +192,21 @@ static int kdf_tls1_prf_derive(void *vctx, unsigned char *key, size_t keylen,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The seed buffer is prepended with a label.
|
||||
* If EMS mode is enforced then the label "master secret" is not allowed,
|
||||
* We do the check this way since the PRF is used for other purposes, as well
|
||||
* as "extended master secret".
|
||||
*/
|
||||
if (ossl_tls1_prf_ems_check_enabled(libctx)) {
|
||||
if (ctx->seedlen >= TLS_MD_MASTER_SECRET_CONST_SIZE
|
||||
&& memcmp(ctx->seed, TLS_MD_MASTER_SECRET_CONST,
|
||||
TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_EMS_NOT_ENABLED);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return tls1_prf_alg(ctx->P_hash, ctx->P_sha1,
|
||||
ctx->sec, ctx->seclen,
|
||||
ctx->seed, ctx->seedlen,
|
||||
|
|
|
@ -347,6 +347,7 @@ SKIP: {
|
|||
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile,
|
||||
'-provider_name', 'fips', '-mac_name', 'HMAC',
|
||||
'-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
|
||||
'-section_name', 'fips_sect', '-self_test_oninstall'])),
|
||||
'-section_name', 'fips_sect', '-self_test_oninstall',
|
||||
'-ems_check'])),
|
||||
"fipsinstall fails when attempting to run self tests on install");
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
#! /usr/bin/env perl
|
||||
# Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
|
||||
# Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
# in the file LICENSE in the source distribution or at
|
||||
# https://www.openssl.org/source/license.html
|
||||
|
||||
|
||||
use OpenSSL::Test::Utils;
|
||||
use OpenSSL::Test qw/:DEFAULT srctop_file srctop_dir bldtop_dir bldtop_file/;
|
||||
use File::Temp qw(tempfile);
|
||||
|
@ -19,13 +18,22 @@ use lib srctop_dir('Configurations');
|
|||
use lib bldtop_dir('.');
|
||||
|
||||
my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
|
||||
my $fipsmodcfg_filename = "fipsmodule.cnf";
|
||||
my $fipsmodcfg = bldtop_file("providers", $fipsmodcfg_filename);
|
||||
|
||||
my $provconf = srctop_file("test", "fips-and-base.cnf");
|
||||
|
||||
# A modified copy of "fipsmodule.cnf"
|
||||
my $fipsmodcfgnew_filename = "fipsmodule_mod.cnf";
|
||||
my $fipsmodcfgnew = bldtop_file("test", $fipsmodcfgnew_filename);
|
||||
|
||||
# A modified copy of "fips-and-base.cnf"
|
||||
my $provconfnew = bldtop_file("test", "temp.cnf");
|
||||
|
||||
plan skip_all => "No TLS/SSL protocols are supported by this OpenSSL build"
|
||||
if alldisabled(grep { $_ ne "ssl3" } available_protocols("tls"));
|
||||
|
||||
plan tests =>
|
||||
($no_fips ? 0 : 1) # sslapitest with fips
|
||||
+ 1; # sslapitest with default provider
|
||||
plan tests => 3;
|
||||
|
||||
(undef, my $tmpfilename) = tempfile();
|
||||
|
||||
|
@ -39,16 +47,97 @@ ok(run(test(["sslapitest", srctop_dir("test", "certs"),
|
|||
"dhparams.pem")])),
|
||||
"running sslapitest");
|
||||
|
||||
unless ($no_fips) {
|
||||
SKIP: {
|
||||
skip "Skipping FIPS tests", 2
|
||||
if $no_fips;
|
||||
|
||||
ok(run(test(["sslapitest", srctop_dir("test", "certs"),
|
||||
srctop_file("test", "recipes", "90-test_sslapi_data",
|
||||
"passwd.txt"), $tmpfilename, "fips",
|
||||
srctop_file("test", "fips-and-base.cnf"),
|
||||
$provconf,
|
||||
srctop_file("test",
|
||||
"recipes",
|
||||
"90-test_sslapi_data",
|
||||
"dhparams.pem")])),
|
||||
"running sslapitest");
|
||||
|
||||
run(test(["fips_version_test", "-config", $provconf, ">=3.1.0"]),
|
||||
capture => 1, statusvar => \my $exit);
|
||||
|
||||
skip "FIPS provider version is too old for TLS_PRF EMS option test", 1
|
||||
if !$exit;
|
||||
|
||||
# Read in a text $infile and replace the regular expression in $srch with the
|
||||
# value in $repl and output to a new file $outfile.
|
||||
sub replace_line_file_internal {
|
||||
|
||||
my ($infile, $srch, $repl, $outfile) = @_;
|
||||
my $msg;
|
||||
|
||||
open(my $in, "<", $infile) or return 0;
|
||||
read($in, $msg, 1024);
|
||||
close $in;
|
||||
|
||||
$msg =~ s/$srch/$repl/;
|
||||
|
||||
open(my $fh, ">", $outfile) or return 0;
|
||||
print $fh $msg;
|
||||
close $fh;
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Read in the text input file $infile
|
||||
# and replace a single Key = Value line with a new value in $value.
|
||||
# OR remove the Key = Value line if the passed in $value is empty.
|
||||
# and then output a new file $outfile.
|
||||
# $key is the Key to find
|
||||
sub replace_kv_file {
|
||||
my ($infile, $key, $value, $outfile) = @_;
|
||||
my $srch = qr/$key\s*=\s*\S*\n/;
|
||||
my $rep;
|
||||
if ($value eq "") {
|
||||
$rep = "";
|
||||
} else {
|
||||
$rep = "$key = $value\n";
|
||||
}
|
||||
return replace_line_file_internal($infile, $srch, $rep, $outfile);
|
||||
}
|
||||
|
||||
# Read in the text $input file
|
||||
# and search for the $key and replace with $newkey
|
||||
# and then output a new file $outfile.
|
||||
sub replace_line_file {
|
||||
my ($infile, $key, $newkey, $outfile) = @_;
|
||||
my $srch = qr/$key/;
|
||||
my $rep = "$newkey";
|
||||
return replace_line_file_internal($infile,
|
||||
$srch, $rep, $outfile);
|
||||
}
|
||||
|
||||
# In order to enable the tls1-prf-ems-check=1 in a fips config file
|
||||
# copy the existing fipsmodule.cnf and modify it.
|
||||
# Then copy fips-and-base.cfg to make a file that includes the changed file
|
||||
# NOTE that this just runs test_no_ems() to check that the connection
|
||||
# fails if ems is not used and the fips check is enabled.
|
||||
ok(replace_kv_file($fipsmodcfg,
|
||||
'tls1-prf-ems-check', '1',
|
||||
$fipsmodcfgnew)
|
||||
&& replace_line_file($provconf,
|
||||
$fipsmodcfg_filename, $fipsmodcfgnew_filename,
|
||||
$provconfnew)
|
||||
&& run(test(["sslapitest", srctop_dir("test", "certs"),
|
||||
srctop_file("test", "recipes", "90-test_sslapi_data",
|
||||
"passwd.txt"),
|
||||
$tmpfilename, "fips",
|
||||
$provconfnew,
|
||||
srctop_file("test",
|
||||
"recipes",
|
||||
"90-test_sslapi_data",
|
||||
"dhparams.pem")])),
|
||||
"running sslapitest");
|
||||
|
||||
unlink $fipsmodcfgnew;
|
||||
unlink $provconfnew;
|
||||
}
|
||||
|
||||
unlink $tmpfilename;
|
||||
|
|
|
@ -99,6 +99,7 @@ static char *tmpfilename = NULL;
|
|||
static char *dhfile = NULL;
|
||||
|
||||
static int is_fips = 0;
|
||||
static int fips_ems_check = 0;
|
||||
|
||||
#define LOG_BUFFER_SIZE 2048
|
||||
static char server_log_buffer[LOG_BUFFER_SIZE + 1] = {0};
|
||||
|
@ -796,7 +797,7 @@ static int test_no_ems(void)
|
|||
{
|
||||
SSL_CTX *cctx = NULL, *sctx = NULL;
|
||||
SSL *clientssl = NULL, *serverssl = NULL;
|
||||
int testresult = 0;
|
||||
int testresult = 0, status;
|
||||
|
||||
if (!create_ssl_ctx_pair(libctx, TLS_server_method(), TLS_client_method(),
|
||||
TLS1_VERSION, TLS1_2_VERSION,
|
||||
|
@ -812,19 +813,25 @@ static int test_no_ems(void)
|
|||
goto end;
|
||||
}
|
||||
|
||||
if (!create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)) {
|
||||
printf("Creating SSL connection failed\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (SSL_get_extms_support(serverssl)) {
|
||||
printf("Server reports Extended Master Secret support\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (SSL_get_extms_support(clientssl)) {
|
||||
printf("Client reports Extended Master Secret support\n");
|
||||
goto end;
|
||||
status = create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE);
|
||||
if (fips_ems_check) {
|
||||
if (status == 1) {
|
||||
printf("When FIPS uses the EMS check a connection that doesnt use EMS should fail\n");
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
if (!status) {
|
||||
printf("Creating SSL connection failed\n");
|
||||
goto end;
|
||||
}
|
||||
if (SSL_get_extms_support(serverssl)) {
|
||||
printf("Server reports Extended Master Secret support\n");
|
||||
goto end;
|
||||
}
|
||||
if (SSL_get_extms_support(clientssl)) {
|
||||
printf("Client reports Extended Master Secret support\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
testresult = 1;
|
||||
|
||||
|
@ -10848,9 +10855,24 @@ int setup_tests(void)
|
|||
&& !TEST_false(OSSL_PROVIDER_available(libctx, "default")))
|
||||
return 0;
|
||||
|
||||
if (strcmp(modulename, "fips") == 0)
|
||||
if (strcmp(modulename, "fips") == 0) {
|
||||
OSSL_PROVIDER *prov = NULL;
|
||||
OSSL_PARAM params[2];
|
||||
|
||||
is_fips = 1;
|
||||
|
||||
prov = OSSL_PROVIDER_load(libctx, "fips");
|
||||
if (prov != NULL) {
|
||||
/* Query the fips provider to check if the check ems option is enabled */
|
||||
params[0] =
|
||||
OSSL_PARAM_construct_int(OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK,
|
||||
&fips_ems_check);
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
OSSL_PROVIDER_get_params(prov, params);
|
||||
OSSL_PROVIDER_unload(prov);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We add, but don't load the test "tls-provider". We'll load it when we
|
||||
* need it.
|
||||
|
@ -10924,6 +10946,12 @@ int setup_tests(void)
|
|||
if (privkey8192 == NULL)
|
||||
goto err;
|
||||
|
||||
if (fips_ems_check) {
|
||||
#ifndef OPENSSL_NO_TLS1_2
|
||||
ADD_TEST(test_no_ems);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
#if !defined(OPENSSL_NO_KTLS) && !defined(OPENSSL_NO_SOCK)
|
||||
# if !defined(OPENSSL_NO_TLS1_2) || !defined(OSSL_NO_USABLE_TLS1_3)
|
||||
ADD_ALL_TESTS(test_ktls, NUM_KTLS_TEST_CIPHERS * 4);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue