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