summaryrefslogtreecommitdiffstats
path: root/providers
diff options
context:
space:
mode:
authorDaiki Ueno <dueno@redhat.com>2023-10-23 13:56:53 +0900
committerHugo Landau <hlandau@openssl.org>2023-10-26 15:47:15 +0100
commitef9d8f2f1fd6d0f66184457bd97ab51ce6092745 (patch)
treee16214ef3e9e89ecf9fa1950ca1e440b31d746ac /providers
parentc61fda2ff88a5dc8d71a6b848008d6f01bfd7fa2 (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.c48
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;