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