1 /* 2 * EAP-TEAP server (RFC 7170) 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/aes_wrap.h" 13 #include "crypto/tls.h" 14 #include "crypto/random.h" 15 #include "eap_common/eap_teap_common.h" 16 #include "eap_i.h" 17 #include "eap_tls_common.h" 18 19 20 static void eap_teap_reset(struct eap_sm *sm, void *priv); 21 22 23 /* Private PAC-Opaque TLV types */ 24 #define PAC_OPAQUE_TYPE_PAD 0 25 #define PAC_OPAQUE_TYPE_KEY 1 26 #define PAC_OPAQUE_TYPE_LIFETIME 2 27 #define PAC_OPAQUE_TYPE_IDENTITY 3 28 29 struct eap_teap_data { 30 struct eap_ssl_data ssl; 31 enum { 32 START, PHASE1, PHASE1B, PHASE2_START, PHASE2_ID, 33 PHASE2_BASIC_AUTH, PHASE2_METHOD, CRYPTO_BINDING, REQUEST_PAC, 34 FAILURE_SEND_RESULT, SUCCESS, FAILURE 35 } state; 36 37 u8 teap_version; 38 u8 peer_version; 39 u16 tls_cs; 40 41 const struct eap_method *phase2_method; 42 void *phase2_priv; 43 44 u8 crypto_binding_nonce[32]; 45 int final_result; 46 47 u8 simck_msk[EAP_TEAP_SIMCK_LEN]; 48 u8 cmk_msk[EAP_TEAP_CMK_LEN]; 49 u8 simck_emsk[EAP_TEAP_SIMCK_LEN]; 50 u8 cmk_emsk[EAP_TEAP_CMK_LEN]; 51 int simck_idx; 52 int cmk_emsk_available; 53 54 u8 pac_opaque_encr[16]; 55 u8 *srv_id; 56 size_t srv_id_len; 57 char *srv_id_info; 58 59 int anon_provisioning; 60 int send_new_pac; /* server triggered re-keying of Tunnel PAC */ 61 struct wpabuf *pending_phase2_resp; 62 struct wpabuf *server_outer_tlvs; 63 struct wpabuf *peer_outer_tlvs; 64 u8 *identity; /* from PAC-Opaque */ 65 size_t identity_len; 66 int eap_seq; 67 int tnc_started; 68 69 int pac_key_lifetime; 70 int pac_key_refresh_time; 71 72 enum teap_error_codes error_code; 73 }; 74 75 76 static int eap_teap_process_phase2_start(struct eap_sm *sm, 77 struct eap_teap_data *data); 78 79 80 static const char * eap_teap_state_txt(int state) 81 { 82 switch (state) { 83 case START: 84 return "START"; 85 case PHASE1: 86 return "PHASE1"; 87 case PHASE1B: 88 return "PHASE1B"; 89 case PHASE2_START: 90 return "PHASE2_START"; 91 case PHASE2_ID: 92 return "PHASE2_ID"; 93 case PHASE2_BASIC_AUTH: 94 return "PHASE2_BASIC_AUTH"; 95 case PHASE2_METHOD: 96 return "PHASE2_METHOD"; 97 case CRYPTO_BINDING: 98 return "CRYPTO_BINDING"; 99 case REQUEST_PAC: 100 return "REQUEST_PAC"; 101 case FAILURE_SEND_RESULT: 102 return "FAILURE_SEND_RESULT"; 103 case SUCCESS: 104 return "SUCCESS"; 105 case FAILURE: 106 return "FAILURE"; 107 default: 108 return "Unknown?!"; 109 } 110 } 111 112 113 static void eap_teap_state(struct eap_teap_data *data, int state) 114 { 115 wpa_printf(MSG_DEBUG, "EAP-TEAP: %s -> %s", 116 eap_teap_state_txt(data->state), 117 eap_teap_state_txt(state)); 118 data->state = state; 119 } 120 121 122 static EapType eap_teap_req_failure(struct eap_teap_data *data, 123 enum teap_error_codes error) 124 { 125 eap_teap_state(data, FAILURE_SEND_RESULT); 126 return EAP_TYPE_NONE; 127 } 128 129 130 static int eap_teap_session_ticket_cb(void *ctx, const u8 *ticket, size_t len, 131 const u8 *client_random, 132 const u8 *server_random, 133 u8 *master_secret) 134 { 135 struct eap_teap_data *data = ctx; 136 const u8 *pac_opaque; 137 size_t pac_opaque_len; 138 u8 *buf, *pos, *end, *pac_key = NULL; 139 os_time_t lifetime = 0; 140 struct os_time now; 141 u8 *identity = NULL; 142 size_t identity_len = 0; 143 144 wpa_printf(MSG_DEBUG, "EAP-TEAP: SessionTicket callback"); 145 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: SessionTicket (PAC-Opaque)", 146 ticket, len); 147 148 if (len < 4 || WPA_GET_BE16(ticket) != PAC_TYPE_PAC_OPAQUE) { 149 wpa_printf(MSG_DEBUG, "EAP-TEAP: Ignore invalid SessionTicket"); 150 return 0; 151 } 152 153 pac_opaque_len = WPA_GET_BE16(ticket + 2); 154 pac_opaque = ticket + 4; 155 if (pac_opaque_len < 8 || pac_opaque_len % 8 || 156 pac_opaque_len > len - 4) { 157 wpa_printf(MSG_DEBUG, 158 "EAP-TEAP: Ignore invalid PAC-Opaque (len=%lu left=%lu)", 159 (unsigned long) pac_opaque_len, 160 (unsigned long) len); 161 return 0; 162 } 163 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: Received PAC-Opaque", 164 pac_opaque, pac_opaque_len); 165 166 buf = os_malloc(pac_opaque_len - 8); 167 if (!buf) { 168 wpa_printf(MSG_DEBUG, 169 "EAP-TEAP: Failed to allocate memory for decrypting PAC-Opaque"); 170 return 0; 171 } 172 173 if (aes_unwrap(data->pac_opaque_encr, sizeof(data->pac_opaque_encr), 174 (pac_opaque_len - 8) / 8, pac_opaque, buf) < 0) { 175 wpa_printf(MSG_DEBUG, "EAP-TEAP: Failed to decrypt PAC-Opaque"); 176 os_free(buf); 177 /* 178 * This may have been caused by server changing the PAC-Opaque 179 * encryption key, so just ignore this PAC-Opaque instead of 180 * failing the authentication completely. Provisioning can now 181 * be used to provision a new PAC. 182 */ 183 return 0; 184 } 185 186 end = buf + pac_opaque_len - 8; 187 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: Decrypted PAC-Opaque", 188 buf, end - buf); 189 190 pos = buf; 191 while (end - pos > 1) { 192 u8 id, elen; 193 194 id = *pos++; 195 elen = *pos++; 196 if (elen > end - pos) 197 break; 198 199 switch (id) { 200 case PAC_OPAQUE_TYPE_PAD: 201 goto done; 202 case PAC_OPAQUE_TYPE_KEY: 203 if (elen != EAP_TEAP_PAC_KEY_LEN) { 204 wpa_printf(MSG_DEBUG, 205 "EAP-TEAP: Invalid PAC-Key length %d", 206 elen); 207 os_free(buf); 208 return -1; 209 } 210 pac_key = pos; 211 wpa_hexdump_key(MSG_DEBUG, 212 "EAP-TEAP: PAC-Key from decrypted PAC-Opaque", 213 pac_key, EAP_TEAP_PAC_KEY_LEN); 214 break; 215 case PAC_OPAQUE_TYPE_LIFETIME: 216 if (elen != 4) { 217 wpa_printf(MSG_DEBUG, 218 "EAP-TEAP: Invalid PAC-Key lifetime length %d", 219 elen); 220 os_free(buf); 221 return -1; 222 } 223 lifetime = WPA_GET_BE32(pos); 224 break; 225 case PAC_OPAQUE_TYPE_IDENTITY: 226 identity = pos; 227 identity_len = elen; 228 break; 229 } 230 231 pos += elen; 232 } 233 done: 234 235 if (!pac_key) { 236 wpa_printf(MSG_DEBUG, 237 "EAP-TEAP: No PAC-Key included in PAC-Opaque"); 238 os_free(buf); 239 return -1; 240 } 241 242 if (identity) { 243 wpa_hexdump_ascii(MSG_DEBUG, 244 "EAP-TEAP: Identity from PAC-Opaque", 245 identity, identity_len); 246 os_free(data->identity); 247 data->identity = os_malloc(identity_len); 248 if (data->identity) { 249 os_memcpy(data->identity, identity, identity_len); 250 data->identity_len = identity_len; 251 } 252 } 253 254 if (os_get_time(&now) < 0 || lifetime <= 0 || now.sec > lifetime) { 255 wpa_printf(MSG_DEBUG, 256 "EAP-TEAP: PAC-Key not valid anymore (lifetime=%ld now=%ld)", 257 lifetime, now.sec); 258 data->send_new_pac = 2; 259 /* 260 * Allow PAC to be used to allow a PAC update with some level 261 * of server authentication (i.e., do not fall back to full TLS 262 * handshake since we cannot be sure that the peer would be 263 * able to validate server certificate now). However, reject 264 * the authentication since the PAC was not valid anymore. Peer 265 * can connect again with the newly provisioned PAC after this. 266 */ 267 } else if (lifetime - now.sec < data->pac_key_refresh_time) { 268 wpa_printf(MSG_DEBUG, 269 "EAP-TEAP: PAC-Key soft timeout; send an update if authentication succeeds"); 270 data->send_new_pac = 1; 271 } 272 273 /* EAP-TEAP uses PAC-Key as the TLS master_secret */ 274 os_memcpy(master_secret, pac_key, EAP_TEAP_PAC_KEY_LEN); 275 276 os_free(buf); 277 278 return 1; 279 } 280 281 282 static int eap_teap_derive_key_auth(struct eap_sm *sm, 283 struct eap_teap_data *data) 284 { 285 int res; 286 287 /* RFC 7170, Section 5.1 */ 288 res = tls_connection_export_key(sm->ssl_ctx, data->ssl.conn, 289 TEAP_TLS_EXPORTER_LABEL_SKS, NULL, 0, 290 data->simck_msk, EAP_TEAP_SIMCK_LEN); 291 if (res) 292 return res; 293 wpa_hexdump_key(MSG_DEBUG, 294 "EAP-TEAP: session_key_seed (S-IMCK[0])", 295 data->simck_msk, EAP_TEAP_SIMCK_LEN); 296 os_memcpy(data->simck_emsk, data->simck_msk, EAP_TEAP_SIMCK_LEN); 297 data->simck_idx = 0; 298 return 0; 299 } 300 301 302 static int eap_teap_update_icmk(struct eap_sm *sm, struct eap_teap_data *data) 303 { 304 u8 *msk = NULL, *emsk = NULL; 305 size_t msk_len = 0, emsk_len = 0; 306 int res; 307 308 wpa_printf(MSG_DEBUG, "EAP-TEAP: Deriving ICMK[%d] (S-IMCK and CMK)", 309 data->simck_idx + 1); 310 311 if (sm->eap_teap_auth == 1) 312 return eap_teap_derive_cmk_basic_pw_auth(data->simck_msk, 313 data->cmk_msk); 314 315 if (!data->phase2_method || !data->phase2_priv) { 316 wpa_printf(MSG_INFO, "EAP-TEAP: Phase 2 method not available"); 317 return -1; 318 } 319 320 if (data->phase2_method->getKey) { 321 msk = data->phase2_method->getKey(sm, data->phase2_priv, 322 &msk_len); 323 if (!msk) { 324 wpa_printf(MSG_INFO, 325 "EAP-TEAP: Could not fetch Phase 2 MSK"); 326 return -1; 327 } 328 } 329 330 if (data->phase2_method->get_emsk) { 331 emsk = data->phase2_method->get_emsk(sm, data->phase2_priv, 332 &emsk_len); 333 } 334 335 res = eap_teap_derive_imck(data->simck_msk, data->simck_emsk, 336 msk, msk_len, emsk, emsk_len, 337 data->simck_msk, data->cmk_msk, 338 data->simck_emsk, data->cmk_emsk); 339 bin_clear_free(msk, msk_len); 340 bin_clear_free(emsk, emsk_len); 341 if (res == 0) { 342 data->simck_idx++; 343 if (emsk) 344 data->cmk_emsk_available = 1; 345 } 346 return 0; 347 } 348 349 350 static void * eap_teap_init(struct eap_sm *sm) 351 { 352 struct eap_teap_data *data; 353 354 data = os_zalloc(sizeof(*data)); 355 if (!data) 356 return NULL; 357 data->teap_version = EAP_TEAP_VERSION; 358 data->state = START; 359 360 if (eap_server_tls_ssl_init(sm, &data->ssl, 0, EAP_TYPE_TEAP)) { 361 wpa_printf(MSG_INFO, "EAP-TEAP: Failed to initialize SSL."); 362 eap_teap_reset(sm, data); 363 return NULL; 364 } 365 366 /* TODO: Add anon-DH TLS cipher suites (and if one is negotiated, 367 * enforce inner EAP with mutual authentication to be used) */ 368 369 if (tls_connection_set_session_ticket_cb(sm->ssl_ctx, data->ssl.conn, 370 eap_teap_session_ticket_cb, 371 data) < 0) { 372 wpa_printf(MSG_INFO, 373 "EAP-TEAP: Failed to set SessionTicket callback"); 374 eap_teap_reset(sm, data); 375 return NULL; 376 } 377 378 if (!sm->pac_opaque_encr_key) { 379 wpa_printf(MSG_INFO, 380 "EAP-TEAP: No PAC-Opaque encryption key configured"); 381 eap_teap_reset(sm, data); 382 return NULL; 383 } 384 os_memcpy(data->pac_opaque_encr, sm->pac_opaque_encr_key, 385 sizeof(data->pac_opaque_encr)); 386 387 if (!sm->eap_fast_a_id) { 388 wpa_printf(MSG_INFO, "EAP-TEAP: No A-ID configured"); 389 eap_teap_reset(sm, data); 390 return NULL; 391 } 392 data->srv_id = os_malloc(sm->eap_fast_a_id_len); 393 if (!data->srv_id) { 394 eap_teap_reset(sm, data); 395 return NULL; 396 } 397 os_memcpy(data->srv_id, sm->eap_fast_a_id, sm->eap_fast_a_id_len); 398 data->srv_id_len = sm->eap_fast_a_id_len; 399 400 if (!sm->eap_fast_a_id_info) { 401 wpa_printf(MSG_INFO, "EAP-TEAP: No A-ID-Info configured"); 402 eap_teap_reset(sm, data); 403 return NULL; 404 } 405 data->srv_id_info = os_strdup(sm->eap_fast_a_id_info); 406 if (!data->srv_id_info) { 407 eap_teap_reset(sm, data); 408 return NULL; 409 } 410 411 /* PAC-Key lifetime in seconds (hard limit) */ 412 data->pac_key_lifetime = sm->pac_key_lifetime; 413 414 /* 415 * PAC-Key refresh time in seconds (soft limit on remaining hard 416 * limit). The server will generate a new PAC-Key when this number of 417 * seconds (or fewer) of the lifetime remains. 418 */ 419 data->pac_key_refresh_time = sm->pac_key_refresh_time; 420 421 return data; 422 } 423 424 425 static void eap_teap_reset(struct eap_sm *sm, void *priv) 426 { 427 struct eap_teap_data *data = priv; 428 429 if (!data) 430 return; 431 if (data->phase2_priv && data->phase2_method) 432 data->phase2_method->reset(sm, data->phase2_priv); 433 eap_server_tls_ssl_deinit(sm, &data->ssl); 434 os_free(data->srv_id); 435 os_free(data->srv_id_info); 436 wpabuf_free(data->pending_phase2_resp); 437 wpabuf_free(data->server_outer_tlvs); 438 wpabuf_free(data->peer_outer_tlvs); 439 os_free(data->identity); 440 forced_memzero(data->simck_msk, EAP_TEAP_SIMCK_LEN); 441 forced_memzero(data->simck_emsk, EAP_TEAP_SIMCK_LEN); 442 forced_memzero(data->cmk_msk, EAP_TEAP_CMK_LEN); 443 forced_memzero(data->cmk_emsk, EAP_TEAP_CMK_LEN); 444 forced_memzero(data->pac_opaque_encr, sizeof(data->pac_opaque_encr)); 445 bin_clear_free(data, sizeof(*data)); 446 } 447 448 449 static struct wpabuf * eap_teap_build_start(struct eap_sm *sm, 450 struct eap_teap_data *data, u8 id) 451 { 452 struct wpabuf *req; 453 size_t outer_tlv_len = sizeof(struct teap_tlv_hdr) + data->srv_id_len; 454 const u8 *start, *end; 455 456 req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TEAP, 457 1 + 4 + outer_tlv_len, EAP_CODE_REQUEST, id); 458 if (!req) { 459 wpa_printf(MSG_ERROR, 460 "EAP-TEAP: Failed to allocate memory for request"); 461 eap_teap_state(data, FAILURE); 462 return NULL; 463 } 464 465 wpabuf_put_u8(req, EAP_TLS_FLAGS_START | EAP_TEAP_FLAGS_OUTER_TLV_LEN | 466 data->teap_version); 467 wpabuf_put_be32(req, outer_tlv_len); 468 469 start = wpabuf_put(req, 0); 470 471 /* RFC 7170, Section 4.2.2: Authority-ID TLV */ 472 eap_teap_put_tlv(req, TEAP_TLV_AUTHORITY_ID, 473 data->srv_id, data->srv_id_len); 474 475 end = wpabuf_put(req, 0); 476 wpabuf_free(data->server_outer_tlvs); 477 data->server_outer_tlvs = wpabuf_alloc_copy(start, end - start); 478 if (!data->server_outer_tlvs) { 479 eap_teap_state(data, FAILURE); 480 return NULL; 481 } 482 483 eap_teap_state(data, PHASE1); 484 485 return req; 486 } 487 488 489 static int eap_teap_phase1_done(struct eap_sm *sm, struct eap_teap_data *data) 490 { 491 char cipher[64]; 492 493 wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 1 done, starting Phase 2"); 494 495 data->tls_cs = tls_connection_get_cipher_suite(data->ssl.conn); 496 wpa_printf(MSG_DEBUG, "EAP-TEAP: TLS cipher suite 0x%04x", 497 data->tls_cs); 498 499 if (tls_get_cipher(sm->ssl_ctx, data->ssl.conn, cipher, sizeof(cipher)) 500 < 0) { 501 wpa_printf(MSG_DEBUG, 502 "EAP-TEAP: Failed to get cipher information"); 503 eap_teap_state(data, FAILURE); 504 return -1; 505 } 506 data->anon_provisioning = os_strstr(cipher, "ADH") != NULL; 507 508 if (data->anon_provisioning) 509 wpa_printf(MSG_DEBUG, "EAP-TEAP: Anonymous provisioning"); 510 511 if (eap_teap_derive_key_auth(sm, data) < 0) { 512 eap_teap_state(data, FAILURE); 513 return -1; 514 } 515 516 eap_teap_state(data, PHASE2_START); 517 518 return 0; 519 } 520 521 522 static struct wpabuf * eap_teap_build_phase2_req(struct eap_sm *sm, 523 struct eap_teap_data *data, 524 u8 id) 525 { 526 struct wpabuf *req; 527 528 if (sm->eap_teap_auth == 1) { 529 wpa_printf(MSG_DEBUG, "EAP-TEAP: Initiate Basic-Password-Auth"); 530 req = wpabuf_alloc(sizeof(struct teap_tlv_hdr)); 531 if (!req) 532 return NULL; 533 eap_teap_put_tlv_hdr(req, TEAP_TLV_BASIC_PASSWORD_AUTH_REQ, 0); 534 return req; 535 } 536 537 wpa_printf(MSG_DEBUG, "EAP-TEAP: Initiate inner EAP method"); 538 if (!data->phase2_priv) { 539 wpa_printf(MSG_DEBUG, 540 "EAP-TEAP: Phase 2 method not initialized"); 541 return NULL; 542 } 543 544 req = data->phase2_method->buildReq(sm, data->phase2_priv, id); 545 if (!req) 546 return NULL; 547 548 wpa_hexdump_buf_key(MSG_MSGDUMP, "EAP-TEAP: Phase 2 EAP-Request", req); 549 return eap_teap_tlv_eap_payload(req); 550 } 551 552 553 static struct wpabuf * eap_teap_build_crypto_binding( 554 struct eap_sm *sm, struct eap_teap_data *data) 555 { 556 struct wpabuf *buf; 557 struct teap_tlv_result *result; 558 struct teap_tlv_crypto_binding *cb; 559 u8 subtype, flags; 560 561 buf = wpabuf_alloc(2 * sizeof(*result) + sizeof(*cb)); 562 if (!buf) 563 return NULL; 564 565 if (data->send_new_pac || data->anon_provisioning || 566 data->phase2_method) 567 data->final_result = 0; 568 else 569 data->final_result = 1; 570 571 if (!data->final_result || data->eap_seq > 0) { 572 /* Intermediate-Result */ 573 wpa_printf(MSG_DEBUG, 574 "EAP-TEAP: Add Intermediate-Result TLV (status=SUCCESS)"); 575 result = wpabuf_put(buf, sizeof(*result)); 576 result->tlv_type = host_to_be16(TEAP_TLV_MANDATORY | 577 TEAP_TLV_INTERMEDIATE_RESULT); 578 result->length = host_to_be16(2); 579 result->status = host_to_be16(TEAP_STATUS_SUCCESS); 580 } 581 582 if (data->final_result) { 583 /* Result TLV */ 584 wpa_printf(MSG_DEBUG, 585 "EAP-TEAP: Add Result TLV (status=SUCCESS)"); 586 result = wpabuf_put(buf, sizeof(*result)); 587 result->tlv_type = host_to_be16(TEAP_TLV_MANDATORY | 588 TEAP_TLV_RESULT); 589 result->length = host_to_be16(2); 590 result->status = host_to_be16(TEAP_STATUS_SUCCESS); 591 } 592 593 /* Crypto-Binding TLV */ 594 cb = wpabuf_put(buf, sizeof(*cb)); 595 cb->tlv_type = host_to_be16(TEAP_TLV_MANDATORY | 596 TEAP_TLV_CRYPTO_BINDING); 597 cb->length = host_to_be16(sizeof(*cb) - sizeof(struct teap_tlv_hdr)); 598 cb->version = EAP_TEAP_VERSION; 599 cb->received_version = data->peer_version; 600 /* FIX: RFC 7170 is not clear on which Flags value to use when 601 * Crypto-Binding TLV is used with Basic-Password-Auth */ 602 flags = data->cmk_emsk_available ? 603 TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC : 604 TEAP_CRYPTO_BINDING_MSK_CMAC; 605 subtype = TEAP_CRYPTO_BINDING_SUBTYPE_REQUEST; 606 cb->subtype = (flags << 4) | subtype; 607 if (random_get_bytes(cb->nonce, sizeof(cb->nonce)) < 0) { 608 wpabuf_free(buf); 609 return NULL; 610 } 611 612 /* 613 * RFC 7170, Section 4.2.13: 614 * The nonce in a request MUST have its least significant bit set to 0. 615 */ 616 cb->nonce[sizeof(cb->nonce) - 1] &= ~0x01; 617 618 os_memcpy(data->crypto_binding_nonce, cb->nonce, sizeof(cb->nonce)); 619 620 if (eap_teap_compound_mac(data->tls_cs, cb, data->server_outer_tlvs, 621 data->peer_outer_tlvs, data->cmk_msk, 622 cb->msk_compound_mac) < 0) { 623 wpabuf_free(buf); 624 return NULL; 625 } 626 627 if (data->cmk_emsk_available && 628 eap_teap_compound_mac(data->tls_cs, cb, data->server_outer_tlvs, 629 data->peer_outer_tlvs, data->cmk_emsk, 630 cb->emsk_compound_mac) < 0) { 631 wpabuf_free(buf); 632 return NULL; 633 } 634 635 wpa_printf(MSG_DEBUG, 636 "EAP-TEAP: Add Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u", 637 cb->version, cb->received_version, flags, subtype); 638 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Nonce", 639 cb->nonce, sizeof(cb->nonce)); 640 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EMSK Compound MAC", 641 cb->emsk_compound_mac, sizeof(cb->emsk_compound_mac)); 642 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC", 643 cb->msk_compound_mac, sizeof(cb->msk_compound_mac)); 644 645 return buf; 646 } 647 648 649 static struct wpabuf * eap_teap_build_pac(struct eap_sm *sm, 650 struct eap_teap_data *data) 651 { 652 u8 pac_key[EAP_TEAP_PAC_KEY_LEN]; 653 u8 *pac_buf, *pac_opaque; 654 struct wpabuf *buf; 655 u8 *pos; 656 size_t buf_len, srv_id_info_len, pac_len; 657 struct teap_tlv_hdr *pac_tlv; 658 struct pac_attr_hdr *pac_info; 659 struct teap_tlv_result *result; 660 struct os_time now; 661 662 wpa_printf(MSG_DEBUG, "EAP-TEAP: Build a new PAC"); 663 664 if (random_get_bytes(pac_key, EAP_TEAP_PAC_KEY_LEN) < 0 || 665 os_get_time(&now) < 0) 666 return NULL; 667 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: Generated PAC-Key", 668 pac_key, EAP_TEAP_PAC_KEY_LEN); 669 670 pac_len = (2 + EAP_TEAP_PAC_KEY_LEN) + (2 + 4) + 671 (2 + sm->identity_len) + 8; 672 pac_buf = os_malloc(pac_len); 673 if (!pac_buf) 674 return NULL; 675 676 srv_id_info_len = os_strlen(data->srv_id_info); 677 678 pos = pac_buf; 679 *pos++ = PAC_OPAQUE_TYPE_KEY; 680 *pos++ = EAP_TEAP_PAC_KEY_LEN; 681 os_memcpy(pos, pac_key, EAP_TEAP_PAC_KEY_LEN); 682 pos += EAP_TEAP_PAC_KEY_LEN; 683 684 wpa_printf(MSG_DEBUG, "EAP-TEAP: PAC-Key lifetime: %u seconds", 685 data->pac_key_lifetime); 686 *pos++ = PAC_OPAQUE_TYPE_LIFETIME; 687 *pos++ = 4; 688 WPA_PUT_BE32(pos, now.sec + data->pac_key_lifetime); 689 pos += 4; 690 691 if (sm->identity) { 692 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: PAC-Opaque Identity", 693 sm->identity, sm->identity_len); 694 *pos++ = PAC_OPAQUE_TYPE_IDENTITY; 695 *pos++ = sm->identity_len; 696 os_memcpy(pos, sm->identity, sm->identity_len); 697 pos += sm->identity_len; 698 } 699 700 pac_len = pos - pac_buf; 701 while (pac_len % 8) { 702 *pos++ = PAC_OPAQUE_TYPE_PAD; 703 pac_len++; 704 } 705 706 pac_opaque = os_malloc(pac_len + 8); 707 if (!pac_opaque) { 708 os_free(pac_buf); 709 return NULL; 710 } 711 if (aes_wrap(data->pac_opaque_encr, sizeof(data->pac_opaque_encr), 712 pac_len / 8, pac_buf, pac_opaque) < 0) { 713 os_free(pac_buf); 714 os_free(pac_opaque); 715 return NULL; 716 } 717 os_free(pac_buf); 718 719 pac_len += 8; 720 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: PAC-Opaque", pac_opaque, pac_len); 721 722 buf_len = sizeof(*pac_tlv) + 723 sizeof(struct pac_attr_hdr) + EAP_TEAP_PAC_KEY_LEN + 724 sizeof(struct pac_attr_hdr) + pac_len + 725 data->srv_id_len + srv_id_info_len + 100 + sizeof(*result); 726 buf = wpabuf_alloc(buf_len); 727 if (!buf) { 728 os_free(pac_opaque); 729 return NULL; 730 } 731 732 /* Result TLV */ 733 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add Result TLV (status=SUCCESS)"); 734 result = wpabuf_put(buf, sizeof(*result)); 735 WPA_PUT_BE16((u8 *) &result->tlv_type, 736 TEAP_TLV_MANDATORY | TEAP_TLV_RESULT); 737 WPA_PUT_BE16((u8 *) &result->length, 2); 738 WPA_PUT_BE16((u8 *) &result->status, TEAP_STATUS_SUCCESS); 739 740 /* PAC TLV */ 741 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add PAC TLV"); 742 pac_tlv = wpabuf_put(buf, sizeof(*pac_tlv)); 743 pac_tlv->tlv_type = host_to_be16(TEAP_TLV_MANDATORY | TEAP_TLV_PAC); 744 745 /* PAC-Key */ 746 eap_teap_put_tlv(buf, PAC_TYPE_PAC_KEY, pac_key, EAP_TEAP_PAC_KEY_LEN); 747 748 /* PAC-Opaque */ 749 eap_teap_put_tlv(buf, PAC_TYPE_PAC_OPAQUE, pac_opaque, pac_len); 750 os_free(pac_opaque); 751 752 /* PAC-Info */ 753 pac_info = wpabuf_put(buf, sizeof(*pac_info)); 754 pac_info->type = host_to_be16(PAC_TYPE_PAC_INFO); 755 756 /* PAC-Lifetime (inside PAC-Info) */ 757 eap_teap_put_tlv_hdr(buf, PAC_TYPE_CRED_LIFETIME, 4); 758 wpabuf_put_be32(buf, now.sec + data->pac_key_lifetime); 759 760 /* A-ID (inside PAC-Info) */ 761 eap_teap_put_tlv(buf, PAC_TYPE_A_ID, data->srv_id, data->srv_id_len); 762 763 /* Note: headers may be misaligned after A-ID */ 764 765 if (sm->identity) { 766 eap_teap_put_tlv(buf, PAC_TYPE_I_ID, sm->identity, 767 sm->identity_len); 768 } 769 770 /* A-ID-Info (inside PAC-Info) */ 771 eap_teap_put_tlv(buf, PAC_TYPE_A_ID_INFO, data->srv_id_info, 772 srv_id_info_len); 773 774 /* PAC-Type (inside PAC-Info) */ 775 eap_teap_put_tlv_hdr(buf, PAC_TYPE_PAC_TYPE, 2); 776 wpabuf_put_be16(buf, PAC_TYPE_TUNNEL_PAC); 777 778 /* Update PAC-Info and PAC TLV Length fields */ 779 pos = wpabuf_put(buf, 0); 780 pac_info->len = host_to_be16(pos - (u8 *) (pac_info + 1)); 781 pac_tlv->length = host_to_be16(pos - (u8 *) (pac_tlv + 1)); 782 783 return buf; 784 } 785 786 787 static int eap_teap_encrypt_phase2(struct eap_sm *sm, 788 struct eap_teap_data *data, 789 struct wpabuf *plain, int piggyback) 790 { 791 struct wpabuf *encr; 792 793 wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TEAP: Encrypting Phase 2 TLVs", 794 plain); 795 encr = eap_server_tls_encrypt(sm, &data->ssl, plain); 796 wpabuf_free(plain); 797 798 if (!encr) 799 return -1; 800 801 if (data->ssl.tls_out && piggyback) { 802 wpa_printf(MSG_DEBUG, 803 "EAP-TEAP: Piggyback Phase 2 data (len=%d) with last Phase 1 Message (len=%d used=%d)", 804 (int) wpabuf_len(encr), 805 (int) wpabuf_len(data->ssl.tls_out), 806 (int) data->ssl.tls_out_pos); 807 if (wpabuf_resize(&data->ssl.tls_out, wpabuf_len(encr)) < 0) { 808 wpa_printf(MSG_WARNING, 809 "EAP-TEAP: Failed to resize output buffer"); 810 wpabuf_free(encr); 811 return -1; 812 } 813 wpabuf_put_buf(data->ssl.tls_out, encr); 814 wpabuf_free(encr); 815 } else { 816 wpabuf_free(data->ssl.tls_out); 817 data->ssl.tls_out_pos = 0; 818 data->ssl.tls_out = encr; 819 } 820 821 return 0; 822 } 823 824 825 static struct wpabuf * eap_teap_buildReq(struct eap_sm *sm, void *priv, u8 id) 826 { 827 struct eap_teap_data *data = priv; 828 struct wpabuf *req = NULL; 829 int piggyback = 0; 830 831 if (data->ssl.state == FRAG_ACK) { 832 return eap_server_tls_build_ack(id, EAP_TYPE_TEAP, 833 data->teap_version); 834 } 835 836 if (data->ssl.state == WAIT_FRAG_ACK) { 837 return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TEAP, 838 data->teap_version, id); 839 } 840 841 switch (data->state) { 842 case START: 843 return eap_teap_build_start(sm, data, id); 844 case PHASE1B: 845 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) { 846 if (eap_teap_phase1_done(sm, data) < 0) 847 return NULL; 848 if (data->state == PHASE2_START) { 849 int res; 850 851 /* 852 * Try to generate Phase 2 data to piggyback 853 * with the end of Phase 1 to avoid extra 854 * roundtrip. 855 */ 856 wpa_printf(MSG_DEBUG, 857 "EAP-TEAP: Try to start Phase 2"); 858 res = eap_teap_process_phase2_start(sm, data); 859 if (res == 1) { 860 req = eap_teap_build_crypto_binding( 861 sm, data); 862 piggyback = 1; 863 break; 864 } 865 866 if (res) 867 break; 868 req = eap_teap_build_phase2_req(sm, data, id); 869 piggyback = 1; 870 } 871 } 872 break; 873 case PHASE2_ID: 874 case PHASE2_BASIC_AUTH: 875 case PHASE2_METHOD: 876 req = eap_teap_build_phase2_req(sm, data, id); 877 break; 878 case CRYPTO_BINDING: 879 req = eap_teap_build_crypto_binding(sm, data); 880 if (data->phase2_method) { 881 /* 882 * Include the start of the next EAP method in the 883 * sequence in the same message with Crypto-Binding to 884 * save a round-trip. 885 */ 886 struct wpabuf *eap; 887 888 eap = eap_teap_build_phase2_req(sm, data, id); 889 req = wpabuf_concat(req, eap); 890 eap_teap_state(data, PHASE2_METHOD); 891 } 892 break; 893 case REQUEST_PAC: 894 req = eap_teap_build_pac(sm, data); 895 break; 896 case FAILURE_SEND_RESULT: 897 req = eap_teap_tlv_result(TEAP_STATUS_FAILURE, 0); 898 if (data->error_code) 899 req = wpabuf_concat( 900 req, eap_teap_tlv_error(data->error_code)); 901 break; 902 default: 903 wpa_printf(MSG_DEBUG, "EAP-TEAP: %s - unexpected state %d", 904 __func__, data->state); 905 return NULL; 906 } 907 908 if (req && eap_teap_encrypt_phase2(sm, data, req, piggyback) < 0) 909 return NULL; 910 911 return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TEAP, 912 data->teap_version, id); 913 } 914 915 916 static Boolean eap_teap_check(struct eap_sm *sm, void *priv, 917 struct wpabuf *respData) 918 { 919 const u8 *pos; 920 size_t len; 921 922 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TEAP, respData, &len); 923 if (!pos || len < 1) { 924 wpa_printf(MSG_INFO, "EAP-TEAP: Invalid frame"); 925 return TRUE; 926 } 927 928 return FALSE; 929 } 930 931 932 static int eap_teap_phase2_init(struct eap_sm *sm, struct eap_teap_data *data, 933 EapType eap_type) 934 { 935 if (data->phase2_priv && data->phase2_method) { 936 data->phase2_method->reset(sm, data->phase2_priv); 937 data->phase2_method = NULL; 938 data->phase2_priv = NULL; 939 } 940 data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF, 941 eap_type); 942 if (!data->phase2_method) 943 return -1; 944 945 sm->init_phase2 = 1; 946 data->phase2_priv = data->phase2_method->init(sm); 947 sm->init_phase2 = 0; 948 949 return data->phase2_priv ? 0 : -1; 950 } 951 952 953 static void eap_teap_process_phase2_response(struct eap_sm *sm, 954 struct eap_teap_data *data, 955 u8 *in_data, size_t in_len) 956 { 957 u8 next_type = EAP_TYPE_NONE; 958 struct eap_hdr *hdr; 959 u8 *pos; 960 size_t left; 961 struct wpabuf buf; 962 const struct eap_method *m = data->phase2_method; 963 void *priv = data->phase2_priv; 964 965 if (!priv) { 966 wpa_printf(MSG_DEBUG, 967 "EAP-TEAP: %s - Phase 2 not initialized?!", 968 __func__); 969 return; 970 } 971 972 hdr = (struct eap_hdr *) in_data; 973 pos = (u8 *) (hdr + 1); 974 975 if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) { 976 left = in_len - sizeof(*hdr); 977 wpa_hexdump(MSG_DEBUG, 978 "EAP-TEAP: Phase 2 type Nak'ed; allowed types", 979 pos + 1, left - 1); 980 #ifdef EAP_SERVER_TNC 981 if (m && m->vendor == EAP_VENDOR_IETF && 982 m->method == EAP_TYPE_TNC) { 983 wpa_printf(MSG_DEBUG, 984 "EAP-TEAP: Peer Nak'ed required TNC negotiation"); 985 next_type = eap_teap_req_failure(data, 0); 986 eap_teap_phase2_init(sm, data, next_type); 987 return; 988 } 989 #endif /* EAP_SERVER_TNC */ 990 eap_sm_process_nak(sm, pos + 1, left - 1); 991 if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS && 992 sm->user->methods[sm->user_eap_method_index].method != 993 EAP_TYPE_NONE) { 994 next_type = sm->user->methods[ 995 sm->user_eap_method_index++].method; 996 wpa_printf(MSG_DEBUG, "EAP-TEAP: try EAP type %d", 997 next_type); 998 } else { 999 next_type = eap_teap_req_failure(data, 0); 1000 } 1001 eap_teap_phase2_init(sm, data, next_type); 1002 return; 1003 } 1004 1005 wpabuf_set(&buf, in_data, in_len); 1006 1007 if (m->check(sm, priv, &buf)) { 1008 wpa_printf(MSG_DEBUG, 1009 "EAP-TEAP: Phase 2 check() asked to ignore the packet"); 1010 eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD); 1011 return; 1012 } 1013 1014 m->process(sm, priv, &buf); 1015 1016 if (!m->isDone(sm, priv)) 1017 return; 1018 1019 if (!m->isSuccess(sm, priv)) { 1020 wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 2 method failed"); 1021 next_type = eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD); 1022 eap_teap_phase2_init(sm, data, next_type); 1023 return; 1024 } 1025 1026 switch (data->state) { 1027 case PHASE2_ID: 1028 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) { 1029 wpa_hexdump_ascii(MSG_DEBUG, 1030 "EAP-TEAP: Phase 2 Identity not found in the user database", 1031 sm->identity, sm->identity_len); 1032 next_type = eap_teap_req_failure( 1033 data, TEAP_ERROR_INNER_METHOD); 1034 break; 1035 } 1036 1037 eap_teap_state(data, PHASE2_METHOD); 1038 if (data->anon_provisioning) { 1039 /* TODO: Allow any inner EAP method that provides 1040 * mutual authentication and EMSK derivation (i.e., 1041 * EAP-pwd or EAP-EKE). */ 1042 next_type = EAP_TYPE_PWD; 1043 sm->user_eap_method_index = 0; 1044 } else { 1045 next_type = sm->user->methods[0].method; 1046 sm->user_eap_method_index = 1; 1047 } 1048 wpa_printf(MSG_DEBUG, "EAP-TEAP: Try EAP type %d", next_type); 1049 break; 1050 case PHASE2_METHOD: 1051 case CRYPTO_BINDING: 1052 eap_teap_update_icmk(sm, data); 1053 eap_teap_state(data, CRYPTO_BINDING); 1054 data->eap_seq++; 1055 next_type = EAP_TYPE_NONE; 1056 #ifdef EAP_SERVER_TNC 1057 if (sm->tnc && !data->tnc_started) { 1058 wpa_printf(MSG_DEBUG, "EAP-TEAP: Initialize TNC"); 1059 next_type = EAP_TYPE_TNC; 1060 data->tnc_started = 1; 1061 } 1062 #endif /* EAP_SERVER_TNC */ 1063 break; 1064 case FAILURE: 1065 break; 1066 default: 1067 wpa_printf(MSG_DEBUG, "EAP-TEAP: %s - unexpected state %d", 1068 __func__, data->state); 1069 break; 1070 } 1071 1072 eap_teap_phase2_init(sm, data, next_type); 1073 } 1074 1075 1076 static void eap_teap_process_phase2_eap(struct eap_sm *sm, 1077 struct eap_teap_data *data, 1078 u8 *in_data, size_t in_len) 1079 { 1080 struct eap_hdr *hdr; 1081 size_t len; 1082 1083 hdr = (struct eap_hdr *) in_data; 1084 if (in_len < (int) sizeof(*hdr)) { 1085 wpa_printf(MSG_INFO, 1086 "EAP-TEAP: Too short Phase 2 EAP frame (len=%lu)", 1087 (unsigned long) in_len); 1088 eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD); 1089 return; 1090 } 1091 len = be_to_host16(hdr->length); 1092 if (len > in_len) { 1093 wpa_printf(MSG_INFO, 1094 "EAP-TEAP: Length mismatch in Phase 2 EAP frame (len=%lu hdr->length=%lu)", 1095 (unsigned long) in_len, (unsigned long) len); 1096 eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD); 1097 return; 1098 } 1099 wpa_printf(MSG_DEBUG, 1100 "EAP-TEAP: Received Phase 2: code=%d identifier=%d length=%lu", 1101 hdr->code, hdr->identifier, 1102 (unsigned long) len); 1103 switch (hdr->code) { 1104 case EAP_CODE_RESPONSE: 1105 eap_teap_process_phase2_response(sm, data, (u8 *) hdr, len); 1106 break; 1107 default: 1108 wpa_printf(MSG_INFO, 1109 "EAP-TEAP: Unexpected code=%d in Phase 2 EAP header", 1110 hdr->code); 1111 break; 1112 } 1113 } 1114 1115 1116 static void eap_teap_process_basic_auth_resp(struct eap_sm *sm, 1117 struct eap_teap_data *data, 1118 u8 *in_data, size_t in_len) 1119 { 1120 u8 *pos, *end, *username, *password, *new_id; 1121 u8 userlen, passlen; 1122 1123 pos = in_data; 1124 end = pos + in_len; 1125 1126 if (end - pos < 1) { 1127 wpa_printf(MSG_DEBUG, 1128 "EAP-TEAP: No room for Basic-Password-Auth-Resp Userlen field"); 1129 eap_teap_req_failure(data, 0); 1130 return; 1131 } 1132 userlen = *pos++; 1133 if (end - pos < userlen) { 1134 wpa_printf(MSG_DEBUG, 1135 "EAP-TEAP: Truncated Basic-Password-Auth-Resp Username field"); 1136 eap_teap_req_failure(data, 0); 1137 return; 1138 } 1139 username = pos; 1140 pos += userlen; 1141 wpa_hexdump_ascii(MSG_DEBUG, 1142 "EAP-TEAP: Basic-Password-Auth-Resp Username", 1143 username, userlen); 1144 1145 if (end - pos < 1) { 1146 wpa_printf(MSG_DEBUG, 1147 "EAP-TEAP: No room for Basic-Password-Auth-Resp Passlen field"); 1148 eap_teap_req_failure(data, 0); 1149 return; 1150 } 1151 passlen = *pos++; 1152 if (end - pos < passlen) { 1153 wpa_printf(MSG_DEBUG, 1154 "EAP-TEAP: Truncated Basic-Password-Auth-Resp Password field"); 1155 eap_teap_req_failure(data, 0); 1156 return; 1157 } 1158 password = pos; 1159 pos += passlen; 1160 wpa_hexdump_ascii_key(MSG_DEBUG, 1161 "EAP-TEAP: Basic-Password-Auth-Resp Password", 1162 password, passlen); 1163 1164 if (end > pos) { 1165 wpa_printf(MSG_DEBUG, 1166 "EAP-TEAP: Unexpected %d extra octet(s) at the end of Basic-Password-Auth-Resp TLV", 1167 (int) (end - pos)); 1168 eap_teap_req_failure(data, 0); 1169 return; 1170 } 1171 1172 if (eap_user_get(sm, username, userlen, 1) != 0) { 1173 wpa_printf(MSG_DEBUG, 1174 "EAP-TEAP: Username not found in the user database"); 1175 eap_teap_req_failure(data, 0); 1176 return; 1177 } 1178 1179 if (!sm->user || !sm->user->password || sm->user->password_hash) { 1180 wpa_printf(MSG_DEBUG, 1181 "EAP-TEAP: No plaintext user password configured"); 1182 eap_teap_req_failure(data, 0); 1183 return; 1184 } 1185 1186 if (sm->user->password_len != passlen || 1187 os_memcmp_const(sm->user->password, password, passlen) != 0) { 1188 wpa_printf(MSG_DEBUG, "EAP-TEAP: Invalid password"); 1189 eap_teap_req_failure(data, 0); 1190 return; 1191 } 1192 1193 wpa_printf(MSG_DEBUG, "EAP-TEAP: Correct password"); 1194 new_id = os_memdup(username, userlen); 1195 if (new_id) { 1196 os_free(sm->identity); 1197 sm->identity = new_id; 1198 sm->identity_len = userlen; 1199 } 1200 eap_teap_state(data, CRYPTO_BINDING); 1201 eap_teap_update_icmk(sm, data); 1202 } 1203 1204 1205 static int eap_teap_parse_tlvs(struct wpabuf *data, 1206 struct eap_teap_tlv_parse *tlv) 1207 { 1208 u16 tlv_type; 1209 int mandatory, res; 1210 size_t len; 1211 u8 *pos, *end; 1212 1213 os_memset(tlv, 0, sizeof(*tlv)); 1214 1215 pos = wpabuf_mhead(data); 1216 end = pos + wpabuf_len(data); 1217 while (end - pos > 4) { 1218 mandatory = pos[0] & 0x80; 1219 tlv_type = WPA_GET_BE16(pos) & 0x3fff; 1220 pos += 2; 1221 len = WPA_GET_BE16(pos); 1222 pos += 2; 1223 if (len > (size_t) (end - pos)) { 1224 wpa_printf(MSG_INFO, "EAP-TEAP: TLV overflow"); 1225 return -1; 1226 } 1227 wpa_printf(MSG_DEBUG, 1228 "EAP-TEAP: Received Phase 2: TLV type %u (%s) length %u%s", 1229 tlv_type, eap_teap_tlv_type_str(tlv_type), 1230 (unsigned int) len, 1231 mandatory ? " (mandatory)" : ""); 1232 1233 res = eap_teap_parse_tlv(tlv, tlv_type, pos, len); 1234 if (res == -2) 1235 break; 1236 if (res < 0) { 1237 if (mandatory) { 1238 wpa_printf(MSG_DEBUG, 1239 "EAP-TEAP: NAK unknown mandatory TLV type %u", 1240 tlv_type); 1241 /* TODO: generate NAK TLV */ 1242 break; 1243 } 1244 1245 wpa_printf(MSG_DEBUG, 1246 "EAP-TEAP: Ignore unknown optional TLV type %u", 1247 tlv_type); 1248 } 1249 1250 pos += len; 1251 } 1252 1253 return 0; 1254 } 1255 1256 1257 static int eap_teap_validate_crypto_binding( 1258 struct eap_teap_data *data, const struct teap_tlv_crypto_binding *cb, 1259 size_t bind_len) 1260 { 1261 u8 flags, subtype; 1262 1263 subtype = cb->subtype & 0x0f; 1264 flags = cb->subtype >> 4; 1265 1266 wpa_printf(MSG_DEBUG, 1267 "EAP-TEAP: Reply Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u", 1268 cb->version, cb->received_version, flags, subtype); 1269 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Nonce", 1270 cb->nonce, sizeof(cb->nonce)); 1271 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EMSK Compound MAC", 1272 cb->emsk_compound_mac, sizeof(cb->emsk_compound_mac)); 1273 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC", 1274 cb->msk_compound_mac, sizeof(cb->msk_compound_mac)); 1275 1276 if (cb->version != EAP_TEAP_VERSION || 1277 cb->received_version != data->peer_version) { 1278 wpa_printf(MSG_DEBUG, 1279 "EAP-TEAP: Unexpected version in Crypto-Binding: Version %u Received Version %u", 1280 cb->version, cb->received_version); 1281 return -1; 1282 } 1283 1284 if (flags < 1 || flags > 3) { 1285 wpa_printf(MSG_DEBUG, 1286 "EAP-TEAP: Unexpected Flags in Crypto-Binding: %u", 1287 flags); 1288 return -1; 1289 } 1290 1291 if (subtype != TEAP_CRYPTO_BINDING_SUBTYPE_RESPONSE) { 1292 wpa_printf(MSG_DEBUG, 1293 "EAP-TEAP: Unexpected Sub-Type in Crypto-Binding: %u", 1294 subtype); 1295 return -1; 1296 } 1297 1298 if (os_memcmp_const(data->crypto_binding_nonce, cb->nonce, 1299 EAP_TEAP_NONCE_LEN - 1) != 0 || 1300 (data->crypto_binding_nonce[EAP_TEAP_NONCE_LEN - 1] | 1) != 1301 cb->nonce[EAP_TEAP_NONCE_LEN - 1]) { 1302 wpa_printf(MSG_DEBUG, 1303 "EAP-TEAP: Invalid Nonce in Crypto-Binding"); 1304 return -1; 1305 } 1306 1307 if (flags == TEAP_CRYPTO_BINDING_MSK_CMAC || 1308 flags == TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC) { 1309 u8 msk_compound_mac[EAP_TEAP_COMPOUND_MAC_LEN]; 1310 1311 if (eap_teap_compound_mac(data->tls_cs, cb, 1312 data->server_outer_tlvs, 1313 data->peer_outer_tlvs, data->cmk_msk, 1314 msk_compound_mac) < 0) 1315 return -1; 1316 if (os_memcmp_const(msk_compound_mac, cb->msk_compound_mac, 1317 EAP_TEAP_COMPOUND_MAC_LEN) != 0) { 1318 wpa_hexdump(MSG_DEBUG, 1319 "EAP-TEAP: Calculated MSK Compound MAC", 1320 msk_compound_mac, 1321 EAP_TEAP_COMPOUND_MAC_LEN); 1322 wpa_printf(MSG_INFO, 1323 "EAP-TEAP: MSK Compound MAC did not match"); 1324 return -1; 1325 } 1326 } 1327 1328 if ((flags == TEAP_CRYPTO_BINDING_EMSK_CMAC || 1329 flags == TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC) && 1330 data->cmk_emsk_available) { 1331 u8 emsk_compound_mac[EAP_TEAP_COMPOUND_MAC_LEN]; 1332 1333 if (eap_teap_compound_mac(data->tls_cs, cb, 1334 data->server_outer_tlvs, 1335 data->peer_outer_tlvs, data->cmk_emsk, 1336 emsk_compound_mac) < 0) 1337 return -1; 1338 if (os_memcmp_const(emsk_compound_mac, cb->emsk_compound_mac, 1339 EAP_TEAP_COMPOUND_MAC_LEN) != 0) { 1340 wpa_hexdump(MSG_DEBUG, 1341 "EAP-TEAP: Calculated EMSK Compound MAC", 1342 emsk_compound_mac, 1343 EAP_TEAP_COMPOUND_MAC_LEN); 1344 wpa_printf(MSG_INFO, 1345 "EAP-TEAP: EMSK Compound MAC did not match"); 1346 return -1; 1347 } 1348 } 1349 1350 if (flags == TEAP_CRYPTO_BINDING_EMSK_CMAC && 1351 !data->cmk_emsk_available) { 1352 wpa_printf(MSG_INFO, 1353 "EAP-TEAP: Peer included only EMSK Compound MAC, but no locally generated inner EAP EMSK to validate this"); 1354 return -1; 1355 } 1356 1357 return 0; 1358 } 1359 1360 1361 static int eap_teap_pac_type(u8 *pac, size_t len, u16 type) 1362 { 1363 struct teap_attr_pac_type *tlv; 1364 1365 if (!pac || len != sizeof(*tlv)) 1366 return 0; 1367 1368 tlv = (struct teap_attr_pac_type *) pac; 1369 1370 return be_to_host16(tlv->type) == PAC_TYPE_PAC_TYPE && 1371 be_to_host16(tlv->length) == 2 && 1372 be_to_host16(tlv->pac_type) == type; 1373 } 1374 1375 1376 static void eap_teap_process_phase2_tlvs(struct eap_sm *sm, 1377 struct eap_teap_data *data, 1378 struct wpabuf *in_data) 1379 { 1380 struct eap_teap_tlv_parse tlv; 1381 int check_crypto_binding = data->state == CRYPTO_BINDING; 1382 1383 if (eap_teap_parse_tlvs(in_data, &tlv) < 0) { 1384 wpa_printf(MSG_DEBUG, 1385 "EAP-TEAP: Failed to parse received Phase 2 TLVs"); 1386 return; 1387 } 1388 1389 if (tlv.result == TEAP_STATUS_FAILURE) { 1390 wpa_printf(MSG_DEBUG, "EAP-TEAP: Result TLV indicated failure"); 1391 eap_teap_state(data, FAILURE); 1392 return; 1393 } 1394 1395 if (tlv.nak) { 1396 wpa_printf(MSG_DEBUG, 1397 "EAP-TEAP: Peer NAK'ed Vendor-Id %u NAK-Type %u", 1398 WPA_GET_BE32(tlv.nak), WPA_GET_BE16(tlv.nak + 4)); 1399 eap_teap_state(data, FAILURE_SEND_RESULT); 1400 return; 1401 } 1402 1403 if (data->state == REQUEST_PAC) { 1404 u16 type, len, res; 1405 1406 if (!tlv.pac || tlv.pac_len < 6) { 1407 wpa_printf(MSG_DEBUG, 1408 "EAP-TEAP: No PAC Acknowledgement received"); 1409 eap_teap_state(data, FAILURE); 1410 return; 1411 } 1412 1413 type = WPA_GET_BE16(tlv.pac); 1414 len = WPA_GET_BE16(tlv.pac + 2); 1415 res = WPA_GET_BE16(tlv.pac + 4); 1416 1417 if (type != PAC_TYPE_PAC_ACKNOWLEDGEMENT || len != 2 || 1418 res != TEAP_STATUS_SUCCESS) { 1419 wpa_printf(MSG_DEBUG, 1420 "EAP-TEAP: PAC TLV did not contain acknowledgement"); 1421 eap_teap_state(data, FAILURE); 1422 return; 1423 } 1424 1425 wpa_printf(MSG_DEBUG, 1426 "EAP-TEAP: PAC-Acknowledgement received - PAC provisioning succeeded"); 1427 eap_teap_state(data, SUCCESS); 1428 return; 1429 } 1430 1431 if (check_crypto_binding) { 1432 if (!tlv.crypto_binding) { 1433 wpa_printf(MSG_DEBUG, 1434 "EAP-TEAP: No Crypto-Binding TLV received"); 1435 eap_teap_state(data, FAILURE); 1436 return; 1437 } 1438 1439 if (data->final_result && 1440 tlv.result != TEAP_STATUS_SUCCESS) { 1441 wpa_printf(MSG_DEBUG, 1442 "EAP-TEAP: Crypto-Binding TLV without Success Result"); 1443 eap_teap_state(data, FAILURE); 1444 return; 1445 } 1446 1447 if (!data->final_result && 1448 tlv.iresult != TEAP_STATUS_SUCCESS) { 1449 wpa_printf(MSG_DEBUG, 1450 "EAP-TEAP: Crypto-Binding TLV without intermediate Success Result"); 1451 eap_teap_state(data, FAILURE); 1452 return; 1453 } 1454 1455 if (eap_teap_validate_crypto_binding(data, tlv.crypto_binding, 1456 tlv.crypto_binding_len)) { 1457 eap_teap_state(data, FAILURE); 1458 return; 1459 } 1460 1461 wpa_printf(MSG_DEBUG, 1462 "EAP-TEAP: Valid Crypto-Binding TLV received"); 1463 if (data->final_result) { 1464 wpa_printf(MSG_DEBUG, 1465 "EAP-TEAP: Authentication completed successfully"); 1466 } 1467 1468 if (data->anon_provisioning && 1469 sm->eap_fast_prov != ANON_PROV && 1470 sm->eap_fast_prov != BOTH_PROV) { 1471 wpa_printf(MSG_DEBUG, 1472 "EAP-TEAP: Client is trying to use unauthenticated provisioning which is disabled"); 1473 eap_teap_state(data, FAILURE); 1474 return; 1475 } 1476 1477 if (sm->eap_fast_prov != AUTH_PROV && 1478 sm->eap_fast_prov != BOTH_PROV && 1479 tlv.request_action == TEAP_REQUEST_ACTION_PROCESS_TLV && 1480 eap_teap_pac_type(tlv.pac, tlv.pac_len, 1481 PAC_TYPE_TUNNEL_PAC)) { 1482 wpa_printf(MSG_DEBUG, 1483 "EAP-TEAP: Client is trying to use authenticated provisioning which is disabled"); 1484 eap_teap_state(data, FAILURE); 1485 return; 1486 } 1487 1488 if (data->anon_provisioning || 1489 (tlv.request_action == TEAP_REQUEST_ACTION_PROCESS_TLV && 1490 eap_teap_pac_type(tlv.pac, tlv.pac_len, 1491 PAC_TYPE_TUNNEL_PAC))) { 1492 wpa_printf(MSG_DEBUG, 1493 "EAP-TEAP: Requested a new Tunnel PAC"); 1494 eap_teap_state(data, REQUEST_PAC); 1495 } else if (data->send_new_pac) { 1496 wpa_printf(MSG_DEBUG, 1497 "EAP-TEAP: Server triggered re-keying of Tunnel PAC"); 1498 eap_teap_state(data, REQUEST_PAC); 1499 } else if (data->final_result) 1500 eap_teap_state(data, SUCCESS); 1501 } 1502 1503 if (tlv.basic_auth_resp) { 1504 if (sm->eap_teap_auth != 1) { 1505 wpa_printf(MSG_DEBUG, 1506 "EAP-TEAP: Unexpected Basic-Password-Auth-Resp when trying to use inner EAP"); 1507 eap_teap_state(data, FAILURE); 1508 return; 1509 } 1510 eap_teap_process_basic_auth_resp(sm, data, tlv.basic_auth_resp, 1511 tlv.basic_auth_resp_len); 1512 } 1513 1514 if (tlv.eap_payload_tlv) { 1515 if (sm->eap_teap_auth == 1) { 1516 wpa_printf(MSG_DEBUG, 1517 "EAP-TEAP: Unexpected EAP Payload TLV when trying to use Basic-Password-Auth"); 1518 eap_teap_state(data, FAILURE); 1519 return; 1520 } 1521 eap_teap_process_phase2_eap(sm, data, tlv.eap_payload_tlv, 1522 tlv.eap_payload_tlv_len); 1523 } 1524 } 1525 1526 1527 static void eap_teap_process_phase2(struct eap_sm *sm, 1528 struct eap_teap_data *data, 1529 struct wpabuf *in_buf) 1530 { 1531 struct wpabuf *in_decrypted; 1532 1533 wpa_printf(MSG_DEBUG, 1534 "EAP-TEAP: Received %lu bytes encrypted data for Phase 2", 1535 (unsigned long) wpabuf_len(in_buf)); 1536 1537 if (data->pending_phase2_resp) { 1538 wpa_printf(MSG_DEBUG, 1539 "EAP-TEAP: Pending Phase 2 response - skip decryption and use old data"); 1540 eap_teap_process_phase2_tlvs(sm, data, 1541 data->pending_phase2_resp); 1542 wpabuf_free(data->pending_phase2_resp); 1543 data->pending_phase2_resp = NULL; 1544 return; 1545 } 1546 1547 in_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn, 1548 in_buf); 1549 if (!in_decrypted) { 1550 wpa_printf(MSG_INFO, 1551 "EAP-TEAP: Failed to decrypt Phase 2 data"); 1552 eap_teap_state(data, FAILURE); 1553 return; 1554 } 1555 1556 wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TEAP: Decrypted Phase 2 TLVs", 1557 in_decrypted); 1558 1559 eap_teap_process_phase2_tlvs(sm, data, in_decrypted); 1560 1561 if (sm->method_pending == METHOD_PENDING_WAIT) { 1562 wpa_printf(MSG_DEBUG, 1563 "EAP-TEAP: Phase 2 method is in pending wait state - save decrypted response"); 1564 wpabuf_free(data->pending_phase2_resp); 1565 data->pending_phase2_resp = in_decrypted; 1566 return; 1567 } 1568 1569 wpabuf_free(in_decrypted); 1570 } 1571 1572 1573 static int eap_teap_process_version(struct eap_sm *sm, void *priv, 1574 int peer_version) 1575 { 1576 struct eap_teap_data *data = priv; 1577 1578 if (peer_version < 1) { 1579 /* Version 1 was the first defined version, so reject 0 */ 1580 wpa_printf(MSG_INFO, 1581 "EAP-TEAP: Peer used unknown TEAP version %u", 1582 peer_version); 1583 return -1; 1584 } 1585 1586 if (peer_version < data->teap_version) { 1587 wpa_printf(MSG_DEBUG, "EAP-TEAP: peer ver=%u, own ver=%u; " 1588 "use version %u", 1589 peer_version, data->teap_version, peer_version); 1590 data->teap_version = peer_version; 1591 } 1592 1593 data->peer_version = peer_version; 1594 1595 return 0; 1596 } 1597 1598 1599 static int eap_teap_process_phase1(struct eap_sm *sm, 1600 struct eap_teap_data *data) 1601 { 1602 if (eap_server_tls_phase1(sm, &data->ssl) < 0) { 1603 wpa_printf(MSG_INFO, "EAP-TEAP: TLS processing failed"); 1604 eap_teap_state(data, FAILURE); 1605 return -1; 1606 } 1607 1608 if (!tls_connection_established(sm->ssl_ctx, data->ssl.conn) || 1609 wpabuf_len(data->ssl.tls_out) > 0) 1610 return 1; 1611 1612 /* 1613 * Phase 1 was completed with the received message (e.g., when using 1614 * abbreviated handshake), so Phase 2 can be started immediately 1615 * without having to send through an empty message to the peer. 1616 */ 1617 1618 return eap_teap_phase1_done(sm, data); 1619 } 1620 1621 1622 static int eap_teap_process_phase2_start(struct eap_sm *sm, 1623 struct eap_teap_data *data) 1624 { 1625 u8 next_type; 1626 1627 if (data->identity) { 1628 /* Used PAC and identity is from PAC-Opaque */ 1629 os_free(sm->identity); 1630 sm->identity = data->identity; 1631 data->identity = NULL; 1632 sm->identity_len = data->identity_len; 1633 data->identity_len = 0; 1634 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) { 1635 wpa_hexdump_ascii(MSG_DEBUG, 1636 "EAP-TEAP: Phase 2 Identity not found in the user database", 1637 sm->identity, sm->identity_len); 1638 next_type = EAP_TYPE_NONE; 1639 eap_teap_state(data, PHASE2_METHOD); 1640 } else if (sm->eap_teap_pac_no_inner) { 1641 wpa_printf(MSG_DEBUG, 1642 "EAP-TEAP: Used PAC and identity already known - skip inner auth"); 1643 /* FIX: Need to derive CMK here. However, how is that 1644 * supposed to be done? RFC 7170 does not tell that for 1645 * the no-inner-auth case. */ 1646 eap_teap_derive_cmk_basic_pw_auth(data->simck_msk, 1647 data->cmk_msk); 1648 eap_teap_state(data, CRYPTO_BINDING); 1649 return 1; 1650 } else if (sm->eap_teap_auth == 1) { 1651 eap_teap_state(data, PHASE2_BASIC_AUTH); 1652 return 1; 1653 } else { 1654 wpa_printf(MSG_DEBUG, 1655 "EAP-TEAP: Identity already known - skip Phase 2 Identity Request"); 1656 next_type = sm->user->methods[0].method; 1657 sm->user_eap_method_index = 1; 1658 eap_teap_state(data, PHASE2_METHOD); 1659 } 1660 1661 } else if (sm->eap_teap_auth == 1) { 1662 eap_teap_state(data, PHASE2_BASIC_AUTH); 1663 return 0; 1664 } else { 1665 eap_teap_state(data, PHASE2_ID); 1666 next_type = EAP_TYPE_IDENTITY; 1667 } 1668 1669 return eap_teap_phase2_init(sm, data, next_type); 1670 } 1671 1672 1673 static void eap_teap_process_msg(struct eap_sm *sm, void *priv, 1674 const struct wpabuf *respData) 1675 { 1676 struct eap_teap_data *data = priv; 1677 1678 switch (data->state) { 1679 case PHASE1: 1680 case PHASE1B: 1681 if (eap_teap_process_phase1(sm, data)) 1682 break; 1683 1684 /* fall through */ 1685 case PHASE2_START: 1686 eap_teap_process_phase2_start(sm, data); 1687 break; 1688 case PHASE2_ID: 1689 case PHASE2_BASIC_AUTH: 1690 case PHASE2_METHOD: 1691 case CRYPTO_BINDING: 1692 case REQUEST_PAC: 1693 eap_teap_process_phase2(sm, data, data->ssl.tls_in); 1694 break; 1695 case FAILURE_SEND_RESULT: 1696 /* Protected failure result indication completed. Ignore the 1697 * received message (which is supposed to include Result TLV 1698 * indicating failure) and terminate exchange with cleartext 1699 * EAP-Failure. */ 1700 eap_teap_state(data, FAILURE); 1701 break; 1702 default: 1703 wpa_printf(MSG_DEBUG, "EAP-TEAP: Unexpected state %d in %s", 1704 data->state, __func__); 1705 break; 1706 } 1707 } 1708 1709 1710 static void eap_teap_process(struct eap_sm *sm, void *priv, 1711 struct wpabuf *respData) 1712 { 1713 struct eap_teap_data *data = priv; 1714 const u8 *pos; 1715 size_t len; 1716 struct wpabuf *resp = respData; 1717 u8 flags; 1718 1719 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TEAP, respData, &len); 1720 if (!pos || len < 1) 1721 return; 1722 1723 flags = *pos++; 1724 len--; 1725 1726 if (flags & EAP_TEAP_FLAGS_OUTER_TLV_LEN) { 1727 /* Extract Outer TLVs from the message before common TLS 1728 * processing */ 1729 u32 message_len = 0, outer_tlv_len; 1730 const u8 *hdr; 1731 1732 if (data->state != PHASE1) { 1733 wpa_printf(MSG_INFO, 1734 "EAP-TEAP: Unexpected Outer TLVs in a message that is not the first message from the peer"); 1735 return; 1736 } 1737 1738 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) { 1739 if (len < 4) { 1740 wpa_printf(MSG_INFO, 1741 "EAP-TEAP: Too short message to include Message Length field"); 1742 return; 1743 } 1744 1745 message_len = WPA_GET_BE32(pos); 1746 pos += 4; 1747 len -= 4; 1748 if (message_len < 4) { 1749 wpa_printf(MSG_INFO, 1750 "EAP-TEAP: Message Length field has too msall value to include Outer TLV Length field"); 1751 return; 1752 } 1753 } 1754 1755 if (len < 4) { 1756 wpa_printf(MSG_INFO, 1757 "EAP-TEAP: Too short message to include Outer TLVs Length field"); 1758 return; 1759 } 1760 1761 outer_tlv_len = WPA_GET_BE32(pos); 1762 pos += 4; 1763 len -= 4; 1764 1765 wpa_printf(MSG_DEBUG, 1766 "EAP-TEAP: Message Length %u Outer TLV Length %u", 1767 message_len, outer_tlv_len); 1768 if (len < outer_tlv_len) { 1769 wpa_printf(MSG_INFO, 1770 "EAP-TEAP: Too short message to include Outer TLVs field"); 1771 return; 1772 } 1773 1774 if (message_len && 1775 (message_len < outer_tlv_len || 1776 message_len < 4 + outer_tlv_len)) { 1777 wpa_printf(MSG_INFO, 1778 "EAP-TEAP: Message Length field has too small value to include Outer TLVs"); 1779 return; 1780 } 1781 1782 if (wpabuf_len(respData) < 4 + outer_tlv_len || 1783 len < outer_tlv_len) 1784 return; 1785 resp = wpabuf_alloc(wpabuf_len(respData) - 4 - outer_tlv_len); 1786 if (!resp) 1787 return; 1788 hdr = wpabuf_head(respData); 1789 wpabuf_put_u8(resp, *hdr++); /* Code */ 1790 wpabuf_put_u8(resp, *hdr++); /* Identifier */ 1791 wpabuf_put_be16(resp, WPA_GET_BE16(hdr) - 4 - outer_tlv_len); 1792 hdr += 2; 1793 wpabuf_put_u8(resp, *hdr++); /* Type */ 1794 /* Flags | Ver */ 1795 wpabuf_put_u8(resp, flags & ~EAP_TEAP_FLAGS_OUTER_TLV_LEN); 1796 1797 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) 1798 wpabuf_put_be32(resp, message_len - 4 - outer_tlv_len); 1799 1800 wpabuf_put_data(resp, pos, len - outer_tlv_len); 1801 pos += len - outer_tlv_len; 1802 wpabuf_free(data->peer_outer_tlvs); 1803 data->peer_outer_tlvs = wpabuf_alloc_copy(pos, outer_tlv_len); 1804 if (!data->peer_outer_tlvs) 1805 return; 1806 wpa_hexdump_buf(MSG_DEBUG, "EAP-TEAP: Outer TLVs", 1807 data->peer_outer_tlvs); 1808 1809 wpa_hexdump_buf(MSG_DEBUG, 1810 "EAP-TEAP: TLS Data message after Outer TLV removal", 1811 resp); 1812 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TEAP, resp, 1813 &len); 1814 if (!pos || len < 1) { 1815 wpa_printf(MSG_INFO, 1816 "EAP-TEAP: Invalid frame after Outer TLV removal"); 1817 return; 1818 } 1819 } 1820 1821 if (data->state == PHASE1) 1822 eap_teap_state(data, PHASE1B); 1823 1824 if (eap_server_tls_process(sm, &data->ssl, resp, data, 1825 EAP_TYPE_TEAP, eap_teap_process_version, 1826 eap_teap_process_msg) < 0) 1827 eap_teap_state(data, FAILURE); 1828 1829 if (resp != respData) 1830 wpabuf_free(resp); 1831 } 1832 1833 1834 static Boolean eap_teap_isDone(struct eap_sm *sm, void *priv) 1835 { 1836 struct eap_teap_data *data = priv; 1837 1838 return data->state == SUCCESS || data->state == FAILURE; 1839 } 1840 1841 1842 static u8 * eap_teap_getKey(struct eap_sm *sm, void *priv, size_t *len) 1843 { 1844 struct eap_teap_data *data = priv; 1845 u8 *eapKeyData; 1846 1847 if (data->state != SUCCESS) 1848 return NULL; 1849 1850 eapKeyData = os_malloc(EAP_TEAP_KEY_LEN); 1851 if (!eapKeyData) 1852 return NULL; 1853 1854 /* FIX: RFC 7170 does not describe whether MSK or EMSK based S-IMCK[j] 1855 * is used in this derivation */ 1856 if (eap_teap_derive_eap_msk(data->simck_msk, eapKeyData) < 0) { 1857 os_free(eapKeyData); 1858 return NULL; 1859 } 1860 *len = EAP_TEAP_KEY_LEN; 1861 1862 return eapKeyData; 1863 } 1864 1865 1866 static u8 * eap_teap_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 1867 { 1868 struct eap_teap_data *data = priv; 1869 u8 *eapKeyData; 1870 1871 if (data->state != SUCCESS) 1872 return NULL; 1873 1874 eapKeyData = os_malloc(EAP_EMSK_LEN); 1875 if (!eapKeyData) 1876 return NULL; 1877 1878 /* FIX: RFC 7170 does not describe whether MSK or EMSK based S-IMCK[j] 1879 * is used in this derivation */ 1880 if (eap_teap_derive_eap_emsk(data->simck_msk, eapKeyData) < 0) { 1881 os_free(eapKeyData); 1882 return NULL; 1883 } 1884 *len = EAP_EMSK_LEN; 1885 1886 return eapKeyData; 1887 } 1888 1889 1890 static Boolean eap_teap_isSuccess(struct eap_sm *sm, void *priv) 1891 { 1892 struct eap_teap_data *data = priv; 1893 1894 return data->state == SUCCESS; 1895 } 1896 1897 1898 static u8 * eap_teap_get_session_id(struct eap_sm *sm, void *priv, size_t *len) 1899 { 1900 struct eap_teap_data *data = priv; 1901 const size_t max_id_len = 100; 1902 int res; 1903 u8 *id; 1904 1905 if (data->state != SUCCESS) 1906 return NULL; 1907 1908 id = os_malloc(max_id_len); 1909 if (!id) 1910 return NULL; 1911 1912 id[0] = EAP_TYPE_TEAP; 1913 res = tls_get_tls_unique(data->ssl.conn, id + 1, max_id_len - 1); 1914 if (res < 0) { 1915 os_free(id); 1916 wpa_printf(MSG_ERROR, "EAP-TEAP: Failed to derive Session-Id"); 1917 return NULL; 1918 } 1919 1920 *len = 1 + res; 1921 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: Derived Session-Id", id, *len); 1922 return id; 1923 } 1924 1925 1926 int eap_server_teap_register(void) 1927 { 1928 struct eap_method *eap; 1929 1930 eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, 1931 EAP_VENDOR_IETF, EAP_TYPE_TEAP, "TEAP"); 1932 if (!eap) 1933 return -1; 1934 1935 eap->init = eap_teap_init; 1936 eap->reset = eap_teap_reset; 1937 eap->buildReq = eap_teap_buildReq; 1938 eap->check = eap_teap_check; 1939 eap->process = eap_teap_process; 1940 eap->isDone = eap_teap_isDone; 1941 eap->getKey = eap_teap_getKey; 1942 eap->get_emsk = eap_teap_get_emsk; 1943 eap->isSuccess = eap_teap_isSuccess; 1944 eap->getSessionId = eap_teap_get_session_id; 1945 1946 return eap_server_method_register(eap); 1947 } 1948