diff options
author | Daiki Ueno <dueno@redhat.com> | 2023-10-23 13:56:53 +0900 |
---|---|---|
committer | Hugo Landau <hlandau@openssl.org> | 2023-10-26 15:47:15 +0100 |
commit | ef9d8f2f1fd6d0f66184457bd97ab51ce6092745 (patch) | |
tree | e16214ef3e9e89ecf9fa1950ca1e440b31d746ac /providers | |
parent | c61fda2ff88a5dc8d71a6b848008d6f01bfd7fa2 (diff) |
Accept longer context for TLS 1.2 exporters
While RFC 5705 implies that the maximum length of context for
exporters to be 65535 bytes as the length is embedded in uint16, the
current implementation enforces much smaller limit, which is less than
1024 bytes. This removes the restriction by dynamically allocating
memory.
Signed-off-by: Daiki Ueno <dueno@redhat.com>
Reviewed-by: Todd Short <todd.short@me.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22465)
Diffstat (limited to 'providers')
-rw-r--r-- | providers/implementations/kdfs/tls1_prf.c | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/providers/implementations/kdfs/tls1_prf.c b/providers/implementations/kdfs/tls1_prf.c index ff305579c3..2792486924 100644 --- a/providers/implementations/kdfs/tls1_prf.c +++ b/providers/implementations/kdfs/tls1_prf.c @@ -69,6 +69,9 @@ #include "prov/provider_util.h" #include "prov/securitycheck.h" #include "internal/e_os.h" +#include "internal/safe_math.h" + +OSSL_SAFE_MATH_UNSIGNED(size_t, size_t) static OSSL_FUNC_kdf_newctx_fn kdf_tls1_prf_new; static OSSL_FUNC_kdf_dupctx_fn kdf_tls1_prf_dup; @@ -85,7 +88,6 @@ static int tls1_prf_alg(EVP_MAC_CTX *mdctx, EVP_MAC_CTX *sha1ctx, const unsigned char *seed, size_t seed_len, 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 @@ -101,8 +103,8 @@ typedef struct { /* Secret value to use for PRF */ unsigned char *sec; size_t seclen; - /* Buffer of concatenated seed data */ - unsigned char seed[TLS1_PRF_MAXBUF]; + /* Concatenated seed data */ + unsigned char *seed; size_t seedlen; } TLS1_PRF; @@ -136,7 +138,7 @@ static void kdf_tls1_prf_reset(void *vctx) EVP_MAC_CTX_free(ctx->P_hash); EVP_MAC_CTX_free(ctx->P_sha1); OPENSSL_clear_free(ctx->sec, ctx->seclen); - OPENSSL_cleanse(ctx->seed, ctx->seedlen); + OPENSSL_clear_free(ctx->seed, ctx->seedlen); memset(ctx, 0, sizeof(*ctx)); ctx->provctx = provctx; } @@ -156,8 +158,9 @@ static void *kdf_tls1_prf_dup(void *vctx) goto err; if (!ossl_prov_memdup(src->sec, src->seclen, &dest->sec, &dest->seclen)) goto err; - memcpy(dest->seed, src->seed, src->seedlen); - dest->seedlen = src->seedlen; + if (!ossl_prov_memdup(src->seed, src->seedlen, &dest->seed, + &dest->seedlen)) + goto err; } return dest; @@ -250,16 +253,29 @@ static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SEED)) != NULL) { for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1, OSSL_KDF_PARAM_SEED)) { - const void *q = ctx->seed + ctx->seedlen; - size_t sz = 0; - - if (p->data_size != 0 - && p->data != NULL - && !OSSL_PARAM_get_octet_string(p, (void **)&q, - TLS1_PRF_MAXBUF - ctx->seedlen, - &sz)) - return 0; - ctx->seedlen += sz; + if (p->data_size != 0 && p->data != NULL) { + const void *val = NULL; + size_t sz = 0; + unsigned char *seed; + size_t seedlen; + int err = 0; + + if (!OSSL_PARAM_get_octet_string_ptr(p, &val, &sz)) + return 0; + + seedlen = safe_add_size_t(ctx->seedlen, sz, &err); + if (err) + return 0; + + seed = OPENSSL_clear_realloc(ctx->seed, ctx->seedlen, seedlen); + if (!seed) + return 0; + + ctx->seed = seed; + if (ossl_assert(sz != 0)) + memcpy(ctx->seed + ctx->seedlen, val, sz); + ctx->seedlen = seedlen; + } } } return 1; |