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