mirror of
https://github.com/status-im/BearSSL.git
synced 2025-02-22 15:38:21 +00:00
Added implementation of keying material export (RFC 5705) (API for PRF implementations changed, to handle chunked seeds).
This commit is contained in:
parent
2b738493bd
commit
ea95d8264c
@ -50,11 +50,32 @@ extern "C" {
|
||||
* rely on the SHA-256 based PRF, but some use SHA-384.
|
||||
*
|
||||
* The PRF always uses as input three parameters: a "secret" (some
|
||||
* bytes), a "label" (ASCII string), and a "seed" (again some bytes).
|
||||
* An arbitrary output length can be produced.
|
||||
* bytes), a "label" (ASCII string), and a "seed" (again some bytes). An
|
||||
* arbitrary output length can be produced. The "seed" is provided as an
|
||||
* arbitrary number of binary chunks, that gets internally concatenated.
|
||||
*/
|
||||
|
||||
/** \brief PRF implementation for TLS 1.0 and 1.1.
|
||||
/**
|
||||
* \brief Type for a seed chunk.
|
||||
*
|
||||
* Each chunk may have an arbitrary length, and may be empty (no byte at
|
||||
* all). If the chunk length is zero, then the pointer to the chunk data
|
||||
* may be `NULL`.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* \brief Pointer to the chunk data.
|
||||
*/
|
||||
const void *data;
|
||||
|
||||
/**
|
||||
* \brief Chunk length (in bytes).
|
||||
*/
|
||||
size_t len;
|
||||
} br_tls_prf_seed_chunk;
|
||||
|
||||
/**
|
||||
* \brief PRF implementation for TLS 1.0 and 1.1.
|
||||
*
|
||||
* This PRF is the one specified by TLS 1.0 and 1.1. It internally uses
|
||||
* MD5 and SHA-1.
|
||||
@ -64,14 +85,15 @@ extern "C" {
|
||||
* \param secret secret value (key) for this computation.
|
||||
* \param secret_len length of "secret" (in bytes).
|
||||
* \param label PRF label (zero-terminated ASCII string).
|
||||
* \param seed seed for this computation (usually non-secret).
|
||||
* \param seed_len length of "seed" (in bytes).
|
||||
* \param seed_num number of seed chunks.
|
||||
* \param seed seed chnks for this computation (usually non-secret).
|
||||
*/
|
||||
void br_tls10_prf(void *dst, size_t len,
|
||||
const void *secret, size_t secret_len,
|
||||
const char *label, const void *seed, size_t seed_len);
|
||||
const void *secret, size_t secret_len, const char *label,
|
||||
size_t seed_num, const br_tls_prf_seed_chunk *seed);
|
||||
|
||||
/** \brief PRF implementation for TLS 1.2, with SHA-256.
|
||||
/**
|
||||
* \brief PRF implementation for TLS 1.2, with SHA-256.
|
||||
*
|
||||
* This PRF is the one specified by TLS 1.2, when the underlying hash
|
||||
* function is SHA-256.
|
||||
@ -81,14 +103,15 @@ void br_tls10_prf(void *dst, size_t len,
|
||||
* \param secret secret value (key) for this computation.
|
||||
* \param secret_len length of "secret" (in bytes).
|
||||
* \param label PRF label (zero-terminated ASCII string).
|
||||
* \param seed seed for this computation (usually non-secret).
|
||||
* \param seed_len length of "seed" (in bytes).
|
||||
* \param seed_num number of seed chunks.
|
||||
* \param seed seed chnks for this computation (usually non-secret).
|
||||
*/
|
||||
void br_tls12_sha256_prf(void *dst, size_t len,
|
||||
const void *secret, size_t secret_len,
|
||||
const char *label, const void *seed, size_t seed_len);
|
||||
const void *secret, size_t secret_len, const char *label,
|
||||
size_t seed_num, const br_tls_prf_seed_chunk *seed);
|
||||
|
||||
/** \brief PRF implementation for TLS 1.2, with SHA-384.
|
||||
/**
|
||||
* \brief PRF implementation for TLS 1.2, with SHA-384.
|
||||
*
|
||||
* This PRF is the one specified by TLS 1.2, when the underlying hash
|
||||
* function is SHA-384.
|
||||
@ -98,26 +121,27 @@ void br_tls12_sha256_prf(void *dst, size_t len,
|
||||
* \param secret secret value (key) for this computation.
|
||||
* \param secret_len length of "secret" (in bytes).
|
||||
* \param label PRF label (zero-terminated ASCII string).
|
||||
* \param seed seed for this computation (usually non-secret).
|
||||
* \param seed_len length of "seed" (in bytes).
|
||||
* \param seed_num number of seed chunks.
|
||||
* \param seed seed chnks for this computation (usually non-secret).
|
||||
*/
|
||||
void br_tls12_sha384_prf(void *dst, size_t len,
|
||||
const void *secret, size_t secret_len,
|
||||
const char *label, const void *seed, size_t seed_len);
|
||||
const void *secret, size_t secret_len, const char *label,
|
||||
size_t seed_num, const br_tls_prf_seed_chunk *seed);
|
||||
|
||||
/** \brief A convenient type name for a PRF implementation.
|
||||
/**
|
||||
* brief A convenient type name for a PRF implementation.
|
||||
*
|
||||
* \param dst destination buffer.
|
||||
* \param len output length (in bytes).
|
||||
* \param secret secret value (key) for this computation.
|
||||
* \param secret_len length of "secret" (in bytes).
|
||||
* \param label PRF label (zero-terminated ASCII string).
|
||||
* \param seed seed for this computation (usually non-secret).
|
||||
* \param seed_len length of "seed" (in bytes).
|
||||
* \param seed_num number of seed chunks.
|
||||
* \param seed seed chnks for this computation (usually non-secret).
|
||||
*/
|
||||
typedef void (*br_tls_prf_impl)(void *dst, size_t len,
|
||||
const void *secret, size_t secret_len,
|
||||
const char *label, const void *seed, size_t seed_len);
|
||||
const void *secret, size_t secret_len, const char *label,
|
||||
size_t seed_num, const br_tls_prf_seed_chunk *seed);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -2075,6 +2075,41 @@ void br_ssl_engine_close(br_ssl_engine_context *cc);
|
||||
*/
|
||||
int br_ssl_engine_renegotiate(br_ssl_engine_context *cc);
|
||||
|
||||
/**
|
||||
* \brief Export key material from a connected SSL engine (RFC 5705).
|
||||
*
|
||||
* This calls compute a secret key of arbitrary length from the master
|
||||
* secret of a connected SSL engine. If the provided context is not
|
||||
* currently in "application data" state (initial handshake is not
|
||||
* finished, another handshake is ongoing, or the connection failed or
|
||||
* was closed), then this function returns 0. Otherwise, a secret key of
|
||||
* length `len` bytes is computed and written in the buffer pointed to
|
||||
* by `dst`, and 1 is returned.
|
||||
*
|
||||
* The computed key follows the specification described in RFC 5705.
|
||||
* That RFC includes two key computations, with and without a "context
|
||||
* value". If `context` is `NULL`, then the variant without context is
|
||||
* used; otherwise, the `context_len` bytes located at the address
|
||||
* pointed to by `context` are used in the computation. Note that it
|
||||
* is possible to have a "with context" key with a context length of
|
||||
* zero bytes, by setting `context` to a non-`NULL` value but
|
||||
* `context_len` to 0.
|
||||
*
|
||||
* When context bytes are used, the context length MUST NOT exceed
|
||||
* 65535 bytes.
|
||||
*
|
||||
* \param cc SSL engine context.
|
||||
* \param dst destination buffer for exported key.
|
||||
* \param len exported key length (in bytes).
|
||||
* \param label disambiguation label.
|
||||
* \param context context value (or `NULL`).
|
||||
* \param context_len context length (in bytes).
|
||||
* \return 1 on success, 0 on error.
|
||||
*/
|
||||
int br_ssl_key_export(br_ssl_engine_context *cc,
|
||||
void *dst, size_t len, const char *label,
|
||||
const void *context, size_t context_len);
|
||||
|
||||
/*
|
||||
* Pre-declaration for the SSL client context.
|
||||
*/
|
||||
|
File diff suppressed because one or more lines are too long
@ -208,6 +208,7 @@ coresrc=" \
|
||||
src/ssl/ssl_hs_client.c \
|
||||
src/ssl/ssl_hs_server.c \
|
||||
src/ssl/ssl_io.c \
|
||||
src/ssl/ssl_keyexport.c \
|
||||
src/ssl/ssl_lru.c \
|
||||
src/ssl/ssl_rec_cbc.c \
|
||||
src/ssl/ssl_rec_chapol.c \
|
||||
|
@ -509,8 +509,8 @@ void br_sha2small_round(const unsigned char *buf, uint32_t *val);
|
||||
*/
|
||||
void br_tls_phash(void *dst, size_t len,
|
||||
const br_hash_class *dig,
|
||||
const void *secret, size_t secret_len,
|
||||
const char *label, const void *seed, size_t seed_len);
|
||||
const void *secret, size_t secret_len, const char *label,
|
||||
size_t seed_num, const br_tls_prf_seed_chunk *seed);
|
||||
|
||||
/*
|
||||
* Copy all configured hash implementations from a multihash context
|
||||
|
@ -28,14 +28,14 @@
|
||||
void
|
||||
br_tls_phash(void *dst, size_t len,
|
||||
const br_hash_class *dig,
|
||||
const void *secret, size_t secret_len,
|
||||
const char *label, const void *seed, size_t seed_len)
|
||||
const void *secret, size_t secret_len, const char *label,
|
||||
size_t seed_num, const br_tls_prf_seed_chunk *seed)
|
||||
{
|
||||
unsigned char *buf;
|
||||
unsigned char tmp[64], a[64];
|
||||
br_hmac_key_context kc;
|
||||
br_hmac_context hc;
|
||||
size_t label_len, hlen;
|
||||
size_t label_len, hlen, u;
|
||||
|
||||
if (len == 0) {
|
||||
return;
|
||||
@ -46,15 +46,17 @@ br_tls_phash(void *dst, size_t len,
|
||||
br_hmac_key_init(&kc, dig, secret, secret_len);
|
||||
br_hmac_init(&hc, &kc, 0);
|
||||
br_hmac_update(&hc, label, label_len);
|
||||
br_hmac_update(&hc, seed, seed_len);
|
||||
for (u = 0; u < seed_num; u ++) {
|
||||
br_hmac_update(&hc, seed[u].data, seed[u].len);
|
||||
}
|
||||
br_hmac_out(&hc, a);
|
||||
for (;;) {
|
||||
size_t u;
|
||||
|
||||
br_hmac_init(&hc, &kc, 0);
|
||||
br_hmac_update(&hc, a, hlen);
|
||||
br_hmac_update(&hc, label, label_len);
|
||||
br_hmac_update(&hc, seed, seed_len);
|
||||
for (u = 0; u < seed_num; u ++) {
|
||||
br_hmac_update(&hc, seed[u].data, seed[u].len);
|
||||
}
|
||||
br_hmac_out(&hc, tmp);
|
||||
for (u = 0; u < hlen && u < len; u ++) {
|
||||
buf[u] ^= tmp[u];
|
||||
|
@ -27,8 +27,8 @@
|
||||
/* see bearssl.h */
|
||||
void
|
||||
br_tls10_prf(void *dst, size_t len,
|
||||
const void *secret, size_t secret_len,
|
||||
const char *label, const void *seed, size_t seed_len)
|
||||
const void *secret, size_t secret_len, const char *label,
|
||||
size_t seed_num, const br_tls_prf_seed_chunk *seed)
|
||||
{
|
||||
const unsigned char *s1;
|
||||
size_t slen;
|
||||
@ -37,7 +37,7 @@ br_tls10_prf(void *dst, size_t len,
|
||||
slen = (secret_len + 1) >> 1;
|
||||
memset(dst, 0, len);
|
||||
br_tls_phash(dst, len, &br_md5_vtable,
|
||||
s1, slen, label, seed, seed_len);
|
||||
s1, slen, label, seed_num, seed);
|
||||
br_tls_phash(dst, len, &br_sha1_vtable,
|
||||
s1 + secret_len - slen, slen, label, seed, seed_len);
|
||||
s1 + secret_len - slen, slen, label, seed_num, seed);
|
||||
}
|
||||
|
@ -27,10 +27,10 @@
|
||||
/* see bearssl.h */
|
||||
void
|
||||
br_tls12_sha256_prf(void *dst, size_t len,
|
||||
const void *secret, size_t secret_len,
|
||||
const char *label, const void *seed, size_t seed_len)
|
||||
const void *secret, size_t secret_len, const char *label,
|
||||
size_t seed_num, const br_tls_prf_seed_chunk *seed)
|
||||
{
|
||||
memset(dst, 0, len);
|
||||
br_tls_phash(dst, len, &br_sha256_vtable,
|
||||
secret, secret_len, label, seed, seed_len);
|
||||
secret, secret_len, label, seed_num, seed);
|
||||
}
|
||||
|
@ -27,10 +27,10 @@
|
||||
/* see bearssl.h */
|
||||
void
|
||||
br_tls12_sha384_prf(void *dst, size_t len,
|
||||
const void *secret, size_t secret_len,
|
||||
const char *label, const void *seed, size_t seed_len)
|
||||
const void *secret, size_t secret_len, const char *label,
|
||||
size_t seed_num, const br_tls_prf_seed_chunk *seed)
|
||||
{
|
||||
memset(dst, 0, len);
|
||||
br_tls_phash(dst, len, &br_sha384_vtable,
|
||||
secret, secret_len, label, seed, seed_len);
|
||||
secret, secret_len, label, seed_num, seed);
|
||||
}
|
||||
|
@ -1335,13 +1335,14 @@ br_ssl_engine_compute_master(br_ssl_engine_context *cc,
|
||||
int prf_id, const void *pms, size_t pms_len)
|
||||
{
|
||||
br_tls_prf_impl iprf;
|
||||
unsigned char seed[64];
|
||||
br_tls_prf_seed_chunk seed[2] = {
|
||||
{ cc->client_random, sizeof cc->client_random },
|
||||
{ cc->server_random, sizeof cc->server_random }
|
||||
};
|
||||
|
||||
iprf = br_ssl_engine_get_PRF(cc, prf_id);
|
||||
memcpy(seed, cc->client_random, 32);
|
||||
memcpy(seed + 32, cc->server_random, 32);
|
||||
iprf(cc->session.master_secret, sizeof cc->session.master_secret,
|
||||
pms, pms_len, "master secret", seed, sizeof seed);
|
||||
pms, pms_len, "master secret", 2, seed);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1352,14 +1353,15 @@ compute_key_block(br_ssl_engine_context *cc, int prf_id,
|
||||
size_t half_len, unsigned char *kb)
|
||||
{
|
||||
br_tls_prf_impl iprf;
|
||||
unsigned char seed[64];
|
||||
br_tls_prf_seed_chunk seed[2] = {
|
||||
{ cc->server_random, sizeof cc->server_random },
|
||||
{ cc->client_random, sizeof cc->client_random }
|
||||
};
|
||||
|
||||
iprf = br_ssl_engine_get_PRF(cc, prf_id);
|
||||
memcpy(seed, cc->server_random, 32);
|
||||
memcpy(seed + 32, cc->client_random, 32);
|
||||
iprf(kb, half_len << 1,
|
||||
cc->session.master_secret, sizeof cc->session.master_secret,
|
||||
"key expansion", seed, sizeof seed);
|
||||
"key expansion", 2, seed);
|
||||
}
|
||||
|
||||
/* see inner.h */
|
||||
|
@ -1192,21 +1192,22 @@ br_ssl_hs_client_run(void *t0ctx)
|
||||
|
||||
int prf_id = T0_POP();
|
||||
int from_client = T0_POPi();
|
||||
unsigned char seed[48];
|
||||
size_t seed_len;
|
||||
unsigned char tmp[48];
|
||||
br_tls_prf_seed_chunk seed;
|
||||
|
||||
br_tls_prf_impl prf = br_ssl_engine_get_PRF(ENG, prf_id);
|
||||
seed.data = tmp;
|
||||
if (ENG->session.version >= BR_TLS12) {
|
||||
seed_len = br_multihash_out(&ENG->mhash, prf_id, seed);
|
||||
seed.len = br_multihash_out(&ENG->mhash, prf_id, tmp);
|
||||
} else {
|
||||
br_multihash_out(&ENG->mhash, br_md5_ID, seed);
|
||||
br_multihash_out(&ENG->mhash, br_sha1_ID, seed + 16);
|
||||
seed_len = 36;
|
||||
br_multihash_out(&ENG->mhash, br_md5_ID, tmp);
|
||||
br_multihash_out(&ENG->mhash, br_sha1_ID, tmp + 16);
|
||||
seed.len = 36;
|
||||
}
|
||||
prf(ENG->pad, 12, ENG->session.master_secret,
|
||||
sizeof ENG->session.master_secret,
|
||||
from_client ? "client finished" : "server finished",
|
||||
seed, seed_len);
|
||||
1, &seed);
|
||||
|
||||
}
|
||||
break;
|
||||
|
@ -754,6 +754,10 @@ cc: mkrand ( addr len -- ) {
|
||||
\ -- PRF for TLS-1.2:
|
||||
\ 4 with SHA-256
|
||||
\ 5 with SHA-384
|
||||
\
|
||||
\ WARNING: if adding a new cipher suite that does not use SHA-256 for the
|
||||
\ PRF (with TLS 1.2), be sure to check the suites_sha384[] array defined
|
||||
\ in ssl/ssl_keyexport.c
|
||||
|
||||
data: cipher-suite-def
|
||||
|
||||
@ -1019,21 +1023,22 @@ cc: switch-chapol-in ( is_client prf_id -- ) {
|
||||
cc: compute-Finished-inner ( from_client prf_id -- ) {
|
||||
int prf_id = T0_POP();
|
||||
int from_client = T0_POPi();
|
||||
unsigned char seed[48];
|
||||
size_t seed_len;
|
||||
unsigned char tmp[48];
|
||||
br_tls_prf_seed_chunk seed;
|
||||
|
||||
br_tls_prf_impl prf = br_ssl_engine_get_PRF(ENG, prf_id);
|
||||
seed.data = tmp;
|
||||
if (ENG->session.version >= BR_TLS12) {
|
||||
seed_len = br_multihash_out(&ENG->mhash, prf_id, seed);
|
||||
seed.len = br_multihash_out(&ENG->mhash, prf_id, tmp);
|
||||
} else {
|
||||
br_multihash_out(&ENG->mhash, br_md5_ID, seed);
|
||||
br_multihash_out(&ENG->mhash, br_sha1_ID, seed + 16);
|
||||
seed_len = 36;
|
||||
br_multihash_out(&ENG->mhash, br_md5_ID, tmp);
|
||||
br_multihash_out(&ENG->mhash, br_sha1_ID, tmp + 16);
|
||||
seed.len = 36;
|
||||
}
|
||||
prf(ENG->pad, 12, ENG->session.master_secret,
|
||||
sizeof ENG->session.master_secret,
|
||||
from_client ? "client finished" : "server finished",
|
||||
seed, seed_len);
|
||||
1, &seed);
|
||||
}
|
||||
|
||||
\ Receive ChangeCipherSpec and Finished from the peer.
|
||||
|
@ -1250,21 +1250,22 @@ br_ssl_hs_server_run(void *t0ctx)
|
||||
|
||||
int prf_id = T0_POP();
|
||||
int from_client = T0_POPi();
|
||||
unsigned char seed[48];
|
||||
size_t seed_len;
|
||||
unsigned char tmp[48];
|
||||
br_tls_prf_seed_chunk seed;
|
||||
|
||||
br_tls_prf_impl prf = br_ssl_engine_get_PRF(ENG, prf_id);
|
||||
seed.data = tmp;
|
||||
if (ENG->session.version >= BR_TLS12) {
|
||||
seed_len = br_multihash_out(&ENG->mhash, prf_id, seed);
|
||||
seed.len = br_multihash_out(&ENG->mhash, prf_id, tmp);
|
||||
} else {
|
||||
br_multihash_out(&ENG->mhash, br_md5_ID, seed);
|
||||
br_multihash_out(&ENG->mhash, br_sha1_ID, seed + 16);
|
||||
seed_len = 36;
|
||||
br_multihash_out(&ENG->mhash, br_md5_ID, tmp);
|
||||
br_multihash_out(&ENG->mhash, br_sha1_ID, tmp + 16);
|
||||
seed.len = 36;
|
||||
}
|
||||
prf(ENG->pad, 12, ENG->session.master_secret,
|
||||
sizeof ENG->session.master_secret,
|
||||
from_client ? "client finished" : "server finished",
|
||||
seed, seed_len);
|
||||
1, &seed);
|
||||
|
||||
}
|
||||
break;
|
||||
|
83
src/ssl/ssl_keyexport.c
Normal file
83
src/ssl/ssl_keyexport.c
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Thomas Pornin <pornin@bolet.org>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "inner.h"
|
||||
|
||||
/*
|
||||
* Supported cipher suites that use SHA-384 for the PRF when selected
|
||||
* for TLS 1.2. All other cipher suites are deemed to use SHA-256.
|
||||
*/
|
||||
static const uint16_t suites_sha384[] = {
|
||||
BR_TLS_RSA_WITH_AES_256_GCM_SHA384,
|
||||
BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
|
||||
BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
|
||||
BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
|
||||
BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
|
||||
BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
|
||||
};
|
||||
|
||||
/* see bearssl_ssl.h */
|
||||
int
|
||||
br_ssl_key_export(br_ssl_engine_context *cc,
|
||||
void *dst, size_t len, const char *label,
|
||||
const void *context, size_t context_len)
|
||||
{
|
||||
br_tls_prf_seed_chunk chunks[4];
|
||||
br_tls_prf_impl iprf;
|
||||
size_t num_chunks, u;
|
||||
unsigned char tmp[2];
|
||||
int prf_id;
|
||||
|
||||
if (cc->application_data != 1) {
|
||||
return 0;
|
||||
}
|
||||
chunks[0].data = cc->client_random;
|
||||
chunks[0].len = sizeof cc->client_random;
|
||||
chunks[1].data = cc->server_random;
|
||||
chunks[1].len = sizeof cc->server_random;
|
||||
if (context != NULL) {
|
||||
br_enc16be(tmp, (unsigned)context_len);
|
||||
chunks[2].data = tmp;
|
||||
chunks[2].len = 2;
|
||||
chunks[3].data = context;
|
||||
chunks[3].len = context_len;
|
||||
num_chunks = 4;
|
||||
} else {
|
||||
num_chunks = 2;
|
||||
}
|
||||
prf_id = BR_SSLPRF_SHA256;
|
||||
for (u = 0; u < (sizeof suites_sha384) / sizeof(uint16_t); u ++) {
|
||||
if (suites_sha384[u] == cc->session.cipher_suite) {
|
||||
prf_id = BR_SSLPRF_SHA384;
|
||||
}
|
||||
}
|
||||
iprf = br_ssl_engine_get_PRF(cc, prf_id);
|
||||
iprf(dst, len,
|
||||
cc->session.master_secret, sizeof cc->session.master_secret,
|
||||
label, num_chunks, chunks);
|
||||
return 1;
|
||||
}
|
@ -1075,21 +1075,43 @@ test_HMAC_DRBG(void)
|
||||
}
|
||||
|
||||
static void
|
||||
do_KAT_PRF(
|
||||
void (*prf)(void *dst, size_t len,
|
||||
const void *secret, size_t secret_len,
|
||||
const char *label, const void *seed, size_t seed_len),
|
||||
do_KAT_PRF(br_tls_prf_impl prf,
|
||||
const char *ssecret, const char *label, const char *sseed,
|
||||
const char *sref)
|
||||
{
|
||||
unsigned char secret[100], seed[100], ref[500], out[500];
|
||||
size_t secret_len, seed_len, ref_len;
|
||||
br_tls_prf_seed_chunk chunks[2];
|
||||
|
||||
secret_len = hextobin(secret, ssecret);
|
||||
seed_len = hextobin(seed, sseed);
|
||||
ref_len = hextobin(ref, sref);
|
||||
prf(out, ref_len, secret, secret_len, label, seed, seed_len);
|
||||
check_equals("TLS PRF KAT", out, ref, ref_len);
|
||||
|
||||
chunks[0].data = seed;
|
||||
chunks[0].len = seed_len;
|
||||
prf(out, ref_len, secret, secret_len, label, 1, chunks);
|
||||
check_equals("TLS PRF KAT 1", out, ref, ref_len);
|
||||
|
||||
chunks[0].data = seed;
|
||||
chunks[0].len = seed_len;
|
||||
chunks[1].data = NULL;
|
||||
chunks[1].len = 0;
|
||||
prf(out, ref_len, secret, secret_len, label, 2, chunks);
|
||||
check_equals("TLS PRF KAT 2", out, ref, ref_len);
|
||||
|
||||
chunks[0].data = NULL;
|
||||
chunks[0].len = 0;
|
||||
chunks[1].data = seed;
|
||||
chunks[1].len = seed_len;
|
||||
prf(out, ref_len, secret, secret_len, label, 2, chunks);
|
||||
check_equals("TLS PRF KAT 3", out, ref, ref_len);
|
||||
|
||||
chunks[0].data = seed;
|
||||
chunks[0].len = seed_len >> 1;
|
||||
chunks[1].data = seed + chunks[0].len;
|
||||
chunks[1].len = seed_len - chunks[0].len;
|
||||
prf(out, ref_len, secret, secret_len, label, 2, chunks);
|
||||
check_equals("TLS PRF KAT 4", out, ref, ref_len);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
x
Reference in New Issue
Block a user