EAP-AKA: Validate RES Length field in AT_RES
authorJouni Malinen <jouni.malinen@atheros.com>
Fri, 7 Nov 2008 06:34:07 +0000 (08:34 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 7 Nov 2008 06:34:07 +0000 (08:34 +0200)
This change breaks interoperability with older wpa_supplicant versions
(everything up to and including wpa_supplicant 0.5.10 and 0.6.5) which
incorrectly used this field as number of bytes, not bits, in RES.

src/eap_common/eap_sim_common.c
src/eap_common/eap_sim_common.h
src/eap_server/eap_aka.c

index 02d20ca..9a0a1e5 100644 (file)
@@ -517,6 +517,7 @@ int eap_sim_parse_attr(const u8 *start, const u8 *end,
                        break;
                case EAP_SIM_AT_RES:
                        wpa_printf(MSG_DEBUG, "EAP-SIM: AT_RES");
+                       attr->res_len_bits = WPA_GET_BE16(apos);
                        apos += 2;
                        alen -= 2;
                        if (!aka || alen < EAP_AKA_MIN_RES_LEN ||
index 49d15cf..98b632c 100644 (file)
@@ -137,6 +137,7 @@ struct eap_sim_attrs {
        const u8 *checkcode;
        size_t num_chal, version_list_len, encr_data_len;
        size_t next_pseudonym_len, next_reauth_id_len, identity_len, res_len;
+       size_t res_len_bits;
        size_t checkcode_len;
        enum eap_sim_id_req id_req;
        int notification, counter, selected_version, client_error_code;
index 2d06965..16c747b 100644 (file)
@@ -666,10 +666,19 @@ static void eap_aka_process_challenge(struct eap_sm *sm,
                return;
        }
 
-       if (attr->res == NULL || attr->res_len != data->res_len ||
+       /*
+        * AT_RES is padded, so verify that there is enough room for RES and
+        * that the RES length in bits matches with the expected RES.
+        */
+       if (attr->res == NULL || attr->res_len < data->res_len ||
+           attr->res_len_bits != data->res_len * 8 ||
            os_memcmp(attr->res, data->res, data->res_len) != 0) {
                wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message did not "
-                          "include valid AT_RES");
+                          "include valid AT_RES (attr len=%lu, res len=%lu "
+                          "bits, expected %lu bits)",
+                          (unsigned long) attr->res_len,
+                          (unsigned long) attr->res_len_bits,
+                          (unsigned long) data->res_len);
                data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;
                eap_aka_state(data, NOTIFICATION);
                return;