]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
EAP-AKA: Add Session-Id derivation during fast-reauth
authorMohit Sethi <mohit.sethi@aalto.fi>
Fri, 17 May 2019 19:06:12 +0000 (22:06 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 25 May 2019 14:17:00 +0000 (17:17 +0300)
The Session-Id derivation for EAP-AKA in RFC 5247 only explained how the
Session-Id is derived for regular authentication. Jouni reported it as
an errata with text explaining how to derive it during fast
reauthentication.

This patch now exports the Session-Id for EAP-AKA during fast
reauthentication based on this Session-Id = 0x17 || NONCE_S || MAC
construction.

Also documented by Alan Dekok in draft-dekok-emu-eap-session-id.

Signed-off-by: Mohit Sethi <mohit.sethi@aalto.fi>
src/eap_peer/eap_aka.c
src/eap_server/eap_server_aka.c

index a4441413f0ddd409ab04f23f053118f39c4ae79a..da5beee21977b341a9768b8dc14d9a2f7c76bea3 100644 (file)
@@ -31,6 +31,7 @@ struct eap_aka_data {
        u8 emsk[EAP_EMSK_LEN];
        u8 rand[EAP_AKA_RAND_LEN], autn[EAP_AKA_AUTN_LEN];
        u8 auts[EAP_AKA_AUTS_LEN];
+       u8 reauth_mac[EAP_SIM_MAC_LEN];
 
        int num_id_req, num_notification;
        u8 *pseudonym;
@@ -1226,6 +1227,14 @@ static struct wpabuf * eap_aka_process_reauthentication(
                                            EAP_AKA_UNABLE_TO_PROCESS_PACKET);
        }
 
+       /* At this stage the received MAC has been verified. Use this MAC for
+        * reauth Session-Id calculation if all other checks pass.
+        * The peer does not use the local MAC but the received MAC in deriving
+        * Session-Id. */
+       os_memcpy(data->reauth_mac, attr->mac, EAP_SIM_MAC_LEN);
+       wpa_hexdump(MSG_DEBUG, "EAP-AKA: Server MAC",
+                   data->reauth_mac, EAP_SIM_MAC_LEN);
+
        if (attr->encr_data == NULL || attr->iv == NULL) {
                wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication "
                           "message did not include encrypted data");
@@ -1497,14 +1506,24 @@ static u8 * eap_aka_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
        if (data->state != SUCCESS)
                return NULL;
 
-       *len = 1 + EAP_AKA_RAND_LEN + EAP_AKA_AUTN_LEN;
+       if (!data->reauth)
+               *len = 1 + EAP_AKA_RAND_LEN + EAP_AKA_AUTN_LEN;
+       else
+               *len = 1 + EAP_SIM_NONCE_S_LEN + EAP_SIM_MAC_LEN;
        id = os_malloc(*len);
        if (id == NULL)
                return NULL;
 
        id[0] = data->eap_method;
-       os_memcpy(id + 1, data->rand, EAP_AKA_RAND_LEN);
-       os_memcpy(id + 1 + EAP_AKA_RAND_LEN, data->autn, EAP_AKA_AUTN_LEN);
+       if (!data->reauth) {
+               os_memcpy(id + 1, data->rand, EAP_AKA_RAND_LEN);
+               os_memcpy(id + 1 + EAP_AKA_RAND_LEN, data->autn,
+                         EAP_AKA_AUTN_LEN);
+       } else {
+               os_memcpy(id + 1, data->nonce_s, EAP_SIM_NONCE_S_LEN);
+               os_memcpy(id + 1 + EAP_SIM_NONCE_S_LEN, data->reauth_mac,
+                         EAP_SIM_MAC_LEN);
+       }
        wpa_hexdump(MSG_DEBUG, "EAP-AKA: Derived Session-Id", id, *len);
 
        return id;
index 1bea706d4990e24f4551b7daa3950c445822ea4b..1f3884e36ac4def70574136ff21c1fc432d2f69e 100644 (file)
@@ -30,6 +30,7 @@ struct eap_aka_data {
        u8 ck[EAP_AKA_CK_LEN];
        u8 ik[EAP_AKA_IK_LEN];
        u8 res[EAP_AKA_RES_MAX_LEN];
+       u8 reauth_mac[EAP_SIM_MAC_LEN];
        size_t res_len;
        enum {
                IDENTITY, CHALLENGE, REAUTH, NOTIFICATION, SUCCESS, FAILURE
@@ -542,6 +543,7 @@ static struct wpabuf * eap_aka_build_reauth(struct eap_sm *sm,
                                            struct eap_aka_data *data, u8 id)
 {
        struct eap_sim_msg *msg;
+       struct wpabuf *buf;
 
        wpa_printf(MSG_DEBUG, "EAP-AKA: Generating Re-authentication");
 
@@ -581,7 +583,16 @@ static struct wpabuf * eap_aka_build_reauth(struct eap_sm *sm,
 
        wpa_printf(MSG_DEBUG, "   AT_MAC");
        eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
-       return eap_sim_msg_finish(msg, data->eap_method, data->k_aut, NULL, 0);
+       buf = eap_sim_msg_finish(msg, data->eap_method, data->k_aut, NULL, 0);
+
+       /* Remember this MAC before sending it to the peer. This MAC is used for
+        * Session-Id calculation after receiving response from the peer and
+        * after all other checks pass. */
+       os_memcpy(data->reauth_mac,
+                 wpabuf_head(buf) + wpabuf_len(buf) - EAP_SIM_MAC_LEN,
+                 EAP_SIM_MAC_LEN);
+
+       return buf;
 }
 
 
@@ -1304,14 +1315,24 @@ static u8 * eap_aka_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
        if (data->state != SUCCESS)
                return NULL;
 
-       *len = 1 + EAP_AKA_RAND_LEN + EAP_AKA_AUTN_LEN;
+       if (!data->reauth)
+               *len = 1 + EAP_AKA_RAND_LEN + EAP_AKA_AUTN_LEN;
+       else
+               *len = 1 + EAP_SIM_NONCE_S_LEN + EAP_SIM_MAC_LEN;
        id = os_malloc(*len);
        if (id == NULL)
                return NULL;
 
        id[0] = data->eap_method;
-       os_memcpy(id + 1, data->rand, EAP_AKA_RAND_LEN);
-       os_memcpy(id + 1 + EAP_AKA_RAND_LEN, data->autn, EAP_AKA_AUTN_LEN);
+       if (!data->reauth) {
+               os_memcpy(id + 1, data->rand, EAP_AKA_RAND_LEN);
+               os_memcpy(id + 1 + EAP_AKA_RAND_LEN, data->autn,
+                         EAP_AKA_AUTN_LEN);
+       } else {
+               os_memcpy(id + 1, data->nonce_s, EAP_SIM_NONCE_S_LEN);
+               os_memcpy(id + 1 + EAP_SIM_NONCE_S_LEN, data->reauth_mac,
+                         EAP_SIM_MAC_LEN);
+       }
        wpa_hexdump(MSG_DEBUG, "EAP-AKA: Derived Session-Id", id, *len);
 
        return id;