summaryrefslogtreecommitdiff
path: root/src/eap_peer/eap_aka.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/eap_peer/eap_aka.c')
-rw-r--r--src/eap_peer/eap_aka.c57
1 files changed, 50 insertions, 7 deletions
diff --git a/src/eap_peer/eap_aka.c b/src/eap_peer/eap_aka.c
index a4441413f0dd..d50bc6186d91 100644
--- a/src/eap_peer/eap_aka.c
+++ b/src/eap_peer/eap_aka.c
@@ -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;
@@ -622,15 +623,22 @@ static struct wpabuf * eap_aka_response_identity(struct eap_sm *sm,
identity_len = data->reauth_id_len;
data->reauth = 1;
} else if ((id_req == ANY_ID || id_req == FULLAUTH_ID) &&
- data->pseudonym) {
+ data->pseudonym &&
+ !eap_sim_anonymous_username(data->pseudonym,
+ data->pseudonym_len)) {
identity = data->pseudonym;
identity_len = data->pseudonym_len;
eap_aka_clear_identities(sm, data, CLEAR_REAUTH_ID);
} else if (id_req != NO_ID_REQ) {
identity = eap_get_config_identity(sm, &identity_len);
if (identity) {
- eap_aka_clear_identities(sm, data, CLEAR_PSEUDONYM |
- CLEAR_REAUTH_ID);
+ int ids = CLEAR_PSEUDONYM | CLEAR_REAUTH_ID;
+
+ if (data->pseudonym &&
+ eap_sim_anonymous_username(data->pseudonym,
+ data->pseudonym_len))
+ ids &= ~CLEAR_PSEUDONYM;
+ eap_aka_clear_identities(sm, data, ids);
}
}
if (id_req != NO_ID_REQ)
@@ -924,8 +932,13 @@ static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm,
attr->checkcode_len)) {
wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the "
"message");
+#ifdef TEST_FUZZ
+ wpa_printf(MSG_INFO,
+ "TEST: Ignore AT_CHECKCODE mismatch for fuzz testing");
+#else /* TEST_FUZZ */
return eap_aka_client_error(data, id,
EAP_AKA_UNABLE_TO_PROCESS_PACKET);
+#endif /* TEST_FUZZ */
}
#ifdef EAP_AKA_PRIME
@@ -1026,7 +1039,9 @@ static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm,
if (data->last_eap_identity) {
identity = data->last_eap_identity;
identity_len = data->last_eap_identity_len;
- } else if (data->pseudonym) {
+ } else if (data->pseudonym &&
+ !eap_sim_anonymous_username(data->pseudonym,
+ data->pseudonym_len)) {
identity = data->pseudonym;
identity_len = data->pseudonym_len;
} else {
@@ -1055,8 +1070,13 @@ static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm,
if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) {
wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
"used invalid AT_MAC");
+#ifdef TEST_FUZZ
+ wpa_printf(MSG_INFO,
+ "TEST: Ignore AT_MAC mismatch for fuzz testing");
+#else /* TEST_FUZZ */
return eap_aka_client_error(data, id,
EAP_AKA_UNABLE_TO_PROCESS_PACKET);
+#endif /* TEST_FUZZ */
}
/* Old reauthentication identity must not be used anymore. In
@@ -1205,8 +1225,13 @@ static struct wpabuf * eap_aka_process_reauthentication(
if (attr->checkcode &&
eap_aka_verify_checkcode(data, attr->checkcode,
attr->checkcode_len)) {
+#ifdef TEST_FUZZ
+ wpa_printf(MSG_INFO,
+ "TEST: Ignore AT_CHECKCODE mismatch for fuzz testing");
+#else /* TEST_FUZZ */
wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the "
"message");
+#endif /* TEST_FUZZ */
return eap_aka_client_error(data, id,
EAP_AKA_UNABLE_TO_PROCESS_PACKET);
}
@@ -1226,6 +1251,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 +1530,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;