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