1 /* 2 * EAP peer state machines (RFC 4137) 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 * This file implements the Peer State Machine as defined in RFC 4137. The used 9 * states and state transitions match mostly with the RFC. However, there are 10 * couple of additional transitions for working around small issues noticed 11 * during testing. These exceptions are explained in comments within the 12 * functions in this file. The method functions, m.func(), are similar to the 13 * ones used in RFC 4137, but some small changes have used here to optimize 14 * operations and to add functionality needed for fast re-authentication 15 * (session resumption). 16 */ 17 18 #include "includes.h" 19 20 #include "common.h" 21 #include "pcsc_funcs.h" 22 #include "state_machine.h" 23 #include "ext_password.h" 24 #include "crypto/crypto.h" 25 #include "crypto/tls.h" 26 #include "crypto/sha256.h" 27 #include "common/wpa_ctrl.h" 28 #include "eap_common/eap_wsc_common.h" 29 #include "eap_i.h" 30 #include "eap_config.h" 31 32 #define STATE_MACHINE_DATA struct eap_sm 33 #define STATE_MACHINE_DEBUG_PREFIX "EAP" 34 35 #define EAP_MAX_AUTH_ROUNDS 100 36 #define EAP_MAX_AUTH_ROUNDS_SHORT 50 37 #define EAP_CLIENT_TIMEOUT_DEFAULT 60 38 39 40 static bool eap_sm_allowMethod(struct eap_sm *sm, int vendor, 41 enum eap_type method); 42 static struct wpabuf * eap_sm_buildNak(struct eap_sm *sm, int id); 43 static void eap_sm_processIdentity(struct eap_sm *sm, 44 const struct wpabuf *req); 45 static void eap_sm_processNotify(struct eap_sm *sm, const struct wpabuf *req); 46 static struct wpabuf * eap_sm_buildNotify(int id); 47 static void eap_sm_parseEapReq(struct eap_sm *sm, const struct wpabuf *req); 48 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 49 static const char * eap_sm_method_state_txt(EapMethodState state); 50 static const char * eap_sm_decision_txt(EapDecision decision); 51 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 52 static void eap_sm_request(struct eap_sm *sm, enum wpa_ctrl_req_type field, 53 const char *msg, size_t msglen); 54 55 56 57 static bool eapol_get_bool(struct eap_sm *sm, enum eapol_bool_var var) 58 { 59 return sm->eapol_cb->get_bool(sm->eapol_ctx, var); 60 } 61 62 63 static void eapol_set_bool(struct eap_sm *sm, enum eapol_bool_var var, 64 bool value) 65 { 66 sm->eapol_cb->set_bool(sm->eapol_ctx, var, value); 67 } 68 69 70 static unsigned int eapol_get_int(struct eap_sm *sm, enum eapol_int_var var) 71 { 72 return sm->eapol_cb->get_int(sm->eapol_ctx, var); 73 } 74 75 76 static void eapol_set_int(struct eap_sm *sm, enum eapol_int_var var, 77 unsigned int value) 78 { 79 sm->eapol_cb->set_int(sm->eapol_ctx, var, value); 80 } 81 82 83 static struct wpabuf * eapol_get_eapReqData(struct eap_sm *sm) 84 { 85 return sm->eapol_cb->get_eapReqData(sm->eapol_ctx); 86 } 87 88 89 static void eap_notify_status(struct eap_sm *sm, const char *status, 90 const char *parameter) 91 { 92 wpa_printf(MSG_DEBUG, "EAP: Status notification: %s (param=%s)", 93 status, parameter); 94 if (sm->eapol_cb->notify_status) 95 sm->eapol_cb->notify_status(sm->eapol_ctx, status, parameter); 96 } 97 98 99 static void eap_report_error(struct eap_sm *sm, int error_code) 100 { 101 wpa_printf(MSG_DEBUG, "EAP: Error notification: %d", error_code); 102 if (sm->eapol_cb->notify_eap_error) 103 sm->eapol_cb->notify_eap_error(sm->eapol_ctx, error_code); 104 } 105 106 107 static void eap_sm_free_key(struct eap_sm *sm) 108 { 109 if (sm->eapKeyData) { 110 bin_clear_free(sm->eapKeyData, sm->eapKeyDataLen); 111 sm->eapKeyData = NULL; 112 } 113 } 114 115 116 static void eap_deinit_prev_method(struct eap_sm *sm, const char *txt) 117 { 118 ext_password_free(sm->ext_pw_buf); 119 sm->ext_pw_buf = NULL; 120 121 if (sm->m == NULL || sm->eap_method_priv == NULL) 122 return; 123 124 wpa_printf(MSG_DEBUG, "EAP: deinitialize previously used EAP method " 125 "(%d, %s) at %s", sm->selectedMethod, sm->m->name, txt); 126 sm->m->deinit(sm, sm->eap_method_priv); 127 sm->eap_method_priv = NULL; 128 sm->m = NULL; 129 } 130 131 132 /** 133 * eap_config_allowed_method - Check whether EAP method is allowed 134 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 135 * @config: EAP configuration 136 * @vendor: Vendor-Id for expanded types or 0 = IETF for legacy types 137 * @method: EAP type 138 * Returns: 1 = allowed EAP method, 0 = not allowed 139 */ 140 static int eap_config_allowed_method(struct eap_sm *sm, 141 struct eap_peer_config *config, 142 int vendor, u32 method) 143 { 144 int i; 145 struct eap_method_type *m; 146 147 if (config == NULL || config->eap_methods == NULL) 148 return 1; 149 150 m = config->eap_methods; 151 for (i = 0; m[i].vendor != EAP_VENDOR_IETF || 152 m[i].method != EAP_TYPE_NONE; i++) { 153 if (m[i].vendor == vendor && m[i].method == method) 154 return 1; 155 } 156 return 0; 157 } 158 159 160 /** 161 * eap_allowed_method - Check whether EAP method is allowed 162 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 163 * @vendor: Vendor-Id for expanded types or 0 = IETF for legacy types 164 * @method: EAP type 165 * Returns: 1 = allowed EAP method, 0 = not allowed 166 */ 167 int eap_allowed_method(struct eap_sm *sm, int vendor, u32 method) 168 { 169 return eap_config_allowed_method(sm, eap_get_config(sm), vendor, 170 method); 171 } 172 173 174 #if defined(PCSC_FUNCS) || defined(CONFIG_EAP_PROXY) 175 static int eap_sm_append_3gpp_realm(struct eap_sm *sm, char *imsi, 176 size_t max_len, size_t *imsi_len, 177 int mnc_len) 178 { 179 char *pos, mnc[4]; 180 181 if (*imsi_len + 36 > max_len) { 182 wpa_printf(MSG_WARNING, "No room for realm in IMSI buffer"); 183 return -1; 184 } 185 186 if (mnc_len != 2 && mnc_len != 3) 187 mnc_len = 3; 188 189 if (mnc_len == 2) { 190 mnc[0] = '0'; 191 mnc[1] = imsi[3]; 192 mnc[2] = imsi[4]; 193 } else if (mnc_len == 3) { 194 mnc[0] = imsi[3]; 195 mnc[1] = imsi[4]; 196 mnc[2] = imsi[5]; 197 } 198 mnc[3] = '\0'; 199 200 pos = imsi + *imsi_len; 201 pos += os_snprintf(pos, imsi + max_len - pos, 202 "@wlan.mnc%s.mcc%c%c%c.3gppnetwork.org", 203 mnc, imsi[0], imsi[1], imsi[2]); 204 *imsi_len = pos - imsi; 205 206 return 0; 207 } 208 #endif /* PCSC_FUNCS || CONFIG_EAP_PROXY */ 209 210 211 /* 212 * This state initializes state machine variables when the machine is 213 * activated (portEnabled = true). This is also used when re-starting 214 * authentication (eapRestart == true). 215 */ 216 SM_STATE(EAP, INITIALIZE) 217 { 218 SM_ENTRY(EAP, INITIALIZE); 219 if (sm->fast_reauth && sm->m && sm->m->has_reauth_data && 220 sm->m->has_reauth_data(sm, sm->eap_method_priv) && 221 !sm->prev_failure && 222 sm->last_config == eap_get_config(sm)) { 223 wpa_printf(MSG_DEBUG, "EAP: maintaining EAP method data for " 224 "fast reauthentication"); 225 sm->m->deinit_for_reauth(sm, sm->eap_method_priv); 226 } else { 227 sm->last_config = eap_get_config(sm); 228 eap_deinit_prev_method(sm, "INITIALIZE"); 229 } 230 sm->selectedMethod = EAP_TYPE_NONE; 231 sm->methodState = METHOD_NONE; 232 sm->allowNotifications = true; 233 sm->decision = DECISION_FAIL; 234 sm->ClientTimeout = EAP_CLIENT_TIMEOUT_DEFAULT; 235 eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout); 236 eapol_set_bool(sm, EAPOL_eapSuccess, false); 237 eapol_set_bool(sm, EAPOL_eapFail, false); 238 eap_sm_free_key(sm); 239 os_free(sm->eapSessionId); 240 sm->eapSessionId = NULL; 241 sm->eapKeyAvailable = false; 242 eapol_set_bool(sm, EAPOL_eapRestart, false); 243 sm->lastId = -1; /* new session - make sure this does not match with 244 * the first EAP-Packet */ 245 /* 246 * RFC 4137 does not reset eapResp and eapNoResp here. However, this 247 * seemed to be able to trigger cases where both were set and if EAPOL 248 * state machine uses eapNoResp first, it may end up not sending a real 249 * reply correctly. This occurred when the workaround in FAIL state set 250 * eapNoResp = true.. Maybe that workaround needs to be fixed to do 251 * something else(?) 252 */ 253 eapol_set_bool(sm, EAPOL_eapResp, false); 254 eapol_set_bool(sm, EAPOL_eapNoResp, false); 255 /* 256 * RFC 4137 does not reset ignore here, but since it is possible for 257 * some method code paths to end up not setting ignore=false, clear the 258 * value here to avoid issues if a previous authentication attempt 259 * failed with ignore=true being left behind in the last 260 * m.check(eapReqData) operation. 261 */ 262 sm->ignore = 0; 263 sm->num_rounds = 0; 264 sm->num_rounds_short = 0; 265 sm->prev_failure = 0; 266 sm->expected_failure = 0; 267 sm->reauthInit = false; 268 sm->erp_seq = (u32) -1; 269 sm->use_machine_cred = 0; 270 sm->eap_fast_mschapv2 = false; 271 } 272 273 274 /* 275 * This state is reached whenever service from the lower layer is interrupted 276 * or unavailable (portEnabled == false). Immediate transition to INITIALIZE 277 * occurs when the port becomes enabled. 278 */ 279 SM_STATE(EAP, DISABLED) 280 { 281 SM_ENTRY(EAP, DISABLED); 282 sm->num_rounds = 0; 283 sm->num_rounds_short = 0; 284 /* 285 * RFC 4137 does not describe clearing of idleWhile here, but doing so 286 * allows the timer tick to be stopped more quickly when EAP is not in 287 * use. 288 */ 289 eapol_set_int(sm, EAPOL_idleWhile, 0); 290 } 291 292 293 /* 294 * The state machine spends most of its time here, waiting for something to 295 * happen. This state is entered unconditionally from INITIALIZE, DISCARD, and 296 * SEND_RESPONSE states. 297 */ 298 SM_STATE(EAP, IDLE) 299 { 300 SM_ENTRY(EAP, IDLE); 301 } 302 303 304 /* 305 * This state is entered when an EAP packet is received (eapReq == true) to 306 * parse the packet header. 307 */ 308 SM_STATE(EAP, RECEIVED) 309 { 310 const struct wpabuf *eapReqData; 311 312 SM_ENTRY(EAP, RECEIVED); 313 eapReqData = eapol_get_eapReqData(sm); 314 /* parse rxReq, rxSuccess, rxFailure, reqId, reqMethod */ 315 eap_sm_parseEapReq(sm, eapReqData); 316 sm->num_rounds++; 317 if (!eapReqData || wpabuf_len(eapReqData) < 20) 318 sm->num_rounds_short++; 319 else 320 sm->num_rounds_short = 0; 321 } 322 323 324 /* 325 * This state is entered when a request for a new type comes in. Either the 326 * correct method is started, or a Nak response is built. 327 */ 328 SM_STATE(EAP, GET_METHOD) 329 { 330 int reinit; 331 enum eap_type method; 332 const struct eap_method *eap_method; 333 334 SM_ENTRY(EAP, GET_METHOD); 335 336 if (sm->reqMethod == EAP_TYPE_EXPANDED) 337 method = sm->reqVendorMethod; 338 else 339 method = sm->reqMethod; 340 341 eap_method = eap_peer_get_eap_method(sm->reqVendor, method); 342 343 if (!eap_sm_allowMethod(sm, sm->reqVendor, method)) { 344 wpa_printf(MSG_DEBUG, "EAP: vendor %u method %u not allowed", 345 sm->reqVendor, method); 346 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD 347 "vendor=%u method=%u -> NAK", 348 sm->reqVendor, method); 349 eap_notify_status(sm, "refuse proposed method", 350 eap_method ? eap_method->name : "unknown"); 351 goto nak; 352 } 353 354 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD 355 "vendor=%u method=%u", sm->reqVendor, method); 356 357 eap_notify_status(sm, "accept proposed method", 358 eap_method ? eap_method->name : "unknown"); 359 /* 360 * RFC 4137 does not define specific operation for fast 361 * re-authentication (session resumption). The design here is to allow 362 * the previously used method data to be maintained for 363 * re-authentication if the method support session resumption. 364 * Otherwise, the previously used method data is freed and a new method 365 * is allocated here. 366 */ 367 if (sm->fast_reauth && 368 sm->m && sm->m->vendor == sm->reqVendor && 369 sm->m->method == method && 370 sm->m->has_reauth_data && 371 sm->m->has_reauth_data(sm, sm->eap_method_priv)) { 372 wpa_printf(MSG_DEBUG, "EAP: Using previous method data" 373 " for fast re-authentication"); 374 reinit = 1; 375 } else { 376 eap_deinit_prev_method(sm, "GET_METHOD"); 377 reinit = 0; 378 } 379 380 sm->selectedMethod = sm->reqMethod; 381 if (sm->m == NULL) 382 sm->m = eap_method; 383 if (!sm->m) { 384 wpa_printf(MSG_DEBUG, "EAP: Could not find selected method: " 385 "vendor %d method %d", 386 sm->reqVendor, method); 387 goto nak; 388 } 389 390 sm->ClientTimeout = EAP_CLIENT_TIMEOUT_DEFAULT; 391 392 wpa_printf(MSG_DEBUG, "EAP: Initialize selected EAP method: " 393 "vendor %u method %u (%s)", 394 sm->reqVendor, method, sm->m->name); 395 if (reinit) { 396 sm->eap_method_priv = sm->m->init_for_reauth( 397 sm, sm->eap_method_priv); 398 } else { 399 sm->waiting_ext_cert_check = 0; 400 sm->ext_cert_check = 0; 401 sm->eap_method_priv = sm->m->init(sm); 402 } 403 404 if (sm->eap_method_priv == NULL) { 405 struct eap_peer_config *config = eap_get_config(sm); 406 wpa_msg(sm->msg_ctx, MSG_INFO, 407 "EAP: Failed to initialize EAP method: vendor %u " 408 "method %u (%s)", 409 sm->reqVendor, method, sm->m->name); 410 sm->m = NULL; 411 sm->methodState = METHOD_NONE; 412 sm->selectedMethod = EAP_TYPE_NONE; 413 if (sm->reqMethod == EAP_TYPE_TLS && config && 414 (config->pending_req_pin || 415 config->pending_req_passphrase)) { 416 /* 417 * Return without generating Nak in order to allow 418 * entering of PIN code or passphrase to retry the 419 * current EAP packet. 420 */ 421 wpa_printf(MSG_DEBUG, "EAP: Pending PIN/passphrase " 422 "request - skip Nak"); 423 return; 424 } 425 426 goto nak; 427 } 428 429 sm->methodState = METHOD_INIT; 430 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_METHOD 431 "EAP vendor %u method %u (%s) selected", 432 sm->reqVendor, method, sm->m->name); 433 return; 434 435 nak: 436 wpabuf_free(sm->eapRespData); 437 sm->eapRespData = NULL; 438 sm->eapRespData = eap_sm_buildNak(sm, sm->reqId); 439 } 440 441 442 #ifdef CONFIG_ERP 443 444 static char * eap_get_realm(struct eap_sm *sm, struct eap_peer_config *config) 445 { 446 char *realm; 447 size_t i, realm_len; 448 449 if (!config) 450 return NULL; 451 452 if (config->identity) { 453 for (i = 0; i < config->identity_len; i++) { 454 if (config->identity[i] == '@') 455 break; 456 } 457 if (i < config->identity_len) { 458 realm_len = config->identity_len - i - 1; 459 realm = os_malloc(realm_len + 1); 460 if (realm == NULL) 461 return NULL; 462 os_memcpy(realm, &config->identity[i + 1], realm_len); 463 realm[realm_len] = '\0'; 464 return realm; 465 } 466 } 467 468 if (config->anonymous_identity) { 469 for (i = 0; i < config->anonymous_identity_len; i++) { 470 if (config->anonymous_identity[i] == '@') 471 break; 472 } 473 if (i < config->anonymous_identity_len) { 474 realm_len = config->anonymous_identity_len - i - 1; 475 realm = os_malloc(realm_len + 1); 476 if (realm == NULL) 477 return NULL; 478 os_memcpy(realm, &config->anonymous_identity[i + 1], 479 realm_len); 480 realm[realm_len] = '\0'; 481 return realm; 482 } 483 } 484 485 #ifdef CONFIG_EAP_PROXY 486 /* When identity is not provided in the config, build the realm from 487 * IMSI for eap_proxy based methods. 488 */ 489 if (!config->identity && !config->anonymous_identity && 490 sm->eapol_cb->get_imsi && 491 (eap_config_allowed_method(sm, config, EAP_VENDOR_IETF, 492 EAP_TYPE_SIM) || 493 eap_config_allowed_method(sm, config, EAP_VENDOR_IETF, 494 EAP_TYPE_AKA) || 495 eap_config_allowed_method(sm, config, EAP_VENDOR_IETF, 496 EAP_TYPE_AKA_PRIME))) { 497 char imsi[100]; 498 size_t imsi_len; 499 int mnc_len, pos; 500 501 wpa_printf(MSG_DEBUG, "EAP: Build realm from IMSI (eap_proxy)"); 502 mnc_len = sm->eapol_cb->get_imsi(sm->eapol_ctx, config->sim_num, 503 imsi, &imsi_len); 504 if (mnc_len < 0) 505 return NULL; 506 507 pos = imsi_len + 1; /* points to the beginning of the realm */ 508 if (eap_sm_append_3gpp_realm(sm, imsi, sizeof(imsi), &imsi_len, 509 mnc_len) < 0) { 510 wpa_printf(MSG_WARNING, "Could not append realm"); 511 return NULL; 512 } 513 514 realm = os_strdup(&imsi[pos]); 515 if (!realm) 516 return NULL; 517 518 wpa_printf(MSG_DEBUG, "EAP: Generated realm '%s'", realm); 519 return realm; 520 } 521 #endif /* CONFIG_EAP_PROXY */ 522 523 return NULL; 524 } 525 526 527 static char * eap_home_realm(struct eap_sm *sm) 528 { 529 return eap_get_realm(sm, eap_get_config(sm)); 530 } 531 532 533 static struct eap_erp_key * 534 eap_erp_get_key(struct eap_sm *sm, const char *realm) 535 { 536 struct eap_erp_key *erp; 537 538 dl_list_for_each(erp, &sm->erp_keys, struct eap_erp_key, list) { 539 char *pos; 540 541 pos = os_strchr(erp->keyname_nai, '@'); 542 if (!pos) 543 continue; 544 pos++; 545 if (os_strcmp(pos, realm) == 0) 546 return erp; 547 } 548 549 return NULL; 550 } 551 552 553 static struct eap_erp_key * 554 eap_erp_get_key_nai(struct eap_sm *sm, const char *nai) 555 { 556 struct eap_erp_key *erp; 557 558 dl_list_for_each(erp, &sm->erp_keys, struct eap_erp_key, list) { 559 if (os_strcmp(erp->keyname_nai, nai) == 0) 560 return erp; 561 } 562 563 return NULL; 564 } 565 566 567 static void eap_peer_erp_free_key(struct eap_erp_key *erp) 568 { 569 dl_list_del(&erp->list); 570 bin_clear_free(erp, sizeof(*erp)); 571 } 572 573 574 static void eap_erp_remove_keys_realm(struct eap_sm *sm, const char *realm) 575 { 576 struct eap_erp_key *erp; 577 578 while ((erp = eap_erp_get_key(sm, realm)) != NULL) { 579 wpa_printf(MSG_DEBUG, "EAP: Delete old ERP key %s", 580 erp->keyname_nai); 581 eap_peer_erp_free_key(erp); 582 } 583 } 584 585 586 int eap_peer_update_erp_next_seq_num(struct eap_sm *sm, u16 next_seq_num) 587 { 588 struct eap_erp_key *erp; 589 char *home_realm; 590 591 home_realm = eap_home_realm(sm); 592 if (!home_realm || os_strlen(home_realm) == 0) { 593 os_free(home_realm); 594 return -1; 595 } 596 597 erp = eap_erp_get_key(sm, home_realm); 598 if (!erp) { 599 wpa_printf(MSG_DEBUG, 600 "EAP: Failed to find ERP key for realm: %s", 601 home_realm); 602 os_free(home_realm); 603 return -1; 604 } 605 606 if ((u32) next_seq_num < erp->next_seq) { 607 /* Sequence number has wrapped around, clear this ERP 608 * info and do a full auth next time. 609 */ 610 eap_peer_erp_free_key(erp); 611 } else { 612 erp->next_seq = (u32) next_seq_num; 613 } 614 615 os_free(home_realm); 616 return 0; 617 } 618 619 620 int eap_peer_get_erp_info(struct eap_sm *sm, struct eap_peer_config *config, 621 const u8 **username, size_t *username_len, 622 const u8 **realm, size_t *realm_len, 623 u16 *erp_next_seq_num, const u8 **rrk, 624 size_t *rrk_len) 625 { 626 struct eap_erp_key *erp; 627 char *home_realm; 628 char *pos; 629 630 if (config) 631 home_realm = eap_get_realm(sm, config); 632 else 633 home_realm = eap_home_realm(sm); 634 if (!home_realm || os_strlen(home_realm) == 0) { 635 os_free(home_realm); 636 return -1; 637 } 638 639 erp = eap_erp_get_key(sm, home_realm); 640 os_free(home_realm); 641 if (!erp) 642 return -1; 643 644 if (erp->next_seq >= 65536) 645 return -1; /* SEQ has range of 0..65535 */ 646 647 pos = os_strchr(erp->keyname_nai, '@'); 648 if (!pos) 649 return -1; /* this cannot really happen */ 650 *username_len = pos - erp->keyname_nai; 651 *username = (u8 *) erp->keyname_nai; 652 653 pos++; 654 *realm_len = os_strlen(pos); 655 *realm = (u8 *) pos; 656 657 *erp_next_seq_num = (u16) erp->next_seq; 658 659 *rrk_len = erp->rRK_len; 660 *rrk = erp->rRK; 661 662 if (*username_len == 0 || *realm_len == 0 || *rrk_len == 0) 663 return -1; 664 665 return 0; 666 } 667 668 #endif /* CONFIG_ERP */ 669 670 671 void eap_peer_erp_free_keys(struct eap_sm *sm) 672 { 673 #ifdef CONFIG_ERP 674 struct eap_erp_key *erp, *tmp; 675 676 dl_list_for_each_safe(erp, tmp, &sm->erp_keys, struct eap_erp_key, list) 677 eap_peer_erp_free_key(erp); 678 #endif /* CONFIG_ERP */ 679 } 680 681 682 /* Note: If ext_session and/or ext_emsk are passed to this function, they are 683 * expected to point to allocated memory and those allocations will be freed 684 * unconditionally. */ 685 void eap_peer_erp_init(struct eap_sm *sm, u8 *ext_session_id, 686 size_t ext_session_id_len, u8 *ext_emsk, 687 size_t ext_emsk_len) 688 { 689 #ifdef CONFIG_ERP 690 u8 *emsk = NULL; 691 size_t emsk_len = 0; 692 u8 *session_id = NULL; 693 size_t session_id_len = 0; 694 u8 EMSKname[EAP_EMSK_NAME_LEN]; 695 u8 len[2], ctx[3]; 696 char *realm; 697 size_t realm_len, nai_buf_len; 698 struct eap_erp_key *erp = NULL; 699 int pos; 700 701 realm = eap_home_realm(sm); 702 if (!realm) 703 goto fail; 704 realm_len = os_strlen(realm); 705 wpa_printf(MSG_DEBUG, "EAP: Realm for ERP keyName-NAI: %s", realm); 706 eap_erp_remove_keys_realm(sm, realm); 707 708 nai_buf_len = 2 * EAP_EMSK_NAME_LEN + 1 + realm_len; 709 if (nai_buf_len > 253) { 710 /* 711 * keyName-NAI has a maximum length of 253 octet to fit in 712 * RADIUS attributes. 713 */ 714 wpa_printf(MSG_DEBUG, 715 "EAP: Too long realm for ERP keyName-NAI maximum length"); 716 goto fail; 717 } 718 nai_buf_len++; /* null termination */ 719 erp = os_zalloc(sizeof(*erp) + nai_buf_len); 720 if (erp == NULL) 721 goto fail; 722 723 if (ext_emsk) { 724 emsk = ext_emsk; 725 emsk_len = ext_emsk_len; 726 } else { 727 emsk = sm->m->get_emsk(sm, sm->eap_method_priv, &emsk_len); 728 } 729 730 if (!emsk || emsk_len == 0 || emsk_len > ERP_MAX_KEY_LEN) { 731 wpa_printf(MSG_DEBUG, 732 "EAP: No suitable EMSK available for ERP"); 733 goto fail; 734 } 735 736 wpa_hexdump_key(MSG_DEBUG, "EAP: EMSK", emsk, emsk_len); 737 738 if (ext_session_id) { 739 session_id = ext_session_id; 740 session_id_len = ext_session_id_len; 741 } else { 742 session_id = sm->eapSessionId; 743 session_id_len = sm->eapSessionIdLen; 744 } 745 746 if (!session_id || session_id_len == 0) { 747 wpa_printf(MSG_DEBUG, 748 "EAP: No suitable session id available for ERP"); 749 goto fail; 750 } 751 752 WPA_PUT_BE16(len, EAP_EMSK_NAME_LEN); 753 if (hmac_sha256_kdf(session_id, session_id_len, "EMSK", len, 754 sizeof(len), EMSKname, EAP_EMSK_NAME_LEN) < 0) { 755 wpa_printf(MSG_DEBUG, "EAP: Could not derive EMSKname"); 756 goto fail; 757 } 758 wpa_hexdump(MSG_DEBUG, "EAP: EMSKname", EMSKname, EAP_EMSK_NAME_LEN); 759 760 pos = wpa_snprintf_hex(erp->keyname_nai, nai_buf_len, 761 EMSKname, EAP_EMSK_NAME_LEN); 762 erp->keyname_nai[pos] = '@'; 763 os_memcpy(&erp->keyname_nai[pos + 1], realm, realm_len); 764 765 WPA_PUT_BE16(len, emsk_len); 766 if (hmac_sha256_kdf(emsk, emsk_len, 767 "EAP Re-authentication Root Key@ietf.org", 768 len, sizeof(len), erp->rRK, emsk_len) < 0) { 769 wpa_printf(MSG_DEBUG, "EAP: Could not derive rRK for ERP"); 770 goto fail; 771 } 772 erp->rRK_len = emsk_len; 773 wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rRK", erp->rRK, erp->rRK_len); 774 775 ctx[0] = EAP_ERP_CS_HMAC_SHA256_128; 776 WPA_PUT_BE16(&ctx[1], erp->rRK_len); 777 if (hmac_sha256_kdf(erp->rRK, erp->rRK_len, 778 "Re-authentication Integrity Key@ietf.org", 779 ctx, sizeof(ctx), erp->rIK, erp->rRK_len) < 0) { 780 wpa_printf(MSG_DEBUG, "EAP: Could not derive rIK for ERP"); 781 goto fail; 782 } 783 erp->rIK_len = erp->rRK_len; 784 wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rIK", erp->rIK, erp->rIK_len); 785 786 wpa_printf(MSG_DEBUG, "EAP: Stored ERP keys %s", erp->keyname_nai); 787 dl_list_add(&sm->erp_keys, &erp->list); 788 erp = NULL; 789 fail: 790 if (ext_emsk) 791 bin_clear_free(ext_emsk, ext_emsk_len); 792 else 793 bin_clear_free(emsk, emsk_len); 794 bin_clear_free(ext_session_id, ext_session_id_len); 795 bin_clear_free(erp, sizeof(*erp)); 796 os_free(realm); 797 #endif /* CONFIG_ERP */ 798 } 799 800 801 #ifdef CONFIG_ERP 802 struct wpabuf * eap_peer_build_erp_reauth_start(struct eap_sm *sm, u8 eap_id) 803 { 804 char *realm; 805 struct eap_erp_key *erp; 806 struct wpabuf *msg; 807 u8 hash[SHA256_MAC_LEN]; 808 809 realm = eap_home_realm(sm); 810 if (!realm) 811 return NULL; 812 813 erp = eap_erp_get_key(sm, realm); 814 os_free(realm); 815 realm = NULL; 816 if (!erp) 817 return NULL; 818 819 if (erp->next_seq >= 65536) 820 return NULL; /* SEQ has range of 0..65535 */ 821 822 /* TODO: check rRK lifetime expiration */ 823 824 wpa_printf(MSG_DEBUG, "EAP: Valid ERP key found %s (SEQ=%u)", 825 erp->keyname_nai, erp->next_seq); 826 827 msg = eap_msg_alloc(EAP_VENDOR_IETF, 828 (enum eap_type) EAP_ERP_TYPE_REAUTH, 829 1 + 2 + 2 + os_strlen(erp->keyname_nai) + 1 + 16, 830 EAP_CODE_INITIATE, eap_id); 831 if (msg == NULL) 832 return NULL; 833 834 wpabuf_put_u8(msg, 0x20); /* Flags: R=0 B=0 L=1 */ 835 wpabuf_put_be16(msg, erp->next_seq); 836 837 wpabuf_put_u8(msg, EAP_ERP_TLV_KEYNAME_NAI); 838 wpabuf_put_u8(msg, os_strlen(erp->keyname_nai)); 839 wpabuf_put_str(msg, erp->keyname_nai); 840 841 wpabuf_put_u8(msg, EAP_ERP_CS_HMAC_SHA256_128); /* Cryptosuite */ 842 843 if (hmac_sha256(erp->rIK, erp->rIK_len, 844 wpabuf_head(msg), wpabuf_len(msg), hash) < 0) { 845 wpabuf_free(msg); 846 return NULL; 847 } 848 wpabuf_put_data(msg, hash, 16); 849 850 sm->erp_seq = erp->next_seq; 851 erp->next_seq++; 852 853 wpa_hexdump_buf(MSG_DEBUG, "ERP: EAP-Initiate/Re-auth", msg); 854 855 return msg; 856 } 857 858 859 static int eap_peer_erp_reauth_start(struct eap_sm *sm, u8 eap_id) 860 { 861 struct wpabuf *msg; 862 863 msg = eap_peer_build_erp_reauth_start(sm, eap_id); 864 if (!msg) 865 return -1; 866 867 wpa_printf(MSG_DEBUG, "EAP: Sending EAP-Initiate/Re-auth"); 868 wpabuf_free(sm->eapRespData); 869 sm->eapRespData = msg; 870 sm->reauthInit = true; 871 return 0; 872 } 873 #endif /* CONFIG_ERP */ 874 875 876 /* 877 * The method processing happens here. The request from the authenticator is 878 * processed, and an appropriate response packet is built. 879 */ 880 SM_STATE(EAP, METHOD) 881 { 882 struct wpabuf *eapReqData; 883 struct eap_method_ret ret; 884 int min_len = 1; 885 886 SM_ENTRY(EAP, METHOD); 887 if (sm->m == NULL) { 888 wpa_printf(MSG_WARNING, "EAP::METHOD - method not selected"); 889 return; 890 } 891 892 eapReqData = eapol_get_eapReqData(sm); 893 if (sm->m->vendor == EAP_VENDOR_IETF && sm->m->method == EAP_TYPE_LEAP) 894 min_len = 0; /* LEAP uses EAP-Success without payload */ 895 if (!eap_hdr_len_valid(eapReqData, min_len)) 896 return; 897 898 /* 899 * Get ignore, methodState, decision, allowNotifications, and 900 * eapRespData. RFC 4137 uses three separate method procedure (check, 901 * process, and buildResp) in this state. These have been combined into 902 * a single function call to m->process() in order to optimize EAP 903 * method implementation interface a bit. These procedures are only 904 * used from within this METHOD state, so there is no need to keep 905 * these as separate C functions. 906 * 907 * The RFC 4137 procedures return values as follows: 908 * ignore = m.check(eapReqData) 909 * (methodState, decision, allowNotifications) = m.process(eapReqData) 910 * eapRespData = m.buildResp(reqId) 911 */ 912 os_memset(&ret, 0, sizeof(ret)); 913 ret.ignore = sm->ignore; 914 ret.methodState = sm->methodState; 915 ret.decision = sm->decision; 916 ret.allowNotifications = sm->allowNotifications; 917 wpabuf_free(sm->eapRespData); 918 sm->eapRespData = NULL; 919 sm->eapRespData = sm->m->process(sm, sm->eap_method_priv, &ret, 920 eapReqData); 921 wpa_printf(MSG_DEBUG, "EAP: method process -> ignore=%s " 922 "methodState=%s decision=%s eapRespData=%p", 923 ret.ignore ? "TRUE" : "FALSE", 924 eap_sm_method_state_txt(ret.methodState), 925 eap_sm_decision_txt(ret.decision), 926 sm->eapRespData); 927 928 sm->ignore = ret.ignore; 929 if (sm->ignore) 930 return; 931 sm->methodState = ret.methodState; 932 sm->decision = ret.decision; 933 sm->allowNotifications = ret.allowNotifications; 934 935 if (sm->m->isKeyAvailable && sm->m->getKey && 936 sm->m->isKeyAvailable(sm, sm->eap_method_priv)) { 937 eap_sm_free_key(sm); 938 sm->eapKeyData = sm->m->getKey(sm, sm->eap_method_priv, 939 &sm->eapKeyDataLen); 940 os_free(sm->eapSessionId); 941 sm->eapSessionId = NULL; 942 if (sm->m->getSessionId) { 943 sm->eapSessionId = sm->m->getSessionId( 944 sm, sm->eap_method_priv, 945 &sm->eapSessionIdLen); 946 wpa_hexdump(MSG_DEBUG, "EAP: Session-Id", 947 sm->eapSessionId, sm->eapSessionIdLen); 948 } 949 } 950 } 951 952 953 /* 954 * This state signals the lower layer that a response packet is ready to be 955 * sent. 956 */ 957 SM_STATE(EAP, SEND_RESPONSE) 958 { 959 SM_ENTRY(EAP, SEND_RESPONSE); 960 wpabuf_free(sm->lastRespData); 961 if (sm->eapRespData) { 962 if (wpabuf_len(sm->eapRespData) >= 20) 963 sm->num_rounds_short = 0; 964 if (sm->workaround) 965 os_memcpy(sm->last_sha1, sm->req_sha1, 20); 966 sm->lastId = sm->reqId; 967 sm->lastRespData = wpabuf_dup(sm->eapRespData); 968 eapol_set_bool(sm, EAPOL_eapResp, true); 969 } else { 970 wpa_printf(MSG_DEBUG, "EAP: No eapRespData available"); 971 sm->lastRespData = NULL; 972 } 973 eapol_set_bool(sm, EAPOL_eapReq, false); 974 eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout); 975 sm->reauthInit = false; 976 } 977 978 979 /* 980 * This state signals the lower layer that the request was discarded, and no 981 * response packet will be sent at this time. 982 */ 983 SM_STATE(EAP, DISCARD) 984 { 985 SM_ENTRY(EAP, DISCARD); 986 eapol_set_bool(sm, EAPOL_eapReq, false); 987 eapol_set_bool(sm, EAPOL_eapNoResp, true); 988 } 989 990 991 /* 992 * Handles requests for Identity method and builds a response. 993 */ 994 SM_STATE(EAP, IDENTITY) 995 { 996 const struct wpabuf *eapReqData; 997 998 SM_ENTRY(EAP, IDENTITY); 999 eapReqData = eapol_get_eapReqData(sm); 1000 if (!eap_hdr_len_valid(eapReqData, 1)) 1001 return; 1002 eap_sm_processIdentity(sm, eapReqData); 1003 wpabuf_free(sm->eapRespData); 1004 sm->eapRespData = NULL; 1005 sm->eapRespData = eap_sm_buildIdentity(sm, sm->reqId, 0); 1006 } 1007 1008 1009 /* 1010 * Handles requests for Notification method and builds a response. 1011 */ 1012 SM_STATE(EAP, NOTIFICATION) 1013 { 1014 const struct wpabuf *eapReqData; 1015 1016 SM_ENTRY(EAP, NOTIFICATION); 1017 eapReqData = eapol_get_eapReqData(sm); 1018 if (!eap_hdr_len_valid(eapReqData, 1)) 1019 return; 1020 eap_sm_processNotify(sm, eapReqData); 1021 wpabuf_free(sm->eapRespData); 1022 sm->eapRespData = NULL; 1023 sm->eapRespData = eap_sm_buildNotify(sm->reqId); 1024 } 1025 1026 1027 /* 1028 * This state retransmits the previous response packet. 1029 */ 1030 SM_STATE(EAP, RETRANSMIT) 1031 { 1032 SM_ENTRY(EAP, RETRANSMIT); 1033 wpabuf_free(sm->eapRespData); 1034 if (sm->lastRespData) 1035 sm->eapRespData = wpabuf_dup(sm->lastRespData); 1036 else 1037 sm->eapRespData = NULL; 1038 } 1039 1040 1041 /* 1042 * This state is entered in case of a successful completion of authentication 1043 * and state machine waits here until port is disabled or EAP authentication is 1044 * restarted. 1045 */ 1046 SM_STATE(EAP, SUCCESS) 1047 { 1048 struct eap_peer_config *config = eap_get_config(sm); 1049 1050 SM_ENTRY(EAP, SUCCESS); 1051 if (sm->eapKeyData != NULL) 1052 sm->eapKeyAvailable = true; 1053 eapol_set_bool(sm, EAPOL_eapSuccess, true); 1054 1055 /* 1056 * RFC 4137 does not clear eapReq here, but this seems to be required 1057 * to avoid processing the same request twice when state machine is 1058 * initialized. 1059 */ 1060 eapol_set_bool(sm, EAPOL_eapReq, false); 1061 1062 /* 1063 * RFC 4137 does not set eapNoResp here, but this seems to be required 1064 * to get EAPOL Supplicant backend state machine into SUCCESS state. In 1065 * addition, either eapResp or eapNoResp is required to be set after 1066 * processing the received EAP frame. 1067 */ 1068 eapol_set_bool(sm, EAPOL_eapNoResp, true); 1069 1070 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS 1071 "EAP authentication completed successfully"); 1072 1073 if (!config || !sm->m) { 1074 /* 1075 * This should not happen under normal conditions, but be more 1076 * careful here since there was an earlier case where 1077 * EAP-Success could end up getting delivered to the state 1078 * machine for processing after the state had been cleaned with 1079 * a call to eap_invalidate_cached_session() (and also 1080 * eapol_sm_notify_config() having been used to clear EAP 1081 * configuration in the EAPOL state machine). 1082 */ 1083 wpa_printf(MSG_DEBUG, 1084 "EAP: State machine not configured - cannot initialize ERP"); 1085 return; 1086 } 1087 if (config->erp && sm->m->get_emsk && sm->eapSessionId && 1088 sm->m->isKeyAvailable && 1089 sm->m->isKeyAvailable(sm, sm->eap_method_priv)) 1090 eap_peer_erp_init(sm, NULL, 0, NULL, 0); 1091 } 1092 1093 1094 /* 1095 * This state is entered in case of a failure and state machine waits here 1096 * until port is disabled or EAP authentication is restarted. 1097 */ 1098 SM_STATE(EAP, FAILURE) 1099 { 1100 SM_ENTRY(EAP, FAILURE); 1101 eapol_set_bool(sm, EAPOL_eapFail, true); 1102 1103 /* 1104 * RFC 4137 does not clear eapReq here, but this seems to be required 1105 * to avoid processing the same request twice when state machine is 1106 * initialized. 1107 */ 1108 eapol_set_bool(sm, EAPOL_eapReq, false); 1109 1110 /* 1111 * RFC 4137 does not set eapNoResp here. However, either eapResp or 1112 * eapNoResp is required to be set after processing the received EAP 1113 * frame. 1114 */ 1115 eapol_set_bool(sm, EAPOL_eapNoResp, true); 1116 1117 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE 1118 "EAP authentication failed"); 1119 1120 sm->prev_failure = 1; 1121 } 1122 1123 1124 static int eap_success_workaround(struct eap_sm *sm, int reqId, int lastId) 1125 { 1126 /* 1127 * At least Microsoft IAS and Meetinghouse Aegis seem to be sending 1128 * EAP-Success/Failure with lastId + 1 even though RFC 3748 and 1129 * RFC 4137 require that reqId == lastId. In addition, it looks like 1130 * Ringmaster v2.1.2.0 would be using lastId + 2 in EAP-Success. 1131 * 1132 * Accept this kind of Id if EAP workarounds are enabled. These are 1133 * unauthenticated plaintext messages, so this should have minimal 1134 * security implications (bit easier to fake EAP-Success/Failure). 1135 */ 1136 if (sm->workaround && (reqId == ((lastId + 1) & 0xff) || 1137 reqId == ((lastId + 2) & 0xff))) { 1138 wpa_printf(MSG_DEBUG, "EAP: Workaround for unexpected " 1139 "identifier field in EAP Success: " 1140 "reqId=%d lastId=%d (these are supposed to be " 1141 "same)", reqId, lastId); 1142 return 1; 1143 } 1144 wpa_printf(MSG_DEBUG, "EAP: EAP-Success Id mismatch - reqId=%d " 1145 "lastId=%d", reqId, lastId); 1146 return 0; 1147 } 1148 1149 1150 /* 1151 * RFC 4137 - Appendix A.1: EAP Peer State Machine - State transitions 1152 */ 1153 1154 static void eap_peer_sm_step_idle(struct eap_sm *sm) 1155 { 1156 /* 1157 * The first three transitions are from RFC 4137. The last two are 1158 * local additions to handle special cases with LEAP and PEAP server 1159 * not sending EAP-Success in some cases. 1160 */ 1161 if (eapol_get_bool(sm, EAPOL_eapReq)) 1162 SM_ENTER(EAP, RECEIVED); 1163 else if ((eapol_get_bool(sm, EAPOL_altAccept) && 1164 sm->decision != DECISION_FAIL) || 1165 (eapol_get_int(sm, EAPOL_idleWhile) == 0 && 1166 sm->decision == DECISION_UNCOND_SUCC)) 1167 SM_ENTER(EAP, SUCCESS); 1168 else if (eapol_get_bool(sm, EAPOL_altReject) || 1169 (eapol_get_int(sm, EAPOL_idleWhile) == 0 && 1170 sm->decision != DECISION_UNCOND_SUCC) || 1171 (eapol_get_bool(sm, EAPOL_altAccept) && 1172 sm->methodState != METHOD_CONT && 1173 sm->decision == DECISION_FAIL)) 1174 SM_ENTER(EAP, FAILURE); 1175 else if (sm->selectedMethod == EAP_TYPE_LEAP && 1176 sm->leap_done && sm->decision != DECISION_FAIL && 1177 sm->methodState == METHOD_DONE) 1178 SM_ENTER(EAP, SUCCESS); 1179 else if (sm->selectedMethod == EAP_TYPE_PEAP && 1180 sm->peap_done && sm->decision != DECISION_FAIL && 1181 sm->methodState == METHOD_DONE) 1182 SM_ENTER(EAP, SUCCESS); 1183 } 1184 1185 1186 static int eap_peer_req_is_duplicate(struct eap_sm *sm) 1187 { 1188 int duplicate; 1189 1190 duplicate = (sm->reqId == sm->lastId) && sm->rxReq; 1191 if (sm->workaround && duplicate && 1192 os_memcmp(sm->req_sha1, sm->last_sha1, 20) != 0) { 1193 /* 1194 * RFC 4137 uses (reqId == lastId) as the only verification for 1195 * duplicate EAP requests. However, this misses cases where the 1196 * AS is incorrectly using the same id again; and 1197 * unfortunately, such implementations exist. Use SHA1 hash as 1198 * an extra verification for the packets being duplicate to 1199 * workaround these issues. 1200 */ 1201 wpa_printf(MSG_DEBUG, "EAP: AS used the same Id again, but " 1202 "EAP packets were not identical"); 1203 wpa_printf(MSG_DEBUG, "EAP: workaround - assume this is not a " 1204 "duplicate packet"); 1205 duplicate = 0; 1206 } 1207 1208 return duplicate; 1209 } 1210 1211 1212 static int eap_peer_sm_allow_canned(struct eap_sm *sm) 1213 { 1214 struct eap_peer_config *config = eap_get_config(sm); 1215 1216 return config && config->phase1 && 1217 os_strstr(config->phase1, "allow_canned_success=1"); 1218 } 1219 1220 1221 static void eap_peer_sm_step_received(struct eap_sm *sm) 1222 { 1223 int duplicate = eap_peer_req_is_duplicate(sm); 1224 1225 /* 1226 * Two special cases below for LEAP are local additions to work around 1227 * odd LEAP behavior (EAP-Success in the middle of authentication and 1228 * then swapped roles). Other transitions are based on RFC 4137. 1229 */ 1230 if (sm->rxSuccess && sm->decision != DECISION_FAIL && 1231 (sm->reqId == sm->lastId || 1232 eap_success_workaround(sm, sm->reqId, sm->lastId))) 1233 SM_ENTER(EAP, SUCCESS); 1234 else if (sm->workaround && sm->lastId == -1 && sm->rxSuccess && 1235 !sm->rxFailure && !sm->rxReq && eap_peer_sm_allow_canned(sm)) 1236 SM_ENTER(EAP, SUCCESS); /* EAP-Success prior any EAP method */ 1237 else if (sm->workaround && sm->lastId == -1 && sm->rxFailure && 1238 !sm->rxReq && sm->methodState != METHOD_CONT && 1239 eap_peer_sm_allow_canned(sm)) 1240 SM_ENTER(EAP, FAILURE); /* EAP-Failure prior any EAP method */ 1241 else if (sm->workaround && sm->rxSuccess && !sm->rxFailure && 1242 !sm->rxReq && sm->methodState != METHOD_CONT && 1243 eap_peer_sm_allow_canned(sm)) 1244 SM_ENTER(EAP, SUCCESS); /* EAP-Success after Identity */ 1245 else if (sm->methodState != METHOD_CONT && 1246 ((sm->rxFailure && 1247 sm->decision != DECISION_UNCOND_SUCC) || 1248 (sm->rxSuccess && sm->decision == DECISION_FAIL && 1249 (sm->selectedMethod != EAP_TYPE_LEAP || 1250 sm->methodState != METHOD_MAY_CONT))) && 1251 (sm->reqId == sm->lastId || 1252 eap_success_workaround(sm, sm->reqId, sm->lastId))) 1253 SM_ENTER(EAP, FAILURE); 1254 else if (sm->rxReq && duplicate) 1255 SM_ENTER(EAP, RETRANSMIT); 1256 else if (sm->rxReq && !duplicate && 1257 sm->reqMethod == EAP_TYPE_NOTIFICATION && 1258 sm->allowNotifications) 1259 SM_ENTER(EAP, NOTIFICATION); 1260 else if (sm->rxReq && !duplicate && 1261 sm->selectedMethod == EAP_TYPE_NONE && 1262 sm->reqMethod == EAP_TYPE_IDENTITY) 1263 SM_ENTER(EAP, IDENTITY); 1264 else if (sm->rxReq && !duplicate && 1265 sm->selectedMethod == EAP_TYPE_NONE && 1266 sm->reqMethod != EAP_TYPE_IDENTITY && 1267 sm->reqMethod != EAP_TYPE_NOTIFICATION) 1268 SM_ENTER(EAP, GET_METHOD); 1269 else if (sm->rxReq && !duplicate && 1270 sm->reqMethod == sm->selectedMethod && 1271 sm->methodState != METHOD_DONE) 1272 SM_ENTER(EAP, METHOD); 1273 else if (sm->selectedMethod == EAP_TYPE_LEAP && 1274 (sm->rxSuccess || sm->rxResp)) 1275 SM_ENTER(EAP, METHOD); 1276 else if (sm->reauthInit) 1277 SM_ENTER(EAP, SEND_RESPONSE); 1278 else 1279 SM_ENTER(EAP, DISCARD); 1280 } 1281 1282 1283 static void eap_peer_sm_step_local(struct eap_sm *sm) 1284 { 1285 switch (sm->EAP_state) { 1286 case EAP_INITIALIZE: 1287 SM_ENTER(EAP, IDLE); 1288 break; 1289 case EAP_DISABLED: 1290 if (eapol_get_bool(sm, EAPOL_portEnabled) && 1291 !sm->force_disabled) 1292 SM_ENTER(EAP, INITIALIZE); 1293 break; 1294 case EAP_IDLE: 1295 eap_peer_sm_step_idle(sm); 1296 break; 1297 case EAP_RECEIVED: 1298 eap_peer_sm_step_received(sm); 1299 break; 1300 case EAP_GET_METHOD: 1301 if (sm->selectedMethod == sm->reqMethod) 1302 SM_ENTER(EAP, METHOD); 1303 else 1304 SM_ENTER(EAP, SEND_RESPONSE); 1305 break; 1306 case EAP_METHOD: 1307 /* 1308 * Note: RFC 4137 uses methodState == DONE && decision == FAIL 1309 * as the condition. eapRespData == NULL here is used to allow 1310 * final EAP method response to be sent without having to change 1311 * all methods to either use methodState MAY_CONT or leaving 1312 * decision to something else than FAIL in cases where the only 1313 * expected response is EAP-Failure. 1314 */ 1315 if (sm->ignore) 1316 SM_ENTER(EAP, DISCARD); 1317 else if (sm->methodState == METHOD_DONE && 1318 sm->decision == DECISION_FAIL && !sm->eapRespData) 1319 SM_ENTER(EAP, FAILURE); 1320 else 1321 SM_ENTER(EAP, SEND_RESPONSE); 1322 break; 1323 case EAP_SEND_RESPONSE: 1324 SM_ENTER(EAP, IDLE); 1325 break; 1326 case EAP_DISCARD: 1327 SM_ENTER(EAP, IDLE); 1328 break; 1329 case EAP_IDENTITY: 1330 SM_ENTER(EAP, SEND_RESPONSE); 1331 break; 1332 case EAP_NOTIFICATION: 1333 SM_ENTER(EAP, SEND_RESPONSE); 1334 break; 1335 case EAP_RETRANSMIT: 1336 SM_ENTER(EAP, SEND_RESPONSE); 1337 break; 1338 case EAP_SUCCESS: 1339 break; 1340 case EAP_FAILURE: 1341 break; 1342 } 1343 } 1344 1345 1346 SM_STEP(EAP) 1347 { 1348 /* Global transitions */ 1349 if (eapol_get_bool(sm, EAPOL_eapRestart) && 1350 eapol_get_bool(sm, EAPOL_portEnabled)) 1351 SM_ENTER_GLOBAL(EAP, INITIALIZE); 1352 else if (!eapol_get_bool(sm, EAPOL_portEnabled) || sm->force_disabled) 1353 SM_ENTER_GLOBAL(EAP, DISABLED); 1354 else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) { 1355 /* RFC 4137 does not place any limit on number of EAP messages 1356 * in an authentication session. However, some error cases have 1357 * ended up in a state were EAP messages were sent between the 1358 * peer and server in a loop (e.g., TLS ACK frame in both 1359 * direction). Since this is quite undesired outcome, limit the 1360 * total number of EAP round-trips and abort authentication if 1361 * this limit is exceeded. 1362 */ 1363 if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) { 1364 wpa_msg(sm->msg_ctx, MSG_INFO, "EAP: more than %d " 1365 "authentication rounds - abort", 1366 EAP_MAX_AUTH_ROUNDS); 1367 sm->num_rounds++; 1368 SM_ENTER_GLOBAL(EAP, FAILURE); 1369 } 1370 } else if (sm->num_rounds_short > EAP_MAX_AUTH_ROUNDS_SHORT) { 1371 if (sm->num_rounds_short == EAP_MAX_AUTH_ROUNDS_SHORT + 1) { 1372 wpa_msg(sm->msg_ctx, MSG_INFO, 1373 "EAP: more than %d authentication rounds (short) - abort", 1374 EAP_MAX_AUTH_ROUNDS_SHORT); 1375 sm->num_rounds_short++; 1376 SM_ENTER_GLOBAL(EAP, FAILURE); 1377 } 1378 } else { 1379 /* Local transitions */ 1380 eap_peer_sm_step_local(sm); 1381 } 1382 } 1383 1384 1385 static bool eap_sm_allowMethod(struct eap_sm *sm, int vendor, 1386 enum eap_type method) 1387 { 1388 if (!eap_allowed_method(sm, vendor, method)) { 1389 wpa_printf(MSG_DEBUG, "EAP: configuration does not allow: " 1390 "vendor %u method %u", vendor, method); 1391 return false; 1392 } 1393 if (eap_peer_get_eap_method(vendor, method)) 1394 return true; 1395 wpa_printf(MSG_DEBUG, "EAP: not included in build: " 1396 "vendor %u method %u", vendor, method); 1397 return false; 1398 } 1399 1400 1401 static struct wpabuf * eap_sm_build_expanded_nak( 1402 struct eap_sm *sm, int id, const struct eap_method *methods, 1403 size_t count) 1404 { 1405 struct wpabuf *resp; 1406 int found = 0; 1407 const struct eap_method *m; 1408 1409 wpa_printf(MSG_DEBUG, "EAP: Building expanded EAP-Nak"); 1410 1411 /* RFC 3748 - 5.3.2: Expanded Nak */ 1412 resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_EXPANDED, 1413 8 + 8 * (count + 1), EAP_CODE_RESPONSE, id); 1414 if (resp == NULL) 1415 return NULL; 1416 1417 wpabuf_put_be24(resp, EAP_VENDOR_IETF); 1418 wpabuf_put_be32(resp, EAP_TYPE_NAK); 1419 1420 for (m = methods; m; m = m->next) { 1421 if (sm->reqVendor == m->vendor && 1422 sm->reqVendorMethod == m->method) 1423 continue; /* do not allow the current method again */ 1424 if (eap_allowed_method(sm, m->vendor, m->method)) { 1425 wpa_printf(MSG_DEBUG, "EAP: allowed type: " 1426 "vendor=%u method=%u", 1427 m->vendor, m->method); 1428 wpabuf_put_u8(resp, EAP_TYPE_EXPANDED); 1429 wpabuf_put_be24(resp, m->vendor); 1430 wpabuf_put_be32(resp, m->method); 1431 1432 found++; 1433 } 1434 } 1435 if (!found) { 1436 wpa_printf(MSG_DEBUG, "EAP: no more allowed methods"); 1437 wpabuf_put_u8(resp, EAP_TYPE_EXPANDED); 1438 wpabuf_put_be24(resp, EAP_VENDOR_IETF); 1439 wpabuf_put_be32(resp, EAP_TYPE_NONE); 1440 } 1441 1442 eap_update_len(resp); 1443 1444 return resp; 1445 } 1446 1447 1448 static struct wpabuf * eap_sm_buildNak(struct eap_sm *sm, int id) 1449 { 1450 struct wpabuf *resp; 1451 u8 *start; 1452 int found = 0, expanded_found = 0; 1453 size_t count; 1454 const struct eap_method *methods, *m; 1455 1456 wpa_printf(MSG_DEBUG, "EAP: Building EAP-Nak (requested type %u " 1457 "vendor=%u method=%u not allowed)", sm->reqMethod, 1458 sm->reqVendor, sm->reqVendorMethod); 1459 methods = eap_peer_get_methods(&count); 1460 if (methods == NULL) 1461 return NULL; 1462 if (sm->reqMethod == EAP_TYPE_EXPANDED) 1463 return eap_sm_build_expanded_nak(sm, id, methods, count); 1464 1465 /* RFC 3748 - 5.3.1: Legacy Nak */ 1466 resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_NAK, 1467 sizeof(struct eap_hdr) + 1 + count + 1, 1468 EAP_CODE_RESPONSE, id); 1469 if (resp == NULL) 1470 return NULL; 1471 1472 start = wpabuf_put(resp, 0); 1473 for (m = methods; m; m = m->next) { 1474 if (m->vendor == EAP_VENDOR_IETF && m->method == sm->reqMethod) 1475 continue; /* do not allow the current method again */ 1476 if (eap_allowed_method(sm, m->vendor, m->method)) { 1477 if (m->vendor != EAP_VENDOR_IETF) { 1478 if (expanded_found) 1479 continue; 1480 expanded_found = 1; 1481 wpabuf_put_u8(resp, EAP_TYPE_EXPANDED); 1482 } else 1483 wpabuf_put_u8(resp, m->method); 1484 found++; 1485 } 1486 } 1487 if (!found) 1488 wpabuf_put_u8(resp, EAP_TYPE_NONE); 1489 wpa_hexdump(MSG_DEBUG, "EAP: allowed methods", start, found); 1490 1491 eap_update_len(resp); 1492 1493 return resp; 1494 } 1495 1496 1497 static void eap_sm_processIdentity(struct eap_sm *sm, const struct wpabuf *req) 1498 { 1499 const u8 *pos; 1500 size_t msg_len; 1501 1502 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_STARTED 1503 "EAP authentication started"); 1504 eap_notify_status(sm, "started", ""); 1505 1506 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, req, 1507 &msg_len); 1508 if (pos == NULL) 1509 return; 1510 1511 /* 1512 * RFC 3748 - 5.1: Identity 1513 * Data field may contain a displayable message in UTF-8. If this 1514 * includes NUL-character, only the data before that should be 1515 * displayed. Some EAP implementasitons may piggy-back additional 1516 * options after the NUL. 1517 */ 1518 /* TODO: could save displayable message so that it can be shown to the 1519 * user in case of interaction is required */ 1520 wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Identity data", 1521 pos, msg_len); 1522 } 1523 1524 1525 #ifdef PCSC_FUNCS 1526 1527 /* 1528 * Rules for figuring out MNC length based on IMSI for SIM cards that do not 1529 * include MNC length field. 1530 */ 1531 static int mnc_len_from_imsi(const char *imsi) 1532 { 1533 char mcc_str[4]; 1534 unsigned int mcc; 1535 1536 os_memcpy(mcc_str, imsi, 3); 1537 mcc_str[3] = '\0'; 1538 mcc = atoi(mcc_str); 1539 1540 if (mcc == 228) 1541 return 2; /* Networks in Switzerland use 2-digit MNC */ 1542 if (mcc == 244) 1543 return 2; /* Networks in Finland use 2-digit MNC */ 1544 1545 return -1; 1546 } 1547 1548 1549 static int eap_sm_imsi_identity(struct eap_sm *sm, 1550 struct eap_peer_config *conf) 1551 { 1552 enum { EAP_SM_SIM, EAP_SM_AKA, EAP_SM_AKA_PRIME } method = EAP_SM_SIM; 1553 char imsi[100]; 1554 size_t imsi_len; 1555 struct eap_method_type *m = conf->eap_methods; 1556 int i, mnc_len; 1557 1558 imsi_len = sizeof(imsi); 1559 if (scard_get_imsi(sm->scard_ctx, imsi, &imsi_len)) { 1560 wpa_printf(MSG_WARNING, "Failed to get IMSI from SIM"); 1561 return -1; 1562 } 1563 1564 wpa_hexdump_ascii(MSG_DEBUG, "IMSI", (u8 *) imsi, imsi_len); 1565 1566 if (imsi_len < 7) { 1567 wpa_printf(MSG_WARNING, "Too short IMSI for SIM identity"); 1568 return -1; 1569 } 1570 1571 /* MNC (2 or 3 digits) */ 1572 mnc_len = scard_get_mnc_len(sm->scard_ctx); 1573 if (mnc_len < 0) 1574 mnc_len = mnc_len_from_imsi(imsi); 1575 if (mnc_len < 0) { 1576 wpa_printf(MSG_INFO, "Failed to get MNC length from (U)SIM " 1577 "assuming 3"); 1578 mnc_len = 3; 1579 } 1580 1581 if (eap_sm_append_3gpp_realm(sm, imsi, sizeof(imsi), &imsi_len, 1582 mnc_len) < 0) { 1583 wpa_printf(MSG_WARNING, "Could not add realm to SIM identity"); 1584 return -1; 1585 } 1586 wpa_hexdump_ascii(MSG_DEBUG, "IMSI + realm", (u8 *) imsi, imsi_len); 1587 1588 for (i = 0; m && (m[i].vendor != EAP_VENDOR_IETF || 1589 m[i].method != EAP_TYPE_NONE); i++) { 1590 if (m[i].vendor == EAP_VENDOR_IETF && 1591 m[i].method == EAP_TYPE_AKA_PRIME) { 1592 method = EAP_SM_AKA_PRIME; 1593 break; 1594 } 1595 1596 if (m[i].vendor == EAP_VENDOR_IETF && 1597 m[i].method == EAP_TYPE_AKA) { 1598 method = EAP_SM_AKA; 1599 break; 1600 } 1601 } 1602 1603 os_free(conf->identity); 1604 conf->identity = os_malloc(1 + imsi_len); 1605 if (conf->identity == NULL) { 1606 wpa_printf(MSG_WARNING, "Failed to allocate buffer for " 1607 "IMSI-based identity"); 1608 return -1; 1609 } 1610 1611 switch (method) { 1612 case EAP_SM_SIM: 1613 conf->identity[0] = '1'; 1614 break; 1615 case EAP_SM_AKA: 1616 conf->identity[0] = '0'; 1617 break; 1618 case EAP_SM_AKA_PRIME: 1619 conf->identity[0] = '6'; 1620 break; 1621 } 1622 os_memcpy(conf->identity + 1, imsi, imsi_len); 1623 conf->identity_len = 1 + imsi_len; 1624 1625 return 0; 1626 } 1627 1628 1629 static int eap_sm_set_scard_pin(struct eap_sm *sm, 1630 struct eap_peer_config *conf) 1631 { 1632 if (scard_set_pin(sm->scard_ctx, conf->cert.pin)) { 1633 /* 1634 * Make sure the same PIN is not tried again in order to avoid 1635 * blocking SIM. 1636 */ 1637 os_free(conf->cert.pin); 1638 conf->cert.pin = NULL; 1639 1640 wpa_printf(MSG_WARNING, "PIN validation failed"); 1641 eap_sm_request_pin(sm); 1642 return -1; 1643 } 1644 return 0; 1645 } 1646 1647 1648 static int eap_sm_get_scard_identity(struct eap_sm *sm, 1649 struct eap_peer_config *conf) 1650 { 1651 if (eap_sm_set_scard_pin(sm, conf)) 1652 return -1; 1653 1654 return eap_sm_imsi_identity(sm, conf); 1655 } 1656 1657 #endif /* PCSC_FUNCS */ 1658 1659 1660 /** 1661 * eap_sm_buildIdentity - Build EAP-Identity/Response for the current network 1662 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 1663 * @id: EAP identifier for the packet 1664 * @encrypted: Whether the packet is for encrypted tunnel (EAP phase 2) 1665 * Returns: Pointer to the allocated EAP-Identity/Response packet or %NULL on 1666 * failure 1667 * 1668 * This function allocates and builds an EAP-Identity/Response packet for the 1669 * current network. The caller is responsible for freeing the returned data. 1670 */ 1671 struct wpabuf * eap_sm_buildIdentity(struct eap_sm *sm, int id, int encrypted) 1672 { 1673 struct eap_peer_config *config = eap_get_config(sm); 1674 struct wpabuf *resp; 1675 const u8 *identity; 1676 size_t identity_len; 1677 struct wpabuf *privacy_identity = NULL; 1678 1679 if (config == NULL) { 1680 wpa_printf(MSG_WARNING, "EAP: buildIdentity: configuration " 1681 "was not available"); 1682 return NULL; 1683 } 1684 1685 if (sm->m && sm->m->get_identity && 1686 (identity = sm->m->get_identity(sm, sm->eap_method_priv, 1687 &identity_len)) != NULL) { 1688 wpa_hexdump_ascii(MSG_DEBUG, "EAP: using method re-auth " 1689 "identity", identity, identity_len); 1690 } else if (!encrypted && config->anonymous_identity) { 1691 identity = config->anonymous_identity; 1692 identity_len = config->anonymous_identity_len; 1693 wpa_hexdump_ascii(MSG_DEBUG, "EAP: using anonymous identity", 1694 identity, identity_len); 1695 } else if (sm->use_machine_cred) { 1696 identity = config->machine_identity; 1697 identity_len = config->machine_identity_len; 1698 wpa_hexdump_ascii(MSG_DEBUG, "EAP: using machine identity", 1699 identity, identity_len); 1700 } else if (config->imsi_privacy_cert && config->identity && 1701 config->identity_len > 0) { 1702 const u8 *pos = config->identity; 1703 const u8 *end = config->identity + config->identity_len; 1704 1705 privacy_identity = wpabuf_alloc(9 + config->identity_len); 1706 if (!privacy_identity) 1707 return NULL; 1708 1709 /* Include method prefix */ 1710 if (*pos == '0' || *pos == '1' || *pos == '6') 1711 wpabuf_put_u8(privacy_identity, *pos); 1712 wpabuf_put_str(privacy_identity, "anonymous"); 1713 1714 /* Include realm */ 1715 while (pos < end && *pos != '@') 1716 pos++; 1717 wpabuf_put_data(privacy_identity, pos, end - pos); 1718 1719 identity = wpabuf_head(privacy_identity); 1720 identity_len = wpabuf_len(privacy_identity); 1721 wpa_hexdump_ascii(MSG_DEBUG, 1722 "EAP: using IMSI privacy anonymous identity", 1723 identity, identity_len); 1724 } else { 1725 identity = config->identity; 1726 identity_len = config->identity_len; 1727 wpa_hexdump_ascii(MSG_DEBUG, "EAP: using real identity", 1728 identity, identity_len); 1729 } 1730 1731 if (config->pcsc) { 1732 #ifdef PCSC_FUNCS 1733 if (!identity) { 1734 if (eap_sm_get_scard_identity(sm, config) < 0) 1735 return NULL; 1736 identity = config->identity; 1737 identity_len = config->identity_len; 1738 wpa_hexdump_ascii(MSG_DEBUG, 1739 "permanent identity from IMSI", 1740 identity, identity_len); 1741 } else if (eap_sm_set_scard_pin(sm, config) < 0) { 1742 return NULL; 1743 } 1744 #else /* PCSC_FUNCS */ 1745 return NULL; 1746 #endif /* PCSC_FUNCS */ 1747 } else if (!identity) { 1748 wpa_printf(MSG_WARNING, 1749 "EAP: buildIdentity: identity configuration was not available"); 1750 eap_sm_request_identity(sm); 1751 return NULL; 1752 } 1753 1754 resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, identity_len, 1755 EAP_CODE_RESPONSE, id); 1756 if (resp == NULL) 1757 return NULL; 1758 1759 wpabuf_put_data(resp, identity, identity_len); 1760 1761 os_free(sm->identity); 1762 sm->identity = os_memdup(identity, identity_len); 1763 sm->identity_len = identity_len; 1764 1765 wpabuf_free(privacy_identity); 1766 1767 return resp; 1768 } 1769 1770 1771 static void eap_sm_processNotify(struct eap_sm *sm, const struct wpabuf *req) 1772 { 1773 const u8 *pos; 1774 char *msg; 1775 size_t i, msg_len; 1776 1777 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_NOTIFICATION, req, 1778 &msg_len); 1779 if (pos == NULL) 1780 return; 1781 wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Notification data", 1782 pos, msg_len); 1783 1784 msg = os_malloc(msg_len + 1); 1785 if (msg == NULL) 1786 return; 1787 for (i = 0; i < msg_len; i++) 1788 msg[i] = isprint(pos[i]) ? (char) pos[i] : '_'; 1789 msg[msg_len] = '\0'; 1790 wpa_msg(sm->msg_ctx, MSG_INFO, "%s%s", 1791 WPA_EVENT_EAP_NOTIFICATION, msg); 1792 os_free(msg); 1793 } 1794 1795 1796 static struct wpabuf * eap_sm_buildNotify(int id) 1797 { 1798 wpa_printf(MSG_DEBUG, "EAP: Generating EAP-Response Notification"); 1799 return eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_NOTIFICATION, 0, 1800 EAP_CODE_RESPONSE, id); 1801 } 1802 1803 1804 static void eap_peer_initiate(struct eap_sm *sm, const struct eap_hdr *hdr, 1805 size_t len) 1806 { 1807 #ifdef CONFIG_ERP 1808 const u8 *pos = (const u8 *) (hdr + 1); 1809 const u8 *end = ((const u8 *) hdr) + len; 1810 struct erp_tlvs parse; 1811 1812 if (len < sizeof(*hdr) + 1) { 1813 wpa_printf(MSG_DEBUG, "EAP: Ignored too short EAP-Initiate"); 1814 return; 1815 } 1816 1817 if (*pos != EAP_ERP_TYPE_REAUTH_START) { 1818 wpa_printf(MSG_DEBUG, 1819 "EAP: Ignored unexpected EAP-Initiate Type=%u", 1820 *pos); 1821 return; 1822 } 1823 1824 pos++; 1825 if (pos >= end) { 1826 wpa_printf(MSG_DEBUG, 1827 "EAP: Too short EAP-Initiate/Re-auth-Start"); 1828 return; 1829 } 1830 pos++; /* Reserved */ 1831 wpa_hexdump(MSG_DEBUG, "EAP: EAP-Initiate/Re-auth-Start TVs/TLVs", 1832 pos, end - pos); 1833 1834 if (erp_parse_tlvs(pos, end, &parse, 0) < 0) 1835 goto invalid; 1836 1837 if (parse.domain) { 1838 wpa_hexdump_ascii(MSG_DEBUG, 1839 "EAP: EAP-Initiate/Re-auth-Start - Domain name", 1840 parse.domain, parse.domain_len); 1841 /* TODO: Derivation of domain specific keys for local ER */ 1842 } 1843 1844 if (eap_peer_erp_reauth_start(sm, hdr->identifier) == 0) 1845 return; 1846 1847 invalid: 1848 #endif /* CONFIG_ERP */ 1849 wpa_printf(MSG_DEBUG, 1850 "EAP: EAP-Initiate/Re-auth-Start - No suitable ERP keys available - try to start full EAP authentication"); 1851 eapol_set_bool(sm, EAPOL_eapTriggerStart, true); 1852 } 1853 1854 1855 void eap_peer_finish(struct eap_sm *sm, const struct eap_hdr *hdr, size_t len) 1856 { 1857 #ifdef CONFIG_ERP 1858 const u8 *pos = (const u8 *) (hdr + 1); 1859 const u8 *end = ((const u8 *) hdr) + len; 1860 const u8 *start; 1861 struct erp_tlvs parse; 1862 u8 flags; 1863 u16 seq; 1864 u8 hash[SHA256_MAC_LEN]; 1865 size_t hash_len; 1866 struct eap_erp_key *erp; 1867 int max_len; 1868 char nai[254]; 1869 u8 seed[4]; 1870 int auth_tag_ok = 0; 1871 1872 if (len < sizeof(*hdr) + 1) { 1873 wpa_printf(MSG_DEBUG, "EAP: Ignored too short EAP-Finish"); 1874 return; 1875 } 1876 1877 if (*pos != EAP_ERP_TYPE_REAUTH) { 1878 wpa_printf(MSG_DEBUG, 1879 "EAP: Ignored unexpected EAP-Finish Type=%u", *pos); 1880 return; 1881 } 1882 1883 if (len < sizeof(*hdr) + 4) { 1884 wpa_printf(MSG_DEBUG, 1885 "EAP: Ignored too short EAP-Finish/Re-auth"); 1886 return; 1887 } 1888 1889 pos++; 1890 flags = *pos++; 1891 seq = WPA_GET_BE16(pos); 1892 pos += 2; 1893 wpa_printf(MSG_DEBUG, "EAP: Flags=0x%x SEQ=%u", flags, seq); 1894 1895 if (seq != sm->erp_seq) { 1896 wpa_printf(MSG_DEBUG, 1897 "EAP: Unexpected EAP-Finish/Re-auth SEQ=%u", seq); 1898 return; 1899 } 1900 1901 /* 1902 * Parse TVs/TLVs. Since we do not yet know the length of the 1903 * Authentication Tag, stop parsing if an unknown TV/TLV is seen and 1904 * just try to find the keyName-NAI first so that we can check the 1905 * Authentication Tag. 1906 */ 1907 if (erp_parse_tlvs(pos, end, &parse, 1) < 0) 1908 return; 1909 1910 if (!parse.keyname) { 1911 wpa_printf(MSG_DEBUG, 1912 "EAP: No keyName-NAI in EAP-Finish/Re-auth Packet"); 1913 return; 1914 } 1915 1916 wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Finish/Re-auth - keyName-NAI", 1917 parse.keyname, parse.keyname_len); 1918 if (parse.keyname_len > 253) { 1919 wpa_printf(MSG_DEBUG, 1920 "EAP: Too long keyName-NAI in EAP-Finish/Re-auth"); 1921 return; 1922 } 1923 os_memcpy(nai, parse.keyname, parse.keyname_len); 1924 nai[parse.keyname_len] = '\0'; 1925 1926 erp = eap_erp_get_key_nai(sm, nai); 1927 if (!erp) { 1928 wpa_printf(MSG_DEBUG, "EAP: No matching ERP key found for %s", 1929 nai); 1930 return; 1931 } 1932 1933 /* Is there enough room for Cryptosuite and Authentication Tag? */ 1934 start = parse.keyname + parse.keyname_len; 1935 max_len = end - start; 1936 hash_len = 16; 1937 if (max_len < 1 + (int) hash_len) { 1938 wpa_printf(MSG_DEBUG, 1939 "EAP: Not enough room for Authentication Tag"); 1940 if (flags & 0x80) 1941 goto no_auth_tag; 1942 return; 1943 } 1944 if (end[-17] != EAP_ERP_CS_HMAC_SHA256_128) { 1945 wpa_printf(MSG_DEBUG, "EAP: Different Cryptosuite used"); 1946 if (flags & 0x80) 1947 goto no_auth_tag; 1948 return; 1949 } 1950 1951 if (hmac_sha256(erp->rIK, erp->rIK_len, (const u8 *) hdr, 1952 end - ((const u8 *) hdr) - hash_len, hash) < 0) 1953 return; 1954 if (os_memcmp(end - hash_len, hash, hash_len) != 0) { 1955 wpa_printf(MSG_DEBUG, 1956 "EAP: Authentication Tag mismatch"); 1957 return; 1958 } 1959 auth_tag_ok = 1; 1960 end -= 1 + hash_len; 1961 1962 no_auth_tag: 1963 /* 1964 * Parse TVs/TLVs again now that we know the exact part of the buffer 1965 * that contains them. 1966 */ 1967 wpa_hexdump(MSG_DEBUG, "EAP: EAP-Finish/Re-Auth TVs/TLVs", 1968 pos, end - pos); 1969 if (erp_parse_tlvs(pos, end, &parse, 0) < 0) 1970 return; 1971 1972 if (flags & 0x80 || !auth_tag_ok) { 1973 wpa_printf(MSG_DEBUG, 1974 "EAP: EAP-Finish/Re-auth indicated failure"); 1975 eapol_set_bool(sm, EAPOL_eapFail, true); 1976 eapol_set_bool(sm, EAPOL_eapReq, false); 1977 eapol_set_bool(sm, EAPOL_eapNoResp, true); 1978 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE 1979 "EAP authentication failed"); 1980 sm->prev_failure = 1; 1981 wpa_printf(MSG_DEBUG, 1982 "EAP: Drop ERP key to try full authentication on next attempt"); 1983 eap_peer_erp_free_key(erp); 1984 return; 1985 } 1986 1987 eap_sm_free_key(sm); 1988 sm->eapKeyDataLen = 0; 1989 sm->eapKeyData = os_malloc(erp->rRK_len); 1990 if (!sm->eapKeyData) 1991 return; 1992 sm->eapKeyDataLen = erp->rRK_len; 1993 1994 WPA_PUT_BE16(seed, seq); 1995 WPA_PUT_BE16(&seed[2], erp->rRK_len); 1996 if (hmac_sha256_kdf(erp->rRK, erp->rRK_len, 1997 "Re-authentication Master Session Key@ietf.org", 1998 seed, sizeof(seed), 1999 sm->eapKeyData, erp->rRK_len) < 0) { 2000 wpa_printf(MSG_DEBUG, "EAP: Could not derive rMSK for ERP"); 2001 eap_sm_free_key(sm); 2002 return; 2003 } 2004 wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rMSK", 2005 sm->eapKeyData, sm->eapKeyDataLen); 2006 sm->eapKeyAvailable = true; 2007 eapol_set_bool(sm, EAPOL_eapSuccess, true); 2008 eapol_set_bool(sm, EAPOL_eapReq, false); 2009 eapol_set_bool(sm, EAPOL_eapNoResp, true); 2010 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS 2011 "EAP re-authentication completed successfully"); 2012 #endif /* CONFIG_ERP */ 2013 } 2014 2015 2016 static void eap_sm_parseEapReq(struct eap_sm *sm, const struct wpabuf *req) 2017 { 2018 const struct eap_hdr *hdr; 2019 size_t plen; 2020 const u8 *pos; 2021 2022 sm->rxReq = sm->rxResp = sm->rxSuccess = sm->rxFailure = false; 2023 sm->reqId = 0; 2024 sm->reqMethod = EAP_TYPE_NONE; 2025 sm->reqVendor = EAP_VENDOR_IETF; 2026 sm->reqVendorMethod = EAP_TYPE_NONE; 2027 2028 if (req == NULL || wpabuf_len(req) < sizeof(*hdr)) 2029 return; 2030 2031 hdr = wpabuf_head(req); 2032 plen = be_to_host16(hdr->length); 2033 if (plen > wpabuf_len(req)) { 2034 wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet " 2035 "(len=%lu plen=%lu)", 2036 (unsigned long) wpabuf_len(req), 2037 (unsigned long) plen); 2038 return; 2039 } 2040 2041 sm->reqId = hdr->identifier; 2042 2043 if (sm->workaround) { 2044 const u8 *addr[1]; 2045 addr[0] = wpabuf_head(req); 2046 sha1_vector(1, addr, &plen, sm->req_sha1); 2047 } 2048 2049 switch (hdr->code) { 2050 case EAP_CODE_REQUEST: 2051 if (plen < sizeof(*hdr) + 1) { 2052 wpa_printf(MSG_DEBUG, "EAP: Too short EAP-Request - " 2053 "no Type field"); 2054 return; 2055 } 2056 sm->rxReq = true; 2057 pos = (const u8 *) (hdr + 1); 2058 sm->reqMethod = *pos++; 2059 if (sm->reqMethod == EAP_TYPE_EXPANDED) { 2060 if (plen < sizeof(*hdr) + 8) { 2061 wpa_printf(MSG_DEBUG, "EAP: Ignored truncated " 2062 "expanded EAP-Packet (plen=%lu)", 2063 (unsigned long) plen); 2064 return; 2065 } 2066 sm->reqVendor = WPA_GET_BE24(pos); 2067 pos += 3; 2068 sm->reqVendorMethod = WPA_GET_BE32(pos); 2069 } 2070 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Request id=%d " 2071 "method=%u vendor=%u vendorMethod=%u", 2072 sm->reqId, sm->reqMethod, sm->reqVendor, 2073 sm->reqVendorMethod); 2074 break; 2075 case EAP_CODE_RESPONSE: 2076 if (sm->selectedMethod == EAP_TYPE_LEAP) { 2077 /* 2078 * LEAP differs from RFC 4137 by using reversed roles 2079 * for mutual authentication and because of this, we 2080 * need to accept EAP-Response frames if LEAP is used. 2081 */ 2082 if (plen < sizeof(*hdr) + 1) { 2083 wpa_printf(MSG_DEBUG, "EAP: Too short " 2084 "EAP-Response - no Type field"); 2085 return; 2086 } 2087 sm->rxResp = true; 2088 pos = (const u8 *) (hdr + 1); 2089 sm->reqMethod = *pos; 2090 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Response for " 2091 "LEAP method=%d id=%d", 2092 sm->reqMethod, sm->reqId); 2093 break; 2094 } 2095 wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Response"); 2096 break; 2097 case EAP_CODE_SUCCESS: 2098 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Success"); 2099 eap_notify_status(sm, "completion", "success"); 2100 sm->rxSuccess = true; 2101 break; 2102 case EAP_CODE_FAILURE: 2103 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Failure"); 2104 eap_notify_status(sm, "completion", "failure"); 2105 2106 /* Get the error code from method */ 2107 if (sm->m && sm->m->get_error_code) { 2108 int error_code; 2109 2110 error_code = sm->m->get_error_code(sm->eap_method_priv); 2111 if (error_code != NO_EAP_METHOD_ERROR) 2112 eap_report_error(sm, error_code); 2113 } 2114 sm->rxFailure = true; 2115 break; 2116 case EAP_CODE_INITIATE: 2117 eap_peer_initiate(sm, hdr, plen); 2118 break; 2119 case EAP_CODE_FINISH: 2120 eap_peer_finish(sm, hdr, plen); 2121 break; 2122 default: 2123 wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Packet with unknown " 2124 "code %d", hdr->code); 2125 break; 2126 } 2127 } 2128 2129 2130 static void eap_peer_sm_tls_event(void *ctx, enum tls_event ev, 2131 union tls_event_data *data) 2132 { 2133 struct eap_sm *sm = ctx; 2134 char *hash_hex = NULL; 2135 2136 switch (ev) { 2137 case TLS_CERT_CHAIN_SUCCESS: 2138 eap_notify_status(sm, "remote certificate verification", 2139 "success"); 2140 if (sm->ext_cert_check) { 2141 sm->waiting_ext_cert_check = 1; 2142 eap_sm_request(sm, WPA_CTRL_REQ_EXT_CERT_CHECK, 2143 NULL, 0); 2144 } 2145 break; 2146 case TLS_CERT_CHAIN_FAILURE: 2147 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_TLS_CERT_ERROR 2148 "reason=%d depth=%d subject='%s' err='%s'", 2149 data->cert_fail.reason, 2150 data->cert_fail.depth, 2151 data->cert_fail.subject, 2152 data->cert_fail.reason_txt); 2153 eap_notify_status(sm, "remote certificate verification", 2154 data->cert_fail.reason_txt); 2155 break; 2156 case TLS_PEER_CERTIFICATE: 2157 if (!sm->eapol_cb->notify_cert) 2158 break; 2159 2160 if (data->peer_cert.hash) { 2161 size_t len = data->peer_cert.hash_len * 2 + 1; 2162 hash_hex = os_malloc(len); 2163 if (hash_hex) { 2164 wpa_snprintf_hex(hash_hex, len, 2165 data->peer_cert.hash, 2166 data->peer_cert.hash_len); 2167 } 2168 } 2169 2170 sm->eapol_cb->notify_cert(sm->eapol_ctx, &data->peer_cert, 2171 hash_hex); 2172 break; 2173 case TLS_ALERT: 2174 if (data->alert.is_local) 2175 eap_notify_status(sm, "local TLS alert", 2176 data->alert.description); 2177 else 2178 eap_notify_status(sm, "remote TLS alert", 2179 data->alert.description); 2180 break; 2181 case TLS_UNSAFE_RENEGOTIATION_DISABLED: 2182 wpa_printf(MSG_INFO, 2183 "TLS handshake failed due to the server not supporting safe renegotiation (RFC 5746); phase1 parameter allow_unsafe_renegotiation=1 can be used to work around this"); 2184 eap_notify_status(sm, "unsafe server renegotiation", "failure"); 2185 break; 2186 } 2187 2188 os_free(hash_hex); 2189 } 2190 2191 2192 /** 2193 * eap_peer_sm_init - Allocate and initialize EAP peer state machine 2194 * @eapol_ctx: Context data to be used with eapol_cb calls 2195 * @eapol_cb: Pointer to EAPOL callback functions 2196 * @msg_ctx: Context data for wpa_msg() calls 2197 * @conf: EAP configuration 2198 * Returns: Pointer to the allocated EAP state machine or %NULL on failure 2199 * 2200 * This function allocates and initializes an EAP state machine. In addition, 2201 * this initializes TLS library for the new EAP state machine. eapol_cb pointer 2202 * will be in use until eap_peer_sm_deinit() is used to deinitialize this EAP 2203 * state machine. Consequently, the caller must make sure that this data 2204 * structure remains alive while the EAP state machine is active. 2205 */ 2206 struct eap_sm * eap_peer_sm_init(void *eapol_ctx, 2207 const struct eapol_callbacks *eapol_cb, 2208 void *msg_ctx, struct eap_config *conf) 2209 { 2210 struct eap_sm *sm; 2211 struct tls_config tlsconf; 2212 2213 sm = os_zalloc(sizeof(*sm)); 2214 if (sm == NULL) 2215 return NULL; 2216 sm->eapol_ctx = eapol_ctx; 2217 sm->eapol_cb = eapol_cb; 2218 sm->msg_ctx = msg_ctx; 2219 sm->ClientTimeout = EAP_CLIENT_TIMEOUT_DEFAULT; 2220 sm->wps = conf->wps; 2221 dl_list_init(&sm->erp_keys); 2222 2223 os_memset(&tlsconf, 0, sizeof(tlsconf)); 2224 #ifndef CONFIG_OPENSC_ENGINE_PATH 2225 tlsconf.opensc_engine_path = conf->opensc_engine_path; 2226 #endif /* CONFIG_OPENSC_ENGINE_PATH */ 2227 #ifndef CONFIG_PKCS11_ENGINE_PATH 2228 tlsconf.pkcs11_engine_path = conf->pkcs11_engine_path; 2229 #endif /* CONFIG_PKCS11_ENGINE_PATH */ 2230 #ifndef CONFIG_PKCS11_MODULE_PATH 2231 tlsconf.pkcs11_module_path = conf->pkcs11_module_path; 2232 #endif /* CONFIG_PKCS11_MODULE_PATH */ 2233 tlsconf.openssl_ciphers = conf->openssl_ciphers; 2234 #ifdef CONFIG_FIPS 2235 tlsconf.fips_mode = 1; 2236 #endif /* CONFIG_FIPS */ 2237 tlsconf.event_cb = eap_peer_sm_tls_event; 2238 tlsconf.cb_ctx = sm; 2239 tlsconf.cert_in_cb = conf->cert_in_cb; 2240 sm->ssl_ctx = tls_init(&tlsconf); 2241 if (sm->ssl_ctx == NULL) { 2242 wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS " 2243 "context."); 2244 os_free(sm); 2245 return NULL; 2246 } 2247 2248 sm->ssl_ctx2 = tls_init(&tlsconf); 2249 if (sm->ssl_ctx2 == NULL) { 2250 wpa_printf(MSG_INFO, "SSL: Failed to initialize TLS " 2251 "context (2)."); 2252 /* Run without separate TLS context within TLS tunnel */ 2253 } 2254 2255 return sm; 2256 } 2257 2258 2259 /** 2260 * eap_peer_sm_deinit - Deinitialize and free an EAP peer state machine 2261 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2262 * 2263 * This function deinitializes EAP state machine and frees all allocated 2264 * resources. 2265 */ 2266 void eap_peer_sm_deinit(struct eap_sm *sm) 2267 { 2268 if (sm == NULL) 2269 return; 2270 eap_deinit_prev_method(sm, "EAP deinit"); 2271 eap_sm_abort(sm); 2272 if (sm->ssl_ctx2) 2273 tls_deinit(sm->ssl_ctx2); 2274 tls_deinit(sm->ssl_ctx); 2275 eap_peer_erp_free_keys(sm); 2276 os_free(sm->identity); 2277 os_free(sm); 2278 } 2279 2280 2281 /** 2282 * eap_peer_sm_step - Step EAP peer state machine 2283 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2284 * Returns: 1 if EAP state was changed or 0 if not 2285 * 2286 * This function advances EAP state machine to a new state to match with the 2287 * current variables. This should be called whenever variables used by the EAP 2288 * state machine have changed. 2289 */ 2290 int eap_peer_sm_step(struct eap_sm *sm) 2291 { 2292 int res = 0; 2293 do { 2294 sm->changed = false; 2295 SM_STEP_RUN(EAP); 2296 if (sm->changed) 2297 res = 1; 2298 } while (sm->changed); 2299 return res; 2300 } 2301 2302 2303 /** 2304 * eap_sm_abort - Abort EAP authentication 2305 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2306 * 2307 * Release system resources that have been allocated for the authentication 2308 * session without fully deinitializing the EAP state machine. 2309 */ 2310 void eap_sm_abort(struct eap_sm *sm) 2311 { 2312 wpabuf_free(sm->lastRespData); 2313 sm->lastRespData = NULL; 2314 wpabuf_free(sm->eapRespData); 2315 sm->eapRespData = NULL; 2316 eap_sm_free_key(sm); 2317 os_free(sm->eapSessionId); 2318 sm->eapSessionId = NULL; 2319 2320 /* This is not clearly specified in the EAP statemachines draft, but 2321 * it seems necessary to make sure that some of the EAPOL variables get 2322 * cleared for the next authentication. */ 2323 eapol_set_bool(sm, EAPOL_eapSuccess, false); 2324 } 2325 2326 2327 #ifdef CONFIG_CTRL_IFACE 2328 static const char * eap_sm_state_txt(int state) 2329 { 2330 switch (state) { 2331 case EAP_INITIALIZE: 2332 return "INITIALIZE"; 2333 case EAP_DISABLED: 2334 return "DISABLED"; 2335 case EAP_IDLE: 2336 return "IDLE"; 2337 case EAP_RECEIVED: 2338 return "RECEIVED"; 2339 case EAP_GET_METHOD: 2340 return "GET_METHOD"; 2341 case EAP_METHOD: 2342 return "METHOD"; 2343 case EAP_SEND_RESPONSE: 2344 return "SEND_RESPONSE"; 2345 case EAP_DISCARD: 2346 return "DISCARD"; 2347 case EAP_IDENTITY: 2348 return "IDENTITY"; 2349 case EAP_NOTIFICATION: 2350 return "NOTIFICATION"; 2351 case EAP_RETRANSMIT: 2352 return "RETRANSMIT"; 2353 case EAP_SUCCESS: 2354 return "SUCCESS"; 2355 case EAP_FAILURE: 2356 return "FAILURE"; 2357 default: 2358 return "UNKNOWN"; 2359 } 2360 } 2361 #endif /* CONFIG_CTRL_IFACE */ 2362 2363 2364 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 2365 static const char * eap_sm_method_state_txt(EapMethodState state) 2366 { 2367 switch (state) { 2368 case METHOD_NONE: 2369 return "NONE"; 2370 case METHOD_INIT: 2371 return "INIT"; 2372 case METHOD_CONT: 2373 return "CONT"; 2374 case METHOD_MAY_CONT: 2375 return "MAY_CONT"; 2376 case METHOD_DONE: 2377 return "DONE"; 2378 default: 2379 return "UNKNOWN"; 2380 } 2381 } 2382 2383 2384 static const char * eap_sm_decision_txt(EapDecision decision) 2385 { 2386 switch (decision) { 2387 case DECISION_FAIL: 2388 return "FAIL"; 2389 case DECISION_COND_SUCC: 2390 return "COND_SUCC"; 2391 case DECISION_UNCOND_SUCC: 2392 return "UNCOND_SUCC"; 2393 default: 2394 return "UNKNOWN"; 2395 } 2396 } 2397 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 2398 2399 2400 #ifdef CONFIG_CTRL_IFACE 2401 2402 /** 2403 * eap_sm_get_status - Get EAP state machine status 2404 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2405 * @buf: Buffer for status information 2406 * @buflen: Maximum buffer length 2407 * @verbose: Whether to include verbose status information 2408 * Returns: Number of bytes written to buf. 2409 * 2410 * Query EAP state machine for status information. This function fills in a 2411 * text area with current status information from the EAPOL state machine. If 2412 * the buffer (buf) is not large enough, status information will be truncated 2413 * to fit the buffer. 2414 */ 2415 int eap_sm_get_status(struct eap_sm *sm, char *buf, size_t buflen, int verbose) 2416 { 2417 int len, ret; 2418 2419 if (sm == NULL) 2420 return 0; 2421 2422 len = os_snprintf(buf, buflen, 2423 "EAP state=%s\n", 2424 eap_sm_state_txt(sm->EAP_state)); 2425 if (os_snprintf_error(buflen, len)) 2426 return 0; 2427 2428 if (sm->selectedMethod != EAP_TYPE_NONE) { 2429 const char *name; 2430 if (sm->m) { 2431 name = sm->m->name; 2432 } else { 2433 const struct eap_method *m = 2434 eap_peer_get_eap_method(EAP_VENDOR_IETF, 2435 sm->selectedMethod); 2436 if (m) 2437 name = m->name; 2438 else 2439 name = "?"; 2440 } 2441 ret = os_snprintf(buf + len, buflen - len, 2442 "selectedMethod=%d (EAP-%s)\n", 2443 sm->selectedMethod, name); 2444 if (os_snprintf_error(buflen - len, ret)) 2445 return len; 2446 len += ret; 2447 2448 if (sm->m && sm->m->get_status) { 2449 len += sm->m->get_status(sm, sm->eap_method_priv, 2450 buf + len, buflen - len, 2451 verbose); 2452 } 2453 } 2454 2455 if (verbose) { 2456 ret = os_snprintf(buf + len, buflen - len, 2457 "reqMethod=%d\n" 2458 "methodState=%s\n" 2459 "decision=%s\n" 2460 "ClientTimeout=%d\n", 2461 sm->reqMethod, 2462 eap_sm_method_state_txt(sm->methodState), 2463 eap_sm_decision_txt(sm->decision), 2464 sm->ClientTimeout); 2465 if (os_snprintf_error(buflen - len, ret)) 2466 return len; 2467 len += ret; 2468 } 2469 2470 return len; 2471 } 2472 #endif /* CONFIG_CTRL_IFACE */ 2473 2474 2475 static void eap_sm_request(struct eap_sm *sm, enum wpa_ctrl_req_type field, 2476 const char *msg, size_t msglen) 2477 { 2478 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 2479 struct eap_peer_config *config; 2480 const char *txt = NULL; 2481 char *tmp; 2482 2483 if (sm == NULL) 2484 return; 2485 config = eap_get_config(sm); 2486 if (config == NULL) 2487 return; 2488 2489 switch (field) { 2490 case WPA_CTRL_REQ_EAP_IDENTITY: 2491 config->pending_req_identity++; 2492 break; 2493 case WPA_CTRL_REQ_EAP_PASSWORD: 2494 config->pending_req_password++; 2495 break; 2496 case WPA_CTRL_REQ_EAP_NEW_PASSWORD: 2497 config->pending_req_new_password++; 2498 break; 2499 case WPA_CTRL_REQ_EAP_PIN: 2500 config->pending_req_pin++; 2501 break; 2502 case WPA_CTRL_REQ_EAP_OTP: 2503 if (msg) { 2504 tmp = os_malloc(msglen + 3); 2505 if (tmp == NULL) 2506 return; 2507 tmp[0] = '['; 2508 os_memcpy(tmp + 1, msg, msglen); 2509 tmp[msglen + 1] = ']'; 2510 tmp[msglen + 2] = '\0'; 2511 txt = tmp; 2512 os_free(config->pending_req_otp); 2513 config->pending_req_otp = tmp; 2514 config->pending_req_otp_len = msglen + 3; 2515 } else { 2516 if (config->pending_req_otp == NULL) 2517 return; 2518 txt = config->pending_req_otp; 2519 } 2520 break; 2521 case WPA_CTRL_REQ_EAP_PASSPHRASE: 2522 config->pending_req_passphrase++; 2523 break; 2524 case WPA_CTRL_REQ_SIM: 2525 config->pending_req_sim++; 2526 txt = msg; 2527 break; 2528 case WPA_CTRL_REQ_EXT_CERT_CHECK: 2529 break; 2530 default: 2531 return; 2532 } 2533 2534 if (sm->eapol_cb->eap_param_needed) 2535 sm->eapol_cb->eap_param_needed(sm->eapol_ctx, field, txt); 2536 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 2537 } 2538 2539 2540 const char * eap_sm_get_method_name(struct eap_sm *sm) 2541 { 2542 if (sm->m == NULL) 2543 return "UNKNOWN"; 2544 return sm->m->name; 2545 } 2546 2547 2548 /** 2549 * eap_sm_request_identity - Request identity from user (ctrl_iface) 2550 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2551 * 2552 * EAP methods can call this function to request identity information for the 2553 * current network. This is normally called when the identity is not included 2554 * in the network configuration. The request will be sent to monitor programs 2555 * through the control interface. 2556 */ 2557 void eap_sm_request_identity(struct eap_sm *sm) 2558 { 2559 eap_sm_request(sm, WPA_CTRL_REQ_EAP_IDENTITY, NULL, 0); 2560 } 2561 2562 2563 /** 2564 * eap_sm_request_password - Request password from user (ctrl_iface) 2565 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2566 * 2567 * EAP methods can call this function to request password information for the 2568 * current network. This is normally called when the password is not included 2569 * in the network configuration. The request will be sent to monitor programs 2570 * through the control interface. 2571 */ 2572 void eap_sm_request_password(struct eap_sm *sm) 2573 { 2574 eap_sm_request(sm, WPA_CTRL_REQ_EAP_PASSWORD, NULL, 0); 2575 } 2576 2577 2578 /** 2579 * eap_sm_request_new_password - Request new password from user (ctrl_iface) 2580 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2581 * 2582 * EAP methods can call this function to request new password information for 2583 * the current network. This is normally called when the EAP method indicates 2584 * that the current password has expired and password change is required. The 2585 * request will be sent to monitor programs through the control interface. 2586 */ 2587 void eap_sm_request_new_password(struct eap_sm *sm) 2588 { 2589 eap_sm_request(sm, WPA_CTRL_REQ_EAP_NEW_PASSWORD, NULL, 0); 2590 } 2591 2592 2593 /** 2594 * eap_sm_request_pin - Request SIM or smart card PIN from user (ctrl_iface) 2595 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2596 * 2597 * EAP methods can call this function to request SIM or smart card PIN 2598 * information for the current network. This is normally called when the PIN is 2599 * not included in the network configuration. The request will be sent to 2600 * monitor programs through the control interface. 2601 */ 2602 void eap_sm_request_pin(struct eap_sm *sm) 2603 { 2604 eap_sm_request(sm, WPA_CTRL_REQ_EAP_PIN, NULL, 0); 2605 } 2606 2607 2608 /** 2609 * eap_sm_request_otp - Request one time password from user (ctrl_iface) 2610 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2611 * @msg: Message to be displayed to the user when asking for OTP 2612 * @msg_len: Length of the user displayable message 2613 * 2614 * EAP methods can call this function to request open time password (OTP) for 2615 * the current network. The request will be sent to monitor programs through 2616 * the control interface. 2617 */ 2618 void eap_sm_request_otp(struct eap_sm *sm, const char *msg, size_t msg_len) 2619 { 2620 eap_sm_request(sm, WPA_CTRL_REQ_EAP_OTP, msg, msg_len); 2621 } 2622 2623 2624 /** 2625 * eap_sm_request_passphrase - Request passphrase from user (ctrl_iface) 2626 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2627 * 2628 * EAP methods can call this function to request passphrase for a private key 2629 * for the current network. This is normally called when the passphrase is not 2630 * included in the network configuration. The request will be sent to monitor 2631 * programs through the control interface. 2632 */ 2633 void eap_sm_request_passphrase(struct eap_sm *sm) 2634 { 2635 eap_sm_request(sm, WPA_CTRL_REQ_EAP_PASSPHRASE, NULL, 0); 2636 } 2637 2638 2639 /** 2640 * eap_sm_request_sim - Request external SIM processing 2641 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2642 * @req: EAP method specific request 2643 */ 2644 void eap_sm_request_sim(struct eap_sm *sm, const char *req) 2645 { 2646 eap_sm_request(sm, WPA_CTRL_REQ_SIM, req, os_strlen(req)); 2647 } 2648 2649 2650 /** 2651 * eap_sm_notify_ctrl_attached - Notification of attached monitor 2652 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2653 * 2654 * Notify EAP state machines that a monitor was attached to the control 2655 * interface to trigger re-sending of pending requests for user input. 2656 */ 2657 void eap_sm_notify_ctrl_attached(struct eap_sm *sm) 2658 { 2659 struct eap_peer_config *config = eap_get_config(sm); 2660 2661 if (config == NULL) 2662 return; 2663 2664 /* Re-send any pending requests for user data since a new control 2665 * interface was added. This handles cases where the EAP authentication 2666 * starts immediately after system startup when the user interface is 2667 * not yet running. */ 2668 if (config->pending_req_identity) 2669 eap_sm_request_identity(sm); 2670 if (config->pending_req_password) 2671 eap_sm_request_password(sm); 2672 if (config->pending_req_new_password) 2673 eap_sm_request_new_password(sm); 2674 if (config->pending_req_otp) 2675 eap_sm_request_otp(sm, NULL, 0); 2676 if (config->pending_req_pin) 2677 eap_sm_request_pin(sm); 2678 if (config->pending_req_passphrase) 2679 eap_sm_request_passphrase(sm); 2680 } 2681 2682 2683 static int eap_allowed_phase2_type(int vendor, int type) 2684 { 2685 if (vendor == EAP_VENDOR_HOSTAP) 2686 return 1; 2687 if (vendor != EAP_VENDOR_IETF) 2688 return 0; 2689 return type != EAP_TYPE_PEAP && type != EAP_TYPE_TTLS && 2690 type != EAP_TYPE_FAST && type != EAP_TYPE_TEAP; 2691 } 2692 2693 2694 /** 2695 * eap_get_phase2_type - Get EAP type for the given EAP phase 2 method name 2696 * @name: EAP method name, e.g., MD5 2697 * @vendor: Buffer for returning EAP Vendor-Id 2698 * Returns: EAP method type or %EAP_TYPE_NONE if not found 2699 * 2700 * This function maps EAP type names into EAP type numbers that are allowed for 2701 * Phase 2, i.e., for tunneled authentication. Phase 2 is used, e.g., with 2702 * EAP-PEAP, EAP-TTLS, and EAP-FAST. 2703 */ 2704 u32 eap_get_phase2_type(const char *name, int *vendor) 2705 { 2706 int v; 2707 u32 type = eap_peer_get_type(name, &v); 2708 if (eap_allowed_phase2_type(v, type)) { 2709 *vendor = v; 2710 return type; 2711 } 2712 *vendor = EAP_VENDOR_IETF; 2713 return EAP_TYPE_NONE; 2714 } 2715 2716 2717 /** 2718 * eap_get_phase2_types - Get list of allowed EAP phase 2 types 2719 * @config: Pointer to a network configuration 2720 * @count: Pointer to a variable to be filled with number of returned EAP types 2721 * Returns: Pointer to allocated type list or %NULL on failure 2722 * 2723 * This function generates an array of allowed EAP phase 2 (tunneled) types for 2724 * the given network configuration. 2725 */ 2726 struct eap_method_type * eap_get_phase2_types(struct eap_peer_config *config, 2727 size_t *count) 2728 { 2729 struct eap_method_type *buf; 2730 u32 method; 2731 int vendor; 2732 size_t mcount; 2733 const struct eap_method *methods, *m; 2734 2735 methods = eap_peer_get_methods(&mcount); 2736 if (methods == NULL) 2737 return NULL; 2738 *count = 0; 2739 buf = os_malloc(mcount * sizeof(struct eap_method_type)); 2740 if (buf == NULL) 2741 return NULL; 2742 2743 for (m = methods; m; m = m->next) { 2744 vendor = m->vendor; 2745 method = m->method; 2746 if (eap_allowed_phase2_type(vendor, method)) { 2747 if (vendor == EAP_VENDOR_IETF && 2748 method == EAP_TYPE_TLS && config && 2749 !config->phase2_cert.private_key) 2750 continue; 2751 buf[*count].vendor = vendor; 2752 buf[*count].method = method; 2753 (*count)++; 2754 } 2755 } 2756 2757 return buf; 2758 } 2759 2760 2761 /** 2762 * eap_set_fast_reauth - Update fast_reauth setting 2763 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2764 * @enabled: 1 = Fast reauthentication is enabled, 0 = Disabled 2765 */ 2766 void eap_set_fast_reauth(struct eap_sm *sm, int enabled) 2767 { 2768 sm->fast_reauth = enabled; 2769 } 2770 2771 2772 /** 2773 * eap_set_workaround - Update EAP workarounds setting 2774 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2775 * @workaround: 1 = Enable EAP workarounds, 0 = Disable EAP workarounds 2776 */ 2777 void eap_set_workaround(struct eap_sm *sm, unsigned int workaround) 2778 { 2779 sm->workaround = workaround; 2780 } 2781 2782 2783 /** 2784 * eap_get_config - Get current network configuration 2785 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2786 * Returns: Pointer to the current network configuration or %NULL if not found 2787 * 2788 * EAP peer methods should avoid using this function if they can use other 2789 * access functions, like eap_get_config_identity() and 2790 * eap_get_config_password(), that do not require direct access to 2791 * struct eap_peer_config. 2792 */ 2793 struct eap_peer_config * eap_get_config(struct eap_sm *sm) 2794 { 2795 return sm->eapol_cb->get_config(sm->eapol_ctx); 2796 } 2797 2798 2799 /** 2800 * eap_get_config_identity - Get identity from the network configuration 2801 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2802 * @len: Buffer for the length of the identity 2803 * Returns: Pointer to the identity or %NULL if not found 2804 */ 2805 const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len) 2806 { 2807 struct eap_peer_config *config = eap_get_config(sm); 2808 2809 if (!config) 2810 return NULL; 2811 2812 if (sm->use_machine_cred) { 2813 *len = config->machine_identity_len; 2814 return config->machine_identity; 2815 } 2816 2817 *len = config->identity_len; 2818 return config->identity; 2819 } 2820 2821 2822 static int eap_get_ext_password(struct eap_sm *sm, 2823 struct eap_peer_config *config) 2824 { 2825 char *name; 2826 const u8 *password; 2827 size_t password_len; 2828 2829 if (sm->use_machine_cred) { 2830 password = config->machine_password; 2831 password_len = config->machine_password_len; 2832 } else { 2833 password = config->password; 2834 password_len = config->password_len; 2835 } 2836 2837 if (!password) 2838 return -1; 2839 2840 name = os_zalloc(password_len + 1); 2841 if (!name) 2842 return -1; 2843 os_memcpy(name, password, password_len); 2844 2845 ext_password_free(sm->ext_pw_buf); 2846 sm->ext_pw_buf = ext_password_get(sm->ext_pw, name); 2847 os_free(name); 2848 2849 return sm->ext_pw_buf == NULL ? -1 : 0; 2850 } 2851 2852 2853 /** 2854 * eap_get_config_password - Get password from the network configuration 2855 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2856 * @len: Buffer for the length of the password 2857 * Returns: Pointer to the password or %NULL if not found 2858 */ 2859 const u8 * eap_get_config_password(struct eap_sm *sm, size_t *len) 2860 { 2861 struct eap_peer_config *config = eap_get_config(sm); 2862 2863 if (!config) 2864 return NULL; 2865 2866 if ((sm->use_machine_cred && 2867 (config->flags & EAP_CONFIG_FLAGS_EXT_MACHINE_PASSWORD)) || 2868 (!sm->use_machine_cred && 2869 (config->flags & EAP_CONFIG_FLAGS_EXT_PASSWORD))) { 2870 if (eap_get_ext_password(sm, config) < 0) 2871 return NULL; 2872 *len = wpabuf_len(sm->ext_pw_buf); 2873 return wpabuf_head(sm->ext_pw_buf); 2874 } 2875 2876 if (sm->use_machine_cred) { 2877 *len = config->machine_password_len; 2878 return config->machine_password; 2879 } 2880 2881 *len = config->password_len; 2882 return config->password; 2883 } 2884 2885 2886 /** 2887 * eap_get_config_password2 - Get password from the network configuration 2888 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2889 * @len: Buffer for the length of the password 2890 * @hash: Buffer for returning whether the password is stored as a 2891 * NtPasswordHash instead of plaintext password; can be %NULL if this 2892 * information is not needed 2893 * Returns: Pointer to the password or %NULL if not found 2894 */ 2895 const u8 * eap_get_config_password2(struct eap_sm *sm, size_t *len, int *hash) 2896 { 2897 struct eap_peer_config *config = eap_get_config(sm); 2898 2899 if (!config) 2900 return NULL; 2901 2902 if ((sm->use_machine_cred && 2903 (config->flags & EAP_CONFIG_FLAGS_EXT_MACHINE_PASSWORD)) || 2904 (!sm->use_machine_cred && 2905 (config->flags & EAP_CONFIG_FLAGS_EXT_PASSWORD))) { 2906 if (eap_get_ext_password(sm, config) < 0) 2907 return NULL; 2908 if (hash) 2909 *hash = 0; 2910 *len = wpabuf_len(sm->ext_pw_buf); 2911 return wpabuf_head(sm->ext_pw_buf); 2912 } 2913 2914 if (sm->use_machine_cred) { 2915 *len = config->machine_password_len; 2916 if (hash) 2917 *hash = !!(config->flags & 2918 EAP_CONFIG_FLAGS_MACHINE_PASSWORD_NTHASH); 2919 return config->machine_password; 2920 } 2921 2922 *len = config->password_len; 2923 if (hash) 2924 *hash = !!(config->flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH); 2925 return config->password; 2926 } 2927 2928 2929 /** 2930 * eap_get_config_new_password - Get new password from network configuration 2931 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2932 * @len: Buffer for the length of the new password 2933 * Returns: Pointer to the new password or %NULL if not found 2934 */ 2935 const u8 * eap_get_config_new_password(struct eap_sm *sm, size_t *len) 2936 { 2937 struct eap_peer_config *config = eap_get_config(sm); 2938 if (config == NULL) 2939 return NULL; 2940 *len = config->new_password_len; 2941 return config->new_password; 2942 } 2943 2944 2945 /** 2946 * eap_get_config_otp - Get one-time password from the network configuration 2947 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2948 * @len: Buffer for the length of the one-time password 2949 * Returns: Pointer to the one-time password or %NULL if not found 2950 */ 2951 const u8 * eap_get_config_otp(struct eap_sm *sm, size_t *len) 2952 { 2953 struct eap_peer_config *config = eap_get_config(sm); 2954 if (config == NULL) 2955 return NULL; 2956 *len = config->otp_len; 2957 return config->otp; 2958 } 2959 2960 2961 /** 2962 * eap_clear_config_otp - Clear used one-time password 2963 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2964 * 2965 * This function clears a used one-time password (OTP) from the current network 2966 * configuration. This should be called when the OTP has been used and is not 2967 * needed anymore. 2968 */ 2969 void eap_clear_config_otp(struct eap_sm *sm) 2970 { 2971 struct eap_peer_config *config = eap_get_config(sm); 2972 if (config == NULL) 2973 return; 2974 os_memset(config->otp, 0, config->otp_len); 2975 os_free(config->otp); 2976 config->otp = NULL; 2977 config->otp_len = 0; 2978 } 2979 2980 2981 /** 2982 * eap_get_config_phase1 - Get phase1 data from the network configuration 2983 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2984 * Returns: Pointer to the phase1 data or %NULL if not found 2985 */ 2986 const char * eap_get_config_phase1(struct eap_sm *sm) 2987 { 2988 struct eap_peer_config *config = eap_get_config(sm); 2989 if (config == NULL) 2990 return NULL; 2991 return config->phase1; 2992 } 2993 2994 2995 /** 2996 * eap_get_config_phase2 - Get phase2 data from the network configuration 2997 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2998 * Returns: Pointer to the phase1 data or %NULL if not found 2999 */ 3000 const char * eap_get_config_phase2(struct eap_sm *sm) 3001 { 3002 struct eap_peer_config *config = eap_get_config(sm); 3003 if (config == NULL) 3004 return NULL; 3005 return config->phase2; 3006 } 3007 3008 3009 int eap_get_config_fragment_size(struct eap_sm *sm) 3010 { 3011 struct eap_peer_config *config = eap_get_config(sm); 3012 if (config == NULL) 3013 return -1; 3014 return config->fragment_size; 3015 } 3016 3017 3018 /** 3019 * eap_key_available - Get key availability (eapKeyAvailable variable) 3020 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 3021 * Returns: 1 if EAP keying material is available, 0 if not 3022 */ 3023 int eap_key_available(struct eap_sm *sm) 3024 { 3025 return sm ? sm->eapKeyAvailable : 0; 3026 } 3027 3028 3029 /** 3030 * eap_notify_success - Notify EAP state machine about external success trigger 3031 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 3032 * 3033 * This function is called when external event, e.g., successful completion of 3034 * WPA-PSK key handshake, is indicating that EAP state machine should move to 3035 * success state. This is mainly used with security modes that do not use EAP 3036 * state machine (e.g., WPA-PSK). 3037 */ 3038 void eap_notify_success(struct eap_sm *sm) 3039 { 3040 if (sm) { 3041 sm->decision = DECISION_COND_SUCC; 3042 sm->EAP_state = EAP_SUCCESS; 3043 } 3044 } 3045 3046 3047 /** 3048 * eap_notify_lower_layer_success - Notification of lower layer success 3049 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 3050 * 3051 * Notify EAP state machines that a lower layer has detected a successful 3052 * authentication. This is used to recover from dropped EAP-Success messages. 3053 */ 3054 void eap_notify_lower_layer_success(struct eap_sm *sm) 3055 { 3056 if (sm == NULL) 3057 return; 3058 3059 if (eapol_get_bool(sm, EAPOL_eapSuccess) || 3060 sm->decision == DECISION_FAIL || 3061 (sm->methodState != METHOD_MAY_CONT && 3062 sm->methodState != METHOD_DONE)) 3063 return; 3064 3065 if (sm->eapKeyData != NULL) 3066 sm->eapKeyAvailable = true; 3067 eapol_set_bool(sm, EAPOL_eapSuccess, true); 3068 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS 3069 "EAP authentication completed successfully (based on lower " 3070 "layer success)"); 3071 } 3072 3073 3074 /** 3075 * eap_get_eapSessionId - Get Session-Id from EAP state machine 3076 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 3077 * @len: Pointer to variable that will be set to number of bytes in the session 3078 * Returns: Pointer to the EAP Session-Id or %NULL on failure 3079 * 3080 * Fetch EAP Session-Id from the EAP state machine. The Session-Id is available 3081 * only after a successful authentication. EAP state machine continues to manage 3082 * the Session-Id and the caller must not change or free the returned data. 3083 */ 3084 const u8 * eap_get_eapSessionId(struct eap_sm *sm, size_t *len) 3085 { 3086 if (sm == NULL || sm->eapSessionId == NULL) { 3087 *len = 0; 3088 return NULL; 3089 } 3090 3091 *len = sm->eapSessionIdLen; 3092 return sm->eapSessionId; 3093 } 3094 3095 3096 /** 3097 * eap_get_eapKeyData - Get master session key (MSK) from EAP state machine 3098 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 3099 * @len: Pointer to variable that will be set to number of bytes in the key 3100 * Returns: Pointer to the EAP keying data or %NULL on failure 3101 * 3102 * Fetch EAP keying material (MSK, eapKeyData) from the EAP state machine. The 3103 * key is available only after a successful authentication. EAP state machine 3104 * continues to manage the key data and the caller must not change or free the 3105 * returned data. 3106 */ 3107 const u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len) 3108 { 3109 if (sm == NULL || sm->eapKeyData == NULL) { 3110 *len = 0; 3111 return NULL; 3112 } 3113 3114 *len = sm->eapKeyDataLen; 3115 return sm->eapKeyData; 3116 } 3117 3118 3119 /** 3120 * eap_get_eapKeyData - Get EAP response data 3121 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 3122 * Returns: Pointer to the EAP response (eapRespData) or %NULL on failure 3123 * 3124 * Fetch EAP response (eapRespData) from the EAP state machine. This data is 3125 * available when EAP state machine has processed an incoming EAP request. The 3126 * EAP state machine does not maintain a reference to the response after this 3127 * function is called and the caller is responsible for freeing the data. 3128 */ 3129 struct wpabuf * eap_get_eapRespData(struct eap_sm *sm) 3130 { 3131 struct wpabuf *resp; 3132 3133 if (sm == NULL || sm->eapRespData == NULL) 3134 return NULL; 3135 3136 resp = sm->eapRespData; 3137 sm->eapRespData = NULL; 3138 3139 return resp; 3140 } 3141 3142 3143 /** 3144 * eap_sm_register_scard_ctx - Notification of smart card context 3145 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 3146 * @ctx: Context data for smart card operations 3147 * 3148 * Notify EAP state machines of context data for smart card operations. This 3149 * context data will be used as a parameter for scard_*() functions. 3150 */ 3151 void eap_register_scard_ctx(struct eap_sm *sm, void *ctx) 3152 { 3153 if (sm) 3154 sm->scard_ctx = ctx; 3155 } 3156 3157 3158 /** 3159 * eap_set_config_blob - Set or add a named configuration blob 3160 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 3161 * @blob: New value for the blob 3162 * 3163 * Adds a new configuration blob or replaces the current value of an existing 3164 * blob. 3165 */ 3166 void eap_set_config_blob(struct eap_sm *sm, struct wpa_config_blob *blob) 3167 { 3168 #ifndef CONFIG_NO_CONFIG_BLOBS 3169 sm->eapol_cb->set_config_blob(sm->eapol_ctx, blob); 3170 #endif /* CONFIG_NO_CONFIG_BLOBS */ 3171 } 3172 3173 3174 /** 3175 * eap_get_config_blob - Get a named configuration blob 3176 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 3177 * @name: Name of the blob 3178 * Returns: Pointer to blob data or %NULL if not found 3179 */ 3180 const struct wpa_config_blob * eap_get_config_blob(struct eap_sm *sm, 3181 const char *name) 3182 { 3183 #ifndef CONFIG_NO_CONFIG_BLOBS 3184 return sm->eapol_cb->get_config_blob(sm->eapol_ctx, name); 3185 #else /* CONFIG_NO_CONFIG_BLOBS */ 3186 return NULL; 3187 #endif /* CONFIG_NO_CONFIG_BLOBS */ 3188 } 3189 3190 3191 /** 3192 * eap_set_force_disabled - Set force_disabled flag 3193 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 3194 * @disabled: 1 = EAP disabled, 0 = EAP enabled 3195 * 3196 * This function is used to force EAP state machine to be disabled when it is 3197 * not in use (e.g., with WPA-PSK or plaintext connections). 3198 */ 3199 void eap_set_force_disabled(struct eap_sm *sm, int disabled) 3200 { 3201 sm->force_disabled = disabled; 3202 } 3203 3204 3205 /** 3206 * eap_set_external_sim - Set external_sim flag 3207 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 3208 * @external_sim: Whether external SIM/USIM processing is used 3209 */ 3210 void eap_set_external_sim(struct eap_sm *sm, int external_sim) 3211 { 3212 sm->external_sim = external_sim; 3213 } 3214 3215 3216 /** 3217 * eap_notify_pending - Notify that EAP method is ready to re-process a request 3218 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 3219 * 3220 * An EAP method can perform a pending operation (e.g., to get a response from 3221 * an external process). Once the response is available, this function can be 3222 * used to request EAPOL state machine to retry delivering the previously 3223 * received (and still unanswered) EAP request to EAP state machine. 3224 */ 3225 void eap_notify_pending(struct eap_sm *sm) 3226 { 3227 sm->eapol_cb->notify_pending(sm->eapol_ctx); 3228 } 3229 3230 3231 /** 3232 * eap_invalidate_cached_session - Mark cached session data invalid 3233 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 3234 */ 3235 void eap_invalidate_cached_session(struct eap_sm *sm) 3236 { 3237 if (sm) 3238 eap_deinit_prev_method(sm, "invalidate"); 3239 } 3240 3241 3242 int eap_is_wps_pbc_enrollee(struct eap_peer_config *conf) 3243 { 3244 if (conf->identity_len != WSC_ID_ENROLLEE_LEN || 3245 os_memcmp(conf->identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN)) 3246 return 0; /* Not a WPS Enrollee */ 3247 3248 if (conf->phase1 == NULL || os_strstr(conf->phase1, "pbc=1") == NULL) 3249 return 0; /* Not using PBC */ 3250 3251 return 1; 3252 } 3253 3254 3255 int eap_is_wps_pin_enrollee(struct eap_peer_config *conf) 3256 { 3257 if (conf->identity_len != WSC_ID_ENROLLEE_LEN || 3258 os_memcmp(conf->identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN)) 3259 return 0; /* Not a WPS Enrollee */ 3260 3261 if (conf->phase1 == NULL || os_strstr(conf->phase1, "pin=") == NULL) 3262 return 0; /* Not using PIN */ 3263 3264 return 1; 3265 } 3266 3267 3268 void eap_sm_set_ext_pw_ctx(struct eap_sm *sm, struct ext_password_data *ext) 3269 { 3270 ext_password_free(sm->ext_pw_buf); 3271 sm->ext_pw_buf = NULL; 3272 sm->ext_pw = ext; 3273 } 3274 3275 3276 /** 3277 * eap_set_anon_id - Set or add anonymous identity 3278 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 3279 * @id: Anonymous identity (e.g., EAP-SIM pseudonym) or %NULL to clear 3280 * @len: Length of anonymous identity in octets 3281 */ 3282 void eap_set_anon_id(struct eap_sm *sm, const u8 *id, size_t len) 3283 { 3284 if (sm->eapol_cb->set_anon_id) 3285 sm->eapol_cb->set_anon_id(sm->eapol_ctx, id, len); 3286 } 3287 3288 3289 int eap_peer_was_failure_expected(struct eap_sm *sm) 3290 { 3291 return sm->expected_failure; 3292 } 3293