]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
EAP-PEAP: Derive EMSK and use 128-octet derivation for MSK
authorJouni Malinen <j@w1.fi>
Fri, 1 Feb 2019 21:52:28 +0000 (23:52 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 1 Feb 2019 21:52:28 +0000 (23:52 +0200)
Derive EMSK when using EAP-PEAP to enable ERP. In addition, change the
MSK derivation for EAP-PEAP to always derive 128 octets of key material
instead of the 64 octets to cover just the MSK. This is needed with the
PRF used in TLS 1.3 since the output length is mixed into the PRF
context.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/eap_peer/eap_peap.c
src/eap_server/eap_server_peap.c

index 34075b1d9af656f8232835f63478e42ac6ed74ba..9b87b6b94451ba1e2d3882c2fe85d223d056e221 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * EAP peer method: EAP-PEAP (draft-josefsson-pppext-eap-tls-eap-10.txt)
- * Copyright (c) 2004-2015, 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.
@@ -169,7 +169,7 @@ static void * eap_peap_init(struct eap_sm *sm)
 static void eap_peap_free_key(struct eap_peap_data *data)
 {
        if (data->key_data) {
-               bin_clear_free(data->key_data, EAP_TLS_KEY_LEN);
+               bin_clear_free(data->key_data, EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
                data->key_data = NULL;
        }
 }
@@ -1081,12 +1081,18 @@ 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,
-                                                       EAP_TLS_KEY_LEN);
+                                                       EAP_TLS_KEY_LEN +
+                                                       EAP_EMSK_LEN);
                        if (data->key_data) {
                                wpa_hexdump_key(MSG_DEBUG,
                                                "EAP-PEAP: Derived key",
                                                data->key_data,
                                                EAP_TLS_KEY_LEN);
+                               wpa_hexdump_key(MSG_DEBUG,
+                                               "EAP-PEAP: Derived EMSK",
+                                               data->key_data +
+                                               EAP_TLS_KEY_LEN,
+                                               EAP_EMSK_LEN);
                        } else {
                                wpa_printf(MSG_DEBUG, "EAP-PEAP: Failed to "
                                           "derive key");
@@ -1264,6 +1270,29 @@ static u8 * eap_peap_getKey(struct eap_sm *sm, void *priv, size_t *len)
 }
 
 
+static u8 * eap_peap_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
+{
+       struct eap_peap_data *data = priv;
+       u8 *key;
+
+       if (!data->key_data || !data->phase2_success)
+               return NULL;
+
+       if (data->crypto_binding_used) {
+               /* [MS-PEAP] does not define EMSK derivation */
+               return NULL;
+       }
+
+       key = os_memdup(data->key_data + EAP_TLS_KEY_LEN, EAP_EMSK_LEN);
+       if (!key)
+               return NULL;
+
+       *len = EAP_EMSK_LEN;
+
+       return key;
+}
+
+
 static u8 * eap_peap_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
 {
        struct eap_peap_data *data = priv;
@@ -1296,6 +1325,7 @@ int eap_peer_peap_register(void)
        eap->process = eap_peap_process;
        eap->isKeyAvailable = eap_peap_isKeyAvailable;
        eap->getKey = eap_peap_getKey;
+       eap->get_emsk = eap_peap_get_emsk;
        eap->get_status = eap_peap_get_status;
        eap->has_reauth_data = eap_peap_has_reauth_data;
        eap->deinit_for_reauth = eap_peap_deinit_for_reauth;
index 18d31b527fdd7c9db8f967b51e33c08ef1a0cf2f..97dba41c800e60df49a522201e9a327bee7ac485 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * hostapd / EAP-PEAP (draft-josefsson-pppext-eap-tls-eap-10.txt)
- * Copyright (c) 2004-2008, 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.
@@ -756,7 +756,7 @@ static void eap_peap_process_phase2_tlv(struct eap_sm *sm,
                        } else {
                                eap_peap_state(data, FAILURE);
                        }
-                       
+
                } else if (status == EAP_TLV_RESULT_FAILURE) {
                        wpa_printf(MSG_INFO, "EAP-PEAP: TLV Result - Failure "
                                   "- requested %s", requested);
@@ -1328,8 +1328,9 @@ 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",
-                                              EAP_TLS_KEY_LEN);
+                                              EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
        if (eapKeyData) {
+               os_memset(eapKeyData + EAP_TLS_KEY_LEN, 0, EAP_EMSK_LEN);
                *len = EAP_TLS_KEY_LEN;
                wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Derived key",
                            eapKeyData, EAP_TLS_KEY_LEN);
@@ -1341,6 +1342,40 @@ static u8 * eap_peap_getKey(struct eap_sm *sm, void *priv, size_t *len)
 }
 
 
+static u8 * eap_peap_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
+{
+       struct eap_peap_data *data = priv;
+       u8 *eapKeyData, *emsk;
+
+       if (data->state != SUCCESS)
+               return NULL;
+
+       if (data->crypto_binding_used) {
+               /* [MS-PEAP] does not define EMSK derivation */
+               return NULL;
+       }
+
+       /* TODO: PEAPv1 - different label in some cases */
+       eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
+                                              "client EAP encryption",
+                                              EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
+       if (eapKeyData) {
+               emsk = os_memdup(eapKeyData + EAP_TLS_KEY_LEN, EAP_EMSK_LEN);
+               bin_clear_free(eapKeyData, EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
+               if (!emsk)
+                       return NULL;
+               *len = EAP_EMSK_LEN;
+               wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Derived EMSK",
+                           emsk, EAP_EMSK_LEN);
+       } else {
+               wpa_printf(MSG_DEBUG, "EAP-PEAP: Failed to derive EMSK");
+               emsk = NULL;
+       }
+
+       return emsk;
+}
+
+
 static Boolean eap_peap_isSuccess(struct eap_sm *sm, void *priv)
 {
        struct eap_peap_data *data = priv;
@@ -1376,6 +1411,7 @@ int eap_server_peap_register(void)
        eap->process = eap_peap_process;
        eap->isDone = eap_peap_isDone;
        eap->getKey = eap_peap_getKey;
+       eap->get_emsk = eap_peap_get_emsk;
        eap->isSuccess = eap_peap_isSuccess;
        eap->getSessionId = eap_peap_get_session_id;