Added implementation of keying material export (RFC 5705) (API for PRF implementations changed, to handle chunked seeds).

This commit is contained in:
Thomas Pornin 2017-07-04 20:43:39 +02:00
parent 2b738493bd
commit ea95d8264c
15 changed files with 256 additions and 77 deletions

View file

@ -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
}

View file

@ -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.
*/