According to the proposed standard change in https://emu-wg.github.io/draft-ietf-emu-eap-tls13/draft-ietf-emu-eap-tls13.html#rfc.section.2.3 Internal SSL library nor the WolfSSL library seem to support an additional context value as specified in rfc5705#section-4. Therefore, this breaks EAP_TLS 1.3 with those. (However, TLS 1.3 remains disabled by default.) Signed-off-by: Ervin Oro <ervin.oro@xxxxxxxx> --- src/crypto/tls.h | 10 +++++++++ src/crypto/tls_gnutls.c | 14 ++++++++++-- src/crypto/tls_internal.c | 9 ++++++++ src/crypto/tls_none.c | 9 ++++++++ src/crypto/tls_openssl.c | 13 ++++++++++- src/crypto/tls_wolfssl.c | 9 ++++++++ src/eap_peer/eap_tls.c | 13 ++++++++--- src/eap_peer/eap_tls_common.c | 24 ++++++++++++++++----- src/eap_peer/eap_tls_common.h | 3 +++ src/eap_server/eap_server_tls.c | 30 +++++++++++++++++++------- src/eap_server/eap_server_tls_common.c | 21 +++++++++++++----- src/eap_server/eap_tls_common.h | 3 +++ 12 files changed, 134 insertions(+), 24 deletions(-) diff --git a/src/crypto/tls.h b/src/crypto/tls.h index 413cccddc..3291ff877 100644 --- a/src/crypto/tls.h +++ b/src/crypto/tls.h @@ -367,6 +367,9 @@ 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) + * @contextlen: the length of the context value (MAY be zero) + * @use_context: 0 if context is not used (no context != 0-length context) * @out: Buffer for output data from TLS-PRF * @out_len: Length of the output buffer * Returns: 0 on success, -1 on failure @@ -378,6 +381,13 @@ int __must_check tls_connection_export_key(void *tls_ctx, const char *label, u8 *out, size_t out_len); +int __must_check tls_connection_export_key2(void *tls_ctx, + struct tls_connection *conn, + const char *label, + const unsigned char *context, + size_t contextlen, int use_context, + u8 *out, size_t out_len); + /** * tls_connection_get_eap_fast_key - Derive key material for EAP-FAST * @tls_ctx: TLS context data from tls_init() diff --git a/src/crypto/tls_gnutls.c b/src/crypto/tls_gnutls.c index 527d01ecf..9e213ea8a 100644 --- a/src/crypto/tls_gnutls.c +++ b/src/crypto/tls_gnutls.c @@ -896,13 +896,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) +{ + return tls_connection_export_key2(tls_ctx, conn, label, NULL, 0, 0 out, + out_len); +} + + +int tls_connection_export_key2(void *tls_ctx, struct tls_connection *conn, + const char *label, const unsigned char *context, + size_t contextlen, int use_context, u8 *out, + size_t out_len) { if (conn == NULL || conn->session == NULL) return -1; return gnutls_prf(conn->session, os_strlen(label), label, - 0 /* client_random first */, 0, NULL, out_len, - (char *) out); + 0 /* client_random first */, contextlen, context, + out_len, (char *) out); } diff --git a/src/crypto/tls_internal.c b/src/crypto/tls_internal.c index 57b3e632d..82177e327 100644 --- a/src/crypto/tls_internal.c +++ b/src/crypto/tls_internal.c @@ -455,6 +455,15 @@ int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn, } +int tls_connection_export_key2(void *tls_ctx, struct tls_connection *conn, + const char *label, const unsigned char *context, + size_t contextlen, int use_context, u8 *out, + size_t out_len) +{ + return -1; +} + + int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, u8 *out, size_t out_len) { diff --git a/src/crypto/tls_none.c b/src/crypto/tls_none.c index 108e9aa2e..99c7fdeac 100644 --- a/src/crypto/tls_none.c +++ b/src/crypto/tls_none.c @@ -100,6 +100,15 @@ int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn, } +int tls_connection_export_key2(void *tls_ctx, struct tls_connection *conn, + const char *label, const unsigned char *context, + size_t contextlen, int use_context, u8 *out, + size_t out_len) +{ + return -1; +} + + int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, u8 *out, size_t out_len) { diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c index 18d76737e..fbc6b60ea 100644 --- a/src/crypto/tls_openssl.c +++ b/src/crypto/tls_openssl.c @@ -3670,10 +3670,21 @@ 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) +{ + return tls_connection_export_key2(tls_ctx, conn, label, NULL, 0, 0, out, + out_len); +} + + +int tls_connection_export_key2(void *tls_ctx, struct tls_connection *conn, + const char *label, const unsigned char *context, + size_t contextlen, int use_context, 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, contextlen, + use_context) != 1) return -1; return 0; } diff --git a/src/crypto/tls_wolfssl.c b/src/crypto/tls_wolfssl.c index b59622e5e..127c5dcd4 100644 --- a/src/crypto/tls_wolfssl.c +++ b/src/crypto/tls_wolfssl.c @@ -1978,6 +1978,15 @@ int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn, } +int tls_connection_export_key2(void *tls_ctx, struct tls_connection *conn, + const char *label, const unsigned char *context, + size_t contextlen, int use_context, u8 *out, + size_t out_len) +{ + return -1; +} + + #define SEED_LEN (RAN_LEN + RAN_LEN) int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, diff --git a/src/eap_peer/eap_tls.c b/src/eap_peer/eap_tls.c index cb747026c..92c2081a4 100644 --- a/src/eap_peer/eap_tls.c +++ b/src/eap_peer/eap_tls.c @@ -174,6 +174,9 @@ static void eap_tls_success(struct eap_sm *sm, struct eap_tls_data *data, struct eap_method_ret *ret) { const char *label; + const unsigned char context[] = {EAP_TYPE_TLS}; + size_t contextlen = 0; + int use_context = 0; wpa_printf(MSG_DEBUG, "EAP-TLS: Done"); @@ -184,6 +187,8 @@ static void eap_tls_success(struct eap_sm *sm, struct eap_tls_data *data, if (data->ssl.tls_v13) { label = "EXPORTER_EAP_TLS_Key_Material"; + contextlen = 1; + use_context = 1; /* A possible NewSessionTicket may be received before * EAP-Success, so need to allow it to be received. */ @@ -197,9 +202,11 @@ 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, - EAP_TLS_KEY_LEN + - EAP_EMSK_LEN); + data->key_data = eap_peer_tls_derive_key2(sm, &data->ssl, label, + context, contextlen, + use_context, + EAP_TLS_KEY_LEN + + EAP_EMSK_LEN); if (data->key_data) { wpa_hexdump_key(MSG_DEBUG, "EAP-TLS: Derived key", data->key_data, EAP_TLS_KEY_LEN); diff --git a/src/eap_peer/eap_tls_common.c b/src/eap_peer/eap_tls_common.c index 7dbd364a5..838dbabd2 100644 --- a/src/eap_peer/eap_tls_common.c +++ b/src/eap_peer/eap_tls_common.c @@ -347,6 +347,9 @@ 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) + * @contextlen: the length of the context value (MAY be zero) + * @use_context: 0 if context is not used (no context != 0-length context) * @len: Length of the key material to generate (usually 64 for MSK) * Returns: Pointer to allocated key on success or %NULL on failure * @@ -358,6 +361,14 @@ 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) +{ + return eap_peer_tls_derive_key2(sm, data, label, NULL, 0, 0, len); +} + + +u8 * eap_peer_tls_derive_key2(struct eap_sm *sm, struct eap_ssl_data *data, + const char *label, const unsigned char *context, + size_t contextlen, int use_context, size_t len) { u8 *out; @@ -365,8 +376,9 @@ 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_key2(data->ssl_ctx, data->conn, label, + context, contextlen, use_context, out, + len)) { os_free(out); return NULL; } @@ -400,14 +412,16 @@ u8 * eap_peer_tls_derive_session_id(struct eap_sm *sm, /* Session-Id = <EAP-Type> || Method-Id * Method-Id = TLS-Exporter("EXPORTER_EAP_TLS_Method-Id", - * "", 64) + * Type-Code, 64) */ *len = 1 + 64; id = os_malloc(*len); if (!id) return NULL; - method_id = eap_peer_tls_derive_key( - sm, data, "EXPORTER_EAP_TLS_Method-Id", 64); + const unsigned char context[] = {EAP_TYPE_TLS}; + method_id = eap_peer_tls_derive_key2( + sm, data, "EXPORTER_EAP_TLS_Method-Id", context, 1, 1, + 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 306e6a98b..c2839922b 100644 --- a/src/eap_peer/eap_tls_common.h +++ b/src/eap_peer/eap_tls_common.h @@ -100,6 +100,9 @@ int eap_peer_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data, 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); +u8 * eap_peer_tls_derive_key2(struct eap_sm *sm, struct eap_ssl_data *data, + const char *label, const unsigned char *context, + size_t contextlen, int use_context, 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_server/eap_server_tls.c b/src/eap_server/eap_server_tls.c index 13d234982..c8ee49717 100644 --- a/src/eap_server/eap_server_tls.c +++ b/src/eap_server/eap_server_tls.c @@ -322,16 +322,23 @@ static u8 * eap_tls_getKey(struct eap_sm *sm, void *priv, size_t *len) struct eap_tls_data *data = priv; u8 *eapKeyData; const char *label; + const unsigned char context[] = {EAP_TYPE_TLS}; + size_t contextlen = 0; + int use_context = 0; if (data->state != SUCCESS) return NULL; - if (data->ssl.tls_v13) + if (data->ssl.tls_v13) { label = "EXPORTER_EAP_TLS_Key_Material"; - else + contextlen = 1; + use_context = 1; + } else { label = "client EAP encryption"; - eapKeyData = eap_server_tls_derive_key(sm, &data->ssl, label, - EAP_TLS_KEY_LEN + EAP_EMSK_LEN); + } + eapKeyData = eap_server_tls_derive_key2(sm, &data->ssl, label, + context, contextlen, use_context, + EAP_TLS_KEY_LEN + EAP_EMSK_LEN); if (eapKeyData) { *len = EAP_TLS_KEY_LEN; wpa_hexdump(MSG_DEBUG, "EAP-TLS: Derived key", @@ -350,16 +357,23 @@ static u8 * eap_tls_get_emsk(struct eap_sm *sm, void *priv, size_t *len) struct eap_tls_data *data = priv; u8 *eapKeyData, *emsk; const char *label; + const unsigned char context[] = {EAP_TYPE_TLS}; + size_t contextlen = 0; + int use_context = 0; if (data->state != SUCCESS) return NULL; - if (data->ssl.tls_v13) + if (data->ssl.tls_v13) { label = "EXPORTER_EAP_TLS_Key_Material"; - else + contextlen = 1; + use_context = 1; + } else { label = "client EAP encryption"; - eapKeyData = eap_server_tls_derive_key(sm, &data->ssl, label, - EAP_TLS_KEY_LEN + EAP_EMSK_LEN); + } + eapKeyData = eap_server_tls_derive_key2(sm, &data->ssl, label, + context, contextlen, use_context, + EAP_TLS_KEY_LEN + EAP_EMSK_LEN); if (eapKeyData) { emsk = os_malloc(EAP_EMSK_LEN); if (emsk) diff --git a/src/eap_server/eap_server_tls_common.c b/src/eap_server/eap_server_tls_common.c index 4ba7c2499..c6386cddd 100644 --- a/src/eap_server/eap_server_tls_common.c +++ b/src/eap_server/eap_server_tls_common.c @@ -108,6 +108,14 @@ 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) +{ + return eap_server_tls_derive_key2(sm, data, label, NULL, 0, 0, len); +} + + +u8 * eap_server_tls_derive_key2(struct eap_sm *sm, struct eap_ssl_data *data, + const char *label, const unsigned char *context, + size_t contextlen, int use_context, size_t len) { u8 *out; @@ -115,8 +123,9 @@ 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_key2(sm->ssl_ctx, data->conn, label, + context, contextlen, use_context, out, + len)) { os_free(out); return NULL; } @@ -150,14 +159,16 @@ u8 * eap_server_tls_derive_session_id(struct eap_sm *sm, /* Session-Id = <EAP-Type> || Method-Id * Method-Id = TLS-Exporter("EXPORTER_EAP_TLS_Method-Id", - * "", 64) + * Type-Code, 64) */ *len = 1 + 64; id = os_malloc(*len); if (!id) return NULL; - method_id = eap_server_tls_derive_key( - sm, data, "EXPORTER_EAP_TLS_Method-Id", 64); + const unsigned char context[] = {EAP_TYPE_TLS}; + method_id = eap_server_tls_derive_key2( + sm, data, "EXPORTER_EAP_TLS_Method-Id", context, 1, 1, + 64); if (!method_id) { os_free(id); return NULL; diff --git a/src/eap_server/eap_tls_common.h b/src/eap_server/eap_tls_common.h index 31f6e72d7..443260972 100644 --- a/src/eap_server/eap_tls_common.h +++ b/src/eap_server/eap_tls_common.h @@ -79,6 +79,9 @@ int eap_server_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data, 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); +u8 * eap_server_tls_derive_key2(struct eap_sm *sm, struct eap_ssl_data *data, + const char *label, const unsigned char *context, + size_t contextlen, int use_context, 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); -- 2.17.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap