sm->peer_challenge = data->key_block_p->client_challenge;
}
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;
sm->auth_challenge = NULL;
sm->peer_challenge = NULL;
if (key_len > isk_len)
key_len = isk_len;
- os_memcpy(isk, key, key_len);
+ if (key_len == 32 &&
+ data->phase2_method->vendor == EAP_VENDOR_IETF &&
+ data->phase2_method->method == EAP_TYPE_MSCHAPV2) {
+ /*
+ * EAP-FAST uses reverse order for MS-MPPE keys when deriving
+ * MSK from EAP-MSCHAPv2. Swap the keys here to get the correct
+ * ISK for EAP-FAST cryptobinding.
+ */
+ os_memcpy(isk, key + 16, 16);
+ os_memcpy(isk + 16, key, 16);
+ } else
+ os_memcpy(isk, key, key_len);
os_free(key);
return 0;
/* Optional challenges generated in Phase 1 (EAP-FAST) */
u8 *peer_challenge, *auth_challenge;
- int mschapv2_full_key; /* Request full MSCHAPv2 key */
int num_rounds;
int force_disabled;
*/
u8 *peer_challenge;
u8 *auth_challenge;
- int full_key;
int phase2;
u8 master_key[MSCHAPV2_MASTER_KEY_LEN];
if (data == NULL)
return NULL;
- data->full_key = sm->mschapv2_full_key;
-
if (sm->peer_challenge) {
- data->full_key = 1;
data->peer_challenge = os_malloc(MSCHAPV2_CHAL_LEN);
if (data->peer_challenge == NULL) {
eap_mschapv2_deinit(sm, data);
if (!data->master_key_valid || !data->success)
return NULL;
- if (data->full_key) {
- /* EAP-FAST needs both send and receive keys */
- key_len = 2 * MSCHAPV2_KEY_LEN;
- } else {
- key_len = MSCHAPV2_KEY_LEN;
- }
+ key_len = 2 * MSCHAPV2_KEY_LEN;
key = os_malloc(key_len);
if (key == NULL)
return NULL;
- if (data->full_key) {
- get_asymetric_start_key(data->master_key, key,
- MSCHAPV2_KEY_LEN, 0, 0);
- get_asymetric_start_key(data->master_key,
- key + MSCHAPV2_KEY_LEN,
- MSCHAPV2_KEY_LEN, 1, 0);
- } else {
- get_asymetric_start_key(data->master_key, key,
- MSCHAPV2_KEY_LEN, 1, 0);
- }
+ /* MSK = server MS-MPPE-Recv-Key | MS-MPPE-Send-Key, i.e.,
+ * peer MS-MPPE-Send-Key | MS-MPPE-Recv-Key */
+ get_asymetric_start_key(data->master_key, key, MSCHAPV2_KEY_LEN, 1, 0);
+ get_asymetric_start_key(data->master_key, key + MSCHAPV2_KEY_LEN,
+ MSCHAPV2_KEY_LEN, 0, 0);
wpa_hexdump_key(MSG_DEBUG, "EAP-MSCHAPV2: Derived key",
key, key_len);
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);
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) {
EAP_VENDOR_IETF, 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) {
if (key_len > isk_len)
key_len = isk_len;
- os_memcpy(isk, key, key_len);
+ if (key_len == 32 &&
+ data->phase2_method->vendor == EAP_VENDOR_IETF &&
+ data->phase2_method->method == EAP_TYPE_MSCHAPV2) {
+ /*
+ * EAP-FAST uses reverse order for MS-MPPE keys when deriving
+ * MSK from EAP-MSCHAPv2. Swap the keys here to get the correct
+ * ISK for EAP-FAST cryptobinding.
+ */
+ os_memcpy(isk, key + 16, 16);
+ os_memcpy(isk + 16, key, 16);
+ } else
+ os_memcpy(isk, key, key_len);
os_free(key);
return 0;
key = os_malloc(*len);
if (key == NULL)
return NULL;
- get_asymetric_start_key(data->master_key, key, MSCHAPV2_KEY_LEN, 0, 0);
+ /* MSK = server MS-MPPE-Recv-Key | MS-MPPE-Send-Key */
+ get_asymetric_start_key(data->master_key, key, MSCHAPV2_KEY_LEN, 0, 1);
get_asymetric_start_key(data->master_key, key + MSCHAPV2_KEY_LEN,
- MSCHAPV2_KEY_LEN, 1, 0);
+ MSCHAPV2_KEY_LEN, 1, 1);
wpa_hexdump_key(MSG_DEBUG, "EAP-MSCHAPV2: Derived key", key, *len);
return key;
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) {
keys->recv_len;
os_memcpy(e->authenticator_pmk, keys->recv,
e->authenticator_pmk_len);
+ if (e->authenticator_pmk_len == 16 && keys->send &&
+ keys->send_len == 16) {
+ /* MS-CHAP-v2 derives 16 octet keys */
+ wpa_printf(MSG_DEBUG, "Use MS-MPPE-Send-Key "
+ "to extend PMK to 32 octets");
+ os_memcpy(e->authenticator_pmk +
+ e->authenticator_pmk_len,
+ keys->send, keys->send_len);
+ e->authenticator_pmk_len += keys->send_len;
+ }
}
os_free(keys->send);