aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorErvin Oro <ervin.oro@aalto.fi>2019-03-11 11:21:36 (GMT)
committerJouni Malinen <j@w1.fi>2019-03-16 16:52:09 (GMT)
commita916ff5cd819ad4410374f421eb4f04fa683604a (patch)
tree021950449e1f6a5322a4d17df699fff86676f09a /src
parentfab49f6145f44760e888b3844a9fff9440a85b27 (diff)
downloadhostap-a916ff5cd819ad4410374f421eb4f04fa683604a.zip
hostap-a916ff5cd819ad4410374f421eb4f04fa683604a.tar.gz
hostap-a916ff5cd819ad4410374f421eb4f04fa683604a.tar.bz2
Add support for an optional context parameter to TLS exporter
Allow an additional context value to be passed to TLS exporter as specified in RFC 5705 section 4. This does not yet implement it for the internal TLS implementation. However, as currently nothing uses context yet, this will not break anything right now. WolfSSL maintainers also stated that they are not going to add context support yet, but would look into it if/when this is required by a published draft or a standard. Signed-off-by: Ervin Oro <ervin.oro@aalto.fi>
Diffstat (limited to 'src')
-rw-r--r--src/crypto/tls.h8
-rw-r--r--src/crypto/tls_gnutls.c11
-rw-r--r--src/crypto/tls_internal.c5
-rw-r--r--src/crypto/tls_none.c3
-rw-r--r--src/crypto/tls_openssl.c6
-rw-r--r--src/crypto/tls_wolfssl.c5
-rw-r--r--src/eap_peer/eap_peap.c1
-rw-r--r--src/eap_peer/eap_tls.c1
-rw-r--r--src/eap_peer/eap_tls_common.c13
-rw-r--r--src/eap_peer/eap_tls_common.h3
-rw-r--r--src/eap_peer/eap_ttls.c4
-rw-r--r--src/eap_server/eap_server_peap.c6
-rw-r--r--src/eap_server/eap_server_tls.c2
-rw-r--r--src/eap_server/eap_server_tls_common.c9
-rw-r--r--src/eap_server/eap_server_ttls.c6
-rw-r--r--src/eap_server/eap_tls_common.h3
16 files changed, 62 insertions, 24 deletions
diff --git a/src/crypto/tls.h b/src/crypto/tls.h
index 6cc9241..9463f58 100644
--- a/src/crypto/tls.h
+++ b/src/crypto/tls.h
@@ -370,15 +370,21 @@ int __must_check tls_connection_get_random(void *tls_ctx,
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_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
* @out: Buffer for output data from TLS-PRF
* @out_len: Length of the output buffer
* Returns: 0 on success, -1 on failure
*
- * Exports keying material using the mechanism described in RFC 5705.
+ * Exports keying material using the mechanism described in RFC 5705. If
+ * context is %NULL, context is not provided; otherwise, context is provided
+ * (including the case of empty context with context_len == 0).
*/
int __must_check 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);
/**
diff --git a/src/crypto/tls_gnutls.c b/src/crypto/tls_gnutls.c
index 73e80f3..ccd2884 100644
--- a/src/crypto/tls_gnutls.c
+++ b/src/crypto/tls_gnutls.c
@@ -898,14 +898,23 @@ int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn,
int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
- const char *label, u8 *out, size_t out_len)
+ const char *label, const u8 *context,
+ size_t context_len, u8 *out, size_t out_len)
{
if (conn == NULL || conn->session == NULL)
return -1;
+#if GNUTLS_VERSION_NUMBER >= 0x030404
+ return gnutls_prf_rfc5705(conn->session, os_strlen(label), label,
+ context_len, (const char *) context,
+ out_len, (char *) out);
+#else /* 3.4.4 */
+ if (context)
+ return -1;
return gnutls_prf(conn->session, os_strlen(label), label,
0 /* client_random first */, 0, NULL, out_len,
(char *) out);
+#endif /* 3.4.4 */
}
diff --git a/src/crypto/tls_internal.c b/src/crypto/tls_internal.c
index 2876630..50a7b30 100644
--- a/src/crypto/tls_internal.c
+++ b/src/crypto/tls_internal.c
@@ -452,8 +452,11 @@ static int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
- const char *label, u8 *out, size_t out_len)
+ 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);
}
diff --git a/src/crypto/tls_none.c b/src/crypto/tls_none.c
index 108e9aa..6d6fb0c 100644
--- a/src/crypto/tls_none.c
+++ b/src/crypto/tls_none.c
@@ -94,7 +94,8 @@ int tls_connection_get_random(void *tls_ctx, struct tls_connection *conn,
int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
- const char *label, u8 *out, size_t out_len)
+ const char *label, const u8 *context,
+ size_t context_len, u8 *out, size_t out_len)
{
return -1;
}
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index b8d0556..fc55518 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -3908,11 +3908,13 @@ static int openssl_get_keyblock_size(SSL *ssl)
int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
- const char *label, u8 *out, size_t out_len)
+ const char *label, const u8 *context,
+ size_t context_len, u8 *out, size_t out_len)
{
if (!conn ||
SSL_export_keying_material(conn->ssl, out, out_len, label,
- os_strlen(label), NULL, 0, 0) != 1)
+ os_strlen(label), context, context_len,
+ context != NULL) != 1)
return -1;
return 0;
}
diff --git a/src/crypto/tls_wolfssl.c b/src/crypto/tls_wolfssl.c
index 39a24b3..41fc946 100644
--- a/src/crypto/tls_wolfssl.c
+++ b/src/crypto/tls_wolfssl.c
@@ -1973,8 +1973,11 @@ int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn,
int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
- const char *label, u8 *out, size_t out_len)
+ const char *label, const u8 *context,
+ size_t context_len, u8 *out, size_t out_len)
{
+ if (context)
+ return -1;
if (!conn || wolfSSL_make_eap_keys(conn->ssl, out, out_len, label) != 0)
return -1;
return 0;
diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c
index 650bea6..8dcf7cc 100644
--- a/src/eap_peer/eap_peap.c
+++ b/src/eap_peer/eap_peap.c
@@ -1084,6 +1084,7 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
"key derivation", label);
data->key_data =
eap_peer_tls_derive_key(sm, &data->ssl, label,
+ NULL, 0,
EAP_TLS_KEY_LEN +
EAP_EMSK_LEN);
if (data->key_data) {
diff --git a/src/eap_peer/eap_tls.c b/src/eap_peer/eap_tls.c
index cb74702..ffea9d2 100644
--- a/src/eap_peer/eap_tls.c
+++ b/src/eap_peer/eap_tls.c
@@ -198,6 +198,7 @@ static void eap_tls_success(struct eap_sm *sm, struct eap_tls_data *data,
eap_tls_free_key(data);
data->key_data = eap_peer_tls_derive_key(sm, &data->ssl, label,
+ NULL, 0,
EAP_TLS_KEY_LEN +
EAP_EMSK_LEN);
if (data->key_data) {
diff --git a/src/eap_peer/eap_tls_common.c b/src/eap_peer/eap_tls_common.c
index 1ee01a2..cb94c45 100644
--- a/src/eap_peer/eap_tls_common.c
+++ b/src/eap_peer/eap_tls_common.c
@@ -349,6 +349,8 @@ void eap_peer_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
* @data: Data for TLS processing
* @label: Label string for deriving the keys, e.g., "client EAP encryption"
+ * @context: Optional extra upper-layer context (max len 2^16)
+ * @context_len: The length of the context value
* @len: Length of the key material to generate (usually 64 for MSK)
* Returns: Pointer to allocated key on success or %NULL on failure
*
@@ -357,9 +359,12 @@ void eap_peer_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
* different label to bind the key usage into the generated material.
*
* The caller is responsible for freeing the returned buffer.
+ *
+ * Note: To provide the RFC 5705 context, the context variable must be non-NULL.
*/
u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
- const char *label, size_t len)
+ const char *label, const u8 *context,
+ size_t context_len, size_t len)
{
u8 *out;
@@ -367,8 +372,8 @@ u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
if (out == NULL)
return NULL;
- if (tls_connection_export_key(data->ssl_ctx, data->conn, label, out,
- len)) {
+ if (tls_connection_export_key(data->ssl_ctx, data->conn, label,
+ context, context_len, out, len)) {
os_free(out);
return NULL;
}
@@ -409,7 +414,7 @@ u8 * eap_peer_tls_derive_session_id(struct eap_sm *sm,
if (!id)
return NULL;
method_id = eap_peer_tls_derive_key(
- sm, data, "EXPORTER_EAP_TLS_Method-Id", 64);
+ sm, data, "EXPORTER_EAP_TLS_Method-Id", NULL, 0, 64);
if (!method_id) {
os_free(id);
return NULL;
diff --git a/src/eap_peer/eap_tls_common.h b/src/eap_peer/eap_tls_common.h
index 306e6a9..5f82529 100644
--- a/src/eap_peer/eap_tls_common.h
+++ b/src/eap_peer/eap_tls_common.h
@@ -99,7 +99,8 @@ int eap_peer_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
struct eap_peer_config *config, u8 eap_type);
void eap_peer_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data);
u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
- const char *label, size_t len);
+ const char *label, const u8 *context,
+ size_t context_len, size_t len);
u8 * eap_peer_tls_derive_session_id(struct eap_sm *sm,
struct eap_ssl_data *data, u8 eap_type,
size_t *len);
diff --git a/src/eap_peer/eap_ttls.c b/src/eap_peer/eap_ttls.c
index 5d26701..1c8dbe2 100644
--- a/src/eap_peer/eap_ttls.c
+++ b/src/eap_peer/eap_ttls.c
@@ -271,6 +271,7 @@ static int eap_ttls_v0_derive_key(struct eap_sm *sm,
eap_ttls_free_key(data);
data->key_data = eap_peer_tls_derive_key(sm, &data->ssl,
"ttls keying material",
+ NULL, 0,
EAP_TLS_KEY_LEN +
EAP_EMSK_LEN);
if (!data->key_data) {
@@ -303,7 +304,8 @@ static int eap_ttls_v0_derive_key(struct eap_sm *sm,
static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm,
struct eap_ttls_data *data, size_t len)
{
- return eap_peer_tls_derive_key(sm, &data->ssl, "ttls challenge", len);
+ return eap_peer_tls_derive_key(sm, &data->ssl, "ttls challenge",
+ NULL, 0, len);
}
#endif /* CONFIG_FIPS */
diff --git a/src/eap_server/eap_server_peap.c b/src/eap_server/eap_server_peap.c
index 3d334a0..92c0e5e 100644
--- a/src/eap_server/eap_server_peap.c
+++ b/src/eap_server/eap_server_peap.c
@@ -331,7 +331,7 @@ static int eap_peap_derive_cmk(struct eap_sm *sm, struct eap_peap_data *data)
* phase 1 of PEAP (based on TLS).
*/
tk = eap_server_tls_derive_key(sm, &data->ssl, "client EAP encryption",
- EAP_TLS_KEY_LEN);
+ NULL, 0, EAP_TLS_KEY_LEN);
if (tk == NULL)
return -1;
wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: TK", tk, 60);
@@ -1333,7 +1333,7 @@ static u8 * eap_peap_getKey(struct eap_sm *sm, void *priv, size_t *len)
/* TODO: PEAPv1 - different label in some cases */
eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
- "client EAP encryption",
+ "client EAP encryption", NULL, 0,
EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
if (eapKeyData) {
os_memset(eapKeyData + EAP_TLS_KEY_LEN, 0, EAP_EMSK_LEN);
@@ -1363,7 +1363,7 @@ static u8 * eap_peap_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
/* TODO: PEAPv1 - different label in some cases */
eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
- "client EAP encryption",
+ "client EAP encryption", NULL, 0,
EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
if (eapKeyData) {
emsk = os_memdup(eapKeyData + EAP_TLS_KEY_LEN, EAP_EMSK_LEN);
diff --git a/src/eap_server/eap_server_tls.c b/src/eap_server/eap_server_tls.c
index 13d2349..357e72a 100644
--- a/src/eap_server/eap_server_tls.c
+++ b/src/eap_server/eap_server_tls.c
@@ -331,6 +331,7 @@ static u8 * eap_tls_getKey(struct eap_sm *sm, void *priv, size_t *len)
else
label = "client EAP encryption";
eapKeyData = eap_server_tls_derive_key(sm, &data->ssl, label,
+ NULL, 0,
EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
if (eapKeyData) {
*len = EAP_TLS_KEY_LEN;
@@ -359,6 +360,7 @@ static u8 * eap_tls_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
else
label = "client EAP encryption";
eapKeyData = eap_server_tls_derive_key(sm, &data->ssl, label,
+ NULL, 0,
EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
if (eapKeyData) {
emsk = os_malloc(EAP_EMSK_LEN);
diff --git a/src/eap_server/eap_server_tls_common.c b/src/eap_server/eap_server_tls_common.c
index 4ba7c24..0eca0ff 100644
--- a/src/eap_server/eap_server_tls_common.c
+++ b/src/eap_server/eap_server_tls_common.c
@@ -107,7 +107,8 @@ void eap_server_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
u8 * eap_server_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
- const char *label, size_t len)
+ const char *label, const u8 *context,
+ size_t context_len, size_t len)
{
u8 *out;
@@ -115,8 +116,8 @@ u8 * eap_server_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
if (out == NULL)
return NULL;
- if (tls_connection_export_key(sm->ssl_ctx, data->conn, label, out,
- len)) {
+ if (tls_connection_export_key(sm->ssl_ctx, data->conn, label,
+ context, context_len, out, len)) {
os_free(out);
return NULL;
}
@@ -157,7 +158,7 @@ u8 * eap_server_tls_derive_session_id(struct eap_sm *sm,
if (!id)
return NULL;
method_id = eap_server_tls_derive_key(
- sm, data, "EXPORTER_EAP_TLS_Method-Id", 64);
+ sm, data, "EXPORTER_EAP_TLS_Method-Id", NULL, 0, 64);
if (!method_id) {
os_free(id);
return NULL;
diff --git a/src/eap_server/eap_server_ttls.c b/src/eap_server/eap_server_ttls.c
index b14996b..52bff8a 100644
--- a/src/eap_server/eap_server_ttls.c
+++ b/src/eap_server/eap_server_ttls.c
@@ -332,7 +332,7 @@ static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm,
struct eap_ttls_data *data, size_t len)
{
return eap_server_tls_derive_key(sm, &data->ssl, "ttls challenge",
- len);
+ NULL, 0, len);
}
@@ -1268,7 +1268,7 @@ static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len)
return NULL;
eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
- "ttls keying material",
+ "ttls keying material", NULL, 0,
EAP_TLS_KEY_LEN);
if (eapKeyData) {
*len = EAP_TLS_KEY_LEN;
@@ -1310,7 +1310,7 @@ static u8 * eap_ttls_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
return NULL;
eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
- "ttls keying material",
+ "ttls keying material", NULL, 0,
EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
if (eapKeyData) {
emsk = os_malloc(EAP_EMSK_LEN);
diff --git a/src/eap_server/eap_tls_common.h b/src/eap_server/eap_tls_common.h
index 31f6e72..0b04983 100644
--- a/src/eap_server/eap_tls_common.h
+++ b/src/eap_server/eap_tls_common.h
@@ -78,7 +78,8 @@ int eap_server_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
int verify_peer, int eap_type);
void eap_server_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data);
u8 * eap_server_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
- const char *label, size_t len);
+ const char *label, const u8 *context,
+ size_t context_len, size_t len);
u8 * eap_server_tls_derive_session_id(struct eap_sm *sm,
struct eap_ssl_data *data, u8 eap_type,
size_t *len);