1 /* 2 * EAP peer method: EAP-TEAP (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/tls.h" 13 #include "eap_common/eap_teap_common.h" 14 #include "eap_i.h" 15 #include "eap_tls_common.h" 16 #include "eap_config.h" 17 #include "eap_teap_pac.h" 18 19 #ifdef EAP_TEAP_DYNAMIC 20 #include "eap_teap_pac.c" 21 #endif /* EAP_TEAP_DYNAMIC */ 22 23 24 static void eap_teap_deinit(struct eap_sm *sm, void *priv); 25 26 27 struct eap_teap_data { 28 struct eap_ssl_data ssl; 29 30 u8 teap_version; /* Negotiated version */ 31 u8 received_version; /* Version number received during negotiation */ 32 u16 tls_cs; 33 34 const struct eap_method *phase2_method; 35 void *phase2_priv; 36 int phase2_success; 37 int inner_method_done; 38 int result_success_done; 39 int on_tx_completion; 40 41 struct eap_method_type phase2_type; 42 struct eap_method_type *phase2_types; 43 size_t num_phase2_types; 44 int resuming; /* starting a resumed session */ 45 #define EAP_TEAP_PROV_UNAUTH 1 46 #define EAP_TEAP_PROV_AUTH 2 47 int provisioning_allowed; /* Allowed PAC provisioning modes */ 48 int provisioning; /* doing PAC provisioning (not the normal auth) */ 49 int anon_provisioning; /* doing anonymous (unauthenticated) 50 * provisioning */ 51 int session_ticket_used; 52 int test_outer_tlvs; 53 54 u8 key_data[EAP_TEAP_KEY_LEN]; 55 u8 *session_id; 56 size_t id_len; 57 u8 emsk[EAP_EMSK_LEN]; 58 int success; 59 60 struct eap_teap_pac *pac; 61 struct eap_teap_pac *current_pac; 62 size_t max_pac_list_len; 63 int use_pac_binary_format; 64 65 u8 simck_msk[EAP_TEAP_SIMCK_LEN]; 66 u8 simck_emsk[EAP_TEAP_SIMCK_LEN]; 67 int simck_idx; 68 int cmk_emsk_available; 69 70 struct wpabuf *pending_phase2_req; 71 struct wpabuf *pending_resp; 72 struct wpabuf *server_outer_tlvs; 73 struct wpabuf *peer_outer_tlvs; 74 }; 75 76 77 static int eap_teap_session_ticket_cb(void *ctx, const u8 *ticket, size_t len, 78 const u8 *client_random, 79 const u8 *server_random, 80 u8 *master_secret) 81 { 82 struct eap_teap_data *data = ctx; 83 84 wpa_printf(MSG_DEBUG, "EAP-TEAP: SessionTicket callback"); 85 86 if (!master_secret) { 87 wpa_printf(MSG_DEBUG, 88 "EAP-TEAP: SessionTicket failed - fall back to full TLS handshake"); 89 data->session_ticket_used = 0; 90 if (data->provisioning_allowed) { 91 wpa_printf(MSG_DEBUG, 92 "EAP-TEAP: Try to provision a new PAC-Key"); 93 data->provisioning = 1; 94 data->current_pac = NULL; 95 } 96 return 0; 97 } 98 99 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: SessionTicket", ticket, len); 100 101 if (!data->current_pac) { 102 wpa_printf(MSG_DEBUG, 103 "EAP-TEAP: No PAC-Key available for using SessionTicket"); 104 data->session_ticket_used = 0; 105 return 0; 106 } 107 108 /* EAP-TEAP uses PAC-Key as the TLS master_secret */ 109 os_memcpy(master_secret, data->current_pac->pac_key, 110 EAP_TEAP_PAC_KEY_LEN); 111 112 data->session_ticket_used = 1; 113 114 return 1; 115 } 116 117 118 static void eap_teap_parse_phase1(struct eap_teap_data *data, 119 const char *phase1) 120 { 121 const char *pos; 122 123 pos = os_strstr(phase1, "teap_provisioning="); 124 if (pos) { 125 data->provisioning_allowed = atoi(pos + 18); 126 wpa_printf(MSG_DEBUG, 127 "EAP-TEAP: Automatic PAC provisioning mode: %d", 128 data->provisioning_allowed); 129 } 130 131 pos = os_strstr(phase1, "teap_max_pac_list_len="); 132 if (pos) { 133 data->max_pac_list_len = atoi(pos + 22); 134 if (data->max_pac_list_len == 0) 135 data->max_pac_list_len = 1; 136 wpa_printf(MSG_DEBUG, "EAP-TEAP: Maximum PAC list length: %lu", 137 (unsigned long) data->max_pac_list_len); 138 } 139 140 if (os_strstr(phase1, "teap_pac_format=binary")) { 141 data->use_pac_binary_format = 1; 142 wpa_printf(MSG_DEBUG, 143 "EAP-TEAP: Using binary format for PAC list"); 144 } 145 146 #ifdef CONFIG_TESTING_OPTIONS 147 if (os_strstr(phase1, "teap_test_outer_tlvs=1")) 148 data->test_outer_tlvs = 1; 149 #endif /* CONFIG_TESTING_OPTIONS */ 150 } 151 152 153 static void * eap_teap_init(struct eap_sm *sm) 154 { 155 struct eap_teap_data *data; 156 struct eap_peer_config *config = eap_get_config(sm); 157 158 if (!config) 159 return NULL; 160 161 data = os_zalloc(sizeof(*data)); 162 if (!data) 163 return NULL; 164 data->teap_version = EAP_TEAP_VERSION; 165 data->max_pac_list_len = 10; 166 167 if (config->phase1) 168 eap_teap_parse_phase1(data, config->phase1); 169 170 if ((data->provisioning_allowed & EAP_TEAP_PROV_AUTH) && 171 !config->ca_cert && !config->ca_path) { 172 /* Prevent PAC provisioning without mutual authentication 173 * (either by validating server certificate or by suitable 174 * inner EAP method). */ 175 wpa_printf(MSG_INFO, 176 "EAP-TEAP: Disable authenticated provisioning due to no ca_cert/ca_path"); 177 data->provisioning_allowed &= ~EAP_TEAP_PROV_AUTH; 178 } 179 180 if (eap_peer_select_phase2_methods(config, "auth=", 181 &data->phase2_types, 182 &data->num_phase2_types) < 0) { 183 eap_teap_deinit(sm, data); 184 return NULL; 185 } 186 187 data->phase2_type.vendor = EAP_VENDOR_IETF; 188 data->phase2_type.method = EAP_TYPE_NONE; 189 190 config->teap_anon_dh = !!(data->provisioning_allowed & 191 EAP_TEAP_PROV_UNAUTH); 192 if (eap_peer_tls_ssl_init(sm, &data->ssl, config, EAP_TYPE_TEAP)) { 193 wpa_printf(MSG_INFO, "EAP-TEAP: Failed to initialize SSL"); 194 eap_teap_deinit(sm, data); 195 return NULL; 196 } 197 198 if (tls_connection_set_session_ticket_cb(sm->ssl_ctx, data->ssl.conn, 199 eap_teap_session_ticket_cb, 200 data) < 0) { 201 wpa_printf(MSG_INFO, 202 "EAP-TEAP: Failed to set SessionTicket callback"); 203 eap_teap_deinit(sm, data); 204 return NULL; 205 } 206 207 if (!config->pac_file) { 208 wpa_printf(MSG_INFO, "EAP-TEAP: No PAC file configured"); 209 eap_teap_deinit(sm, data); 210 return NULL; 211 } 212 213 if (data->use_pac_binary_format && 214 eap_teap_load_pac_bin(sm, &data->pac, config->pac_file) < 0) { 215 wpa_printf(MSG_INFO, "EAP-TEAP: Failed to load PAC file"); 216 eap_teap_deinit(sm, data); 217 return NULL; 218 } 219 220 if (!data->use_pac_binary_format && 221 eap_teap_load_pac(sm, &data->pac, config->pac_file) < 0) { 222 wpa_printf(MSG_INFO, "EAP-TEAP: Failed to load PAC file"); 223 eap_teap_deinit(sm, data); 224 return NULL; 225 } 226 eap_teap_pac_list_truncate(data->pac, data->max_pac_list_len); 227 228 return data; 229 } 230 231 232 static void eap_teap_clear(struct eap_teap_data *data) 233 { 234 forced_memzero(data->key_data, EAP_TEAP_KEY_LEN); 235 forced_memzero(data->emsk, EAP_EMSK_LEN); 236 os_free(data->session_id); 237 data->session_id = NULL; 238 wpabuf_free(data->pending_phase2_req); 239 data->pending_phase2_req = NULL; 240 wpabuf_free(data->pending_resp); 241 data->pending_resp = NULL; 242 wpabuf_free(data->server_outer_tlvs); 243 data->server_outer_tlvs = NULL; 244 wpabuf_free(data->peer_outer_tlvs); 245 data->peer_outer_tlvs = NULL; 246 forced_memzero(data->simck_msk, EAP_TEAP_SIMCK_LEN); 247 forced_memzero(data->simck_emsk, EAP_TEAP_SIMCK_LEN); 248 } 249 250 251 static void eap_teap_deinit(struct eap_sm *sm, void *priv) 252 { 253 struct eap_teap_data *data = priv; 254 struct eap_teap_pac *pac, *prev; 255 256 if (!data) 257 return; 258 if (data->phase2_priv && data->phase2_method) 259 data->phase2_method->deinit(sm, data->phase2_priv); 260 eap_teap_clear(data); 261 os_free(data->phase2_types); 262 eap_peer_tls_ssl_deinit(sm, &data->ssl); 263 264 pac = data->pac; 265 prev = NULL; 266 while (pac) { 267 prev = pac; 268 pac = pac->next; 269 eap_teap_free_pac(prev); 270 } 271 272 os_free(data); 273 } 274 275 276 static int eap_teap_derive_msk(struct eap_teap_data *data) 277 { 278 /* FIX: RFC 7170 does not describe whether MSK or EMSK based S-IMCK[j] 279 * is used in this derivation */ 280 if (eap_teap_derive_eap_msk(data->simck_msk, data->key_data) < 0 || 281 eap_teap_derive_eap_emsk(data->simck_msk, data->emsk) < 0) 282 return -1; 283 data->success = 1; 284 return 0; 285 } 286 287 288 static int eap_teap_derive_key_auth(struct eap_sm *sm, 289 struct eap_teap_data *data) 290 { 291 int res; 292 293 /* RFC 7170, Section 5.1 */ 294 res = tls_connection_export_key(sm->ssl_ctx, data->ssl.conn, 295 TEAP_TLS_EXPORTER_LABEL_SKS, NULL, 0, 296 data->simck_msk, EAP_TEAP_SIMCK_LEN); 297 if (res) 298 return res; 299 wpa_hexdump_key(MSG_DEBUG, 300 "EAP-TEAP: session_key_seed (S-IMCK[0])", 301 data->simck_msk, EAP_TEAP_SIMCK_LEN); 302 os_memcpy(data->simck_emsk, data->simck_msk, EAP_TEAP_SIMCK_LEN); 303 data->simck_idx = 0; 304 return 0; 305 } 306 307 308 static int eap_teap_init_phase2_method(struct eap_sm *sm, 309 struct eap_teap_data *data) 310 { 311 data->inner_method_done = 0; 312 data->phase2_method = 313 eap_peer_get_eap_method(data->phase2_type.vendor, 314 data->phase2_type.method); 315 if (!data->phase2_method) 316 return -1; 317 318 sm->init_phase2 = 1; 319 data->phase2_priv = data->phase2_method->init(sm); 320 sm->init_phase2 = 0; 321 322 return data->phase2_priv == NULL ? -1 : 0; 323 } 324 325 326 static int eap_teap_select_phase2_method(struct eap_teap_data *data, u8 type) 327 { 328 size_t i; 329 330 /* TODO: TNC with anonymous provisioning; need to require both 331 * completed inner EAP authentication (EAP-pwd or EAP-EKE) and TNC */ 332 333 if (data->anon_provisioning && 334 !eap_teap_allowed_anon_prov_phase2_method(type)) { 335 wpa_printf(MSG_INFO, 336 "EAP-TEAP: EAP type %u not allowed during unauthenticated provisioning", 337 type); 338 return -1; 339 } 340 341 #ifdef EAP_TNC 342 if (type == EAP_TYPE_TNC) { 343 data->phase2_type.vendor = EAP_VENDOR_IETF; 344 data->phase2_type.method = EAP_TYPE_TNC; 345 wpa_printf(MSG_DEBUG, 346 "EAP-TEAP: Selected Phase 2 EAP vendor %d method %d for TNC", 347 data->phase2_type.vendor, 348 data->phase2_type.method); 349 return 0; 350 } 351 #endif /* EAP_TNC */ 352 353 for (i = 0; i < data->num_phase2_types; i++) { 354 if (data->phase2_types[i].vendor != EAP_VENDOR_IETF || 355 data->phase2_types[i].method != type) 356 continue; 357 358 data->phase2_type.vendor = data->phase2_types[i].vendor; 359 data->phase2_type.method = data->phase2_types[i].method; 360 wpa_printf(MSG_DEBUG, 361 "EAP-TEAP: Selected Phase 2 EAP vendor %d method %d", 362 data->phase2_type.vendor, 363 data->phase2_type.method); 364 break; 365 } 366 367 if (type != data->phase2_type.method || type == EAP_TYPE_NONE) 368 return -1; 369 370 return 0; 371 } 372 373 374 static int eap_teap_phase2_request(struct eap_sm *sm, 375 struct eap_teap_data *data, 376 struct eap_method_ret *ret, 377 struct eap_hdr *hdr, 378 struct wpabuf **resp) 379 { 380 size_t len = be_to_host16(hdr->length); 381 u8 *pos; 382 struct eap_method_ret iret; 383 struct eap_peer_config *config = eap_get_config(sm); 384 struct wpabuf msg; 385 386 if (len <= sizeof(struct eap_hdr)) { 387 wpa_printf(MSG_INFO, 388 "EAP-TEAP: too short Phase 2 request (len=%lu)", 389 (unsigned long) len); 390 return -1; 391 } 392 pos = (u8 *) (hdr + 1); 393 wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 2 Request: type=%d", *pos); 394 if (*pos == EAP_TYPE_IDENTITY) { 395 *resp = eap_sm_buildIdentity(sm, hdr->identifier, 1); 396 return 0; 397 } 398 399 if (data->phase2_priv && data->phase2_method && 400 *pos != data->phase2_type.method) { 401 wpa_printf(MSG_DEBUG, 402 "EAP-TEAP: Phase 2 EAP sequence - deinitialize previous method"); 403 data->phase2_method->deinit(sm, data->phase2_priv); 404 data->phase2_method = NULL; 405 data->phase2_priv = NULL; 406 data->phase2_type.vendor = EAP_VENDOR_IETF; 407 data->phase2_type.method = EAP_TYPE_NONE; 408 } 409 410 if (data->phase2_type.vendor == EAP_VENDOR_IETF && 411 data->phase2_type.method == EAP_TYPE_NONE && 412 eap_teap_select_phase2_method(data, *pos) < 0) { 413 if (eap_peer_tls_phase2_nak(data->phase2_types, 414 data->num_phase2_types, 415 hdr, resp)) 416 return -1; 417 return 0; 418 } 419 420 if ((!data->phase2_priv && eap_teap_init_phase2_method(sm, data) < 0) || 421 !data->phase2_method) { 422 wpa_printf(MSG_INFO, 423 "EAP-TEAP: Failed to initialize Phase 2 EAP method %d", 424 *pos); 425 ret->methodState = METHOD_DONE; 426 ret->decision = DECISION_FAIL; 427 return -1; 428 } 429 430 os_memset(&iret, 0, sizeof(iret)); 431 wpabuf_set(&msg, hdr, len); 432 *resp = data->phase2_method->process(sm, data->phase2_priv, &iret, 433 &msg); 434 if (iret.methodState == METHOD_DONE) 435 data->inner_method_done = 1; 436 if (!(*resp) || 437 (iret.methodState == METHOD_DONE && 438 iret.decision == DECISION_FAIL)) { 439 ret->methodState = METHOD_DONE; 440 ret->decision = DECISION_FAIL; 441 } else if ((iret.methodState == METHOD_DONE || 442 iret.methodState == METHOD_MAY_CONT) && 443 (iret.decision == DECISION_UNCOND_SUCC || 444 iret.decision == DECISION_COND_SUCC)) { 445 data->phase2_success = 1; 446 } 447 448 if (!(*resp) && config && 449 (config->pending_req_identity || config->pending_req_password || 450 config->pending_req_otp || config->pending_req_new_password || 451 config->pending_req_sim)) { 452 wpabuf_free(data->pending_phase2_req); 453 data->pending_phase2_req = wpabuf_alloc_copy(hdr, len); 454 } else if (!(*resp)) 455 return -1; 456 457 return 0; 458 } 459 460 461 static struct wpabuf * eap_teap_tlv_nak(int vendor_id, int tlv_type) 462 { 463 struct wpabuf *buf; 464 struct teap_tlv_nak *nak; 465 466 wpa_printf(MSG_DEBUG, 467 "EAP-TEAP: Add NAK TLV (Vendor-Id %u NAK-Type %u)", 468 vendor_id, tlv_type); 469 buf = wpabuf_alloc(sizeof(*nak)); 470 if (!buf) 471 return NULL; 472 nak = wpabuf_put(buf, sizeof(*nak)); 473 nak->tlv_type = host_to_be16(TEAP_TLV_MANDATORY | TEAP_TLV_NAK); 474 nak->length = host_to_be16(6); 475 nak->vendor_id = host_to_be32(vendor_id); 476 nak->nak_type = host_to_be16(tlv_type); 477 return buf; 478 } 479 480 481 static struct wpabuf * eap_teap_tlv_pac_ack(void) 482 { 483 struct wpabuf *buf; 484 struct teap_tlv_result *res; 485 struct teap_tlv_pac_ack *ack; 486 487 buf = wpabuf_alloc(sizeof(*res) + sizeof(*ack)); 488 if (!buf) 489 return NULL; 490 491 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add PAC TLV (ack)"); 492 ack = wpabuf_put(buf, sizeof(*ack)); 493 ack->tlv_type = host_to_be16(TEAP_TLV_PAC | TEAP_TLV_MANDATORY); 494 ack->length = host_to_be16(sizeof(*ack) - sizeof(struct teap_tlv_hdr)); 495 ack->pac_type = host_to_be16(PAC_TYPE_PAC_ACKNOWLEDGEMENT); 496 ack->pac_len = host_to_be16(2); 497 ack->result = host_to_be16(TEAP_STATUS_SUCCESS); 498 499 return buf; 500 } 501 502 503 static struct wpabuf * eap_teap_process_eap_payload_tlv( 504 struct eap_sm *sm, struct eap_teap_data *data, 505 struct eap_method_ret *ret, 506 u8 *eap_payload_tlv, size_t eap_payload_tlv_len) 507 { 508 struct eap_hdr *hdr; 509 struct wpabuf *resp = NULL; 510 511 if (eap_payload_tlv_len < sizeof(*hdr)) { 512 wpa_printf(MSG_DEBUG, 513 "EAP-TEAP: too short EAP Payload TLV (len=%lu)", 514 (unsigned long) eap_payload_tlv_len); 515 return NULL; 516 } 517 518 hdr = (struct eap_hdr *) eap_payload_tlv; 519 if (be_to_host16(hdr->length) > eap_payload_tlv_len) { 520 wpa_printf(MSG_DEBUG, 521 "EAP-TEAP: EAP packet overflow in EAP Payload TLV"); 522 return NULL; 523 } 524 525 if (hdr->code != EAP_CODE_REQUEST) { 526 wpa_printf(MSG_INFO, 527 "EAP-TEAP: Unexpected code=%d in Phase 2 EAP header", 528 hdr->code); 529 return NULL; 530 } 531 532 if (eap_teap_phase2_request(sm, data, ret, hdr, &resp)) { 533 wpa_printf(MSG_INFO, 534 "EAP-TEAP: Phase 2 Request processing failed"); 535 return NULL; 536 } 537 538 return eap_teap_tlv_eap_payload(resp); 539 } 540 541 542 static struct wpabuf * eap_teap_process_basic_auth_req( 543 struct eap_sm *sm, struct eap_teap_data *data, 544 u8 *basic_auth_req, size_t basic_auth_req_len) 545 { 546 const u8 *identity, *password; 547 size_t identity_len, password_len, plen; 548 struct wpabuf *resp; 549 550 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: Basic-Password-Auth-Req prompt", 551 basic_auth_req, basic_auth_req_len); 552 /* TODO: send over control interface */ 553 554 identity = eap_get_config_identity(sm, &identity_len); 555 password = eap_get_config_password(sm, &password_len); 556 if (!identity || !password || 557 identity_len > 255 || password_len > 255) { 558 wpa_printf(MSG_DEBUG, 559 "EAP-TEAP: No username/password suitable for Basic-Password-Auth"); 560 return eap_teap_tlv_nak(0, TEAP_TLV_BASIC_PASSWORD_AUTH_REQ); 561 } 562 563 plen = 1 + identity_len + 1 + password_len; 564 resp = wpabuf_alloc(sizeof(struct teap_tlv_hdr) + plen); 565 if (!resp) 566 return NULL; 567 eap_teap_put_tlv_hdr(resp, TEAP_TLV_BASIC_PASSWORD_AUTH_RESP, plen); 568 wpabuf_put_u8(resp, identity_len); 569 wpabuf_put_data(resp, identity, identity_len); 570 wpabuf_put_u8(resp, password_len); 571 wpabuf_put_data(resp, password, password_len); 572 wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TEAP: Basic-Password-Auth-Resp", 573 resp); 574 575 /* Assume this succeeds so that Result TLV(Success) from the server can 576 * be used to terminate TEAP. */ 577 data->phase2_success = 1; 578 579 return resp; 580 } 581 582 583 static int 584 eap_teap_validate_crypto_binding(struct eap_teap_data *data, 585 const struct teap_tlv_crypto_binding *cb) 586 { 587 u8 flags, subtype; 588 589 subtype = cb->subtype & 0x0f; 590 flags = cb->subtype >> 4; 591 592 wpa_printf(MSG_DEBUG, 593 "EAP-TEAP: Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u", 594 cb->version, cb->received_version, flags, subtype); 595 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Nonce", 596 cb->nonce, sizeof(cb->nonce)); 597 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EMSK Compound MAC", 598 cb->emsk_compound_mac, sizeof(cb->emsk_compound_mac)); 599 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC", 600 cb->msk_compound_mac, sizeof(cb->msk_compound_mac)); 601 602 if (cb->version != EAP_TEAP_VERSION || 603 cb->received_version != data->received_version || 604 subtype != TEAP_CRYPTO_BINDING_SUBTYPE_REQUEST || 605 flags < 1 || flags > 3) { 606 wpa_printf(MSG_INFO, 607 "EAP-TEAP: Invalid Version/Flags/Sub-Type in Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u", 608 cb->version, cb->received_version, flags, subtype); 609 return -1; 610 } 611 612 if (cb->nonce[EAP_TEAP_NONCE_LEN - 1] & 0x01) { 613 wpa_printf(MSG_INFO, 614 "EAP-TEAP: Invalid Crypto-Binding TLV Nonce in request"); 615 return -1; 616 } 617 618 return 0; 619 } 620 621 622 static int eap_teap_write_crypto_binding( 623 struct eap_teap_data *data, 624 struct teap_tlv_crypto_binding *rbind, 625 const struct teap_tlv_crypto_binding *cb, 626 const u8 *cmk_msk, const u8 *cmk_emsk) 627 { 628 u8 subtype, flags; 629 630 rbind->tlv_type = host_to_be16(TEAP_TLV_MANDATORY | 631 TEAP_TLV_CRYPTO_BINDING); 632 rbind->length = host_to_be16(sizeof(*rbind) - 633 sizeof(struct teap_tlv_hdr)); 634 rbind->version = EAP_TEAP_VERSION; 635 rbind->received_version = data->received_version; 636 /* FIX: RFC 7170 is not clear on which Flags value to use when 637 * Crypto-Binding TLV is used with Basic-Password-Auth */ 638 flags = cmk_emsk ? TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC : 639 TEAP_CRYPTO_BINDING_MSK_CMAC; 640 subtype = TEAP_CRYPTO_BINDING_SUBTYPE_RESPONSE; 641 rbind->subtype = (flags << 4) | subtype; 642 os_memcpy(rbind->nonce, cb->nonce, sizeof(cb->nonce)); 643 inc_byte_array(rbind->nonce, sizeof(rbind->nonce)); 644 os_memset(rbind->emsk_compound_mac, 0, EAP_TEAP_COMPOUND_MAC_LEN); 645 os_memset(rbind->msk_compound_mac, 0, EAP_TEAP_COMPOUND_MAC_LEN); 646 647 if (eap_teap_compound_mac(data->tls_cs, rbind, data->server_outer_tlvs, 648 data->peer_outer_tlvs, cmk_msk, 649 rbind->msk_compound_mac) < 0) 650 return -1; 651 if (cmk_emsk && 652 eap_teap_compound_mac(data->tls_cs, rbind, data->server_outer_tlvs, 653 data->peer_outer_tlvs, cmk_emsk, 654 rbind->emsk_compound_mac) < 0) 655 return -1; 656 657 wpa_printf(MSG_DEBUG, 658 "EAP-TEAP: Reply Crypto-Binding TLV: Version %u Received Version %u Flags %u SubType %u", 659 rbind->version, rbind->received_version, flags, subtype); 660 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Nonce", 661 rbind->nonce, sizeof(rbind->nonce)); 662 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EMSK Compound MAC", 663 rbind->emsk_compound_mac, sizeof(rbind->emsk_compound_mac)); 664 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC", 665 rbind->msk_compound_mac, sizeof(rbind->msk_compound_mac)); 666 667 return 0; 668 } 669 670 671 static int eap_teap_get_cmk(struct eap_sm *sm, struct eap_teap_data *data, 672 u8 *cmk_msk, u8 *cmk_emsk) 673 { 674 u8 *msk = NULL, *emsk = NULL; 675 size_t msk_len = 0, emsk_len = 0; 676 int res; 677 678 wpa_printf(MSG_DEBUG, 679 "EAP-TEAP: Determining CMK[%d] for Compound MAC calculation", 680 data->simck_idx + 1); 681 682 if (!data->phase2_method) 683 return eap_teap_derive_cmk_basic_pw_auth(data->simck_msk, 684 cmk_msk); 685 686 if (!data->phase2_method || !data->phase2_priv) { 687 wpa_printf(MSG_INFO, "EAP-TEAP: Phase 2 method not available"); 688 return -1; 689 } 690 691 if (data->phase2_method->isKeyAvailable && 692 !data->phase2_method->isKeyAvailable(sm, data->phase2_priv)) { 693 wpa_printf(MSG_INFO, 694 "EAP-TEAP: Phase 2 key material not available"); 695 return -1; 696 } 697 698 if (data->phase2_method->isKeyAvailable && 699 data->phase2_method->getKey) { 700 msk = data->phase2_method->getKey(sm, data->phase2_priv, 701 &msk_len); 702 if (!msk) { 703 wpa_printf(MSG_INFO, 704 "EAP-TEAP: Could not fetch Phase 2 MSK"); 705 return -1; 706 } 707 } 708 709 if (data->phase2_method->isKeyAvailable && 710 data->phase2_method->get_emsk) { 711 emsk = data->phase2_method->get_emsk(sm, data->phase2_priv, 712 &emsk_len); 713 } 714 715 res = eap_teap_derive_imck(data->simck_msk, data->simck_emsk, 716 msk, msk_len, emsk, emsk_len, 717 data->simck_msk, cmk_msk, 718 data->simck_emsk, cmk_emsk); 719 bin_clear_free(msk, msk_len); 720 bin_clear_free(emsk, emsk_len); 721 if (res == 0) { 722 data->simck_idx++; 723 if (emsk) 724 data->cmk_emsk_available = 1; 725 } 726 return res; 727 } 728 729 730 static int eap_teap_session_id(struct eap_teap_data *data) 731 { 732 const size_t max_id_len = 100; 733 int res; 734 735 os_free(data->session_id); 736 data->session_id = os_malloc(max_id_len); 737 if (!data->session_id) 738 return -1; 739 740 data->session_id[0] = EAP_TYPE_TEAP; 741 res = tls_get_tls_unique(data->ssl.conn, data->session_id + 1, 742 max_id_len - 1); 743 if (res < 0) { 744 os_free(data->session_id); 745 data->session_id = NULL; 746 wpa_printf(MSG_ERROR, "EAP-TEAP: Failed to derive Session-Id"); 747 return -1; 748 } 749 750 data->id_len = 1 + res; 751 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: Derived Session-Id", 752 data->session_id, data->id_len); 753 return 0; 754 } 755 756 757 static struct wpabuf * eap_teap_process_crypto_binding( 758 struct eap_sm *sm, struct eap_teap_data *data, 759 struct eap_method_ret *ret, 760 const struct teap_tlv_crypto_binding *cb, size_t bind_len) 761 { 762 struct wpabuf *resp; 763 u8 *pos; 764 u8 cmk_msk[EAP_TEAP_CMK_LEN]; 765 u8 cmk_emsk[EAP_TEAP_CMK_LEN]; 766 const u8 *cmk_emsk_ptr = NULL; 767 int res; 768 size_t len; 769 u8 flags; 770 771 if (eap_teap_validate_crypto_binding(data, cb) < 0 || 772 eap_teap_get_cmk(sm, data, cmk_msk, cmk_emsk) < 0) 773 return NULL; 774 775 /* Validate received MSK/EMSK Compound MAC */ 776 flags = cb->subtype >> 4; 777 778 if (flags == TEAP_CRYPTO_BINDING_MSK_CMAC || 779 flags == TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC) { 780 u8 msk_compound_mac[EAP_TEAP_COMPOUND_MAC_LEN]; 781 782 if (eap_teap_compound_mac(data->tls_cs, cb, 783 data->server_outer_tlvs, 784 data->peer_outer_tlvs, cmk_msk, 785 msk_compound_mac) < 0) 786 return NULL; 787 res = os_memcmp_const(msk_compound_mac, cb->msk_compound_mac, 788 EAP_TEAP_COMPOUND_MAC_LEN); 789 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Received MSK Compound MAC", 790 cb->msk_compound_mac, EAP_TEAP_COMPOUND_MAC_LEN); 791 wpa_hexdump(MSG_MSGDUMP, 792 "EAP-TEAP: Calculated MSK Compound MAC", 793 msk_compound_mac, EAP_TEAP_COMPOUND_MAC_LEN); 794 if (res != 0) { 795 wpa_printf(MSG_INFO, 796 "EAP-TEAP: MSK Compound MAC did not match"); 797 return NULL; 798 } 799 } 800 801 if ((flags == TEAP_CRYPTO_BINDING_EMSK_CMAC || 802 flags == TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC) && 803 data->cmk_emsk_available) { 804 u8 emsk_compound_mac[EAP_TEAP_COMPOUND_MAC_LEN]; 805 806 if (eap_teap_compound_mac(data->tls_cs, cb, 807 data->server_outer_tlvs, 808 data->peer_outer_tlvs, cmk_emsk, 809 emsk_compound_mac) < 0) 810 return NULL; 811 res = os_memcmp_const(emsk_compound_mac, cb->emsk_compound_mac, 812 EAP_TEAP_COMPOUND_MAC_LEN); 813 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Received EMSK Compound MAC", 814 cb->emsk_compound_mac, EAP_TEAP_COMPOUND_MAC_LEN); 815 wpa_hexdump(MSG_MSGDUMP, 816 "EAP-TEAP: Calculated EMSK Compound MAC", 817 emsk_compound_mac, EAP_TEAP_COMPOUND_MAC_LEN); 818 if (res != 0) { 819 wpa_printf(MSG_INFO, 820 "EAP-TEAP: EMSK Compound MAC did not match"); 821 return NULL; 822 } 823 824 cmk_emsk_ptr = cmk_emsk; 825 } 826 827 if (flags == TEAP_CRYPTO_BINDING_EMSK_CMAC && 828 !data->cmk_emsk_available) { 829 wpa_printf(MSG_INFO, 830 "EAP-TEAP: Server included only EMSK Compound MAC, but no locally generated inner EAP EMSK to validate this"); 831 return NULL; 832 } 833 834 /* 835 * Compound MAC was valid, so authentication succeeded. Reply with 836 * crypto binding to allow server to complete authentication. 837 */ 838 839 len = sizeof(struct teap_tlv_crypto_binding); 840 resp = wpabuf_alloc(len); 841 if (!resp) 842 return NULL; 843 844 if (data->phase2_success && eap_teap_derive_msk(data) < 0) { 845 wpa_printf(MSG_INFO, "EAP-TEAP: Failed to generate MSK"); 846 ret->methodState = METHOD_DONE; 847 ret->decision = DECISION_FAIL; 848 data->phase2_success = 0; 849 wpabuf_free(resp); 850 return NULL; 851 } 852 853 if (data->phase2_success && eap_teap_session_id(data) < 0) { 854 wpabuf_free(resp); 855 return NULL; 856 } 857 858 pos = wpabuf_put(resp, sizeof(struct teap_tlv_crypto_binding)); 859 if (eap_teap_write_crypto_binding( 860 data, (struct teap_tlv_crypto_binding *) pos, 861 cb, cmk_msk, cmk_emsk_ptr) < 0) { 862 wpabuf_free(resp); 863 return NULL; 864 } 865 866 return resp; 867 } 868 869 870 static void eap_teap_parse_pac_tlv(struct eap_teap_pac *entry, int type, 871 u8 *pos, size_t len, int *pac_key_found) 872 { 873 switch (type & 0x7fff) { 874 case PAC_TYPE_PAC_KEY: 875 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: PAC-Key", pos, len); 876 if (len != EAP_TEAP_PAC_KEY_LEN) { 877 wpa_printf(MSG_DEBUG, 878 "EAP-TEAP: Invalid PAC-Key length %lu", 879 (unsigned long) len); 880 break; 881 } 882 *pac_key_found = 1; 883 os_memcpy(entry->pac_key, pos, len); 884 break; 885 case PAC_TYPE_PAC_OPAQUE: 886 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: PAC-Opaque", pos, len); 887 entry->pac_opaque = pos; 888 entry->pac_opaque_len = len; 889 break; 890 case PAC_TYPE_PAC_INFO: 891 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: PAC-Info", pos, len); 892 entry->pac_info = pos; 893 entry->pac_info_len = len; 894 break; 895 default: 896 wpa_printf(MSG_DEBUG, "EAP-TEAP: Ignored unknown PAC type %d", 897 type); 898 break; 899 } 900 } 901 902 903 static int eap_teap_process_pac_tlv(struct eap_teap_pac *entry, 904 u8 *pac, size_t pac_len) 905 { 906 struct pac_attr_hdr *hdr; 907 u8 *pos; 908 size_t left, len; 909 int type, pac_key_found = 0; 910 911 pos = pac; 912 left = pac_len; 913 914 while (left > sizeof(*hdr)) { 915 hdr = (struct pac_attr_hdr *) pos; 916 type = be_to_host16(hdr->type); 917 len = be_to_host16(hdr->len); 918 pos += sizeof(*hdr); 919 left -= sizeof(*hdr); 920 if (len > left) { 921 wpa_printf(MSG_DEBUG, 922 "EAP-TEAP: PAC TLV overrun (type=%d len=%lu left=%lu)", 923 type, (unsigned long) len, 924 (unsigned long) left); 925 return -1; 926 } 927 928 eap_teap_parse_pac_tlv(entry, type, pos, len, &pac_key_found); 929 930 pos += len; 931 left -= len; 932 } 933 934 if (!pac_key_found || !entry->pac_opaque || !entry->pac_info) { 935 wpa_printf(MSG_DEBUG, 936 "EAP-TEAP: PAC TLV does not include all the required fields"); 937 return -1; 938 } 939 940 return 0; 941 } 942 943 944 static int eap_teap_parse_pac_info(struct eap_teap_pac *entry, int type, 945 u8 *pos, size_t len) 946 { 947 u16 pac_type; 948 u32 lifetime; 949 struct os_time now; 950 951 switch (type & 0x7fff) { 952 case PAC_TYPE_CRED_LIFETIME: 953 if (len != 4) { 954 wpa_hexdump(MSG_DEBUG, 955 "EAP-TEAP: PAC-Info - Invalid CRED_LIFETIME length - ignored", 956 pos, len); 957 return 0; 958 } 959 960 /* 961 * This is not currently saved separately in PAC files since 962 * the server can automatically initiate PAC update when 963 * needed. Anyway, the information is available from PAC-Info 964 * dump if it is needed for something in the future. 965 */ 966 lifetime = WPA_GET_BE32(pos); 967 os_get_time(&now); 968 wpa_printf(MSG_DEBUG, 969 "EAP-TEAP: PAC-Info - CRED_LIFETIME %d (%d days)", 970 lifetime, (lifetime - (u32) now.sec) / 86400); 971 break; 972 case PAC_TYPE_A_ID: 973 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: PAC-Info - A-ID", 974 pos, len); 975 entry->a_id = pos; 976 entry->a_id_len = len; 977 break; 978 case PAC_TYPE_I_ID: 979 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: PAC-Info - I-ID", 980 pos, len); 981 entry->i_id = pos; 982 entry->i_id_len = len; 983 break; 984 case PAC_TYPE_A_ID_INFO: 985 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: PAC-Info - A-ID-Info", 986 pos, len); 987 entry->a_id_info = pos; 988 entry->a_id_info_len = len; 989 break; 990 case PAC_TYPE_PAC_TYPE: 991 /* RFC 7170, Section 4.2.12.6 - PAC-Type TLV */ 992 if (len != 2) { 993 wpa_printf(MSG_INFO, 994 "EAP-TEAP: Invalid PAC-Type length %lu (expected 2)", 995 (unsigned long) len); 996 wpa_hexdump_ascii(MSG_DEBUG, 997 "EAP-TEAP: PAC-Info - PAC-Type", 998 pos, len); 999 return -1; 1000 } 1001 pac_type = WPA_GET_BE16(pos); 1002 if (pac_type != PAC_TYPE_TUNNEL_PAC) { 1003 wpa_printf(MSG_INFO, 1004 "EAP-TEAP: Unsupported PAC Type %d", 1005 pac_type); 1006 return -1; 1007 } 1008 1009 wpa_printf(MSG_DEBUG, "EAP-TEAP: PAC-Info - PAC-Type %d", 1010 pac_type); 1011 entry->pac_type = pac_type; 1012 break; 1013 default: 1014 wpa_printf(MSG_DEBUG, 1015 "EAP-TEAP: Ignored unknown PAC-Info type %d", type); 1016 break; 1017 } 1018 1019 return 0; 1020 } 1021 1022 1023 static int eap_teap_process_pac_info(struct eap_teap_pac *entry) 1024 { 1025 struct pac_attr_hdr *hdr; 1026 u8 *pos; 1027 size_t left, len; 1028 int type; 1029 1030 /* RFC 7170, Section 4.2.12.4 */ 1031 1032 /* PAC-Type defaults to Tunnel PAC (Type 1) */ 1033 entry->pac_type = PAC_TYPE_TUNNEL_PAC; 1034 1035 pos = entry->pac_info; 1036 left = entry->pac_info_len; 1037 while (left > sizeof(*hdr)) { 1038 hdr = (struct pac_attr_hdr *) pos; 1039 type = be_to_host16(hdr->type); 1040 len = be_to_host16(hdr->len); 1041 pos += sizeof(*hdr); 1042 left -= sizeof(*hdr); 1043 if (len > left) { 1044 wpa_printf(MSG_DEBUG, 1045 "EAP-TEAP: PAC-Info overrun (type=%d len=%lu left=%lu)", 1046 type, (unsigned long) len, 1047 (unsigned long) left); 1048 return -1; 1049 } 1050 1051 if (eap_teap_parse_pac_info(entry, type, pos, len) < 0) 1052 return -1; 1053 1054 pos += len; 1055 left -= len; 1056 } 1057 1058 if (!entry->a_id || !entry->a_id_info) { 1059 wpa_printf(MSG_DEBUG, 1060 "EAP-TEAP: PAC-Info does not include all the required fields"); 1061 return -1; 1062 } 1063 1064 return 0; 1065 } 1066 1067 1068 static struct wpabuf * eap_teap_process_pac(struct eap_sm *sm, 1069 struct eap_teap_data *data, 1070 struct eap_method_ret *ret, 1071 u8 *pac, size_t pac_len) 1072 { 1073 struct eap_peer_config *config = eap_get_config(sm); 1074 struct eap_teap_pac entry; 1075 1076 os_memset(&entry, 0, sizeof(entry)); 1077 if (eap_teap_process_pac_tlv(&entry, pac, pac_len) || 1078 eap_teap_process_pac_info(&entry)) 1079 return NULL; 1080 1081 eap_teap_add_pac(&data->pac, &data->current_pac, &entry); 1082 eap_teap_pac_list_truncate(data->pac, data->max_pac_list_len); 1083 if (data->use_pac_binary_format) 1084 eap_teap_save_pac_bin(sm, data->pac, config->pac_file); 1085 else 1086 eap_teap_save_pac(sm, data->pac, config->pac_file); 1087 1088 wpa_printf(MSG_DEBUG, 1089 "EAP-TEAP: Send PAC-Acknowledgement - %s initiated provisioning completed successfully", 1090 data->provisioning ? "peer" : "server"); 1091 return eap_teap_tlv_pac_ack(); 1092 } 1093 1094 1095 static int eap_teap_parse_decrypted(struct wpabuf *decrypted, 1096 struct eap_teap_tlv_parse *tlv, 1097 struct wpabuf **resp) 1098 { 1099 u16 tlv_type; 1100 int mandatory, res; 1101 size_t len; 1102 u8 *pos, *end; 1103 1104 os_memset(tlv, 0, sizeof(*tlv)); 1105 1106 /* Parse TLVs from the decrypted Phase 2 data */ 1107 pos = wpabuf_mhead(decrypted); 1108 end = pos + wpabuf_len(decrypted); 1109 while (end - pos >= 4) { 1110 mandatory = pos[0] & 0x80; 1111 tlv_type = WPA_GET_BE16(pos) & 0x3fff; 1112 pos += 2; 1113 len = WPA_GET_BE16(pos); 1114 pos += 2; 1115 if (len > (size_t) (end - pos)) { 1116 wpa_printf(MSG_INFO, "EAP-TEAP: TLV overflow"); 1117 return -1; 1118 } 1119 wpa_printf(MSG_DEBUG, 1120 "EAP-TEAP: Received Phase 2: TLV type %u (%s) length %u%s", 1121 tlv_type, eap_teap_tlv_type_str(tlv_type), 1122 (unsigned int) len, 1123 mandatory ? " (mandatory)" : ""); 1124 1125 res = eap_teap_parse_tlv(tlv, tlv_type, pos, len); 1126 if (res == -2) 1127 break; 1128 if (res < 0) { 1129 if (mandatory) { 1130 wpa_printf(MSG_DEBUG, 1131 "EAP-TEAP: NAK unknown mandatory TLV type %u", 1132 tlv_type); 1133 *resp = eap_teap_tlv_nak(0, tlv_type); 1134 break; 1135 } 1136 1137 wpa_printf(MSG_DEBUG, 1138 "EAP-TEAP: Ignore unknown optional TLV type %u", 1139 tlv_type); 1140 } 1141 1142 pos += len; 1143 } 1144 1145 return 0; 1146 } 1147 1148 1149 static struct wpabuf * eap_teap_pac_request(void) 1150 { 1151 struct wpabuf *req; 1152 struct teap_tlv_request_action *act; 1153 struct teap_tlv_hdr *pac; 1154 struct teap_attr_pac_type *type; 1155 1156 req = wpabuf_alloc(sizeof(*act) + sizeof(*pac) + sizeof(*type)); 1157 if (!req) 1158 return NULL; 1159 1160 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add Request Action TLV (Process TLV)"); 1161 act = wpabuf_put(req, sizeof(*act)); 1162 act->tlv_type = host_to_be16(TEAP_TLV_REQUEST_ACTION); 1163 act->length = host_to_be16(2); 1164 act->status = TEAP_STATUS_SUCCESS; 1165 act->action = TEAP_REQUEST_ACTION_PROCESS_TLV; 1166 1167 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add PAC TLV (PAC-Type = Tunnel)"); 1168 pac = wpabuf_put(req, sizeof(*pac)); 1169 pac->tlv_type = host_to_be16(TEAP_TLV_PAC); 1170 pac->length = host_to_be16(sizeof(*type)); 1171 1172 type = wpabuf_put(req, sizeof(*type)); 1173 type->type = host_to_be16(PAC_TYPE_PAC_TYPE); 1174 type->length = host_to_be16(2); 1175 type->pac_type = host_to_be16(PAC_TYPE_TUNNEL_PAC); 1176 1177 return req; 1178 } 1179 1180 1181 static int eap_teap_process_decrypted(struct eap_sm *sm, 1182 struct eap_teap_data *data, 1183 struct eap_method_ret *ret, 1184 u8 identifier, 1185 struct wpabuf *decrypted, 1186 struct wpabuf **out_data) 1187 { 1188 struct wpabuf *resp = NULL, *tmp; 1189 struct eap_teap_tlv_parse tlv; 1190 int failed = 0; 1191 enum teap_error_codes error = 0; 1192 1193 if (eap_teap_parse_decrypted(decrypted, &tlv, &resp) < 0) { 1194 /* Parsing failed - no response available */ 1195 return 0; 1196 } 1197 1198 if (resp) { 1199 /* Parsing rejected the message - send out an error response */ 1200 goto send_resp; 1201 } 1202 1203 if (tlv.result == TEAP_STATUS_FAILURE) { 1204 /* Server indicated failure - respond similarly per 1205 * RFC 7170, 3.6.3. This authentication exchange cannot succeed 1206 * and will be terminated with a cleartext EAP Failure. */ 1207 wpa_printf(MSG_DEBUG, 1208 "EAP-TEAP: Server rejected authentication"); 1209 resp = eap_teap_tlv_result(TEAP_STATUS_FAILURE, 0); 1210 ret->methodState = METHOD_DONE; 1211 ret->decision = DECISION_FAIL; 1212 goto send_resp; 1213 } 1214 1215 if ((tlv.iresult == TEAP_STATUS_SUCCESS || 1216 (!data->result_success_done && 1217 tlv.result == TEAP_STATUS_SUCCESS)) && 1218 !tlv.crypto_binding) { 1219 /* Result TLV or Intermediate-Result TLV indicating success, 1220 * but no Crypto-Binding TLV */ 1221 wpa_printf(MSG_DEBUG, 1222 "EAP-TEAP: Result TLV or Intermediate-Result TLV indicating success, but no Crypto-Binding TLV"); 1223 failed = 1; 1224 error = TEAP_ERROR_TUNNEL_COMPROMISE_ERROR; 1225 goto done; 1226 } 1227 1228 if (tlv.iresult != TEAP_STATUS_SUCCESS && 1229 tlv.iresult != TEAP_STATUS_FAILURE && 1230 data->inner_method_done) { 1231 wpa_printf(MSG_DEBUG, 1232 "EAP-TEAP: Inner EAP method exchange completed, but no Intermediate-Result TLV included"); 1233 failed = 1; 1234 error = TEAP_ERROR_TUNNEL_COMPROMISE_ERROR; 1235 goto done; 1236 } 1237 1238 if (tlv.basic_auth_req) { 1239 tmp = eap_teap_process_basic_auth_req(sm, data, 1240 tlv.basic_auth_req, 1241 tlv.basic_auth_req_len); 1242 if (!tmp) 1243 failed = 1; 1244 resp = wpabuf_concat(resp, tmp); 1245 } else if (tlv.eap_payload_tlv) { 1246 tmp = eap_teap_process_eap_payload_tlv(sm, data, ret, 1247 tlv.eap_payload_tlv, 1248 tlv.eap_payload_tlv_len); 1249 if (!tmp) 1250 failed = 1; 1251 resp = wpabuf_concat(resp, tmp); 1252 1253 if (tlv.iresult == TEAP_STATUS_SUCCESS || 1254 tlv.iresult == TEAP_STATUS_FAILURE) { 1255 tmp = eap_teap_tlv_result(failed ? 1256 TEAP_STATUS_FAILURE : 1257 TEAP_STATUS_SUCCESS, 1); 1258 resp = wpabuf_concat(resp, tmp); 1259 if (tlv.iresult == TEAP_STATUS_FAILURE) 1260 failed = 1; 1261 } 1262 } 1263 1264 if (tlv.crypto_binding) { 1265 if (tlv.iresult != TEAP_STATUS_SUCCESS && 1266 tlv.result != TEAP_STATUS_SUCCESS) { 1267 wpa_printf(MSG_DEBUG, 1268 "EAP-TEAP: Unexpected Crypto-Binding TLV without Result TLV or Intermediate-Result TLV indicating success"); 1269 failed = 1; 1270 error = TEAP_ERROR_UNEXPECTED_TLVS_EXCHANGED; 1271 goto done; 1272 } 1273 1274 tmp = eap_teap_process_crypto_binding(sm, data, ret, 1275 tlv.crypto_binding, 1276 tlv.crypto_binding_len); 1277 if (!tmp) { 1278 failed = 1; 1279 error = TEAP_ERROR_TUNNEL_COMPROMISE_ERROR; 1280 } else { 1281 resp = wpabuf_concat(resp, tmp); 1282 if (tlv.result == TEAP_STATUS_SUCCESS && !failed) 1283 data->result_success_done = 1; 1284 if (tlv.iresult == TEAP_STATUS_SUCCESS && !failed) 1285 data->inner_method_done = 0; 1286 } 1287 } 1288 1289 if (data->result_success_done && data->session_ticket_used && 1290 eap_teap_derive_msk(data) == 0) { 1291 /* Assume the server might accept authentication without going 1292 * through inner authentication. */ 1293 wpa_printf(MSG_DEBUG, 1294 "EAP-TEAP: PAC used - server may decide to skip inner authentication"); 1295 ret->methodState = METHOD_MAY_CONT; 1296 ret->decision = DECISION_COND_SUCC; 1297 } 1298 1299 if (tlv.pac) { 1300 if (tlv.result == TEAP_STATUS_SUCCESS) { 1301 tmp = eap_teap_process_pac(sm, data, ret, 1302 tlv.pac, tlv.pac_len); 1303 resp = wpabuf_concat(resp, tmp); 1304 } else { 1305 wpa_printf(MSG_DEBUG, 1306 "EAP-TEAP: PAC TLV without Result TLV acknowledging success"); 1307 failed = 1; 1308 error = TEAP_ERROR_UNEXPECTED_TLVS_EXCHANGED; 1309 } 1310 } 1311 1312 if (!data->current_pac && data->provisioning && !failed && !tlv.pac && 1313 tlv.crypto_binding && 1314 (!data->anon_provisioning || 1315 (data->phase2_success && data->phase2_method && 1316 data->phase2_method->vendor == 0 && 1317 eap_teap_allowed_anon_prov_cipher_suite(data->tls_cs) && 1318 eap_teap_allowed_anon_prov_phase2_method( 1319 data->phase2_method->method))) && 1320 (tlv.iresult == TEAP_STATUS_SUCCESS || 1321 tlv.result == TEAP_STATUS_SUCCESS)) { 1322 /* 1323 * Need to request Tunnel PAC when using authenticated 1324 * provisioning. 1325 */ 1326 wpa_printf(MSG_DEBUG, "EAP-TEAP: Request Tunnel PAC"); 1327 tmp = eap_teap_pac_request(); 1328 resp = wpabuf_concat(resp, tmp); 1329 } 1330 1331 done: 1332 if (failed) { 1333 tmp = eap_teap_tlv_result(TEAP_STATUS_FAILURE, 0); 1334 resp = wpabuf_concat(tmp, resp); 1335 1336 if (error != 0) { 1337 tmp = eap_teap_tlv_error(error); 1338 resp = wpabuf_concat(tmp, resp); 1339 } 1340 1341 ret->methodState = METHOD_DONE; 1342 ret->decision = DECISION_FAIL; 1343 } else if (tlv.result == TEAP_STATUS_SUCCESS) { 1344 tmp = eap_teap_tlv_result(TEAP_STATUS_SUCCESS, 0); 1345 resp = wpabuf_concat(tmp, resp); 1346 } 1347 1348 if (resp && tlv.result == TEAP_STATUS_SUCCESS && !failed && 1349 tlv.crypto_binding && data->phase2_success) { 1350 /* Successfully completed Phase 2 */ 1351 wpa_printf(MSG_DEBUG, 1352 "EAP-TEAP: Authentication completed successfully"); 1353 ret->methodState = METHOD_MAY_CONT; 1354 data->on_tx_completion = data->provisioning ? 1355 METHOD_MAY_CONT : METHOD_DONE; 1356 ret->decision = DECISION_UNCOND_SUCC; 1357 } 1358 1359 if (!resp) { 1360 wpa_printf(MSG_DEBUG, 1361 "EAP-TEAP: No recognized TLVs - send empty response packet"); 1362 resp = wpabuf_alloc(1); 1363 } 1364 1365 send_resp: 1366 if (!resp) 1367 return 0; 1368 1369 wpa_hexdump_buf(MSG_DEBUG, "EAP-TEAP: Encrypting Phase 2 data", resp); 1370 if (eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TEAP, 1371 data->teap_version, identifier, 1372 resp, out_data)) { 1373 wpa_printf(MSG_INFO, 1374 "EAP-TEAP: Failed to encrypt a Phase 2 frame"); 1375 } 1376 wpabuf_free(resp); 1377 1378 return 0; 1379 } 1380 1381 1382 static int eap_teap_decrypt(struct eap_sm *sm, struct eap_teap_data *data, 1383 struct eap_method_ret *ret, u8 identifier, 1384 const struct wpabuf *in_data, 1385 struct wpabuf **out_data) 1386 { 1387 struct wpabuf *in_decrypted; 1388 int res; 1389 1390 wpa_printf(MSG_DEBUG, 1391 "EAP-TEAP: Received %lu bytes encrypted data for Phase 2", 1392 (unsigned long) wpabuf_len(in_data)); 1393 1394 if (data->pending_phase2_req) { 1395 wpa_printf(MSG_DEBUG, 1396 "EAP-TEAP: Pending Phase 2 request - skip decryption and use old data"); 1397 /* Clear TLS reassembly state. */ 1398 eap_peer_tls_reset_input(&data->ssl); 1399 1400 in_decrypted = data->pending_phase2_req; 1401 data->pending_phase2_req = NULL; 1402 goto continue_req; 1403 } 1404 1405 if (wpabuf_len(in_data) == 0) { 1406 /* Received TLS ACK - requesting more fragments */ 1407 res = eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TEAP, 1408 data->teap_version, 1409 identifier, NULL, out_data); 1410 if (res == 0 && !data->ssl.tls_out && 1411 data->on_tx_completion) { 1412 wpa_printf(MSG_DEBUG, 1413 "EAP-TEAP: Mark authentication completed at full TX of fragments"); 1414 ret->methodState = data->on_tx_completion; 1415 data->on_tx_completion = 0; 1416 ret->decision = DECISION_UNCOND_SUCC; 1417 } 1418 return res; 1419 } 1420 1421 res = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted); 1422 if (res) 1423 return res; 1424 1425 continue_req: 1426 wpa_hexdump_buf(MSG_MSGDUMP, "EAP-TEAP: Decrypted Phase 2 TLV(s)", 1427 in_decrypted); 1428 1429 if (wpabuf_len(in_decrypted) < 4) { 1430 wpa_printf(MSG_INFO, 1431 "EAP-TEAP: Too short Phase 2 TLV frame (len=%lu)", 1432 (unsigned long) wpabuf_len(in_decrypted)); 1433 wpabuf_free(in_decrypted); 1434 return -1; 1435 } 1436 1437 res = eap_teap_process_decrypted(sm, data, ret, identifier, 1438 in_decrypted, out_data); 1439 1440 wpabuf_free(in_decrypted); 1441 1442 return res; 1443 } 1444 1445 1446 static void eap_teap_select_pac(struct eap_teap_data *data, 1447 const u8 *a_id, size_t a_id_len) 1448 { 1449 if (!a_id) 1450 return; 1451 data->current_pac = eap_teap_get_pac(data->pac, a_id, a_id_len, 1452 PAC_TYPE_TUNNEL_PAC); 1453 if (data->current_pac) { 1454 wpa_printf(MSG_DEBUG, 1455 "EAP-TEAP: PAC found for this A-ID (PAC-Type %d)", 1456 data->current_pac->pac_type); 1457 wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TEAP: A-ID-Info", 1458 data->current_pac->a_id_info, 1459 data->current_pac->a_id_info_len); 1460 } 1461 } 1462 1463 1464 static int eap_teap_use_pac_opaque(struct eap_sm *sm, 1465 struct eap_teap_data *data, 1466 struct eap_teap_pac *pac) 1467 { 1468 u8 *tlv; 1469 size_t tlv_len, olen; 1470 struct teap_tlv_hdr *ehdr; 1471 1472 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add PAC-Opaque TLS extension"); 1473 olen = pac->pac_opaque_len; 1474 tlv_len = sizeof(*ehdr) + olen; 1475 tlv = os_malloc(tlv_len); 1476 if (tlv) { 1477 ehdr = (struct teap_tlv_hdr *) tlv; 1478 ehdr->tlv_type = host_to_be16(PAC_TYPE_PAC_OPAQUE); 1479 ehdr->length = host_to_be16(olen); 1480 os_memcpy(ehdr + 1, pac->pac_opaque, olen); 1481 } 1482 if (!tlv || 1483 tls_connection_client_hello_ext(sm->ssl_ctx, data->ssl.conn, 1484 TLS_EXT_PAC_OPAQUE, 1485 tlv, tlv_len) < 0) { 1486 wpa_printf(MSG_DEBUG, 1487 "EAP-TEAP: Failed to add PAC-Opaque TLS extension"); 1488 os_free(tlv); 1489 return -1; 1490 } 1491 os_free(tlv); 1492 1493 return 0; 1494 } 1495 1496 1497 static int eap_teap_clear_pac_opaque_ext(struct eap_sm *sm, 1498 struct eap_teap_data *data) 1499 { 1500 if (tls_connection_client_hello_ext(sm->ssl_ctx, data->ssl.conn, 1501 TLS_EXT_PAC_OPAQUE, NULL, 0) < 0) { 1502 wpa_printf(MSG_DEBUG, 1503 "EAP-TEAP: Failed to remove PAC-Opaque TLS extension"); 1504 return -1; 1505 } 1506 return 0; 1507 } 1508 1509 1510 static int eap_teap_process_start(struct eap_sm *sm, 1511 struct eap_teap_data *data, u8 flags, 1512 const u8 *pos, size_t left) 1513 { 1514 const u8 *a_id = NULL; 1515 size_t a_id_len = 0; 1516 1517 /* TODO: Support (mostly theoretical) case of TEAP/Start request being 1518 * fragmented */ 1519 1520 /* EAP-TEAP version negotiation (RFC 7170, Section 3.2) */ 1521 data->received_version = flags & EAP_TLS_VERSION_MASK; 1522 wpa_printf(MSG_DEBUG, "EAP-TEAP: Start (server ver=%u, own ver=%u)", 1523 data->received_version, data->teap_version); 1524 if (data->received_version < 1) { 1525 /* Version 1 was the first defined version, so reject 0 */ 1526 wpa_printf(MSG_INFO, 1527 "EAP-TEAP: Server used unknown TEAP version %u", 1528 data->received_version); 1529 return -1; 1530 } 1531 if (data->received_version < data->teap_version) 1532 data->teap_version = data->received_version; 1533 wpa_printf(MSG_DEBUG, "EAP-TEAP: Using TEAP version %d", 1534 data->teap_version); 1535 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Start message payload", pos, left); 1536 1537 /* Parse Authority-ID TLV from Outer TLVs, if present */ 1538 if (flags & EAP_TEAP_FLAGS_OUTER_TLV_LEN) { 1539 const u8 *outer_pos, *outer_end; 1540 u32 outer_tlv_len; 1541 1542 if (left < 4) { 1543 wpa_printf(MSG_INFO, 1544 "EAP-TEAP: Not enough room for the Outer TLV Length field"); 1545 return -1; 1546 } 1547 1548 outer_tlv_len = WPA_GET_BE32(pos); 1549 pos += 4; 1550 left -= 4; 1551 1552 if (outer_tlv_len > left) { 1553 wpa_printf(MSG_INFO, 1554 "EAP-TEAP: Truncated Outer TLVs field (Outer TLV Length: %u; remaining buffer: %u)", 1555 outer_tlv_len, (unsigned int) left); 1556 return -1; 1557 } 1558 1559 outer_pos = pos + left - outer_tlv_len; 1560 outer_end = outer_pos + outer_tlv_len; 1561 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Start message Outer TLVs", 1562 outer_pos, outer_tlv_len); 1563 wpabuf_free(data->server_outer_tlvs); 1564 data->server_outer_tlvs = wpabuf_alloc_copy(outer_pos, 1565 outer_tlv_len); 1566 if (!data->server_outer_tlvs) 1567 return -1; 1568 left -= outer_tlv_len; 1569 if (left > 0) { 1570 wpa_hexdump(MSG_INFO, 1571 "EAP-TEAP: Unexpected TLS Data in Start message", 1572 pos, left); 1573 return -1; 1574 } 1575 1576 while (outer_pos < outer_end) { 1577 u16 tlv_type, tlv_len; 1578 1579 if (outer_end - outer_pos < 4) { 1580 wpa_printf(MSG_INFO, 1581 "EAP-TEAP: Truncated Outer TLV header"); 1582 return -1; 1583 } 1584 tlv_type = WPA_GET_BE16(outer_pos); 1585 outer_pos += 2; 1586 tlv_len = WPA_GET_BE16(outer_pos); 1587 outer_pos += 2; 1588 /* Outer TLVs are required to be optional, so no need to 1589 * check the M flag */ 1590 tlv_type &= TEAP_TLV_TYPE_MASK; 1591 wpa_printf(MSG_DEBUG, 1592 "EAP-TEAP: Outer TLV: Type=%u Length=%u", 1593 tlv_type, tlv_len); 1594 if (outer_end - outer_pos < tlv_len) { 1595 wpa_printf(MSG_INFO, 1596 "EAP-TEAP: Truncated Outer TLV (Type %u)", 1597 tlv_type); 1598 return -1; 1599 } 1600 if (tlv_type == TEAP_TLV_AUTHORITY_ID) { 1601 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: Authority-ID", 1602 outer_pos, tlv_len); 1603 if (a_id) { 1604 wpa_printf(MSG_INFO, 1605 "EAP-TEAP: Multiple Authority-ID TLVs in TEAP/Start"); 1606 return -1; 1607 } 1608 a_id = outer_pos; 1609 a_id_len = tlv_len; 1610 } else { 1611 wpa_printf(MSG_DEBUG, 1612 "EAP-TEAP: Ignore unknown Outer TLV (Type %u)", 1613 tlv_type); 1614 } 1615 outer_pos += tlv_len; 1616 } 1617 } else if (left > 0) { 1618 wpa_hexdump(MSG_INFO, 1619 "EAP-TEAP: Unexpected TLS Data in Start message", 1620 pos, left); 1621 return -1; 1622 } 1623 1624 eap_teap_select_pac(data, a_id, a_id_len); 1625 1626 if (data->resuming && data->current_pac) { 1627 wpa_printf(MSG_DEBUG, 1628 "EAP-TEAP: Trying to resume session - do not add PAC-Opaque to TLS ClientHello"); 1629 if (eap_teap_clear_pac_opaque_ext(sm, data) < 0) 1630 return -1; 1631 } else if (data->current_pac) { 1632 /* 1633 * PAC found for the A-ID and we are not resuming an old 1634 * session, so add PAC-Opaque extension to ClientHello. 1635 */ 1636 if (eap_teap_use_pac_opaque(sm, data, data->current_pac) < 0) 1637 return -1; 1638 } else if (data->provisioning_allowed) { 1639 wpa_printf(MSG_DEBUG, 1640 "EAP-TEAP: No PAC found - starting provisioning"); 1641 if (eap_teap_clear_pac_opaque_ext(sm, data) < 0) 1642 return -1; 1643 data->provisioning = 1; 1644 } 1645 1646 return 0; 1647 } 1648 1649 1650 #ifdef CONFIG_TESTING_OPTIONS 1651 static struct wpabuf * eap_teap_add_dummy_outer_tlvs(struct eap_teap_data *data, 1652 struct wpabuf *resp) 1653 { 1654 struct wpabuf *resp2; 1655 u16 len; 1656 const u8 *pos; 1657 u8 flags; 1658 1659 wpabuf_free(data->peer_outer_tlvs); 1660 data->peer_outer_tlvs = wpabuf_alloc(4 + 4); 1661 if (!data->peer_outer_tlvs) { 1662 wpabuf_free(resp); 1663 return NULL; 1664 } 1665 1666 /* Outer TLVs (dummy Vendor-Specific TLV for testing) */ 1667 wpabuf_put_be16(data->peer_outer_tlvs, TEAP_TLV_VENDOR_SPECIFIC); 1668 wpabuf_put_be16(data->peer_outer_tlvs, 4); 1669 wpabuf_put_be32(data->peer_outer_tlvs, EAP_VENDOR_HOSTAP); 1670 wpa_hexdump_buf(MSG_DEBUG, "EAP-TEAP: TESTING - Add dummy Outer TLVs", 1671 data->peer_outer_tlvs); 1672 1673 wpa_hexdump_buf(MSG_DEBUG, 1674 "EAP-TEAP: TEAP/Start response before modification", 1675 resp); 1676 resp2 = wpabuf_alloc(wpabuf_len(resp) + 4 + 1677 wpabuf_len(data->peer_outer_tlvs)); 1678 if (!resp2) { 1679 wpabuf_free(resp); 1680 return NULL; 1681 } 1682 1683 pos = wpabuf_head(resp); 1684 wpabuf_put_u8(resp2, *pos++); /* Code */ 1685 wpabuf_put_u8(resp2, *pos++); /* Identifier */ 1686 len = WPA_GET_BE16(pos); 1687 pos += 2; 1688 wpabuf_put_be16(resp2, len + 4 + wpabuf_len(data->peer_outer_tlvs)); 1689 wpabuf_put_u8(resp2, *pos++); /* Type */ 1690 /* Flags | Ver (with Outer TLV length included flag set to 1) */ 1691 flags = *pos++; 1692 if (flags & (EAP_TEAP_FLAGS_OUTER_TLV_LEN | 1693 EAP_TLS_FLAGS_LENGTH_INCLUDED)) { 1694 wpa_printf(MSG_INFO, 1695 "EAP-TEAP: Cannot add Outer TLVs for testing"); 1696 wpabuf_free(resp); 1697 wpabuf_free(resp2); 1698 return NULL; 1699 } 1700 flags |= EAP_TEAP_FLAGS_OUTER_TLV_LEN; 1701 wpabuf_put_u8(resp2, flags); 1702 /* Outer TLV Length */ 1703 wpabuf_put_be32(resp2, wpabuf_len(data->peer_outer_tlvs)); 1704 /* TLS Data */ 1705 wpabuf_put_data(resp2, pos, wpabuf_len(resp) - 6); 1706 wpabuf_put_buf(resp2, data->peer_outer_tlvs); /* Outer TLVs */ 1707 1708 wpabuf_free(resp); 1709 wpa_hexdump_buf(MSG_DEBUG, 1710 "EAP-TEAP: TEAP/Start response after modification", 1711 resp2); 1712 return resp2; 1713 } 1714 #endif /* CONFIG_TESTING_OPTIONS */ 1715 1716 1717 static struct wpabuf * eap_teap_process(struct eap_sm *sm, void *priv, 1718 struct eap_method_ret *ret, 1719 const struct wpabuf *reqData) 1720 { 1721 const struct eap_hdr *req; 1722 size_t left; 1723 int res; 1724 u8 flags, id; 1725 struct wpabuf *resp; 1726 const u8 *pos; 1727 struct eap_teap_data *data = priv; 1728 struct wpabuf msg; 1729 1730 pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_TEAP, ret, 1731 reqData, &left, &flags); 1732 if (!pos) 1733 return NULL; 1734 1735 req = wpabuf_head(reqData); 1736 id = req->identifier; 1737 1738 if (flags & EAP_TLS_FLAGS_START) { 1739 if (eap_teap_process_start(sm, data, flags, pos, left) < 0) 1740 return NULL; 1741 1742 /* Outer TLVs are not used in further packet processing and 1743 * there cannot be TLS Data in this TEAP/Start message, so 1744 * enforce that by ignoring whatever data might remain in the 1745 * buffer. */ 1746 left = 0; 1747 } else if (flags & EAP_TEAP_FLAGS_OUTER_TLV_LEN) { 1748 /* TODO: RFC 7170, Section 4.3.1 indicates that the unexpected 1749 * Outer TLVs MUST be ignored instead of ignoring the full 1750 * message. */ 1751 wpa_printf(MSG_INFO, 1752 "EAP-TEAP: Outer TLVs present in non-Start message -> ignore message"); 1753 return NULL; 1754 } 1755 1756 wpabuf_set(&msg, pos, left); 1757 1758 resp = NULL; 1759 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) && 1760 !data->resuming) { 1761 /* Process tunneled (encrypted) phase 2 data. */ 1762 res = eap_teap_decrypt(sm, data, ret, id, &msg, &resp); 1763 if (res < 0) { 1764 ret->methodState = METHOD_DONE; 1765 ret->decision = DECISION_FAIL; 1766 /* 1767 * Ack possible Alert that may have caused failure in 1768 * decryption. 1769 */ 1770 res = 1; 1771 } 1772 } else { 1773 if (sm->waiting_ext_cert_check && data->pending_resp) { 1774 struct eap_peer_config *config = eap_get_config(sm); 1775 1776 if (config->pending_ext_cert_check == 1777 EXT_CERT_CHECK_GOOD) { 1778 wpa_printf(MSG_DEBUG, 1779 "EAP-TEAP: External certificate check succeeded - continue handshake"); 1780 resp = data->pending_resp; 1781 data->pending_resp = NULL; 1782 sm->waiting_ext_cert_check = 0; 1783 return resp; 1784 } 1785 1786 if (config->pending_ext_cert_check == 1787 EXT_CERT_CHECK_BAD) { 1788 wpa_printf(MSG_DEBUG, 1789 "EAP-TEAP: External certificate check failed - force authentication failure"); 1790 ret->methodState = METHOD_DONE; 1791 ret->decision = DECISION_FAIL; 1792 sm->waiting_ext_cert_check = 0; 1793 return NULL; 1794 } 1795 1796 wpa_printf(MSG_DEBUG, 1797 "EAP-TEAP: Continuing to wait external server certificate validation"); 1798 return NULL; 1799 } 1800 1801 /* Continue processing TLS handshake (phase 1). */ 1802 res = eap_peer_tls_process_helper(sm, &data->ssl, 1803 EAP_TYPE_TEAP, 1804 data->teap_version, id, &msg, 1805 &resp); 1806 if (res < 0) { 1807 wpa_printf(MSG_DEBUG, 1808 "EAP-TEAP: TLS processing failed"); 1809 ret->methodState = METHOD_DONE; 1810 ret->decision = DECISION_FAIL; 1811 return resp; 1812 } 1813 1814 if (sm->waiting_ext_cert_check) { 1815 wpa_printf(MSG_DEBUG, 1816 "EAP-TEAP: Waiting external server certificate validation"); 1817 wpabuf_free(data->pending_resp); 1818 data->pending_resp = resp; 1819 return NULL; 1820 } 1821 1822 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) { 1823 char cipher[80]; 1824 1825 wpa_printf(MSG_DEBUG, 1826 "EAP-TEAP: TLS done, proceed to Phase 2"); 1827 data->tls_cs = 1828 tls_connection_get_cipher_suite(data->ssl.conn); 1829 wpa_printf(MSG_DEBUG, 1830 "EAP-TEAP: TLS cipher suite 0x%04x", 1831 data->tls_cs); 1832 1833 if (data->provisioning && 1834 (!(data->provisioning_allowed & 1835 EAP_TEAP_PROV_AUTH) || 1836 tls_get_cipher(sm->ssl_ctx, data->ssl.conn, 1837 cipher, sizeof(cipher)) < 0 || 1838 os_strstr(cipher, "ADH-") || 1839 os_strstr(cipher, "anon"))) { 1840 wpa_printf(MSG_DEBUG, 1841 "EAP-TEAP: Using anonymous (unauthenticated) provisioning"); 1842 data->anon_provisioning = 1; 1843 } else { 1844 data->anon_provisioning = 0; 1845 } 1846 data->resuming = 0; 1847 if (eap_teap_derive_key_auth(sm, data) < 0) { 1848 wpa_printf(MSG_DEBUG, 1849 "EAP-TEAP: Could not derive keys"); 1850 ret->methodState = METHOD_DONE; 1851 ret->decision = DECISION_FAIL; 1852 wpabuf_free(resp); 1853 return NULL; 1854 } 1855 } 1856 1857 if (res == 2) { 1858 /* 1859 * Application data included in the handshake message. 1860 */ 1861 wpabuf_free(data->pending_phase2_req); 1862 data->pending_phase2_req = resp; 1863 resp = NULL; 1864 res = eap_teap_decrypt(sm, data, ret, id, &msg, &resp); 1865 } 1866 } 1867 1868 if (res == 1) { 1869 wpabuf_free(resp); 1870 return eap_peer_tls_build_ack(id, EAP_TYPE_TEAP, 1871 data->teap_version); 1872 } 1873 1874 #ifdef CONFIG_TESTING_OPTIONS 1875 if (data->test_outer_tlvs && res == 0 && resp && 1876 (flags & EAP_TLS_FLAGS_START) && wpabuf_len(resp) >= 6) 1877 resp = eap_teap_add_dummy_outer_tlvs(data, resp); 1878 #endif /* CONFIG_TESTING_OPTIONS */ 1879 1880 return resp; 1881 } 1882 1883 1884 #if 0 /* TODO */ 1885 static Boolean eap_teap_has_reauth_data(struct eap_sm *sm, void *priv) 1886 { 1887 struct eap_teap_data *data = priv; 1888 1889 return tls_connection_established(sm->ssl_ctx, data->ssl.conn); 1890 } 1891 1892 1893 static void eap_teap_deinit_for_reauth(struct eap_sm *sm, void *priv) 1894 { 1895 struct eap_teap_data *data = priv; 1896 1897 if (data->phase2_priv && data->phase2_method && 1898 data->phase2_method->deinit_for_reauth) 1899 data->phase2_method->deinit_for_reauth(sm, data->phase2_priv); 1900 eap_teap_clear(data); 1901 } 1902 1903 1904 static void * eap_teap_init_for_reauth(struct eap_sm *sm, void *priv) 1905 { 1906 struct eap_teap_data *data = priv; 1907 1908 if (eap_peer_tls_reauth_init(sm, &data->ssl)) { 1909 eap_teap_deinit(sm, data); 1910 return NULL; 1911 } 1912 if (data->phase2_priv && data->phase2_method && 1913 data->phase2_method->init_for_reauth) 1914 data->phase2_method->init_for_reauth(sm, data->phase2_priv); 1915 data->phase2_success = 0; 1916 data->inner_method_done = 0; 1917 data->result_success_done = 0; 1918 data->done_on_tx_completion = 0; 1919 data->resuming = 1; 1920 data->provisioning = 0; 1921 data->anon_provisioning = 0; 1922 data->simck_idx = 0; 1923 return priv; 1924 } 1925 #endif 1926 1927 1928 static int eap_teap_get_status(struct eap_sm *sm, void *priv, char *buf, 1929 size_t buflen, int verbose) 1930 { 1931 struct eap_teap_data *data = priv; 1932 int len, ret; 1933 1934 len = eap_peer_tls_status(sm, &data->ssl, buf, buflen, verbose); 1935 if (data->phase2_method) { 1936 ret = os_snprintf(buf + len, buflen - len, 1937 "EAP-TEAP Phase 2 method=%s\n", 1938 data->phase2_method->name); 1939 if (os_snprintf_error(buflen - len, ret)) 1940 return len; 1941 len += ret; 1942 } 1943 return len; 1944 } 1945 1946 1947 static Boolean eap_teap_isKeyAvailable(struct eap_sm *sm, void *priv) 1948 { 1949 struct eap_teap_data *data = priv; 1950 1951 return data->success; 1952 } 1953 1954 1955 static u8 * eap_teap_getKey(struct eap_sm *sm, void *priv, size_t *len) 1956 { 1957 struct eap_teap_data *data = priv; 1958 u8 *key; 1959 1960 if (!data->success) 1961 return NULL; 1962 1963 key = os_memdup(data->key_data, EAP_TEAP_KEY_LEN); 1964 if (!key) 1965 return NULL; 1966 1967 *len = EAP_TEAP_KEY_LEN; 1968 1969 return key; 1970 } 1971 1972 1973 static u8 * eap_teap_get_session_id(struct eap_sm *sm, void *priv, size_t *len) 1974 { 1975 struct eap_teap_data *data = priv; 1976 u8 *id; 1977 1978 if (!data->success || !data->session_id) 1979 return NULL; 1980 1981 id = os_memdup(data->session_id, data->id_len); 1982 if (!id) 1983 return NULL; 1984 1985 *len = data->id_len; 1986 1987 return id; 1988 } 1989 1990 1991 static u8 * eap_teap_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 1992 { 1993 struct eap_teap_data *data = priv; 1994 u8 *key; 1995 1996 if (!data->success) 1997 return NULL; 1998 1999 key = os_memdup(data->emsk, EAP_EMSK_LEN); 2000 if (!key) 2001 return NULL; 2002 2003 *len = EAP_EMSK_LEN; 2004 2005 return key; 2006 } 2007 2008 2009 int eap_peer_teap_register(void) 2010 { 2011 struct eap_method *eap; 2012 2013 eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 2014 EAP_VENDOR_IETF, EAP_TYPE_TEAP, "TEAP"); 2015 if (!eap) 2016 return -1; 2017 2018 eap->init = eap_teap_init; 2019 eap->deinit = eap_teap_deinit; 2020 eap->process = eap_teap_process; 2021 eap->isKeyAvailable = eap_teap_isKeyAvailable; 2022 eap->getKey = eap_teap_getKey; 2023 eap->getSessionId = eap_teap_get_session_id; 2024 eap->get_status = eap_teap_get_status; 2025 #if 0 /* TODO */ 2026 eap->has_reauth_data = eap_teap_has_reauth_data; 2027 eap->deinit_for_reauth = eap_teap_deinit_for_reauth; 2028 eap->init_for_reauth = eap_teap_init_for_reauth; 2029 #endif 2030 eap->get_emsk = eap_teap_get_emsk; 2031 2032 return eap_peer_method_register(eap); 2033 } 2034