diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c index ae8565eba..2c6932edc 100644 --- a/src/eap_peer/eap_peap.c +++ b/src/eap_peer/eap_peap.c @@ -208,6 +208,21 @@ 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); diff --git a/src/eap_server/eap_peap.c b/src/eap_server/eap_peap.c index b461d1cb7..d38a115fb 100644 --- a/src/eap_server/eap_peap.c +++ b/src/eap_server/eap_peap.c @@ -862,6 +862,21 @@ static void eap_peap_process_phase2_response(struct eap_sm *sm, eap_peap_phase2_init(sm, data, EAP_TYPE_NONE); return; } + + if (data->phase2_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, data->phase2_key, 16); + os_memcpy(data->phase2_key, data->phase2_key + 16, 16); + os_memcpy(data->phase2_key + 16, tmp, 16); + } } switch (data->state) {