#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;
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
/* 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;
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;
}
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;
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;
const char label[LONG_LABEL_LEN + 1] = "test label";
const unsigned char context[] = "context";
const unsigned char *emptycontext = NULL;
- unsigned char ckeymat1[80], ckeymat2[80], ckeymat3[80];
- unsigned char skeymat1[80], skeymat2[80], skeymat3[80];
+ unsigned char longcontext[1280];
+ unsigned char ckeymat1[80], ckeymat2[80], ckeymat3[80], ckeymat4[80];
+ unsigned char skeymat1[80], skeymat2[80], skeymat3[80], skeymat4[80];
size_t labellen;
const int protocols[] = {
TLS1_VERSION,
labellen = SMALL_LABEL_LEN;
}
+ memset(longcontext, 1, sizeof(longcontext));
+
if (!TEST_int_eq(SSL_export_keying_material(clientssl, ckeymat1,
sizeof(ckeymat1), label,
labellen, context,
sizeof(ckeymat3), label,
labellen,
NULL, 0, 0), 1)
+ || !TEST_int_eq(SSL_export_keying_material(clientssl, ckeymat4,
+ sizeof(ckeymat4), label,
+ labellen,
+ longcontext,
+ sizeof(longcontext), 1),
+ 1)
|| !TEST_int_eq(SSL_export_keying_material(serverssl, skeymat1,
sizeof(skeymat1), label,
labellen,
sizeof(skeymat3), label,
labellen,
NULL, 0, 0), 1)
+ || !TEST_int_eq(SSL_export_keying_material(serverssl, skeymat4,
+ sizeof(skeymat4), label,
+ labellen,
+ longcontext,
+ sizeof(longcontext), 1),
+ 1)
/*
* Check that both sides created the same key material with the
* same context.
*/
|| !TEST_mem_eq(ckeymat3, sizeof(ckeymat3), skeymat3,
sizeof(skeymat3))
+ /*
+ * Check that both sides created the same key material with a
+ * long context.
+ */
+ || !TEST_mem_eq(ckeymat4, sizeof(ckeymat4), skeymat4,
+ sizeof(skeymat4))
/* Different contexts should produce different results */
|| !TEST_mem_ne(ckeymat1, sizeof(ckeymat1), ckeymat2,
sizeof(ckeymat2)))