1 /* 2 * hostapd / EAP-PEAP (draft-josefsson-pppext-eap-tls-eap-10.txt) 3 * Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "includes.h" 10 11 #include "common.h" 12 #include "crypto/sha1.h" 13 #include "crypto/tls.h" 14 #include "crypto/random.h" 15 #include "eap_i.h" 16 #include "eap_tls_common.h" 17 #include "eap_common/eap_tlv_common.h" 18 #include "eap_common/eap_peap_common.h" 19 #include "tncs.h" 20 21 22 /* Maximum supported PEAP version 23 * 0 = Microsoft's PEAP version 0; draft-kamath-pppext-peapv0-00.txt 24 * 1 = draft-josefsson-ppext-eap-tls-eap-05.txt 25 */ 26 #define EAP_PEAP_VERSION 1 27 28 29 static void eap_peap_reset(struct eap_sm *sm, void *priv); 30 31 32 struct eap_peap_data { 33 struct eap_ssl_data ssl; 34 enum { 35 START, PHASE1, PHASE1_ID2, PHASE2_START, PHASE2_ID, 36 PHASE2_METHOD, PHASE2_SOH, 37 PHASE2_TLV, SUCCESS_REQ, FAILURE_REQ, SUCCESS, FAILURE 38 } state; 39 40 int peap_version; 41 int recv_version; 42 const struct eap_method *phase2_method; 43 void *phase2_priv; 44 int force_version; 45 struct wpabuf *pending_phase2_resp; 46 enum { TLV_REQ_NONE, TLV_REQ_SUCCESS, TLV_REQ_FAILURE } tlv_request; 47 int crypto_binding_sent; 48 int crypto_binding_used; 49 enum { NO_BINDING, OPTIONAL_BINDING, REQUIRE_BINDING } crypto_binding; 50 u8 binding_nonce[32]; 51 u8 ipmk[40]; 52 u8 cmk[20]; 53 u8 *phase2_key; 54 size_t phase2_key_len; 55 struct wpabuf *soh_response; 56 }; 57 58 59 static const char * eap_peap_state_txt(int state) 60 { 61 switch (state) { 62 case START: 63 return "START"; 64 case PHASE1: 65 return "PHASE1"; 66 case PHASE1_ID2: 67 return "PHASE1_ID2"; 68 case PHASE2_START: 69 return "PHASE2_START"; 70 case PHASE2_ID: 71 return "PHASE2_ID"; 72 case PHASE2_METHOD: 73 return "PHASE2_METHOD"; 74 case PHASE2_SOH: 75 return "PHASE2_SOH"; 76 case PHASE2_TLV: 77 return "PHASE2_TLV"; 78 case SUCCESS_REQ: 79 return "SUCCESS_REQ"; 80 case FAILURE_REQ: 81 return "FAILURE_REQ"; 82 case SUCCESS: 83 return "SUCCESS"; 84 case FAILURE: 85 return "FAILURE"; 86 default: 87 return "Unknown?!"; 88 } 89 } 90 91 92 static void eap_peap_state(struct eap_peap_data *data, int state) 93 { 94 wpa_printf(MSG_DEBUG, "EAP-PEAP: %s -> %s", 95 eap_peap_state_txt(data->state), 96 eap_peap_state_txt(state)); 97 data->state = state; 98 if (state == FAILURE || state == FAILURE_REQ) 99 tls_connection_remove_session(data->ssl.conn); 100 } 101 102 103 static void eap_peap_valid_session(struct eap_sm *sm, 104 struct eap_peap_data *data) 105 { 106 struct wpabuf *buf; 107 108 if (!sm->tls_session_lifetime || 109 tls_connection_resumed(sm->ssl_ctx, data->ssl.conn)) 110 return; 111 112 buf = wpabuf_alloc(1 + 1 + sm->identity_len); 113 if (!buf) 114 return; 115 wpabuf_put_u8(buf, EAP_TYPE_PEAP); 116 if (sm->identity) { 117 u8 id_len; 118 119 if (sm->identity_len <= 255) 120 id_len = sm->identity_len; 121 else 122 id_len = 255; 123 wpabuf_put_u8(buf, id_len); 124 wpabuf_put_data(buf, sm->identity, id_len); 125 } else { 126 wpabuf_put_u8(buf, 0); 127 } 128 tls_connection_set_success_data(data->ssl.conn, buf); 129 } 130 131 132 static void eap_peap_req_success(struct eap_sm *sm, 133 struct eap_peap_data *data) 134 { 135 if (data->state == FAILURE || data->state == FAILURE_REQ) { 136 eap_peap_state(data, FAILURE); 137 return; 138 } 139 140 if (data->peap_version == 0) { 141 data->tlv_request = TLV_REQ_SUCCESS; 142 eap_peap_state(data, PHASE2_TLV); 143 } else { 144 eap_peap_state(data, SUCCESS_REQ); 145 } 146 } 147 148 149 static void eap_peap_req_failure(struct eap_sm *sm, 150 struct eap_peap_data *data) 151 { 152 if (data->state == FAILURE || data->state == FAILURE_REQ || 153 data->state == SUCCESS_REQ || data->tlv_request != TLV_REQ_NONE) { 154 eap_peap_state(data, FAILURE); 155 return; 156 } 157 158 if (data->peap_version == 0) { 159 data->tlv_request = TLV_REQ_FAILURE; 160 eap_peap_state(data, PHASE2_TLV); 161 } else { 162 eap_peap_state(data, FAILURE_REQ); 163 } 164 } 165 166 167 static void * eap_peap_init(struct eap_sm *sm) 168 { 169 struct eap_peap_data *data; 170 171 data = os_zalloc(sizeof(*data)); 172 if (data == NULL) 173 return NULL; 174 data->peap_version = EAP_PEAP_VERSION; 175 data->force_version = -1; 176 if (sm->user && sm->user->force_version >= 0) { 177 data->force_version = sm->user->force_version; 178 wpa_printf(MSG_DEBUG, "EAP-PEAP: forcing version %d", 179 data->force_version); 180 data->peap_version = data->force_version; 181 } 182 data->state = START; 183 data->crypto_binding = OPTIONAL_BINDING; 184 185 if (eap_server_tls_ssl_init(sm, &data->ssl, 0, EAP_TYPE_PEAP)) { 186 wpa_printf(MSG_INFO, "EAP-PEAP: Failed to initialize SSL."); 187 eap_peap_reset(sm, data); 188 return NULL; 189 } 190 191 return data; 192 } 193 194 195 static void eap_peap_reset(struct eap_sm *sm, void *priv) 196 { 197 struct eap_peap_data *data = priv; 198 if (data == NULL) 199 return; 200 if (data->phase2_priv && data->phase2_method) 201 data->phase2_method->reset(sm, data->phase2_priv); 202 eap_server_tls_ssl_deinit(sm, &data->ssl); 203 wpabuf_free(data->pending_phase2_resp); 204 os_free(data->phase2_key); 205 wpabuf_free(data->soh_response); 206 bin_clear_free(data, sizeof(*data)); 207 } 208 209 210 static struct wpabuf * eap_peap_build_start(struct eap_sm *sm, 211 struct eap_peap_data *data, u8 id) 212 { 213 struct wpabuf *req; 214 215 req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PEAP, 1, 216 EAP_CODE_REQUEST, id); 217 if (req == NULL) { 218 wpa_printf(MSG_ERROR, "EAP-PEAP: Failed to allocate memory for" 219 " request"); 220 eap_peap_state(data, FAILURE); 221 return NULL; 222 } 223 224 wpabuf_put_u8(req, EAP_TLS_FLAGS_START | data->peap_version); 225 226 eap_peap_state(data, PHASE1); 227 228 return req; 229 } 230 231 232 static struct wpabuf * eap_peap_build_phase2_req(struct eap_sm *sm, 233 struct eap_peap_data *data, 234 u8 id) 235 { 236 struct wpabuf *buf, *encr_req, msgbuf; 237 const u8 *req; 238 size_t req_len; 239 240 if (data->phase2_method == NULL || data->phase2_priv == NULL) { 241 wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 method not ready"); 242 return NULL; 243 } 244 buf = data->phase2_method->buildReq(sm, data->phase2_priv, id); 245 if (buf == NULL) 246 return NULL; 247 248 req = wpabuf_head(buf); 249 req_len = wpabuf_len(buf); 250 wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: Encrypting Phase 2 data", 251 req, req_len); 252 253 if (data->peap_version == 0 && 254 data->phase2_method->method != EAP_TYPE_TLV) { 255 req += sizeof(struct eap_hdr); 256 req_len -= sizeof(struct eap_hdr); 257 } 258 259 wpabuf_set(&msgbuf, req, req_len); 260 encr_req = eap_server_tls_encrypt(sm, &data->ssl, &msgbuf); 261 wpabuf_free(buf); 262 263 return encr_req; 264 } 265 266 267 #ifdef EAP_SERVER_TNC 268 static struct wpabuf * eap_peap_build_phase2_soh(struct eap_sm *sm, 269 struct eap_peap_data *data, 270 u8 id) 271 { 272 struct wpabuf *buf1, *buf, *encr_req, msgbuf; 273 const u8 *req; 274 size_t req_len; 275 276 buf1 = tncs_build_soh_request(); 277 if (buf1 == NULL) 278 return NULL; 279 280 buf = eap_msg_alloc(EAP_VENDOR_MICROSOFT, 0x21, wpabuf_len(buf1), 281 EAP_CODE_REQUEST, id); 282 if (buf == NULL) { 283 wpabuf_free(buf1); 284 return NULL; 285 } 286 wpabuf_put_buf(buf, buf1); 287 wpabuf_free(buf1); 288 289 req = wpabuf_head(buf); 290 req_len = wpabuf_len(buf); 291 292 wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: Encrypting Phase 2 SOH data", 293 req, req_len); 294 295 req += sizeof(struct eap_hdr); 296 req_len -= sizeof(struct eap_hdr); 297 wpabuf_set(&msgbuf, req, req_len); 298 299 encr_req = eap_server_tls_encrypt(sm, &data->ssl, &msgbuf); 300 wpabuf_free(buf); 301 302 return encr_req; 303 } 304 #endif /* EAP_SERVER_TNC */ 305 306 307 static void eap_peap_get_isk(struct eap_peap_data *data, 308 u8 *isk, size_t isk_len) 309 { 310 size_t key_len; 311 312 os_memset(isk, 0, isk_len); 313 if (data->phase2_key == NULL) 314 return; 315 316 key_len = data->phase2_key_len; 317 if (key_len > isk_len) 318 key_len = isk_len; 319 os_memcpy(isk, data->phase2_key, key_len); 320 } 321 322 323 static int eap_peap_derive_cmk(struct eap_sm *sm, struct eap_peap_data *data) 324 { 325 u8 *tk; 326 u8 isk[32], imck[60]; 327 int res; 328 329 /* 330 * Tunnel key (TK) is the first 60 octets of the key generated by 331 * phase 1 of PEAP (based on TLS). 332 */ 333 tk = eap_server_tls_derive_key(sm, &data->ssl, "client EAP encryption", 334 NULL, 0, EAP_TLS_KEY_LEN); 335 if (tk == NULL) 336 return -1; 337 wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: TK", tk, 60); 338 339 if (tls_connection_resumed(sm->ssl_ctx, data->ssl.conn)) { 340 /* Fast-connect: IPMK|CMK = TK */ 341 os_memcpy(data->ipmk, tk, 40); 342 wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IPMK from TK", 343 data->ipmk, 40); 344 os_memcpy(data->cmk, tk + 40, 20); 345 wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: CMK from TK", 346 data->cmk, 20); 347 os_free(tk); 348 return 0; 349 } 350 351 eap_peap_get_isk(data, isk, sizeof(isk)); 352 wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: ISK", isk, sizeof(isk)); 353 354 /* 355 * IPMK Seed = "Inner Methods Compound Keys" | ISK 356 * TempKey = First 40 octets of TK 357 * IPMK|CMK = PRF+(TempKey, IPMK Seed, 60) 358 * (note: draft-josefsson-pppext-eap-tls-eap-10.txt includes a space 359 * in the end of the label just before ISK; is that just a typo?) 360 */ 361 wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: TempKey", tk, 40); 362 res = peap_prfplus(data->peap_version, tk, 40, 363 "Inner Methods Compound Keys", 364 isk, sizeof(isk), imck, sizeof(imck)); 365 forced_memzero(isk, sizeof(isk)); 366 if (res < 0) { 367 os_free(tk); 368 return -1; 369 } 370 wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IMCK (IPMKj)", 371 imck, sizeof(imck)); 372 373 os_free(tk); 374 375 os_memcpy(data->ipmk, imck, 40); 376 wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IPMK (S-IPMKj)", data->ipmk, 40); 377 os_memcpy(data->cmk, imck + 40, 20); 378 wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: CMK (CMKj)", data->cmk, 20); 379 forced_memzero(imck, sizeof(imck)); 380 381 return 0; 382 } 383 384 385 static struct wpabuf * eap_peap_build_phase2_tlv(struct eap_sm *sm, 386 struct eap_peap_data *data, 387 u8 id) 388 { 389 struct wpabuf *buf, *encr_req; 390 size_t mlen; 391 392 mlen = 6; /* Result TLV */ 393 if (data->peap_version == 0 && data->tlv_request == TLV_REQ_SUCCESS && 394 data->crypto_binding != NO_BINDING) { 395 mlen += 60; /* Cryptobinding TLV */ 396 #ifdef EAP_SERVER_TNC 397 if (data->soh_response) 398 mlen += wpabuf_len(data->soh_response); 399 #endif /* EAP_SERVER_TNC */ 400 } 401 402 buf = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TLV, mlen, 403 EAP_CODE_REQUEST, id); 404 if (buf == NULL) 405 return NULL; 406 407 wpabuf_put_u8(buf, 0x80); /* Mandatory */ 408 wpabuf_put_u8(buf, EAP_TLV_RESULT_TLV); 409 /* Length */ 410 wpabuf_put_be16(buf, 2); 411 /* Status */ 412 wpabuf_put_be16(buf, data->tlv_request == TLV_REQ_SUCCESS ? 413 EAP_TLV_RESULT_SUCCESS : EAP_TLV_RESULT_FAILURE); 414 415 if (data->peap_version == 0 && data->tlv_request == TLV_REQ_SUCCESS && 416 data->crypto_binding != NO_BINDING) { 417 u8 *mac; 418 u8 eap_type = EAP_TYPE_PEAP; 419 const u8 *addr[2]; 420 size_t len[2]; 421 u16 tlv_type; 422 423 #ifdef EAP_SERVER_TNC 424 if (data->soh_response) { 425 wpa_printf(MSG_DEBUG, "EAP-PEAP: Adding MS-SOH " 426 "Response TLV"); 427 wpabuf_put_buf(buf, data->soh_response); 428 wpabuf_free(data->soh_response); 429 data->soh_response = NULL; 430 } 431 #endif /* EAP_SERVER_TNC */ 432 433 if (eap_peap_derive_cmk(sm, data) < 0 || 434 random_get_bytes(data->binding_nonce, 32)) { 435 wpabuf_free(buf); 436 return NULL; 437 } 438 439 /* Compound_MAC: HMAC-SHA1-160(cryptobinding TLV | EAP type) */ 440 addr[0] = wpabuf_put(buf, 0); 441 len[0] = 60; 442 addr[1] = &eap_type; 443 len[1] = 1; 444 445 tlv_type = EAP_TLV_CRYPTO_BINDING_TLV; 446 wpabuf_put_be16(buf, tlv_type); 447 wpabuf_put_be16(buf, 56); 448 449 wpabuf_put_u8(buf, 0); /* Reserved */ 450 wpabuf_put_u8(buf, data->peap_version); /* Version */ 451 wpabuf_put_u8(buf, data->recv_version); /* RecvVersion */ 452 wpabuf_put_u8(buf, 0); /* SubType: 0 = Request, 1 = Response */ 453 wpabuf_put_data(buf, data->binding_nonce, 32); /* Nonce */ 454 mac = wpabuf_put(buf, 20); /* Compound_MAC */ 455 wpa_hexdump(MSG_MSGDUMP, "EAP-PEAP: Compound_MAC CMK", 456 data->cmk, 20); 457 wpa_hexdump(MSG_MSGDUMP, "EAP-PEAP: Compound_MAC data 1", 458 addr[0], len[0]); 459 wpa_hexdump(MSG_MSGDUMP, "EAP-PEAP: Compound_MAC data 2", 460 addr[1], len[1]); 461 hmac_sha1_vector(data->cmk, 20, 2, addr, len, mac); 462 wpa_hexdump(MSG_MSGDUMP, "EAP-PEAP: Compound_MAC", 463 mac, SHA1_MAC_LEN); 464 data->crypto_binding_sent = 1; 465 } 466 467 wpa_hexdump_buf_key(MSG_DEBUG, "EAP-PEAP: Encrypting Phase 2 TLV data", 468 buf); 469 470 encr_req = eap_server_tls_encrypt(sm, &data->ssl, buf); 471 wpabuf_free(buf); 472 473 return encr_req; 474 } 475 476 477 static struct wpabuf * eap_peap_build_phase2_term(struct eap_sm *sm, 478 struct eap_peap_data *data, 479 u8 id, int success) 480 { 481 struct wpabuf *encr_req, msgbuf; 482 size_t req_len; 483 struct eap_hdr *hdr; 484 485 req_len = sizeof(*hdr); 486 hdr = os_zalloc(req_len); 487 if (hdr == NULL) 488 return NULL; 489 490 hdr->code = success ? EAP_CODE_SUCCESS : EAP_CODE_FAILURE; 491 hdr->identifier = id; 492 hdr->length = host_to_be16(req_len); 493 494 wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: Encrypting Phase 2 data", 495 (u8 *) hdr, req_len); 496 497 wpabuf_set(&msgbuf, hdr, req_len); 498 encr_req = eap_server_tls_encrypt(sm, &data->ssl, &msgbuf); 499 os_free(hdr); 500 501 return encr_req; 502 } 503 504 505 static struct wpabuf * eap_peap_buildReq(struct eap_sm *sm, void *priv, u8 id) 506 { 507 struct eap_peap_data *data = priv; 508 509 if (data->ssl.state == FRAG_ACK) { 510 return eap_server_tls_build_ack(id, EAP_TYPE_PEAP, 511 data->peap_version); 512 } 513 514 if (data->ssl.state == WAIT_FRAG_ACK) { 515 return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_PEAP, 516 data->peap_version, id); 517 } 518 519 switch (data->state) { 520 case START: 521 return eap_peap_build_start(sm, data, id); 522 case PHASE1: 523 case PHASE1_ID2: 524 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) { 525 wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase1 done, " 526 "starting Phase2"); 527 eap_peap_state(data, PHASE2_START); 528 } 529 break; 530 case PHASE2_ID: 531 case PHASE2_METHOD: 532 wpabuf_free(data->ssl.tls_out); 533 data->ssl.tls_out_pos = 0; 534 data->ssl.tls_out = eap_peap_build_phase2_req(sm, data, id); 535 break; 536 #ifdef EAP_SERVER_TNC 537 case PHASE2_SOH: 538 wpabuf_free(data->ssl.tls_out); 539 data->ssl.tls_out_pos = 0; 540 data->ssl.tls_out = eap_peap_build_phase2_soh(sm, data, id); 541 break; 542 #endif /* EAP_SERVER_TNC */ 543 case PHASE2_TLV: 544 wpabuf_free(data->ssl.tls_out); 545 data->ssl.tls_out_pos = 0; 546 data->ssl.tls_out = eap_peap_build_phase2_tlv(sm, data, id); 547 break; 548 case SUCCESS_REQ: 549 wpabuf_free(data->ssl.tls_out); 550 data->ssl.tls_out_pos = 0; 551 data->ssl.tls_out = eap_peap_build_phase2_term(sm, data, id, 552 1); 553 break; 554 case FAILURE_REQ: 555 wpabuf_free(data->ssl.tls_out); 556 data->ssl.tls_out_pos = 0; 557 data->ssl.tls_out = eap_peap_build_phase2_term(sm, data, id, 558 0); 559 break; 560 default: 561 wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - unexpected state %d", 562 __func__, data->state); 563 return NULL; 564 } 565 566 return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_PEAP, 567 data->peap_version, id); 568 } 569 570 571 static Boolean eap_peap_check(struct eap_sm *sm, void *priv, 572 struct wpabuf *respData) 573 { 574 const u8 *pos; 575 size_t len; 576 577 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PEAP, respData, &len); 578 if (pos == NULL || len < 1) { 579 wpa_printf(MSG_INFO, "EAP-PEAP: Invalid frame"); 580 return TRUE; 581 } 582 583 return FALSE; 584 } 585 586 587 static int eap_peap_phase2_init(struct eap_sm *sm, struct eap_peap_data *data, 588 int vendor, EapType eap_type) 589 { 590 if (data->phase2_priv && data->phase2_method) { 591 data->phase2_method->reset(sm, data->phase2_priv); 592 data->phase2_method = NULL; 593 data->phase2_priv = NULL; 594 } 595 data->phase2_method = eap_server_get_eap_method(vendor, eap_type); 596 if (!data->phase2_method) 597 return -1; 598 599 sm->init_phase2 = 1; 600 data->phase2_priv = data->phase2_method->init(sm); 601 sm->init_phase2 = 0; 602 return 0; 603 } 604 605 606 static int eap_tlv_validate_cryptobinding(struct eap_sm *sm, 607 struct eap_peap_data *data, 608 const u8 *crypto_tlv, 609 size_t crypto_tlv_len) 610 { 611 u8 buf[61], mac[SHA1_MAC_LEN]; 612 const u8 *pos; 613 614 if (crypto_tlv_len != 4 + 56) { 615 wpa_printf(MSG_DEBUG, "EAP-PEAP: Invalid cryptobinding TLV " 616 "length %d", (int) crypto_tlv_len); 617 return -1; 618 } 619 620 pos = crypto_tlv; 621 pos += 4; /* TLV header */ 622 if (pos[1] != data->peap_version) { 623 wpa_printf(MSG_DEBUG, "EAP-PEAP: Cryptobinding TLV Version " 624 "mismatch (was %d; expected %d)", 625 pos[1], data->peap_version); 626 return -1; 627 } 628 629 if (pos[3] != 1) { 630 wpa_printf(MSG_DEBUG, "EAP-PEAP: Unexpected Cryptobinding TLV " 631 "SubType %d", pos[3]); 632 return -1; 633 } 634 pos += 4; 635 pos += 32; /* Nonce */ 636 637 /* Compound_MAC: HMAC-SHA1-160(cryptobinding TLV | EAP type) */ 638 os_memcpy(buf, crypto_tlv, 60); 639 os_memset(buf + 4 + 4 + 32, 0, 20); /* Compound_MAC */ 640 buf[60] = EAP_TYPE_PEAP; 641 hmac_sha1(data->cmk, 20, buf, sizeof(buf), mac); 642 643 if (os_memcmp_const(mac, pos, SHA1_MAC_LEN) != 0) { 644 wpa_printf(MSG_DEBUG, "EAP-PEAP: Invalid Compound_MAC in " 645 "cryptobinding TLV"); 646 wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: CMK", data->cmk, 20); 647 wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Cryptobinding seed data", 648 buf, 61); 649 return -1; 650 } 651 652 wpa_printf(MSG_DEBUG, "EAP-PEAP: Valid cryptobinding TLV received"); 653 654 return 0; 655 } 656 657 658 static void eap_peap_process_phase2_tlv(struct eap_sm *sm, 659 struct eap_peap_data *data, 660 struct wpabuf *in_data) 661 { 662 const u8 *pos; 663 size_t left; 664 const u8 *result_tlv = NULL, *crypto_tlv = NULL; 665 size_t result_tlv_len = 0, crypto_tlv_len = 0; 666 int tlv_type, mandatory, tlv_len; 667 668 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TLV, in_data, &left); 669 if (pos == NULL) { 670 wpa_printf(MSG_DEBUG, "EAP-PEAP: Invalid EAP-TLV header"); 671 return; 672 } 673 674 /* Parse TLVs */ 675 wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Received TLVs", pos, left); 676 while (left >= 4) { 677 mandatory = !!(pos[0] & 0x80); 678 tlv_type = pos[0] & 0x3f; 679 tlv_type = (tlv_type << 8) | pos[1]; 680 tlv_len = ((int) pos[2] << 8) | pos[3]; 681 pos += 4; 682 left -= 4; 683 if ((size_t) tlv_len > left) { 684 wpa_printf(MSG_DEBUG, "EAP-PEAP: TLV underrun " 685 "(tlv_len=%d left=%lu)", tlv_len, 686 (unsigned long) left); 687 eap_peap_state(data, FAILURE); 688 return; 689 } 690 switch (tlv_type) { 691 case EAP_TLV_RESULT_TLV: 692 result_tlv = pos; 693 result_tlv_len = tlv_len; 694 break; 695 case EAP_TLV_CRYPTO_BINDING_TLV: 696 crypto_tlv = pos; 697 crypto_tlv_len = tlv_len; 698 break; 699 default: 700 wpa_printf(MSG_DEBUG, "EAP-PEAP: Unsupported TLV Type " 701 "%d%s", tlv_type, 702 mandatory ? " (mandatory)" : ""); 703 if (mandatory) { 704 eap_peap_state(data, FAILURE); 705 return; 706 } 707 /* Ignore this TLV, but process other TLVs */ 708 break; 709 } 710 711 pos += tlv_len; 712 left -= tlv_len; 713 } 714 if (left) { 715 wpa_printf(MSG_DEBUG, "EAP-PEAP: Last TLV too short in " 716 "Request (left=%lu)", (unsigned long) left); 717 eap_peap_state(data, FAILURE); 718 return; 719 } 720 721 /* Process supported TLVs */ 722 if (crypto_tlv && data->crypto_binding_sent) { 723 wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Cryptobinding TLV", 724 crypto_tlv, crypto_tlv_len); 725 if (eap_tlv_validate_cryptobinding(sm, data, crypto_tlv - 4, 726 crypto_tlv_len + 4) < 0) { 727 eap_peap_state(data, FAILURE); 728 return; 729 } 730 data->crypto_binding_used = 1; 731 } else if (!crypto_tlv && data->crypto_binding_sent && 732 data->crypto_binding == REQUIRE_BINDING) { 733 wpa_printf(MSG_DEBUG, "EAP-PEAP: No cryptobinding TLV"); 734 eap_peap_state(data, FAILURE); 735 return; 736 } 737 738 if (result_tlv) { 739 int status; 740 const char *requested; 741 742 wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Result TLV", 743 result_tlv, result_tlv_len); 744 if (result_tlv_len < 2) { 745 wpa_printf(MSG_INFO, "EAP-PEAP: Too short Result TLV " 746 "(len=%lu)", 747 (unsigned long) result_tlv_len); 748 eap_peap_state(data, FAILURE); 749 return; 750 } 751 requested = data->tlv_request == TLV_REQ_SUCCESS ? "Success" : 752 "Failure"; 753 status = WPA_GET_BE16(result_tlv); 754 if (status == EAP_TLV_RESULT_SUCCESS) { 755 wpa_printf(MSG_INFO, "EAP-PEAP: TLV Result - Success " 756 "- requested %s", requested); 757 if (data->tlv_request == TLV_REQ_SUCCESS) { 758 eap_peap_state(data, SUCCESS); 759 eap_peap_valid_session(sm, data); 760 } else { 761 eap_peap_state(data, FAILURE); 762 } 763 764 } else if (status == EAP_TLV_RESULT_FAILURE) { 765 wpa_printf(MSG_INFO, "EAP-PEAP: TLV Result - Failure " 766 "- requested %s", requested); 767 eap_peap_state(data, FAILURE); 768 } else { 769 wpa_printf(MSG_INFO, "EAP-PEAP: Unknown TLV Result " 770 "Status %d", status); 771 eap_peap_state(data, FAILURE); 772 } 773 } 774 } 775 776 777 #ifdef EAP_SERVER_TNC 778 static void eap_peap_process_phase2_soh(struct eap_sm *sm, 779 struct eap_peap_data *data, 780 struct wpabuf *in_data) 781 { 782 const u8 *pos, *vpos; 783 size_t left; 784 const u8 *soh_tlv = NULL; 785 size_t soh_tlv_len = 0; 786 int tlv_type, mandatory, tlv_len, vtlv_len; 787 u32 next_type; 788 u32 vendor_id; 789 790 pos = eap_hdr_validate(EAP_VENDOR_MICROSOFT, 0x21, in_data, &left); 791 if (pos == NULL) { 792 wpa_printf(MSG_DEBUG, "EAP-PEAP: Not a valid SoH EAP " 793 "Extensions Method header - skip TNC"); 794 goto auth_method; 795 } 796 797 /* Parse TLVs */ 798 wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Received TLVs (SoH)", pos, left); 799 while (left >= 4) { 800 mandatory = !!(pos[0] & 0x80); 801 tlv_type = pos[0] & 0x3f; 802 tlv_type = (tlv_type << 8) | pos[1]; 803 tlv_len = ((int) pos[2] << 8) | pos[3]; 804 pos += 4; 805 left -= 4; 806 if ((size_t) tlv_len > left) { 807 wpa_printf(MSG_DEBUG, "EAP-PEAP: TLV underrun " 808 "(tlv_len=%d left=%lu)", tlv_len, 809 (unsigned long) left); 810 eap_peap_state(data, FAILURE); 811 return; 812 } 813 switch (tlv_type) { 814 case EAP_TLV_VENDOR_SPECIFIC_TLV: 815 if (tlv_len < 4) { 816 wpa_printf(MSG_DEBUG, "EAP-PEAP: Too short " 817 "vendor specific TLV (len=%d)", 818 (int) tlv_len); 819 eap_peap_state(data, FAILURE); 820 return; 821 } 822 823 vendor_id = WPA_GET_BE32(pos); 824 if (vendor_id != EAP_VENDOR_MICROSOFT) { 825 if (mandatory) { 826 eap_peap_state(data, FAILURE); 827 return; 828 } 829 break; 830 } 831 832 vpos = pos + 4; 833 mandatory = !!(vpos[0] & 0x80); 834 tlv_type = vpos[0] & 0x3f; 835 tlv_type = (tlv_type << 8) | vpos[1]; 836 vtlv_len = ((int) vpos[2] << 8) | vpos[3]; 837 vpos += 4; 838 if (vpos + vtlv_len > pos + left) { 839 wpa_printf(MSG_DEBUG, "EAP-PEAP: Vendor TLV " 840 "underrun"); 841 eap_peap_state(data, FAILURE); 842 return; 843 } 844 845 if (tlv_type == 1) { 846 soh_tlv = vpos; 847 soh_tlv_len = vtlv_len; 848 break; 849 } 850 851 wpa_printf(MSG_DEBUG, "EAP-PEAP: Unsupported MS-TLV " 852 "Type %d%s", tlv_type, 853 mandatory ? " (mandatory)" : ""); 854 if (mandatory) { 855 eap_peap_state(data, FAILURE); 856 return; 857 } 858 /* Ignore this TLV, but process other TLVs */ 859 break; 860 default: 861 wpa_printf(MSG_DEBUG, "EAP-PEAP: Unsupported TLV Type " 862 "%d%s", tlv_type, 863 mandatory ? " (mandatory)" : ""); 864 if (mandatory) { 865 eap_peap_state(data, FAILURE); 866 return; 867 } 868 /* Ignore this TLV, but process other TLVs */ 869 break; 870 } 871 872 pos += tlv_len; 873 left -= tlv_len; 874 } 875 if (left) { 876 wpa_printf(MSG_DEBUG, "EAP-PEAP: Last TLV too short in " 877 "Request (left=%lu)", (unsigned long) left); 878 eap_peap_state(data, FAILURE); 879 return; 880 } 881 882 /* Process supported TLVs */ 883 if (soh_tlv) { 884 int failure = 0; 885 wpabuf_free(data->soh_response); 886 data->soh_response = tncs_process_soh(soh_tlv, soh_tlv_len, 887 &failure); 888 if (failure) { 889 eap_peap_state(data, FAILURE); 890 return; 891 } 892 } else { 893 wpa_printf(MSG_DEBUG, "EAP-PEAP: No SoH TLV received"); 894 eap_peap_state(data, FAILURE); 895 return; 896 } 897 898 auth_method: 899 eap_peap_state(data, PHASE2_METHOD); 900 next_type = sm->user->methods[0].method; 901 sm->user_eap_method_index = 1; 902 wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP vendor %d type %d", 903 sm->user->methods[0].vendor, next_type); 904 eap_peap_phase2_init(sm, data, sm->user->methods[0].vendor, next_type); 905 } 906 #endif /* EAP_SERVER_TNC */ 907 908 909 static void eap_peap_process_phase2_response(struct eap_sm *sm, 910 struct eap_peap_data *data, 911 struct wpabuf *in_data) 912 { 913 int next_vendor = EAP_VENDOR_IETF; 914 u32 next_type = EAP_TYPE_NONE; 915 const struct eap_hdr *hdr; 916 const u8 *pos; 917 size_t left; 918 919 if (data->state == PHASE2_TLV) { 920 eap_peap_process_phase2_tlv(sm, data, in_data); 921 return; 922 } 923 924 #ifdef EAP_SERVER_TNC 925 if (data->state == PHASE2_SOH) { 926 eap_peap_process_phase2_soh(sm, data, in_data); 927 return; 928 } 929 #endif /* EAP_SERVER_TNC */ 930 931 if (data->phase2_priv == NULL) { 932 wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - Phase2 not " 933 "initialized?!", __func__); 934 return; 935 } 936 937 hdr = wpabuf_head(in_data); 938 pos = (const u8 *) (hdr + 1); 939 940 if (wpabuf_len(in_data) > sizeof(*hdr) && *pos == EAP_TYPE_NAK) { 941 left = wpabuf_len(in_data) - sizeof(*hdr); 942 wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Phase2 type Nak'ed; " 943 "allowed types", pos + 1, left - 1); 944 eap_sm_process_nak(sm, pos + 1, left - 1); 945 if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS && 946 (sm->user->methods[sm->user_eap_method_index].vendor != 947 EAP_VENDOR_IETF || 948 sm->user->methods[sm->user_eap_method_index].method != 949 EAP_TYPE_NONE)) { 950 next_vendor = sm->user->methods[ 951 sm->user_eap_method_index].vendor; 952 next_type = sm->user->methods[ 953 sm->user_eap_method_index++].method; 954 wpa_printf(MSG_DEBUG, 955 "EAP-PEAP: try EAP vendor %d type 0x%x", 956 next_vendor, next_type); 957 } else { 958 eap_peap_req_failure(sm, data); 959 next_vendor = EAP_VENDOR_IETF; 960 next_type = EAP_TYPE_NONE; 961 } 962 eap_peap_phase2_init(sm, data, next_vendor, next_type); 963 return; 964 } 965 966 if (data->phase2_method->check(sm, data->phase2_priv, in_data)) { 967 wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 check() asked to " 968 "ignore the packet"); 969 return; 970 } 971 972 data->phase2_method->process(sm, data->phase2_priv, in_data); 973 974 if (sm->method_pending == METHOD_PENDING_WAIT) { 975 wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 method is in " 976 "pending wait state - save decrypted response"); 977 wpabuf_free(data->pending_phase2_resp); 978 data->pending_phase2_resp = wpabuf_dup(in_data); 979 } 980 981 if (!data->phase2_method->isDone(sm, data->phase2_priv)) 982 return; 983 984 if (!data->phase2_method->isSuccess(sm, data->phase2_priv)) { 985 wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 method failed"); 986 eap_peap_req_failure(sm, data); 987 next_vendor = EAP_VENDOR_IETF; 988 next_type = EAP_TYPE_NONE; 989 eap_peap_phase2_init(sm, data, next_vendor, next_type); 990 return; 991 } 992 993 os_free(data->phase2_key); 994 if (data->phase2_method->getKey) { 995 data->phase2_key = data->phase2_method->getKey( 996 sm, data->phase2_priv, &data->phase2_key_len); 997 if (data->phase2_key == NULL) { 998 wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 getKey " 999 "failed"); 1000 eap_peap_req_failure(sm, data); 1001 eap_peap_phase2_init(sm, data, EAP_VENDOR_IETF, 1002 EAP_TYPE_NONE); 1003 return; 1004 } 1005 } 1006 1007 switch (data->state) { 1008 case PHASE1_ID2: 1009 case PHASE2_ID: 1010 case PHASE2_SOH: 1011 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) { 1012 wpa_hexdump_ascii(MSG_DEBUG, "EAP_PEAP: Phase2 " 1013 "Identity not found in the user " 1014 "database", 1015 sm->identity, sm->identity_len); 1016 eap_peap_req_failure(sm, data); 1017 next_vendor = EAP_VENDOR_IETF; 1018 next_type = EAP_TYPE_NONE; 1019 break; 1020 } 1021 1022 #ifdef EAP_SERVER_TNC 1023 if (data->state != PHASE2_SOH && sm->tnc && 1024 data->peap_version == 0) { 1025 eap_peap_state(data, PHASE2_SOH); 1026 wpa_printf(MSG_DEBUG, "EAP-PEAP: Try to initialize " 1027 "TNC (NAP SOH)"); 1028 next_vendor = EAP_VENDOR_IETF; 1029 next_type = EAP_TYPE_NONE; 1030 break; 1031 } 1032 #endif /* EAP_SERVER_TNC */ 1033 1034 eap_peap_state(data, PHASE2_METHOD); 1035 next_vendor = sm->user->methods[0].vendor; 1036 next_type = sm->user->methods[0].method; 1037 sm->user_eap_method_index = 1; 1038 wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP vendor %d type 0x%x", 1039 next_vendor, next_type); 1040 break; 1041 case PHASE2_METHOD: 1042 eap_peap_req_success(sm, data); 1043 next_vendor = EAP_VENDOR_IETF; 1044 next_type = EAP_TYPE_NONE; 1045 break; 1046 case FAILURE: 1047 break; 1048 default: 1049 wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - unexpected state %d", 1050 __func__, data->state); 1051 break; 1052 } 1053 1054 eap_peap_phase2_init(sm, data, next_vendor, next_type); 1055 } 1056 1057 1058 static void eap_peap_process_phase2(struct eap_sm *sm, 1059 struct eap_peap_data *data, 1060 const struct wpabuf *respData, 1061 struct wpabuf *in_buf) 1062 { 1063 struct wpabuf *in_decrypted; 1064 const struct eap_hdr *hdr; 1065 size_t len; 1066 1067 wpa_printf(MSG_DEBUG, "EAP-PEAP: received %lu bytes encrypted data for" 1068 " Phase 2", (unsigned long) wpabuf_len(in_buf)); 1069 1070 if (data->pending_phase2_resp) { 1071 wpa_printf(MSG_DEBUG, "EAP-PEAP: Pending Phase 2 response - " 1072 "skip decryption and use old data"); 1073 eap_peap_process_phase2_response(sm, data, 1074 data->pending_phase2_resp); 1075 wpabuf_free(data->pending_phase2_resp); 1076 data->pending_phase2_resp = NULL; 1077 return; 1078 } 1079 1080 in_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn, 1081 in_buf); 1082 if (in_decrypted == NULL) { 1083 wpa_printf(MSG_INFO, "EAP-PEAP: Failed to decrypt Phase 2 " 1084 "data"); 1085 eap_peap_state(data, FAILURE); 1086 return; 1087 } 1088 1089 wpa_hexdump_buf_key(MSG_DEBUG, "EAP-PEAP: Decrypted Phase 2 EAP", 1090 in_decrypted); 1091 1092 if (data->peap_version == 0 && data->state != PHASE2_TLV) { 1093 const struct eap_hdr *resp; 1094 struct eap_hdr *nhdr; 1095 struct wpabuf *nbuf = 1096 wpabuf_alloc(sizeof(struct eap_hdr) + 1097 wpabuf_len(in_decrypted)); 1098 if (nbuf == NULL) { 1099 wpabuf_free(in_decrypted); 1100 return; 1101 } 1102 1103 resp = wpabuf_head(respData); 1104 nhdr = wpabuf_put(nbuf, sizeof(*nhdr)); 1105 nhdr->code = resp->code; 1106 nhdr->identifier = resp->identifier; 1107 nhdr->length = host_to_be16(sizeof(struct eap_hdr) + 1108 wpabuf_len(in_decrypted)); 1109 wpabuf_put_buf(nbuf, in_decrypted); 1110 wpabuf_free(in_decrypted); 1111 1112 in_decrypted = nbuf; 1113 } 1114 1115 hdr = wpabuf_head(in_decrypted); 1116 if (wpabuf_len(in_decrypted) < (int) sizeof(*hdr)) { 1117 wpa_printf(MSG_INFO, "EAP-PEAP: Too short Phase 2 " 1118 "EAP frame (len=%lu)", 1119 (unsigned long) wpabuf_len(in_decrypted)); 1120 wpabuf_free(in_decrypted); 1121 eap_peap_req_failure(sm, data); 1122 return; 1123 } 1124 len = be_to_host16(hdr->length); 1125 if (len > wpabuf_len(in_decrypted)) { 1126 wpa_printf(MSG_INFO, "EAP-PEAP: Length mismatch in " 1127 "Phase 2 EAP frame (len=%lu hdr->length=%lu)", 1128 (unsigned long) wpabuf_len(in_decrypted), 1129 (unsigned long) len); 1130 wpabuf_free(in_decrypted); 1131 eap_peap_req_failure(sm, data); 1132 return; 1133 } 1134 wpa_printf(MSG_DEBUG, "EAP-PEAP: received Phase 2: code=%d " 1135 "identifier=%d length=%lu", hdr->code, hdr->identifier, 1136 (unsigned long) len); 1137 switch (hdr->code) { 1138 case EAP_CODE_RESPONSE: 1139 eap_peap_process_phase2_response(sm, data, in_decrypted); 1140 break; 1141 case EAP_CODE_SUCCESS: 1142 wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 Success"); 1143 if (data->state == SUCCESS_REQ) { 1144 eap_peap_state(data, SUCCESS); 1145 eap_peap_valid_session(sm, data); 1146 } 1147 break; 1148 case EAP_CODE_FAILURE: 1149 wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 Failure"); 1150 eap_peap_state(data, FAILURE); 1151 break; 1152 default: 1153 wpa_printf(MSG_INFO, "EAP-PEAP: Unexpected code=%d in " 1154 "Phase 2 EAP header", hdr->code); 1155 break; 1156 } 1157 1158 wpabuf_free(in_decrypted); 1159 } 1160 1161 1162 static int eap_peap_process_version(struct eap_sm *sm, void *priv, 1163 int peer_version) 1164 { 1165 struct eap_peap_data *data = priv; 1166 1167 data->recv_version = peer_version; 1168 if (data->force_version >= 0 && peer_version != data->force_version) { 1169 wpa_printf(MSG_INFO, "EAP-PEAP: peer did not select the forced" 1170 " version (forced=%d peer=%d) - reject", 1171 data->force_version, peer_version); 1172 return -1; 1173 } 1174 if (peer_version < data->peap_version) { 1175 wpa_printf(MSG_DEBUG, "EAP-PEAP: peer ver=%d, own ver=%d; " 1176 "use version %d", 1177 peer_version, data->peap_version, peer_version); 1178 data->peap_version = peer_version; 1179 } 1180 1181 return 0; 1182 } 1183 1184 1185 static void eap_peap_process_msg(struct eap_sm *sm, void *priv, 1186 const struct wpabuf *respData) 1187 { 1188 struct eap_peap_data *data = priv; 1189 1190 switch (data->state) { 1191 case PHASE1: 1192 if (eap_server_tls_phase1(sm, &data->ssl) < 0) { 1193 eap_peap_state(data, FAILURE); 1194 break; 1195 } 1196 break; 1197 case PHASE2_START: 1198 eap_peap_state(data, PHASE2_ID); 1199 eap_peap_phase2_init(sm, data, EAP_VENDOR_IETF, 1200 EAP_TYPE_IDENTITY); 1201 break; 1202 case PHASE1_ID2: 1203 case PHASE2_ID: 1204 case PHASE2_METHOD: 1205 case PHASE2_SOH: 1206 case PHASE2_TLV: 1207 eap_peap_process_phase2(sm, data, respData, data->ssl.tls_in); 1208 break; 1209 case SUCCESS_REQ: 1210 eap_peap_state(data, SUCCESS); 1211 eap_peap_valid_session(sm, data); 1212 break; 1213 case FAILURE_REQ: 1214 eap_peap_state(data, FAILURE); 1215 break; 1216 default: 1217 wpa_printf(MSG_DEBUG, "EAP-PEAP: Unexpected state %d in %s", 1218 data->state, __func__); 1219 break; 1220 } 1221 } 1222 1223 1224 static void eap_peap_process(struct eap_sm *sm, void *priv, 1225 struct wpabuf *respData) 1226 { 1227 struct eap_peap_data *data = priv; 1228 const struct wpabuf *buf; 1229 const u8 *pos; 1230 u8 id_len; 1231 1232 if (eap_server_tls_process(sm, &data->ssl, respData, data, 1233 EAP_TYPE_PEAP, eap_peap_process_version, 1234 eap_peap_process_msg) < 0) { 1235 eap_peap_state(data, FAILURE); 1236 return; 1237 } 1238 1239 if (data->state == SUCCESS || 1240 !tls_connection_established(sm->ssl_ctx, data->ssl.conn) || 1241 !tls_connection_resumed(sm->ssl_ctx, data->ssl.conn)) 1242 return; 1243 1244 buf = tls_connection_get_success_data(data->ssl.conn); 1245 if (!buf || wpabuf_len(buf) < 2) { 1246 wpa_printf(MSG_DEBUG, 1247 "EAP-PEAP: No success data in resumed session - reject attempt"); 1248 eap_peap_state(data, FAILURE); 1249 return; 1250 } 1251 1252 pos = wpabuf_head(buf); 1253 if (*pos != EAP_TYPE_PEAP) { 1254 wpa_printf(MSG_DEBUG, 1255 "EAP-PEAP: Resumed session for another EAP type (%u) - reject attempt", 1256 *pos); 1257 eap_peap_state(data, FAILURE); 1258 return; 1259 } 1260 1261 pos++; 1262 id_len = *pos++; 1263 wpa_hexdump_ascii(MSG_DEBUG, "EAP-PEAP: Identity from cached session", 1264 pos, id_len); 1265 os_free(sm->identity); 1266 sm->identity = os_malloc(id_len ? id_len : 1); 1267 if (!sm->identity) { 1268 sm->identity_len = 0; 1269 eap_peap_state(data, FAILURE); 1270 return; 1271 } 1272 1273 os_memcpy(sm->identity, pos, id_len); 1274 sm->identity_len = id_len; 1275 1276 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) { 1277 wpa_hexdump_ascii(MSG_DEBUG, "EAP-PEAP: Phase2 Identity not found in the user database", 1278 sm->identity, sm->identity_len); 1279 eap_peap_state(data, FAILURE); 1280 return; 1281 } 1282 1283 wpa_printf(MSG_DEBUG, 1284 "EAP-PEAP: Resuming previous session - skip Phase2"); 1285 eap_peap_req_success(sm, data); 1286 if (data->state == SUCCESS_REQ) 1287 tls_connection_set_success_data_resumed(data->ssl.conn); 1288 } 1289 1290 1291 static Boolean eap_peap_isDone(struct eap_sm *sm, void *priv) 1292 { 1293 struct eap_peap_data *data = priv; 1294 return data->state == SUCCESS || data->state == FAILURE; 1295 } 1296 1297 1298 static u8 * eap_peap_getKey(struct eap_sm *sm, void *priv, size_t *len) 1299 { 1300 struct eap_peap_data *data = priv; 1301 u8 *eapKeyData; 1302 1303 if (data->state != SUCCESS) 1304 return NULL; 1305 1306 if (data->crypto_binding_used) { 1307 u8 csk[128]; 1308 /* 1309 * Note: It looks like Microsoft implementation requires null 1310 * termination for this label while the one used for deriving 1311 * IPMK|CMK did not use null termination. 1312 */ 1313 if (peap_prfplus(data->peap_version, data->ipmk, 40, 1314 "Session Key Generating Function", 1315 (u8 *) "\00", 1, csk, sizeof(csk)) < 0) 1316 return NULL; 1317 wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: CSK", csk, sizeof(csk)); 1318 eapKeyData = os_malloc(EAP_TLS_KEY_LEN); 1319 if (eapKeyData) { 1320 os_memcpy(eapKeyData, csk, EAP_TLS_KEY_LEN); 1321 *len = EAP_TLS_KEY_LEN; 1322 wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Derived key", 1323 eapKeyData, EAP_TLS_KEY_LEN); 1324 } else { 1325 wpa_printf(MSG_DEBUG, "EAP-PEAP: Failed to derive " 1326 "key"); 1327 } 1328 1329 forced_memzero(csk, sizeof(csk)); 1330 1331 return eapKeyData; 1332 } 1333 1334 /* TODO: PEAPv1 - different label in some cases */ 1335 eapKeyData = eap_server_tls_derive_key(sm, &data->ssl, 1336 "client EAP encryption", NULL, 0, 1337 EAP_TLS_KEY_LEN + EAP_EMSK_LEN); 1338 if (eapKeyData) { 1339 os_memset(eapKeyData + EAP_TLS_KEY_LEN, 0, EAP_EMSK_LEN); 1340 *len = EAP_TLS_KEY_LEN; 1341 wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Derived key", 1342 eapKeyData, EAP_TLS_KEY_LEN); 1343 } else { 1344 wpa_printf(MSG_DEBUG, "EAP-PEAP: Failed to derive key"); 1345 } 1346 1347 return eapKeyData; 1348 } 1349 1350 1351 static u8 * eap_peap_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 1352 { 1353 struct eap_peap_data *data = priv; 1354 u8 *eapKeyData, *emsk; 1355 1356 if (data->state != SUCCESS) 1357 return NULL; 1358 1359 if (data->crypto_binding_used) { 1360 /* [MS-PEAP] does not define EMSK derivation */ 1361 return NULL; 1362 } 1363 1364 /* TODO: PEAPv1 - different label in some cases */ 1365 eapKeyData = eap_server_tls_derive_key(sm, &data->ssl, 1366 "client EAP encryption", NULL, 0, 1367 EAP_TLS_KEY_LEN + EAP_EMSK_LEN); 1368 if (eapKeyData) { 1369 emsk = os_memdup(eapKeyData + EAP_TLS_KEY_LEN, EAP_EMSK_LEN); 1370 bin_clear_free(eapKeyData, EAP_TLS_KEY_LEN + EAP_EMSK_LEN); 1371 if (!emsk) 1372 return NULL; 1373 *len = EAP_EMSK_LEN; 1374 wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Derived EMSK", 1375 emsk, EAP_EMSK_LEN); 1376 } else { 1377 wpa_printf(MSG_DEBUG, "EAP-PEAP: Failed to derive EMSK"); 1378 emsk = NULL; 1379 } 1380 1381 return emsk; 1382 } 1383 1384 1385 static Boolean eap_peap_isSuccess(struct eap_sm *sm, void *priv) 1386 { 1387 struct eap_peap_data *data = priv; 1388 return data->state == SUCCESS; 1389 } 1390 1391 1392 static u8 * eap_peap_get_session_id(struct eap_sm *sm, void *priv, size_t *len) 1393 { 1394 struct eap_peap_data *data = priv; 1395 1396 if (data->state != SUCCESS) 1397 return NULL; 1398 1399 return eap_server_tls_derive_session_id(sm, &data->ssl, EAP_TYPE_PEAP, 1400 len); 1401 } 1402 1403 1404 int eap_server_peap_register(void) 1405 { 1406 struct eap_method *eap; 1407 1408 eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, 1409 EAP_VENDOR_IETF, EAP_TYPE_PEAP, "PEAP"); 1410 if (eap == NULL) 1411 return -1; 1412 1413 eap->init = eap_peap_init; 1414 eap->reset = eap_peap_reset; 1415 eap->buildReq = eap_peap_buildReq; 1416 eap->check = eap_peap_check; 1417 eap->process = eap_peap_process; 1418 eap->isDone = eap_peap_isDone; 1419 eap->getKey = eap_peap_getKey; 1420 eap->get_emsk = eap_peap_get_emsk; 1421 eap->isSuccess = eap_peap_isSuccess; 1422 eap->getSessionId = eap_peap_get_session_id; 1423 1424 return eap_server_method_register(eap); 1425 } 1426