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