hostapd: Fix internal crypto build without TLS
[wpasupplicant] / src / eap_peer / eap_peap.c
index a350448..894fc63 100644 (file)
@@ -60,6 +60,7 @@ struct eap_peap_data {
                                 * EAP-Success and expect AS to send outer
                                 * (unencrypted) EAP-Success after this */
        int resuming; /* starting a resumed session */
+       int reauth; /* reauthentication */
        u8 *key_data;
 
        struct wpabuf *pending_phase2_req;
@@ -118,9 +119,15 @@ static int eap_peap_parse_phase1(struct eap_peap_data *data,
        }
 
 #ifdef EAP_TNC
-       if (os_strstr(phase1, "tnc=soh")) {
+       if (os_strstr(phase1, "tnc=soh2")) {
+               data->soh = 2;
+               wpa_printf(MSG_DEBUG, "EAP-PEAP: SoH version 2 enabled");
+       } else if (os_strstr(phase1, "tnc=soh1")) {
                data->soh = 1;
-               wpa_printf(MSG_DEBUG, "EAP-PEAP: SoH enabled");
+               wpa_printf(MSG_DEBUG, "EAP-PEAP: SoH version 1 enabled");
+       } else if (os_strstr(phase1, "tnc=soh")) {
+               data->soh = 2;
+               wpa_printf(MSG_DEBUG, "EAP-PEAP: SoH version 2 enabled");
        }
 #endif /* EAP_TNC */
 
@@ -140,7 +147,7 @@ static void * eap_peap_init(struct eap_sm *sm)
        data->peap_version = EAP_PEAP_VERSION;
        data->force_peap_version = -1;
        data->peap_outer_success = 2;
-       data->crypto_binding = NO_BINDING;
+       data->crypto_binding = OPTIONAL_BINDING;
 
        if (config && config->phase1 &&
            eap_peap_parse_phase1(data, config->phase1) < 0) {
@@ -231,21 +238,6 @@ static int eap_peap_get_isk(struct eap_sm *sm, struct eap_peap_data *data,
                return -1;
        }
 
-       if (key_len == 32 &&
-           data->phase2_method->vendor == EAP_VENDOR_IETF &&
-           data->phase2_method->method == EAP_TYPE_MSCHAPV2) {
-               /*
-                * Microsoft uses reverse order for MS-MPPE keys in
-                * EAP-PEAP when compared to EAP-FAST derivation of
-                * ISK. Swap the keys here to get the correct ISK for
-                * EAP-PEAPv0 cryptobinding.
-                */
-               u8 tmp[16];
-               os_memcpy(tmp, key, 16);
-               os_memcpy(key, key + 16, 16);
-               os_memcpy(key + 16, tmp, 16);
-       }
-
        if (key_len > isk_len)
                key_len = isk_len;
        os_memcpy(isk, key, key_len);
@@ -269,6 +261,18 @@ static int eap_peap_derive_cmk(struct eap_sm *sm, struct eap_peap_data *data)
                return -1;
        wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: TK", tk, 60);
 
+       if (data->reauth &&
+           tls_connection_resumed(sm->ssl_ctx, data->ssl.conn)) {
+               /* Fast-connect: IPMK|CMK = TK */
+               os_memcpy(data->ipmk, tk, 40);
+               wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IPMK from TK",
+                               data->ipmk, 40);
+               os_memcpy(data->cmk, tk + 40, 20);
+               wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: CMK from TK",
+                               data->cmk, 20);
+               return 0;
+       }
+
        if (eap_peap_get_isk(sm, data, isk, sizeof(isk)) < 0)
                return -1;
        wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: ISK", isk, sizeof(isk));
@@ -286,7 +290,6 @@ static int eap_peap_derive_cmk(struct eap_sm *sm, struct eap_peap_data *data)
        wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IMCK (IPMKj)",
                        imck, sizeof(imck));
 
-       /* TODO: fast-connect: IPMK|CMK = TK */
        os_memcpy(data->ipmk, imck, 40);
        wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IPMK (S-IPMKj)", data->ipmk, 40);
        os_memcpy(data->cmk, imck + 40, 20);
@@ -656,7 +659,8 @@ static int eap_peap_phase2_request(struct eap_sm *sm,
                                struct wpabuf *buf;
                                wpa_printf(MSG_DEBUG,
                                           "EAP-PEAP: SoH EAP Extensions");
-                               buf = tncc_process_soh_request(epos, eleft);
+                               buf = tncc_process_soh_request(data->soh,
+                                                              epos, eleft);
                                if (buf) {
                                        *resp = eap_msg_alloc(
                                                EAP_VENDOR_MICROSOFT, 0x21,
@@ -712,11 +716,9 @@ static int eap_peap_phase2_request(struct eap_sm *sm,
                                data->phase2_type.method);
                        if (data->phase2_method) {
                                sm->init_phase2 = 1;
-                               sm->mschapv2_full_key = 1;
                                data->phase2_priv =
                                        data->phase2_method->init(sm);
                                sm->init_phase2 = 0;
-                               sm->mschapv2_full_key = 0;
                        }
                }
                if (data->phase2_priv == NULL || data->phase2_method == NULL) {
@@ -1191,6 +1193,7 @@ static void * eap_peap_init_for_reauth(struct eap_sm *sm, void *priv)
        data->phase2_eap_success = 0;
        data->phase2_eap_started = 0;
        data->resuming = 1;
+       data->reauth = 1;
        sm->peap_done = FALSE;
        return priv;
 }