TLS: Add support for RFC 5705 TLS exporter context with internal TLS
Use the provided context, if any, to generate the seed for TLS PRF. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
a916ff5cd8
commit
32f4760664
5 changed files with 73 additions and 23 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* TLS interface functions and an internal TLS implementation
|
||||
* Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
|
@ -412,7 +412,8 @@ static int tls_get_keyblock_size(struct tls_connection *conn)
|
|||
|
||||
|
||||
static int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
|
||||
const char *label, int server_random_first,
|
||||
const char *label, const u8 *context,
|
||||
size_t context_len, int server_random_first,
|
||||
int skip_keyblock, u8 *out, size_t out_len)
|
||||
{
|
||||
int ret = -1, skip = 0;
|
||||
|
@ -431,15 +432,15 @@ static int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
|
|||
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (conn->client) {
|
||||
ret = tlsv1_client_prf(conn->client, label,
|
||||
server_random_first,
|
||||
ret = tlsv1_client_prf(conn->client, label, context,
|
||||
context_len, server_random_first,
|
||||
_out, skip + out_len);
|
||||
}
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server) {
|
||||
ret = tlsv1_server_prf(conn->server, label,
|
||||
server_random_first,
|
||||
ret = tlsv1_server_prf(conn->server, label, context,
|
||||
context_len, server_random_first,
|
||||
_out, skip + out_len);
|
||||
}
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
|
@ -455,17 +456,16 @@ int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
|
|||
const char *label, const u8 *context,
|
||||
size_t context_len, u8 *out, size_t out_len)
|
||||
{
|
||||
if (context)
|
||||
return -1;
|
||||
return tls_connection_prf(tls_ctx, conn, label, 0, 0, out, out_len);
|
||||
return tls_connection_prf(tls_ctx, conn, label, context, context_len,
|
||||
0, 0, out, out_len);
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
|
||||
u8 *out, size_t out_len)
|
||||
{
|
||||
return tls_connection_prf(tls_ctx, conn, "key expansion", 1, 1, out,
|
||||
out_len);
|
||||
return tls_connection_prf(tls_ctx, conn, "key expansion", NULL, 0,
|
||||
1, 1, out, out_len);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* TLS v1.0/v1.1/v1.2 client (RFC 2246, RFC 4346, RFC 5246)
|
||||
* Copyright (c) 2006-2015, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2006-2019, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
|
@ -514,6 +514,8 @@ int tlsv1_client_established(struct tlsv1_client *conn)
|
|||
* tlsv1_client_prf - Use TLS-PRF to derive keying material
|
||||
* @conn: TLSv1 client connection data from tlsv1_client_init()
|
||||
* @label: Label (e.g., description of the key) for PRF
|
||||
* @context: Optional extra upper-layer context (max len 2^16)
|
||||
* @context_len: The length of the context value
|
||||
* @server_random_first: seed is 0 = client_random|server_random,
|
||||
* 1 = server_random|client_random
|
||||
* @out: Buffer for output data from TLS-PRF
|
||||
|
@ -521,13 +523,26 @@ int tlsv1_client_established(struct tlsv1_client *conn)
|
|||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int tlsv1_client_prf(struct tlsv1_client *conn, const char *label,
|
||||
const u8 *context, size_t context_len,
|
||||
int server_random_first, u8 *out, size_t out_len)
|
||||
{
|
||||
u8 seed[2 * TLS_RANDOM_LEN];
|
||||
u8 *seed, *pos;
|
||||
size_t seed_len = 2 * TLS_RANDOM_LEN;
|
||||
int res;
|
||||
|
||||
if (conn->state != ESTABLISHED)
|
||||
return -1;
|
||||
|
||||
if (context_len > 65535)
|
||||
return -1;
|
||||
|
||||
if (context)
|
||||
seed_len += 2 + context_len;
|
||||
|
||||
seed = os_malloc(seed_len);
|
||||
if (!seed)
|
||||
return -1;
|
||||
|
||||
if (server_random_first) {
|
||||
os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);
|
||||
os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random,
|
||||
|
@ -538,9 +553,18 @@ int tlsv1_client_prf(struct tlsv1_client *conn, const char *label,
|
|||
TLS_RANDOM_LEN);
|
||||
}
|
||||
|
||||
return tls_prf(conn->rl.tls_version,
|
||||
if (context) {
|
||||
pos = seed + 2 * TLS_RANDOM_LEN;
|
||||
WPA_PUT_BE16(pos, context_len);
|
||||
pos += 2;
|
||||
os_memcpy(pos, context, context_len);
|
||||
}
|
||||
|
||||
res = tls_prf(conn->rl.tls_version,
|
||||
conn->master_secret, TLS_MASTER_SECRET_LEN,
|
||||
label, seed, 2 * TLS_RANDOM_LEN, out, out_len);
|
||||
label, seed, seed_len, out, out_len);
|
||||
os_free(seed);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* TLS v1.0/v1.1/v1.2 client (RFC 2246, RFC 4346, RFC 5246)
|
||||
* Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2006-2019, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
|
@ -19,6 +19,7 @@ struct tlsv1_client * tlsv1_client_init(void);
|
|||
void tlsv1_client_deinit(struct tlsv1_client *conn);
|
||||
int tlsv1_client_established(struct tlsv1_client *conn);
|
||||
int tlsv1_client_prf(struct tlsv1_client *conn, const char *label,
|
||||
const u8 *context, size_t context_len,
|
||||
int server_random_first, u8 *out, size_t out_len);
|
||||
u8 * tlsv1_client_handshake(struct tlsv1_client *conn,
|
||||
const u8 *in_data, size_t in_len,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* TLS v1.0/v1.1/v1.2 server (RFC 2246, RFC 4346, RFC 5246)
|
||||
* Copyright (c) 2006-2014, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2006-2019, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
|
@ -462,6 +462,8 @@ int tlsv1_server_established(struct tlsv1_server *conn)
|
|||
* tlsv1_server_prf - Use TLS-PRF to derive keying material
|
||||
* @conn: TLSv1 server connection data from tlsv1_server_init()
|
||||
* @label: Label (e.g., description of the key) for PRF
|
||||
* @context: Optional extra upper-layer context (max len 2^16)
|
||||
* @context_len: The length of the context value
|
||||
* @server_random_first: seed is 0 = client_random|server_random,
|
||||
* 1 = server_random|client_random
|
||||
* @out: Buffer for output data from TLS-PRF
|
||||
|
@ -469,13 +471,26 @@ int tlsv1_server_established(struct tlsv1_server *conn)
|
|||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int tlsv1_server_prf(struct tlsv1_server *conn, const char *label,
|
||||
const u8 *context, size_t context_len,
|
||||
int server_random_first, u8 *out, size_t out_len)
|
||||
{
|
||||
u8 seed[2 * TLS_RANDOM_LEN];
|
||||
u8 *seed, *pos;
|
||||
size_t seed_len = 2 * TLS_RANDOM_LEN;
|
||||
int res;
|
||||
|
||||
if (conn->state != ESTABLISHED)
|
||||
return -1;
|
||||
|
||||
if (context_len > 65535)
|
||||
return -1;
|
||||
|
||||
if (context)
|
||||
seed_len += 2 + context_len;
|
||||
|
||||
seed = os_malloc(seed_len);
|
||||
if (!seed)
|
||||
return -1;
|
||||
|
||||
if (server_random_first) {
|
||||
os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);
|
||||
os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random,
|
||||
|
@ -486,9 +501,18 @@ int tlsv1_server_prf(struct tlsv1_server *conn, const char *label,
|
|||
TLS_RANDOM_LEN);
|
||||
}
|
||||
|
||||
return tls_prf(conn->rl.tls_version,
|
||||
if (context) {
|
||||
pos = seed + 2 * TLS_RANDOM_LEN;
|
||||
WPA_PUT_BE16(pos, context_len);
|
||||
pos += 2;
|
||||
os_memcpy(pos, context, context_len);
|
||||
}
|
||||
|
||||
res = tls_prf(conn->rl.tls_version,
|
||||
conn->master_secret, TLS_MASTER_SECRET_LEN,
|
||||
label, seed, 2 * TLS_RANDOM_LEN, out, out_len);
|
||||
label, seed, seed_len, out, out_len);
|
||||
os_free(seed);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* TLS v1.0/v1.1/v1.2 server (RFC 2246, RFC 4346, RFC 5246)
|
||||
* Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2006-2019, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
|
@ -19,6 +19,7 @@ struct tlsv1_server * tlsv1_server_init(struct tlsv1_credentials *cred);
|
|||
void tlsv1_server_deinit(struct tlsv1_server *conn);
|
||||
int tlsv1_server_established(struct tlsv1_server *conn);
|
||||
int tlsv1_server_prf(struct tlsv1_server *conn, const char *label,
|
||||
const u8 *context, size_t context_len,
|
||||
int server_random_first, u8 *out, size_t out_len);
|
||||
u8 * tlsv1_server_handshake(struct tlsv1_server *conn,
|
||||
const u8 *in_data, size_t in_len, size_t *out_len);
|
||||
|
|
Loading…
Reference in a new issue