summaryrefslogtreecommitdiff
path: root/providers
diff options
context:
space:
mode:
authorslontis <shane.lontis@oracle.com>2023-02-08 17:22:43 +1000
committerTomas Mraz <tomas@openssl.org>2023-03-07 18:24:45 +0100
commit50ea5cdcb735916591e35a04c1f5a659bf253ddc (patch)
tree8cdfdf314aa83a346256e15dcf36a18c8e931bea /providers
parentde13699370183ab565f548267afa57e25a921ca9 (diff)
downloadopenssl-new-50ea5cdcb735916591e35a04c1f5a659bf253ddc.tar.gz
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)
Diffstat (limited to 'providers')
-rw-r--r--providers/common/include/prov/proverr.h2
-rw-r--r--providers/common/include/prov/securitycheck.h1
-rw-r--r--providers/common/provider_err.c3
-rw-r--r--providers/common/securitycheck_default.c6
-rw-r--r--providers/common/securitycheck_fips.c6
-rw-r--r--providers/fips/fipsprov.c32
-rw-r--r--providers/implementations/kdfs/tls1_prf.c26
7 files changed, 72 insertions, 4 deletions
diff --git a/providers/common/include/prov/proverr.h b/providers/common/include/prov/proverr.h
index 8ad6cc048d..69e14465c7 100644
--- a/providers/common/include/prov/proverr.h
+++ b/providers/common/include/prov/proverr.h
@@ -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
diff --git a/providers/common/include/prov/securitycheck.h b/providers/common/include/prov/securitycheck.h
index 4a7f85f711..62e60cc010 100644
--- a/providers/common/include/prov/securitycheck.h
+++ b/providers/common/include/prov/securitycheck.h
@@ -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);
diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c
index f6144072aa..954aabe80c 100644
--- a/providers/common/provider_err.c
+++ b/providers/common/provider_err.c
@@ -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),
diff --git a/providers/common/securitycheck_default.c b/providers/common/securitycheck_default.c
index de7f0d3a0a..63c875ecd0 100644
--- a/providers/common/securitycheck_default.c
+++ b/providers/common/securitycheck_default.c
@@ -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)
{
diff --git a/providers/common/securitycheck_fips.c b/providers/common/securitycheck_fips.c
index b7659bd395..2bc8a59926 100644
--- a/providers/common/securitycheck_fips.c
+++ b/providers/common/securitycheck_fips.c
@@ -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)
{
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index ab58ab891d..a16c379fba 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -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)
{
diff --git a/providers/implementations/kdfs/tls1_prf.c b/providers/implementations/kdfs/tls1_prf.c
index 8a38073084..2c2dbf31cc 100644
--- a/providers/implementations/kdfs/tls1_prf.c
+++ b/providers/implementations/kdfs/tls1_prf.c
@@ -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,