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