1 /* 2 * EAPOL supplicant state machines 3 * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "includes.h" 10 11 #include "common.h" 12 #include "state_machine.h" 13 #include "wpabuf.h" 14 #include "eloop.h" 15 #include "crypto/crypto.h" 16 #include "crypto/md5.h" 17 #include "common/eapol_common.h" 18 #include "eap_peer/eap.h" 19 #include "eap_peer/eap_config.h" 20 #include "eap_peer/eap_proxy.h" 21 #include "eapol_supp_sm.h" 22 23 #define STATE_MACHINE_DATA struct eapol_sm 24 #define STATE_MACHINE_DEBUG_PREFIX "EAPOL" 25 26 27 /* IEEE 802.1X-2004 - Supplicant - EAPOL state machines */ 28 29 /** 30 * struct eapol_sm - Internal data for EAPOL state machines 31 */ 32 struct eapol_sm { 33 /* Timers */ 34 unsigned int authWhile; 35 unsigned int heldWhile; 36 unsigned int startWhen; 37 unsigned int idleWhile; /* for EAP state machine */ 38 int timer_tick_enabled; 39 40 /* Global variables */ 41 bool eapFail; 42 bool eapolEap; 43 bool eapSuccess; 44 bool initialize; 45 bool keyDone; 46 bool keyRun; 47 PortControl portControl; 48 bool portEnabled; 49 PortStatus suppPortStatus; /* dot1xSuppControlledPortStatus */ 50 bool portValid; 51 bool suppAbort; 52 bool suppFail; 53 bool suppStart; 54 bool suppSuccess; 55 bool suppTimeout; 56 57 /* Supplicant PAE state machine */ 58 enum { 59 SUPP_PAE_UNKNOWN = 0, 60 SUPP_PAE_DISCONNECTED = 1, 61 SUPP_PAE_LOGOFF = 2, 62 SUPP_PAE_CONNECTING = 3, 63 SUPP_PAE_AUTHENTICATING = 4, 64 SUPP_PAE_AUTHENTICATED = 5, 65 /* unused(6) */ 66 SUPP_PAE_HELD = 7, 67 SUPP_PAE_RESTART = 8, 68 SUPP_PAE_S_FORCE_AUTH = 9, 69 SUPP_PAE_S_FORCE_UNAUTH = 10 70 } SUPP_PAE_state; /* dot1xSuppPaeState */ 71 /* Variables */ 72 bool userLogoff; 73 bool logoffSent; 74 unsigned int startCount; 75 bool eapRestart; 76 PortControl sPortMode; 77 /* Constants */ 78 unsigned int heldPeriod; /* dot1xSuppHeldPeriod */ 79 unsigned int startPeriod; /* dot1xSuppStartPeriod */ 80 unsigned int maxStart; /* dot1xSuppMaxStart */ 81 82 /* Key Receive state machine */ 83 enum { 84 KEY_RX_UNKNOWN = 0, 85 KEY_RX_NO_KEY_RECEIVE, KEY_RX_KEY_RECEIVE 86 } KEY_RX_state; 87 /* Variables */ 88 bool rxKey; 89 90 /* Supplicant Backend state machine */ 91 enum { 92 SUPP_BE_UNKNOWN = 0, 93 SUPP_BE_INITIALIZE = 1, 94 SUPP_BE_IDLE = 2, 95 SUPP_BE_REQUEST = 3, 96 SUPP_BE_RECEIVE = 4, 97 SUPP_BE_RESPONSE = 5, 98 SUPP_BE_FAIL = 6, 99 SUPP_BE_TIMEOUT = 7, 100 SUPP_BE_SUCCESS = 8 101 } SUPP_BE_state; /* dot1xSuppBackendPaeState */ 102 /* Variables */ 103 bool eapNoResp; 104 bool eapReq; 105 bool eapResp; 106 /* Constants */ 107 unsigned int authPeriod; /* dot1xSuppAuthPeriod */ 108 109 /* Statistics */ 110 unsigned int dot1xSuppEapolFramesRx; 111 unsigned int dot1xSuppEapolFramesTx; 112 unsigned int dot1xSuppEapolStartFramesTx; 113 unsigned int dot1xSuppEapolLogoffFramesTx; 114 unsigned int dot1xSuppEapolRespFramesTx; 115 unsigned int dot1xSuppEapolReqIdFramesRx; 116 unsigned int dot1xSuppEapolReqFramesRx; 117 unsigned int dot1xSuppInvalidEapolFramesRx; 118 unsigned int dot1xSuppEapLengthErrorFramesRx; 119 unsigned int dot1xSuppLastEapolFrameVersion; 120 unsigned char dot1xSuppLastEapolFrameSource[6]; 121 122 /* Miscellaneous variables (not defined in IEEE 802.1X-2004) */ 123 bool changed; 124 struct eap_sm *eap; 125 struct eap_peer_config *config; 126 bool initial_req; 127 u8 *last_rx_key; 128 size_t last_rx_key_len; 129 struct wpabuf *eapReqData; /* for EAP */ 130 bool altAccept; /* for EAP */ 131 bool altReject; /* for EAP */ 132 bool eapTriggerStart; 133 bool replay_counter_valid; 134 u8 last_replay_counter[16]; 135 struct eapol_config conf; 136 struct eapol_ctx *ctx; 137 enum { EAPOL_CB_IN_PROGRESS = 0, EAPOL_CB_SUCCESS, EAPOL_CB_FAILURE } 138 cb_status; 139 bool cached_pmk; 140 141 bool unicast_key_received, broadcast_key_received; 142 143 bool force_authorized_update; 144 145 #ifdef CONFIG_EAP_PROXY 146 bool use_eap_proxy; 147 struct eap_proxy_sm *eap_proxy; 148 #endif /* CONFIG_EAP_PROXY */ 149 }; 150 151 152 static void eapol_sm_txLogoff(struct eapol_sm *sm); 153 static void eapol_sm_txStart(struct eapol_sm *sm); 154 static void eapol_sm_processKey(struct eapol_sm *sm); 155 static void eapol_sm_getSuppRsp(struct eapol_sm *sm); 156 static void eapol_sm_txSuppRsp(struct eapol_sm *sm); 157 static void eapol_sm_abortSupp(struct eapol_sm *sm); 158 static void eapol_sm_abort_cached(struct eapol_sm *sm); 159 static void eapol_sm_step_timeout(void *eloop_ctx, void *timeout_ctx); 160 static void eapol_sm_set_port_authorized(struct eapol_sm *sm); 161 static void eapol_sm_set_port_unauthorized(struct eapol_sm *sm); 162 163 164 /* Port Timers state machine - implemented as a function that will be called 165 * once a second as a registered event loop timeout */ 166 static void eapol_port_timers_tick(void *eloop_ctx, void *timeout_ctx) 167 { 168 struct eapol_sm *sm = timeout_ctx; 169 170 if (sm->authWhile > 0) { 171 sm->authWhile--; 172 if (sm->authWhile == 0) 173 wpa_printf(MSG_DEBUG, "EAPOL: authWhile --> 0"); 174 } 175 if (sm->heldWhile > 0) { 176 sm->heldWhile--; 177 if (sm->heldWhile == 0) 178 wpa_printf(MSG_DEBUG, "EAPOL: heldWhile --> 0"); 179 } 180 if (sm->startWhen > 0) { 181 sm->startWhen--; 182 if (sm->startWhen == 0) 183 wpa_printf(MSG_DEBUG, "EAPOL: startWhen --> 0"); 184 } 185 if (sm->idleWhile > 0) { 186 sm->idleWhile--; 187 if (sm->idleWhile == 0) 188 wpa_printf(MSG_DEBUG, "EAPOL: idleWhile --> 0"); 189 } 190 191 if (sm->authWhile | sm->heldWhile | sm->startWhen | sm->idleWhile) { 192 if (eloop_register_timeout(1, 0, eapol_port_timers_tick, 193 eloop_ctx, sm) < 0) 194 sm->timer_tick_enabled = 0; 195 } else { 196 wpa_printf(MSG_DEBUG, "EAPOL: disable timer tick"); 197 sm->timer_tick_enabled = 0; 198 } 199 eapol_sm_step(sm); 200 } 201 202 203 static int eapol_sm_confirm_auth(struct eapol_sm *sm) 204 { 205 if (!sm->ctx->confirm_auth_cb) 206 return 0; 207 208 return sm->ctx->confirm_auth_cb(sm->ctx->ctx); 209 } 210 211 212 static void eapol_enable_timer_tick(struct eapol_sm *sm) 213 { 214 if (sm->timer_tick_enabled) 215 return; 216 wpa_printf(MSG_DEBUG, "EAPOL: enable timer tick"); 217 eloop_cancel_timeout(eapol_port_timers_tick, NULL, sm); 218 if (eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm) == 0) 219 sm->timer_tick_enabled = 1; 220 } 221 222 223 SM_STATE(SUPP_PAE, LOGOFF) 224 { 225 SM_ENTRY(SUPP_PAE, LOGOFF); 226 eapol_sm_txLogoff(sm); 227 sm->logoffSent = true; 228 eapol_sm_set_port_unauthorized(sm); 229 } 230 231 232 SM_STATE(SUPP_PAE, DISCONNECTED) 233 { 234 SM_ENTRY(SUPP_PAE, DISCONNECTED); 235 sm->sPortMode = Auto; 236 sm->startCount = 0; 237 sm->eapTriggerStart = false; 238 sm->logoffSent = false; 239 eapol_sm_set_port_unauthorized(sm); 240 sm->suppAbort = true; 241 242 sm->unicast_key_received = false; 243 sm->broadcast_key_received = false; 244 245 /* 246 * IEEE Std 802.1X-2004 does not clear heldWhile here, but doing so 247 * allows the timer tick to be stopped more quickly when the port is 248 * not enabled. Since this variable is used only within HELD state, 249 * clearing it on initialization does not change actual state machine 250 * behavior. 251 */ 252 sm->heldWhile = 0; 253 } 254 255 256 SM_STATE(SUPP_PAE, CONNECTING) 257 { 258 int send_start = sm->SUPP_PAE_state == SUPP_PAE_CONNECTING || 259 sm->SUPP_PAE_state == SUPP_PAE_HELD; 260 SM_ENTRY(SUPP_PAE, CONNECTING); 261 262 if (sm->eapTriggerStart) 263 send_start = 1; 264 if (sm->ctx->preauth) 265 send_start = 1; 266 sm->eapTriggerStart = false; 267 268 if (send_start) { 269 sm->startWhen = sm->startPeriod; 270 sm->startCount++; 271 } else { 272 /* 273 * Do not send EAPOL-Start immediately since in most cases, 274 * Authenticator is going to start authentication immediately 275 * after association and an extra EAPOL-Start is just going to 276 * delay authentication. Use a short timeout to send the first 277 * EAPOL-Start if Authenticator does not start authentication. 278 */ 279 if (sm->conf.wps && !(sm->conf.wps & EAPOL_PEER_IS_WPS20_AP)) { 280 /* Reduce latency on starting WPS negotiation. */ 281 wpa_printf(MSG_DEBUG, 282 "EAPOL: Using shorter startWhen for WPS"); 283 sm->startWhen = 1; 284 } else { 285 sm->startWhen = 2; 286 } 287 } 288 eapol_enable_timer_tick(sm); 289 sm->eapolEap = false; 290 if (send_start) 291 eapol_sm_txStart(sm); 292 } 293 294 295 SM_STATE(SUPP_PAE, AUTHENTICATING) 296 { 297 SM_ENTRY(SUPP_PAE, AUTHENTICATING); 298 sm->startCount = 0; 299 sm->suppSuccess = false; 300 sm->suppFail = false; 301 sm->suppTimeout = false; 302 sm->keyRun = false; 303 sm->keyDone = false; 304 sm->suppStart = true; 305 } 306 307 308 SM_STATE(SUPP_PAE, HELD) 309 { 310 SM_ENTRY(SUPP_PAE, HELD); 311 sm->heldWhile = sm->heldPeriod; 312 eapol_enable_timer_tick(sm); 313 eapol_sm_set_port_unauthorized(sm); 314 sm->cb_status = EAPOL_CB_FAILURE; 315 } 316 317 318 SM_STATE(SUPP_PAE, AUTHENTICATED) 319 { 320 SM_ENTRY(SUPP_PAE, AUTHENTICATED); 321 eapol_sm_set_port_authorized(sm); 322 sm->cb_status = EAPOL_CB_SUCCESS; 323 } 324 325 326 SM_STATE(SUPP_PAE, RESTART) 327 { 328 if (eapol_sm_confirm_auth(sm)) { 329 /* Don't process restart, we are already reconnecting */ 330 return; 331 } 332 333 SM_ENTRY(SUPP_PAE, RESTART); 334 sm->eapRestart = true; 335 if (sm->altAccept) { 336 /* 337 * Prevent EAP peer state machine from failing due to prior 338 * external EAP success notification (altSuccess=true in the 339 * IDLE state could result in a transition to the FAILURE state. 340 */ 341 wpa_printf(MSG_DEBUG, "EAPOL: Clearing prior altAccept TRUE"); 342 sm->eapSuccess = false; 343 sm->altAccept = false; 344 } 345 } 346 347 348 SM_STATE(SUPP_PAE, S_FORCE_AUTH) 349 { 350 SM_ENTRY(SUPP_PAE, S_FORCE_AUTH); 351 eapol_sm_set_port_authorized(sm); 352 sm->sPortMode = ForceAuthorized; 353 } 354 355 356 SM_STATE(SUPP_PAE, S_FORCE_UNAUTH) 357 { 358 SM_ENTRY(SUPP_PAE, S_FORCE_UNAUTH); 359 eapol_sm_set_port_unauthorized(sm); 360 sm->sPortMode = ForceUnauthorized; 361 eapol_sm_txLogoff(sm); 362 } 363 364 365 SM_STEP(SUPP_PAE) 366 { 367 if ((sm->userLogoff && !sm->logoffSent) && 368 !(sm->initialize || !sm->portEnabled)) 369 SM_ENTER_GLOBAL(SUPP_PAE, LOGOFF); 370 else if (((sm->portControl == Auto) && 371 (sm->sPortMode != sm->portControl)) || 372 sm->initialize || !sm->portEnabled) 373 SM_ENTER_GLOBAL(SUPP_PAE, DISCONNECTED); 374 else if ((sm->portControl == ForceAuthorized) && 375 (sm->sPortMode != sm->portControl) && 376 !(sm->initialize || !sm->portEnabled)) 377 SM_ENTER_GLOBAL(SUPP_PAE, S_FORCE_AUTH); 378 else if ((sm->portControl == ForceUnauthorized) && 379 (sm->sPortMode != sm->portControl) && 380 !(sm->initialize || !sm->portEnabled)) 381 SM_ENTER_GLOBAL(SUPP_PAE, S_FORCE_UNAUTH); 382 else switch (sm->SUPP_PAE_state) { 383 case SUPP_PAE_UNKNOWN: 384 break; 385 case SUPP_PAE_LOGOFF: 386 if (!sm->userLogoff) 387 SM_ENTER(SUPP_PAE, DISCONNECTED); 388 break; 389 case SUPP_PAE_DISCONNECTED: 390 SM_ENTER(SUPP_PAE, CONNECTING); 391 break; 392 case SUPP_PAE_CONNECTING: 393 if (sm->startWhen == 0 && sm->startCount < sm->maxStart) 394 SM_ENTER(SUPP_PAE, CONNECTING); 395 else if (sm->startWhen == 0 && 396 sm->startCount >= sm->maxStart && 397 sm->portValid) 398 SM_ENTER(SUPP_PAE, AUTHENTICATED); 399 else if (sm->eapSuccess || sm->eapFail) 400 SM_ENTER(SUPP_PAE, AUTHENTICATING); 401 else if (sm->eapolEap) 402 SM_ENTER(SUPP_PAE, RESTART); 403 else if (sm->startWhen == 0 && 404 sm->startCount >= sm->maxStart && 405 !sm->portValid) 406 SM_ENTER(SUPP_PAE, HELD); 407 break; 408 case SUPP_PAE_AUTHENTICATING: 409 if (sm->eapSuccess && !sm->portValid && 410 sm->conf.accept_802_1x_keys && 411 sm->conf.required_keys == 0) { 412 wpa_printf(MSG_DEBUG, "EAPOL: IEEE 802.1X for " 413 "plaintext connection; no EAPOL-Key frames " 414 "required"); 415 sm->portValid = true; 416 if (sm->ctx->eapol_done_cb) 417 sm->ctx->eapol_done_cb(sm->ctx->ctx); 418 } 419 if (sm->eapSuccess && sm->portValid) 420 SM_ENTER(SUPP_PAE, AUTHENTICATED); 421 else if (sm->eapFail || (sm->keyDone && !sm->portValid)) 422 SM_ENTER(SUPP_PAE, HELD); 423 else if (sm->suppTimeout) 424 SM_ENTER(SUPP_PAE, CONNECTING); 425 else if (sm->eapTriggerStart) 426 SM_ENTER(SUPP_PAE, CONNECTING); 427 break; 428 case SUPP_PAE_HELD: 429 if (sm->heldWhile == 0) 430 SM_ENTER(SUPP_PAE, CONNECTING); 431 else if (sm->eapolEap) 432 SM_ENTER(SUPP_PAE, RESTART); 433 break; 434 case SUPP_PAE_AUTHENTICATED: 435 if (sm->eapolEap && sm->portValid) 436 SM_ENTER(SUPP_PAE, RESTART); 437 else if (!sm->portValid) 438 SM_ENTER(SUPP_PAE, DISCONNECTED); 439 break; 440 case SUPP_PAE_RESTART: 441 if (!sm->eapRestart) 442 SM_ENTER(SUPP_PAE, AUTHENTICATING); 443 break; 444 case SUPP_PAE_S_FORCE_AUTH: 445 break; 446 case SUPP_PAE_S_FORCE_UNAUTH: 447 break; 448 } 449 } 450 451 452 SM_STATE(KEY_RX, NO_KEY_RECEIVE) 453 { 454 SM_ENTRY(KEY_RX, NO_KEY_RECEIVE); 455 } 456 457 458 SM_STATE(KEY_RX, KEY_RECEIVE) 459 { 460 SM_ENTRY(KEY_RX, KEY_RECEIVE); 461 eapol_sm_processKey(sm); 462 sm->rxKey = false; 463 } 464 465 466 SM_STEP(KEY_RX) 467 { 468 if (sm->initialize || !sm->portEnabled) 469 SM_ENTER_GLOBAL(KEY_RX, NO_KEY_RECEIVE); 470 switch (sm->KEY_RX_state) { 471 case KEY_RX_UNKNOWN: 472 break; 473 case KEY_RX_NO_KEY_RECEIVE: 474 if (sm->rxKey) 475 SM_ENTER(KEY_RX, KEY_RECEIVE); 476 break; 477 case KEY_RX_KEY_RECEIVE: 478 if (sm->rxKey) 479 SM_ENTER(KEY_RX, KEY_RECEIVE); 480 break; 481 } 482 } 483 484 485 SM_STATE(SUPP_BE, REQUEST) 486 { 487 SM_ENTRY(SUPP_BE, REQUEST); 488 sm->authWhile = 0; 489 sm->eapReq = true; 490 eapol_sm_getSuppRsp(sm); 491 } 492 493 494 SM_STATE(SUPP_BE, RESPONSE) 495 { 496 SM_ENTRY(SUPP_BE, RESPONSE); 497 eapol_sm_txSuppRsp(sm); 498 sm->eapResp = false; 499 } 500 501 502 SM_STATE(SUPP_BE, SUCCESS) 503 { 504 SM_ENTRY(SUPP_BE, SUCCESS); 505 sm->keyRun = true; 506 sm->suppSuccess = true; 507 508 #ifdef CONFIG_EAP_PROXY 509 if (sm->use_eap_proxy) { 510 if (eap_proxy_key_available(sm->eap_proxy)) { 511 u8 *session_id, *emsk; 512 size_t session_id_len, emsk_len; 513 514 /* New key received - clear IEEE 802.1X EAPOL-Key replay 515 * counter */ 516 sm->replay_counter_valid = false; 517 518 session_id = eap_proxy_get_eap_session_id( 519 sm->eap_proxy, &session_id_len); 520 emsk = eap_proxy_get_emsk(sm->eap_proxy, &emsk_len); 521 if (sm->config->erp && session_id && emsk) { 522 eap_peer_erp_init(sm->eap, session_id, 523 session_id_len, emsk, 524 emsk_len); 525 } else { 526 os_free(session_id); 527 bin_clear_free(emsk, emsk_len); 528 } 529 } 530 return; 531 } 532 #endif /* CONFIG_EAP_PROXY */ 533 534 if (eap_key_available(sm->eap)) { 535 /* New key received - clear IEEE 802.1X EAPOL-Key replay 536 * counter */ 537 sm->replay_counter_valid = false; 538 } 539 } 540 541 542 SM_STATE(SUPP_BE, FAIL) 543 { 544 SM_ENTRY(SUPP_BE, FAIL); 545 sm->suppFail = true; 546 } 547 548 549 SM_STATE(SUPP_BE, TIMEOUT) 550 { 551 SM_ENTRY(SUPP_BE, TIMEOUT); 552 sm->suppTimeout = true; 553 } 554 555 556 SM_STATE(SUPP_BE, IDLE) 557 { 558 SM_ENTRY(SUPP_BE, IDLE); 559 sm->suppStart = false; 560 sm->initial_req = true; 561 } 562 563 564 SM_STATE(SUPP_BE, INITIALIZE) 565 { 566 SM_ENTRY(SUPP_BE, INITIALIZE); 567 eapol_sm_abortSupp(sm); 568 sm->suppAbort = false; 569 570 /* 571 * IEEE Std 802.1X-2004 does not clear authWhile here, but doing so 572 * allows the timer tick to be stopped more quickly when the port is 573 * not enabled. Since this variable is used only within RECEIVE state, 574 * clearing it on initialization does not change actual state machine 575 * behavior. 576 */ 577 sm->authWhile = 0; 578 } 579 580 581 SM_STATE(SUPP_BE, RECEIVE) 582 { 583 SM_ENTRY(SUPP_BE, RECEIVE); 584 sm->authWhile = sm->authPeriod; 585 eapol_enable_timer_tick(sm); 586 sm->eapolEap = false; 587 sm->eapNoResp = false; 588 sm->initial_req = false; 589 } 590 591 592 SM_STEP(SUPP_BE) 593 { 594 if (sm->initialize || sm->suppAbort) 595 SM_ENTER_GLOBAL(SUPP_BE, INITIALIZE); 596 else switch (sm->SUPP_BE_state) { 597 case SUPP_BE_UNKNOWN: 598 break; 599 case SUPP_BE_REQUEST: 600 /* 601 * IEEE Std 802.1X-2004 has transitions from REQUEST to FAIL 602 * and SUCCESS based on eapFail and eapSuccess, respectively. 603 * However, IEEE Std 802.1X-2004 is also specifying that 604 * eapNoResp should be set in conjunction with eapSuccess and 605 * eapFail which would mean that more than one of the 606 * transitions here would be activated at the same time. 607 * Skipping RESPONSE and/or RECEIVE states in these cases can 608 * cause problems and the direct transitions to do not seem 609 * correct. Because of this, the conditions for these 610 * transitions are verified only after eapNoResp. They are 611 * unlikely to be used since eapNoResp should always be set if 612 * either of eapSuccess or eapFail is set. 613 */ 614 if (sm->eapResp && sm->eapNoResp) { 615 wpa_printf(MSG_DEBUG, "EAPOL: SUPP_BE REQUEST: both " 616 "eapResp and eapNoResp set?!"); 617 } 618 if (sm->eapResp) 619 SM_ENTER(SUPP_BE, RESPONSE); 620 else if (sm->eapNoResp) 621 SM_ENTER(SUPP_BE, RECEIVE); 622 else if (sm->eapFail) 623 SM_ENTER(SUPP_BE, FAIL); 624 else if (sm->eapSuccess) 625 SM_ENTER(SUPP_BE, SUCCESS); 626 break; 627 case SUPP_BE_RESPONSE: 628 SM_ENTER(SUPP_BE, RECEIVE); 629 break; 630 case SUPP_BE_SUCCESS: 631 SM_ENTER(SUPP_BE, IDLE); 632 break; 633 case SUPP_BE_FAIL: 634 SM_ENTER(SUPP_BE, IDLE); 635 break; 636 case SUPP_BE_TIMEOUT: 637 SM_ENTER(SUPP_BE, IDLE); 638 break; 639 case SUPP_BE_IDLE: 640 if (sm->eapFail && sm->suppStart) 641 SM_ENTER(SUPP_BE, FAIL); 642 else if (sm->eapolEap && sm->suppStart) 643 SM_ENTER(SUPP_BE, REQUEST); 644 else if (sm->eapSuccess && sm->suppStart) 645 SM_ENTER(SUPP_BE, SUCCESS); 646 break; 647 case SUPP_BE_INITIALIZE: 648 SM_ENTER(SUPP_BE, IDLE); 649 break; 650 case SUPP_BE_RECEIVE: 651 if (sm->eapolEap) 652 SM_ENTER(SUPP_BE, REQUEST); 653 else if (sm->eapFail) 654 SM_ENTER(SUPP_BE, FAIL); 655 else if (sm->authWhile == 0) 656 SM_ENTER(SUPP_BE, TIMEOUT); 657 else if (sm->eapSuccess) 658 SM_ENTER(SUPP_BE, SUCCESS); 659 break; 660 } 661 } 662 663 664 static void eapol_sm_txLogoff(struct eapol_sm *sm) 665 { 666 wpa_printf(MSG_DEBUG, "EAPOL: txLogoff"); 667 sm->ctx->eapol_send(sm->ctx->eapol_send_ctx, 668 IEEE802_1X_TYPE_EAPOL_LOGOFF, (u8 *) "", 0); 669 sm->dot1xSuppEapolLogoffFramesTx++; 670 sm->dot1xSuppEapolFramesTx++; 671 } 672 673 674 static void eapol_sm_txStart(struct eapol_sm *sm) 675 { 676 wpa_printf(MSG_DEBUG, "EAPOL: txStart"); 677 sm->ctx->eapol_send(sm->ctx->eapol_send_ctx, 678 IEEE802_1X_TYPE_EAPOL_START, (u8 *) "", 0); 679 sm->dot1xSuppEapolStartFramesTx++; 680 sm->dot1xSuppEapolFramesTx++; 681 } 682 683 684 #define IEEE8021X_ENCR_KEY_LEN 32 685 #define IEEE8021X_SIGN_KEY_LEN 32 686 687 struct eap_key_data { 688 u8 encr_key[IEEE8021X_ENCR_KEY_LEN]; 689 u8 sign_key[IEEE8021X_SIGN_KEY_LEN]; 690 }; 691 692 693 static void eapol_sm_processKey(struct eapol_sm *sm) 694 { 695 #ifdef CONFIG_WEP 696 #ifndef CONFIG_FIPS 697 struct ieee802_1x_hdr *hdr; 698 struct ieee802_1x_eapol_key *key; 699 struct eap_key_data keydata; 700 u8 orig_key_sign[IEEE8021X_KEY_SIGN_LEN], datakey[32]; 701 #ifndef CONFIG_NO_RC4 702 u8 ekey[IEEE8021X_KEY_IV_LEN + IEEE8021X_ENCR_KEY_LEN]; 703 #endif /* CONFIG_NO_RC4 */ 704 int key_len, res, sign_key_len, encr_key_len; 705 u16 rx_key_length; 706 size_t plen; 707 708 wpa_printf(MSG_DEBUG, "EAPOL: processKey"); 709 if (sm->last_rx_key == NULL) 710 return; 711 712 if (!sm->conf.accept_802_1x_keys) { 713 wpa_printf(MSG_WARNING, "EAPOL: Received IEEE 802.1X EAPOL-Key" 714 " even though this was not accepted - " 715 "ignoring this packet"); 716 return; 717 } 718 719 if (sm->last_rx_key_len < sizeof(*hdr) + sizeof(*key)) 720 return; 721 hdr = (struct ieee802_1x_hdr *) sm->last_rx_key; 722 key = (struct ieee802_1x_eapol_key *) (hdr + 1); 723 plen = be_to_host16(hdr->length); 724 if (sizeof(*hdr) + plen > sm->last_rx_key_len || plen < sizeof(*key)) { 725 wpa_printf(MSG_WARNING, "EAPOL: Too short EAPOL-Key frame"); 726 return; 727 } 728 rx_key_length = WPA_GET_BE16(key->key_length); 729 wpa_printf(MSG_DEBUG, "EAPOL: RX IEEE 802.1X ver=%d type=%d len=%d " 730 "EAPOL-Key: type=%d key_length=%d key_index=0x%x", 731 hdr->version, hdr->type, be_to_host16(hdr->length), 732 key->type, rx_key_length, key->key_index); 733 734 eapol_sm_notify_lower_layer_success(sm, 1); 735 sign_key_len = IEEE8021X_SIGN_KEY_LEN; 736 encr_key_len = IEEE8021X_ENCR_KEY_LEN; 737 res = eapol_sm_get_key(sm, (u8 *) &keydata, sizeof(keydata)); 738 if (res < 0) { 739 wpa_printf(MSG_DEBUG, "EAPOL: Could not get master key for " 740 "decrypting EAPOL-Key keys"); 741 return; 742 } 743 if (res == 16) { 744 /* LEAP derives only 16 bytes of keying material. */ 745 res = eapol_sm_get_key(sm, (u8 *) &keydata, 16); 746 if (res) { 747 wpa_printf(MSG_DEBUG, "EAPOL: Could not get LEAP " 748 "master key for decrypting EAPOL-Key keys"); 749 return; 750 } 751 sign_key_len = 16; 752 encr_key_len = 16; 753 os_memcpy(keydata.sign_key, keydata.encr_key, 16); 754 } else if (res) { 755 wpa_printf(MSG_DEBUG, "EAPOL: Could not get enough master key " 756 "data for decrypting EAPOL-Key keys (res=%d)", res); 757 return; 758 } 759 760 /* The key replay_counter must increase when same master key */ 761 if (sm->replay_counter_valid && 762 os_memcmp(sm->last_replay_counter, key->replay_counter, 763 IEEE8021X_REPLAY_COUNTER_LEN) >= 0) { 764 wpa_printf(MSG_WARNING, "EAPOL: EAPOL-Key replay counter did " 765 "not increase - ignoring key"); 766 wpa_hexdump(MSG_DEBUG, "EAPOL: last replay counter", 767 sm->last_replay_counter, 768 IEEE8021X_REPLAY_COUNTER_LEN); 769 wpa_hexdump(MSG_DEBUG, "EAPOL: received replay counter", 770 key->replay_counter, IEEE8021X_REPLAY_COUNTER_LEN); 771 return; 772 } 773 774 /* Verify key signature (HMAC-MD5) */ 775 os_memcpy(orig_key_sign, key->key_signature, IEEE8021X_KEY_SIGN_LEN); 776 os_memset(key->key_signature, 0, IEEE8021X_KEY_SIGN_LEN); 777 hmac_md5(keydata.sign_key, sign_key_len, 778 sm->last_rx_key, sizeof(*hdr) + be_to_host16(hdr->length), 779 key->key_signature); 780 if (os_memcmp_const(orig_key_sign, key->key_signature, 781 IEEE8021X_KEY_SIGN_LEN) != 0) { 782 wpa_printf(MSG_DEBUG, "EAPOL: Invalid key signature in " 783 "EAPOL-Key packet"); 784 os_memcpy(key->key_signature, orig_key_sign, 785 IEEE8021X_KEY_SIGN_LEN); 786 return; 787 } 788 wpa_printf(MSG_DEBUG, "EAPOL: EAPOL-Key key signature verified"); 789 790 key_len = plen - sizeof(*key); 791 if (key_len > 32 || rx_key_length > 32) { 792 wpa_printf(MSG_WARNING, "EAPOL: Too long key data length %d", 793 key_len ? key_len : rx_key_length); 794 return; 795 } 796 if (key_len == rx_key_length) { 797 #ifdef CONFIG_NO_RC4 798 if (encr_key_len) { 799 /* otherwise unused */ 800 } 801 wpa_printf(MSG_ERROR, "EAPOL: RC4 not supported in the build"); 802 return; 803 #else /* CONFIG_NO_RC4 */ 804 os_memcpy(ekey, key->key_iv, IEEE8021X_KEY_IV_LEN); 805 os_memcpy(ekey + IEEE8021X_KEY_IV_LEN, keydata.encr_key, 806 encr_key_len); 807 os_memcpy(datakey, key + 1, key_len); 808 rc4_skip(ekey, IEEE8021X_KEY_IV_LEN + encr_key_len, 0, 809 datakey, key_len); 810 wpa_hexdump_key(MSG_DEBUG, "EAPOL: Decrypted(RC4) key", 811 datakey, key_len); 812 #endif /* CONFIG_NO_RC4 */ 813 } else if (key_len == 0) { 814 /* 815 * IEEE 802.1X-2004 specifies that least significant Key Length 816 * octets from MS-MPPE-Send-Key are used as the key if the key 817 * data is not present. This seems to be meaning the beginning 818 * of the MS-MPPE-Send-Key. In addition, MS-MPPE-Send-Key in 819 * Supplicant corresponds to MS-MPPE-Recv-Key in Authenticator. 820 * Anyway, taking the beginning of the keying material from EAP 821 * seems to interoperate with Authenticators. 822 */ 823 key_len = rx_key_length; 824 os_memcpy(datakey, keydata.encr_key, key_len); 825 wpa_hexdump_key(MSG_DEBUG, "EAPOL: using part of EAP keying " 826 "material data encryption key", 827 datakey, key_len); 828 } else { 829 wpa_printf(MSG_DEBUG, "EAPOL: Invalid key data length %d " 830 "(key_length=%d)", key_len, rx_key_length); 831 return; 832 } 833 834 sm->replay_counter_valid = true; 835 os_memcpy(sm->last_replay_counter, key->replay_counter, 836 IEEE8021X_REPLAY_COUNTER_LEN); 837 838 wpa_printf(MSG_DEBUG, "EAPOL: Setting dynamic WEP key: %s keyidx %d " 839 "len %d", 840 key->key_index & IEEE8021X_KEY_INDEX_FLAG ? 841 "unicast" : "broadcast", 842 key->key_index & IEEE8021X_KEY_INDEX_MASK, key_len); 843 844 if (sm->ctx->set_wep_key && 845 sm->ctx->set_wep_key(sm->ctx->ctx, 846 !!(key->key_index & IEEE8021X_KEY_INDEX_FLAG), 847 key->key_index & IEEE8021X_KEY_INDEX_MASK, 848 datakey, key_len) < 0) { 849 wpa_printf(MSG_WARNING, "EAPOL: Failed to set WEP key to the " 850 " driver."); 851 } else { 852 if (key->key_index & IEEE8021X_KEY_INDEX_FLAG) 853 sm->unicast_key_received = true; 854 else 855 sm->broadcast_key_received = true; 856 857 if ((sm->unicast_key_received || 858 !(sm->conf.required_keys & EAPOL_REQUIRE_KEY_UNICAST)) && 859 (sm->broadcast_key_received || 860 !(sm->conf.required_keys & EAPOL_REQUIRE_KEY_BROADCAST))) 861 { 862 wpa_printf(MSG_DEBUG, "EAPOL: all required EAPOL-Key " 863 "frames received"); 864 sm->portValid = true; 865 if (sm->ctx->eapol_done_cb) 866 sm->ctx->eapol_done_cb(sm->ctx->ctx); 867 } 868 } 869 #endif /* CONFIG_FIPS */ 870 #endif /* CONFIG_WEP */ 871 } 872 873 874 static void eapol_sm_getSuppRsp(struct eapol_sm *sm) 875 { 876 wpa_printf(MSG_DEBUG, "EAPOL: getSuppRsp"); 877 /* EAP layer processing; no special code is needed, since Supplicant 878 * Backend state machine is waiting for eapNoResp or eapResp to be set 879 * and these are only set in the EAP state machine when the processing 880 * has finished. */ 881 } 882 883 884 static void eapol_sm_txSuppRsp(struct eapol_sm *sm) 885 { 886 struct wpabuf *resp; 887 888 wpa_printf(MSG_DEBUG, "EAPOL: txSuppRsp"); 889 890 #ifdef CONFIG_EAP_PROXY 891 if (sm->use_eap_proxy) { 892 /* Get EAP Response from EAP Proxy */ 893 resp = eap_proxy_get_eapRespData(sm->eap_proxy); 894 if (resp == NULL) { 895 wpa_printf(MSG_WARNING, "EAPOL: txSuppRsp - EAP Proxy " 896 "response data not available"); 897 return; 898 } 899 } else 900 #endif /* CONFIG_EAP_PROXY */ 901 902 resp = eap_get_eapRespData(sm->eap); 903 if (resp == NULL) { 904 wpa_printf(MSG_WARNING, "EAPOL: txSuppRsp - EAP response data " 905 "not available"); 906 return; 907 } 908 909 /* Send EAP-Packet from the EAP layer to the Authenticator */ 910 sm->ctx->eapol_send(sm->ctx->eapol_send_ctx, 911 IEEE802_1X_TYPE_EAP_PACKET, wpabuf_head(resp), 912 wpabuf_len(resp)); 913 914 /* eapRespData is not used anymore, so free it here */ 915 wpabuf_free(resp); 916 917 if (sm->initial_req) 918 sm->dot1xSuppEapolReqIdFramesRx++; 919 else 920 sm->dot1xSuppEapolReqFramesRx++; 921 sm->dot1xSuppEapolRespFramesTx++; 922 sm->dot1xSuppEapolFramesTx++; 923 } 924 925 926 static void eapol_sm_abortSupp(struct eapol_sm *sm) 927 { 928 /* release system resources that may have been allocated for the 929 * authentication session */ 930 os_free(sm->last_rx_key); 931 sm->last_rx_key = NULL; 932 wpabuf_free(sm->eapReqData); 933 sm->eapReqData = NULL; 934 eap_sm_abort(sm->eap); 935 #ifdef CONFIG_EAP_PROXY 936 eap_proxy_sm_abort(sm->eap_proxy); 937 #endif /* CONFIG_EAP_PROXY */ 938 } 939 940 941 static void eapol_sm_step_timeout(void *eloop_ctx, void *timeout_ctx) 942 { 943 eapol_sm_step(timeout_ctx); 944 } 945 946 947 static void eapol_sm_set_port_authorized(struct eapol_sm *sm) 948 { 949 int cb; 950 951 cb = sm->suppPortStatus != Authorized || sm->force_authorized_update; 952 sm->force_authorized_update = false; 953 sm->suppPortStatus = Authorized; 954 if (cb && sm->ctx->port_cb) 955 sm->ctx->port_cb(sm->ctx->ctx, 1); 956 } 957 958 959 static void eapol_sm_set_port_unauthorized(struct eapol_sm *sm) 960 { 961 int cb; 962 963 cb = sm->suppPortStatus != Unauthorized || sm->force_authorized_update; 964 sm->force_authorized_update = false; 965 sm->suppPortStatus = Unauthorized; 966 if (cb && sm->ctx->port_cb) 967 sm->ctx->port_cb(sm->ctx->ctx, 0); 968 } 969 970 971 /** 972 * eapol_sm_step - EAPOL state machine step function 973 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 974 * 975 * This function is called to notify the state machine about changed external 976 * variables. It will step through the EAPOL state machines in loop to process 977 * all triggered state changes. 978 */ 979 void eapol_sm_step(struct eapol_sm *sm) 980 { 981 int i; 982 983 /* In theory, it should be ok to run this in loop until !changed. 984 * However, it is better to use a limit on number of iterations to 985 * allow events (e.g., SIGTERM) to stop the program cleanly if the 986 * state machine were to generate a busy loop. */ 987 for (i = 0; i < 100; i++) { 988 sm->changed = false; 989 SM_STEP_RUN(SUPP_PAE); 990 SM_STEP_RUN(KEY_RX); 991 SM_STEP_RUN(SUPP_BE); 992 #ifdef CONFIG_EAP_PROXY 993 if (sm->use_eap_proxy) { 994 /* Drive the EAP proxy state machine */ 995 if (eap_proxy_sm_step(sm->eap_proxy, sm->eap)) 996 sm->changed = true; 997 } else 998 #endif /* CONFIG_EAP_PROXY */ 999 if (eap_peer_sm_step(sm->eap)) 1000 sm->changed = true; 1001 if (!sm->changed) 1002 break; 1003 } 1004 1005 if (sm->changed) { 1006 /* restart EAPOL state machine step from timeout call in order 1007 * to allow other events to be processed. */ 1008 eloop_cancel_timeout(eapol_sm_step_timeout, NULL, sm); 1009 eloop_register_timeout(0, 0, eapol_sm_step_timeout, NULL, sm); 1010 } 1011 1012 if (sm->ctx->cb && sm->cb_status != EAPOL_CB_IN_PROGRESS) { 1013 enum eapol_supp_result result; 1014 if (sm->cb_status == EAPOL_CB_SUCCESS) 1015 result = EAPOL_SUPP_RESULT_SUCCESS; 1016 else if (eap_peer_was_failure_expected(sm->eap)) 1017 result = EAPOL_SUPP_RESULT_EXPECTED_FAILURE; 1018 else 1019 result = EAPOL_SUPP_RESULT_FAILURE; 1020 sm->cb_status = EAPOL_CB_IN_PROGRESS; 1021 sm->ctx->cb(sm, result, sm->ctx->cb_ctx); 1022 } 1023 } 1024 1025 1026 #ifdef CONFIG_CTRL_IFACE 1027 static const char *eapol_supp_pae_state(int state) 1028 { 1029 switch (state) { 1030 case SUPP_PAE_LOGOFF: 1031 return "LOGOFF"; 1032 case SUPP_PAE_DISCONNECTED: 1033 return "DISCONNECTED"; 1034 case SUPP_PAE_CONNECTING: 1035 return "CONNECTING"; 1036 case SUPP_PAE_AUTHENTICATING: 1037 return "AUTHENTICATING"; 1038 case SUPP_PAE_HELD: 1039 return "HELD"; 1040 case SUPP_PAE_AUTHENTICATED: 1041 return "AUTHENTICATED"; 1042 case SUPP_PAE_RESTART: 1043 return "RESTART"; 1044 default: 1045 return "UNKNOWN"; 1046 } 1047 } 1048 1049 1050 static const char *eapol_supp_be_state(int state) 1051 { 1052 switch (state) { 1053 case SUPP_BE_REQUEST: 1054 return "REQUEST"; 1055 case SUPP_BE_RESPONSE: 1056 return "RESPONSE"; 1057 case SUPP_BE_SUCCESS: 1058 return "SUCCESS"; 1059 case SUPP_BE_FAIL: 1060 return "FAIL"; 1061 case SUPP_BE_TIMEOUT: 1062 return "TIMEOUT"; 1063 case SUPP_BE_IDLE: 1064 return "IDLE"; 1065 case SUPP_BE_INITIALIZE: 1066 return "INITIALIZE"; 1067 case SUPP_BE_RECEIVE: 1068 return "RECEIVE"; 1069 default: 1070 return "UNKNOWN"; 1071 } 1072 } 1073 1074 1075 static const char * eapol_port_status(PortStatus status) 1076 { 1077 if (status == Authorized) 1078 return "Authorized"; 1079 else 1080 return "Unauthorized"; 1081 } 1082 #endif /* CONFIG_CTRL_IFACE */ 1083 1084 1085 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 1086 static const char * eapol_port_control(PortControl ctrl) 1087 { 1088 switch (ctrl) { 1089 case Auto: 1090 return "Auto"; 1091 case ForceUnauthorized: 1092 return "ForceUnauthorized"; 1093 case ForceAuthorized: 1094 return "ForceAuthorized"; 1095 default: 1096 return "Unknown"; 1097 } 1098 } 1099 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 1100 1101 1102 /** 1103 * eapol_sm_configure - Set EAPOL variables 1104 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1105 * @heldPeriod: dot1xSuppHeldPeriod 1106 * @authPeriod: dot1xSuppAuthPeriod 1107 * @startPeriod: dot1xSuppStartPeriod 1108 * @maxStart: dot1xSuppMaxStart 1109 * 1110 * Set configurable EAPOL state machine variables. Each variable can be set to 1111 * the given value or ignored if set to -1 (to set only some of the variables). 1112 */ 1113 void eapol_sm_configure(struct eapol_sm *sm, int heldPeriod, int authPeriod, 1114 int startPeriod, int maxStart) 1115 { 1116 if (sm == NULL) 1117 return; 1118 if (heldPeriod >= 0) 1119 sm->heldPeriod = heldPeriod; 1120 if (authPeriod >= 0) 1121 sm->authPeriod = authPeriod; 1122 if (startPeriod >= 0) 1123 sm->startPeriod = startPeriod; 1124 if (maxStart >= 0) 1125 sm->maxStart = maxStart; 1126 } 1127 1128 1129 /** 1130 * eapol_sm_get_method_name - Get EAPOL method name 1131 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1132 * Returns: Static string containing name of current eap method or NULL 1133 */ 1134 const char * eapol_sm_get_method_name(struct eapol_sm *sm) 1135 { 1136 if (sm->SUPP_PAE_state != SUPP_PAE_AUTHENTICATED || 1137 sm->suppPortStatus != Authorized) 1138 return NULL; 1139 1140 return eap_sm_get_method_name(sm->eap); 1141 } 1142 1143 1144 #ifdef CONFIG_CTRL_IFACE 1145 /** 1146 * eapol_sm_get_status - Get EAPOL state machine status 1147 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1148 * @buf: Buffer for status information 1149 * @buflen: Maximum buffer length 1150 * @verbose: Whether to include verbose status information 1151 * Returns: Number of bytes written to buf. 1152 * 1153 * Query EAPOL state machine for status information. This function fills in a 1154 * text area with current status information from the EAPOL state machine. If 1155 * the buffer (buf) is not large enough, status information will be truncated 1156 * to fit the buffer. 1157 */ 1158 int eapol_sm_get_status(struct eapol_sm *sm, char *buf, size_t buflen, 1159 int verbose) 1160 { 1161 int len, ret; 1162 if (sm == NULL) 1163 return 0; 1164 1165 len = os_snprintf(buf, buflen, 1166 "Supplicant PAE state=%s\n" 1167 "suppPortStatus=%s\n", 1168 eapol_supp_pae_state(sm->SUPP_PAE_state), 1169 eapol_port_status(sm->suppPortStatus)); 1170 if (os_snprintf_error(buflen, len)) 1171 return 0; 1172 1173 if (verbose) { 1174 ret = os_snprintf(buf + len, buflen - len, 1175 "heldPeriod=%u\n" 1176 "authPeriod=%u\n" 1177 "startPeriod=%u\n" 1178 "maxStart=%u\n" 1179 "portControl=%s\n" 1180 "Supplicant Backend state=%s\n", 1181 sm->heldPeriod, 1182 sm->authPeriod, 1183 sm->startPeriod, 1184 sm->maxStart, 1185 eapol_port_control(sm->portControl), 1186 eapol_supp_be_state(sm->SUPP_BE_state)); 1187 if (os_snprintf_error(buflen - len, ret)) 1188 return len; 1189 len += ret; 1190 } 1191 1192 #ifdef CONFIG_EAP_PROXY 1193 if (sm->use_eap_proxy) 1194 len += eap_proxy_sm_get_status(sm->eap_proxy, 1195 buf + len, buflen - len, 1196 verbose); 1197 else 1198 #endif /* CONFIG_EAP_PROXY */ 1199 len += eap_sm_get_status(sm->eap, buf + len, buflen - len, verbose); 1200 1201 return len; 1202 } 1203 1204 1205 /** 1206 * eapol_sm_get_mib - Get EAPOL state machine MIBs 1207 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1208 * @buf: Buffer for MIB information 1209 * @buflen: Maximum buffer length 1210 * Returns: Number of bytes written to buf. 1211 * 1212 * Query EAPOL state machine for MIB information. This function fills in a 1213 * text area with current MIB information from the EAPOL state machine. If 1214 * the buffer (buf) is not large enough, MIB information will be truncated to 1215 * fit the buffer. 1216 */ 1217 int eapol_sm_get_mib(struct eapol_sm *sm, char *buf, size_t buflen) 1218 { 1219 size_t len; 1220 int ret; 1221 1222 if (sm == NULL) 1223 return 0; 1224 ret = os_snprintf(buf, buflen, 1225 "dot1xSuppPaeState=%d\n" 1226 "dot1xSuppHeldPeriod=%u\n" 1227 "dot1xSuppAuthPeriod=%u\n" 1228 "dot1xSuppStartPeriod=%u\n" 1229 "dot1xSuppMaxStart=%u\n" 1230 "dot1xSuppSuppControlledPortStatus=%s\n" 1231 "dot1xSuppBackendPaeState=%d\n", 1232 sm->SUPP_PAE_state, 1233 sm->heldPeriod, 1234 sm->authPeriod, 1235 sm->startPeriod, 1236 sm->maxStart, 1237 sm->suppPortStatus == Authorized ? 1238 "Authorized" : "Unauthorized", 1239 sm->SUPP_BE_state); 1240 1241 if (os_snprintf_error(buflen, ret)) 1242 return 0; 1243 len = ret; 1244 1245 ret = os_snprintf(buf + len, buflen - len, 1246 "dot1xSuppEapolFramesRx=%u\n" 1247 "dot1xSuppEapolFramesTx=%u\n" 1248 "dot1xSuppEapolStartFramesTx=%u\n" 1249 "dot1xSuppEapolLogoffFramesTx=%u\n" 1250 "dot1xSuppEapolRespFramesTx=%u\n" 1251 "dot1xSuppEapolReqIdFramesRx=%u\n" 1252 "dot1xSuppEapolReqFramesRx=%u\n" 1253 "dot1xSuppInvalidEapolFramesRx=%u\n" 1254 "dot1xSuppEapLengthErrorFramesRx=%u\n" 1255 "dot1xSuppLastEapolFrameVersion=%u\n" 1256 "dot1xSuppLastEapolFrameSource=" MACSTR "\n", 1257 sm->dot1xSuppEapolFramesRx, 1258 sm->dot1xSuppEapolFramesTx, 1259 sm->dot1xSuppEapolStartFramesTx, 1260 sm->dot1xSuppEapolLogoffFramesTx, 1261 sm->dot1xSuppEapolRespFramesTx, 1262 sm->dot1xSuppEapolReqIdFramesRx, 1263 sm->dot1xSuppEapolReqFramesRx, 1264 sm->dot1xSuppInvalidEapolFramesRx, 1265 sm->dot1xSuppEapLengthErrorFramesRx, 1266 sm->dot1xSuppLastEapolFrameVersion, 1267 MAC2STR(sm->dot1xSuppLastEapolFrameSource)); 1268 1269 if (os_snprintf_error(buflen - len, ret)) 1270 return len; 1271 len += ret; 1272 1273 return len; 1274 } 1275 #endif /* CONFIG_CTRL_IFACE */ 1276 1277 1278 /** 1279 * eapol_sm_rx_eapol - Process received EAPOL frames 1280 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1281 * @src: Source MAC address of the EAPOL packet 1282 * @buf: Pointer to the beginning of the EAPOL data (EAPOL header) 1283 * @len: Length of the EAPOL frame 1284 * @encrypted: Whether the frame was encrypted 1285 * Returns: 1 = EAPOL frame processed, 0 = not for EAPOL state machine, 1286 * -1 failure 1287 */ 1288 int eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src, const u8 *buf, 1289 size_t len, enum frame_encryption encrypted) 1290 { 1291 const struct ieee802_1x_hdr *hdr; 1292 const struct ieee802_1x_eapol_key *key; 1293 int data_len; 1294 int res = 1; 1295 size_t plen; 1296 1297 if (sm == NULL) 1298 return 0; 1299 1300 if (encrypted == FRAME_NOT_ENCRYPTED && sm->ctx->encryption_required && 1301 sm->ctx->encryption_required(sm->ctx->ctx)) { 1302 wpa_printf(MSG_DEBUG, 1303 "EAPOL: Discard unencrypted EAPOL frame when encryption since encryption was expected"); 1304 return 0; 1305 } 1306 1307 sm->dot1xSuppEapolFramesRx++; 1308 if (len < sizeof(*hdr)) { 1309 sm->dot1xSuppInvalidEapolFramesRx++; 1310 return 0; 1311 } 1312 hdr = (const struct ieee802_1x_hdr *) buf; 1313 sm->dot1xSuppLastEapolFrameVersion = hdr->version; 1314 os_memcpy(sm->dot1xSuppLastEapolFrameSource, src, ETH_ALEN); 1315 if (hdr->version < EAPOL_VERSION) { 1316 /* TODO: backwards compatibility */ 1317 } 1318 plen = be_to_host16(hdr->length); 1319 if (plen > len - sizeof(*hdr)) { 1320 sm->dot1xSuppEapLengthErrorFramesRx++; 1321 return 0; 1322 } 1323 #ifdef CONFIG_WPS 1324 if (sm->conf.wps && sm->conf.workaround && 1325 plen < len - sizeof(*hdr) && 1326 hdr->type == IEEE802_1X_TYPE_EAP_PACKET && 1327 len - sizeof(*hdr) > sizeof(struct eap_hdr)) { 1328 const struct eap_hdr *ehdr = 1329 (const struct eap_hdr *) (hdr + 1); 1330 u16 elen; 1331 1332 elen = be_to_host16(ehdr->length); 1333 if (elen > plen && elen <= len - sizeof(*hdr)) { 1334 /* 1335 * Buffalo WHR-G125 Ver.1.47 seems to send EAP-WPS 1336 * packets with too short EAPOL header length field 1337 * (14 octets). This is fixed in firmware Ver.1.49. 1338 * As a workaround, fix the EAPOL header based on the 1339 * correct length in the EAP packet. 1340 */ 1341 wpa_printf(MSG_DEBUG, "EAPOL: Workaround - fix EAPOL " 1342 "payload length based on EAP header: " 1343 "%d -> %d", (int) plen, elen); 1344 plen = elen; 1345 } 1346 } 1347 #endif /* CONFIG_WPS */ 1348 data_len = plen + sizeof(*hdr); 1349 1350 switch (hdr->type) { 1351 case IEEE802_1X_TYPE_EAP_PACKET: 1352 if (sm->conf.workaround) { 1353 /* 1354 * An AP has been reported to send out EAP message with 1355 * undocumented code 10 at some point near the 1356 * completion of EAP authentication. This can result in 1357 * issues with the unexpected EAP message triggering 1358 * restart of EAPOL authentication. Avoid this by 1359 * skipping the message without advancing the state 1360 * machine. 1361 */ 1362 const struct eap_hdr *ehdr = 1363 (const struct eap_hdr *) (hdr + 1); 1364 if (plen >= sizeof(*ehdr) && ehdr->code == 10) { 1365 wpa_printf(MSG_DEBUG, "EAPOL: Ignore EAP packet with unknown code 10"); 1366 break; 1367 } 1368 } 1369 1370 if (sm->cached_pmk) { 1371 /* Trying to use PMKSA caching, but Authenticator did 1372 * not seem to have a matching entry. Need to restart 1373 * EAPOL state machines. 1374 */ 1375 eapol_sm_abort_cached(sm); 1376 } 1377 wpabuf_free(sm->eapReqData); 1378 sm->eapReqData = wpabuf_alloc_copy(hdr + 1, plen); 1379 if (sm->eapReqData) { 1380 wpa_printf(MSG_DEBUG, "EAPOL: Received EAP-Packet " 1381 "frame"); 1382 sm->eapolEap = true; 1383 #ifdef CONFIG_EAP_PROXY 1384 if (sm->use_eap_proxy) { 1385 eap_proxy_packet_update( 1386 sm->eap_proxy, 1387 wpabuf_mhead_u8(sm->eapReqData), 1388 wpabuf_len(sm->eapReqData)); 1389 wpa_printf(MSG_DEBUG, "EAPOL: eap_proxy " 1390 "EAP Req updated"); 1391 } 1392 #endif /* CONFIG_EAP_PROXY */ 1393 eapol_sm_step(sm); 1394 } 1395 break; 1396 case IEEE802_1X_TYPE_EAPOL_KEY: 1397 if (plen < sizeof(*key)) { 1398 wpa_printf(MSG_DEBUG, "EAPOL: Too short EAPOL-Key " 1399 "frame received"); 1400 break; 1401 } 1402 key = (const struct ieee802_1x_eapol_key *) (hdr + 1); 1403 if (key->type == EAPOL_KEY_TYPE_WPA || 1404 key->type == EAPOL_KEY_TYPE_RSN) { 1405 /* WPA Supplicant takes care of this frame. */ 1406 wpa_printf(MSG_DEBUG, "EAPOL: Ignoring WPA EAPOL-Key " 1407 "frame in EAPOL state machines"); 1408 res = 0; 1409 break; 1410 } 1411 if (key->type != EAPOL_KEY_TYPE_RC4) { 1412 wpa_printf(MSG_DEBUG, "EAPOL: Ignored unknown " 1413 "EAPOL-Key type %d", key->type); 1414 break; 1415 } 1416 os_free(sm->last_rx_key); 1417 sm->last_rx_key = os_malloc(data_len); 1418 if (sm->last_rx_key) { 1419 wpa_printf(MSG_DEBUG, "EAPOL: Received EAPOL-Key " 1420 "frame"); 1421 os_memcpy(sm->last_rx_key, buf, data_len); 1422 sm->last_rx_key_len = data_len; 1423 sm->rxKey = true; 1424 eapol_sm_step(sm); 1425 } 1426 break; 1427 #ifdef CONFIG_MACSEC 1428 case IEEE802_1X_TYPE_EAPOL_MKA: 1429 wpa_printf(MSG_EXCESSIVE, 1430 "EAPOL type %d will be handled by MKA", 1431 hdr->type); 1432 break; 1433 #endif /* CONFIG_MACSEC */ 1434 default: 1435 wpa_printf(MSG_DEBUG, "EAPOL: Received unknown EAPOL type %d", 1436 hdr->type); 1437 sm->dot1xSuppInvalidEapolFramesRx++; 1438 break; 1439 } 1440 1441 return res; 1442 } 1443 1444 1445 /** 1446 * eapol_sm_notify_tx_eapol_key - Notification about transmitted EAPOL packet 1447 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1448 * 1449 * Notify EAPOL state machine about transmitted EAPOL packet from an external 1450 * component, e.g., WPA. This will update the statistics. 1451 */ 1452 void eapol_sm_notify_tx_eapol_key(struct eapol_sm *sm) 1453 { 1454 if (sm) 1455 sm->dot1xSuppEapolFramesTx++; 1456 } 1457 1458 1459 /** 1460 * eapol_sm_notify_portEnabled - Notification about portEnabled change 1461 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1462 * @enabled: New portEnabled value 1463 * 1464 * Notify EAPOL state machine about new portEnabled value. 1465 */ 1466 void eapol_sm_notify_portEnabled(struct eapol_sm *sm, bool enabled) 1467 { 1468 if (sm == NULL) 1469 return; 1470 wpa_printf(MSG_DEBUG, "EAPOL: External notification - " 1471 "portEnabled=%d", enabled); 1472 if (sm->portEnabled != enabled) 1473 sm->force_authorized_update = true; 1474 sm->portEnabled = enabled; 1475 eapol_sm_step(sm); 1476 } 1477 1478 1479 /** 1480 * eapol_sm_notify_portValid - Notification about portValid change 1481 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1482 * @valid: New portValid value 1483 * 1484 * Notify EAPOL state machine about new portValid value. 1485 */ 1486 void eapol_sm_notify_portValid(struct eapol_sm *sm, bool valid) 1487 { 1488 if (sm == NULL) 1489 return; 1490 wpa_printf(MSG_DEBUG, "EAPOL: External notification - " 1491 "portValid=%d", valid); 1492 sm->portValid = valid; 1493 eapol_sm_step(sm); 1494 } 1495 1496 1497 /** 1498 * eapol_sm_notify_eap_success - Notification of external EAP success trigger 1499 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1500 * @success: %true = set success, %false = clear success 1501 * 1502 * Notify the EAPOL state machine that external event has forced EAP state to 1503 * success (success = %true). This can be cleared by setting success = %false. 1504 * 1505 * This function is called to update EAP state when WPA-PSK key handshake has 1506 * been completed successfully since WPA-PSK does not use EAP state machine. 1507 */ 1508 void eapol_sm_notify_eap_success(struct eapol_sm *sm, bool success) 1509 { 1510 if (sm == NULL) 1511 return; 1512 wpa_printf(MSG_DEBUG, "EAPOL: External notification - " 1513 "EAP success=%d", success); 1514 sm->eapSuccess = success; 1515 sm->altAccept = success; 1516 if (success) 1517 eap_notify_success(sm->eap); 1518 eapol_sm_step(sm); 1519 } 1520 1521 1522 /** 1523 * eapol_sm_notify_eap_fail - Notification of external EAP failure trigger 1524 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1525 * @fail: %true = set failure, %false = clear failure 1526 * 1527 * Notify EAPOL state machine that external event has forced EAP state to 1528 * failure (fail = %true). This can be cleared by setting fail = %false. 1529 */ 1530 void eapol_sm_notify_eap_fail(struct eapol_sm *sm, bool fail) 1531 { 1532 if (sm == NULL) 1533 return; 1534 wpa_printf(MSG_DEBUG, "EAPOL: External notification - " 1535 "EAP fail=%d", fail); 1536 sm->eapFail = fail; 1537 sm->altReject = fail; 1538 eapol_sm_step(sm); 1539 } 1540 1541 1542 /** 1543 * eapol_sm_notify_config - Notification of EAPOL configuration change 1544 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1545 * @config: Pointer to current network EAP configuration 1546 * @conf: Pointer to EAPOL configuration data 1547 * 1548 * Notify EAPOL state machine that configuration has changed. config will be 1549 * stored as a backpointer to network configuration. This can be %NULL to clear 1550 * the stored pointed. conf will be copied to local EAPOL/EAP configuration 1551 * data. If conf is %NULL, this part of the configuration change will be 1552 * skipped. 1553 */ 1554 void eapol_sm_notify_config(struct eapol_sm *sm, 1555 struct eap_peer_config *config, 1556 const struct eapol_config *conf) 1557 { 1558 if (sm == NULL) 1559 return; 1560 1561 sm->config = config; 1562 #ifdef CONFIG_EAP_PROXY 1563 sm->use_eap_proxy = eap_proxy_notify_config(sm->eap_proxy, config) > 0; 1564 #endif /* CONFIG_EAP_PROXY */ 1565 1566 if (conf == NULL) 1567 return; 1568 1569 sm->conf.accept_802_1x_keys = conf->accept_802_1x_keys; 1570 sm->conf.required_keys = conf->required_keys; 1571 sm->conf.fast_reauth = conf->fast_reauth; 1572 sm->conf.workaround = conf->workaround; 1573 sm->conf.wps = conf->wps; 1574 #ifdef CONFIG_EAP_PROXY 1575 if (sm->use_eap_proxy) { 1576 /* Using EAP Proxy, so skip EAP state machine update */ 1577 return; 1578 } 1579 #endif /* CONFIG_EAP_PROXY */ 1580 if (sm->eap) { 1581 eap_set_fast_reauth(sm->eap, conf->fast_reauth); 1582 eap_set_workaround(sm->eap, conf->workaround); 1583 eap_set_force_disabled(sm->eap, conf->eap_disabled); 1584 eap_set_external_sim(sm->eap, conf->external_sim); 1585 } 1586 } 1587 1588 1589 /** 1590 * eapol_sm_get_key - Get master session key (MSK) from EAP 1591 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1592 * @key: Pointer for key buffer 1593 * @len: Number of bytes to copy to key 1594 * Returns: 0 on success (len of key available), maximum available key len 1595 * (>0) if key is available but it is shorter than len, or -1 on failure. 1596 * 1597 * Fetch EAP keying material (MSK, eapKeyData) from EAP state machine. The key 1598 * is available only after a successful authentication. 1599 */ 1600 int eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len) 1601 { 1602 const u8 *eap_key; 1603 size_t eap_len; 1604 1605 #ifdef CONFIG_EAP_PROXY 1606 if (sm && sm->use_eap_proxy) { 1607 /* Get key from EAP proxy */ 1608 if (sm == NULL || !eap_proxy_key_available(sm->eap_proxy)) { 1609 wpa_printf(MSG_DEBUG, "EAPOL: EAP key not available"); 1610 return -1; 1611 } 1612 eap_key = eap_proxy_get_eapKeyData(sm->eap_proxy, &eap_len); 1613 if (eap_key == NULL) { 1614 wpa_printf(MSG_DEBUG, "EAPOL: Failed to get " 1615 "eapKeyData"); 1616 return -1; 1617 } 1618 goto key_fetched; 1619 } 1620 #endif /* CONFIG_EAP_PROXY */ 1621 if (sm == NULL || !eap_key_available(sm->eap)) { 1622 wpa_printf(MSG_DEBUG, "EAPOL: EAP key not available"); 1623 return -1; 1624 } 1625 eap_key = eap_get_eapKeyData(sm->eap, &eap_len); 1626 if (eap_key == NULL) { 1627 wpa_printf(MSG_DEBUG, "EAPOL: Failed to get eapKeyData"); 1628 return -1; 1629 } 1630 #ifdef CONFIG_EAP_PROXY 1631 key_fetched: 1632 #endif /* CONFIG_EAP_PROXY */ 1633 if (len > eap_len) { 1634 wpa_printf(MSG_DEBUG, "EAPOL: Requested key length (%lu) not " 1635 "available (len=%lu)", 1636 (unsigned long) len, (unsigned long) eap_len); 1637 return eap_len; 1638 } 1639 os_memcpy(key, eap_key, len); 1640 wpa_printf(MSG_DEBUG, "EAPOL: Successfully fetched key (len=%lu)", 1641 (unsigned long) len); 1642 return 0; 1643 } 1644 1645 1646 /** 1647 * eapol_sm_get_session_id - Get EAP Session-Id 1648 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1649 * @len: Pointer to variable that will be set to number of bytes in the session 1650 * Returns: Pointer to the EAP Session-Id or %NULL on failure 1651 * 1652 * The Session-Id is available only after a successful authentication. 1653 */ 1654 const u8 * eapol_sm_get_session_id(struct eapol_sm *sm, size_t *len) 1655 { 1656 if (sm == NULL || !eap_key_available(sm->eap)) { 1657 wpa_printf(MSG_DEBUG, "EAPOL: EAP Session-Id not available"); 1658 return NULL; 1659 } 1660 return eap_get_eapSessionId(sm->eap, len); 1661 } 1662 1663 1664 /** 1665 * eapol_sm_notify_logoff - Notification of logon/logoff commands 1666 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1667 * @logoff: Whether command was logoff 1668 * 1669 * Notify EAPOL state machines that user requested logon/logoff. 1670 */ 1671 void eapol_sm_notify_logoff(struct eapol_sm *sm, bool logoff) 1672 { 1673 if (sm) { 1674 sm->userLogoff = logoff; 1675 if (!logoff) { 1676 /* If there is a delayed txStart queued, start now. */ 1677 sm->startWhen = 0; 1678 } 1679 eapol_sm_step(sm); 1680 } 1681 } 1682 1683 1684 /** 1685 * eapol_sm_notify_pmkid_attempt - Notification of successful PMKSA caching 1686 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1687 * 1688 * Notify EAPOL state machines that PMKSA caching was successful. This is used 1689 * to move EAPOL and EAP state machines into authenticated/successful state. 1690 */ 1691 void eapol_sm_notify_cached(struct eapol_sm *sm) 1692 { 1693 if (sm == NULL) 1694 return; 1695 wpa_printf(MSG_DEBUG, "EAPOL: PMKSA caching was used - skip EAPOL"); 1696 sm->eapSuccess = true; 1697 eap_notify_success(sm->eap); 1698 eapol_sm_step(sm); 1699 } 1700 1701 1702 /** 1703 * eapol_sm_notify_pmkid_attempt - Notification of PMKSA caching 1704 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1705 * 1706 * Notify EAPOL state machines if PMKSA caching is used. 1707 */ 1708 void eapol_sm_notify_pmkid_attempt(struct eapol_sm *sm) 1709 { 1710 if (sm == NULL) 1711 return; 1712 wpa_printf(MSG_DEBUG, "RSN: Trying to use cached PMKSA"); 1713 sm->cached_pmk = true; 1714 } 1715 1716 1717 static void eapol_sm_abort_cached(struct eapol_sm *sm) 1718 { 1719 wpa_printf(MSG_DEBUG, "RSN: Authenticator did not accept PMKID, " 1720 "doing full EAP authentication"); 1721 if (sm == NULL) 1722 return; 1723 sm->cached_pmk = false; 1724 sm->SUPP_PAE_state = SUPP_PAE_CONNECTING; 1725 eapol_sm_set_port_unauthorized(sm); 1726 1727 /* Make sure we do not start sending EAPOL-Start frames first, but 1728 * instead move to RESTART state to start EAPOL authentication. */ 1729 sm->startWhen = 3; 1730 eapol_enable_timer_tick(sm); 1731 1732 if (sm->ctx->aborted_cached) 1733 sm->ctx->aborted_cached(sm->ctx->ctx); 1734 } 1735 1736 1737 /** 1738 * eapol_sm_register_scard_ctx - Notification of smart card context 1739 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1740 * @ctx: Context data for smart card operations 1741 * 1742 * Notify EAPOL state machines of context data for smart card operations. This 1743 * context data will be used as a parameter for scard_*() functions. 1744 */ 1745 void eapol_sm_register_scard_ctx(struct eapol_sm *sm, void *ctx) 1746 { 1747 if (sm) { 1748 sm->ctx->scard_ctx = ctx; 1749 eap_register_scard_ctx(sm->eap, ctx); 1750 } 1751 } 1752 1753 1754 /** 1755 * eapol_sm_notify_portControl - Notification of portControl changes 1756 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1757 * @portControl: New value for portControl variable 1758 * 1759 * Notify EAPOL state machines that portControl variable has changed. 1760 */ 1761 void eapol_sm_notify_portControl(struct eapol_sm *sm, PortControl portControl) 1762 { 1763 if (sm == NULL) 1764 return; 1765 wpa_printf(MSG_DEBUG, "EAPOL: External notification - " 1766 "portControl=%s", eapol_port_control(portControl)); 1767 sm->portControl = portControl; 1768 eapol_sm_step(sm); 1769 } 1770 1771 1772 /** 1773 * eapol_sm_notify_ctrl_attached - Notification of attached monitor 1774 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1775 * 1776 * Notify EAPOL state machines that a monitor was attached to the control 1777 * interface to trigger re-sending of pending requests for user input. 1778 */ 1779 void eapol_sm_notify_ctrl_attached(struct eapol_sm *sm) 1780 { 1781 if (sm == NULL) 1782 return; 1783 eap_sm_notify_ctrl_attached(sm->eap); 1784 } 1785 1786 1787 /** 1788 * eapol_sm_notify_ctrl_response - Notification of received user input 1789 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1790 * 1791 * Notify EAPOL state machines that a control response, i.e., user 1792 * input, was received in order to trigger retrying of a pending EAP request. 1793 */ 1794 void eapol_sm_notify_ctrl_response(struct eapol_sm *sm) 1795 { 1796 if (sm == NULL) 1797 return; 1798 if (sm->eapReqData && !sm->eapReq) { 1799 wpa_printf(MSG_DEBUG, "EAPOL: received control response (user " 1800 "input) notification - retrying pending EAP " 1801 "Request"); 1802 sm->eapolEap = true; 1803 sm->eapReq = true; 1804 eapol_sm_step(sm); 1805 } 1806 } 1807 1808 1809 /** 1810 * eapol_sm_request_reauth - Request reauthentication 1811 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1812 * 1813 * This function can be used to request EAPOL reauthentication, e.g., when the 1814 * current PMKSA entry is nearing expiration. 1815 */ 1816 void eapol_sm_request_reauth(struct eapol_sm *sm) 1817 { 1818 if (sm == NULL || sm->SUPP_PAE_state != SUPP_PAE_AUTHENTICATED) 1819 return; 1820 eapol_sm_txStart(sm); 1821 } 1822 1823 1824 /** 1825 * eapol_sm_notify_lower_layer_success - Notification of lower layer success 1826 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1827 * @in_eapol_sm: Whether the caller is already running inside EAPOL state 1828 * machine loop (eapol_sm_step()) 1829 * 1830 * Notify EAPOL (and EAP) state machines that a lower layer has detected a 1831 * successful authentication. This is used to recover from dropped EAP-Success 1832 * messages. 1833 */ 1834 void eapol_sm_notify_lower_layer_success(struct eapol_sm *sm, int in_eapol_sm) 1835 { 1836 if (sm == NULL) 1837 return; 1838 eap_notify_lower_layer_success(sm->eap); 1839 if (!in_eapol_sm) 1840 eapol_sm_step(sm); 1841 } 1842 1843 1844 /** 1845 * eapol_sm_invalidate_cached_session - Mark cached EAP session data invalid 1846 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 1847 */ 1848 void eapol_sm_invalidate_cached_session(struct eapol_sm *sm) 1849 { 1850 if (sm) 1851 eap_invalidate_cached_session(sm->eap); 1852 } 1853 1854 1855 static struct eap_peer_config * eapol_sm_get_config(void *ctx) 1856 { 1857 struct eapol_sm *sm = ctx; 1858 return sm ? sm->config : NULL; 1859 } 1860 1861 1862 static struct wpabuf * eapol_sm_get_eapReqData(void *ctx) 1863 { 1864 struct eapol_sm *sm = ctx; 1865 if (sm == NULL || sm->eapReqData == NULL) 1866 return NULL; 1867 1868 return sm->eapReqData; 1869 } 1870 1871 1872 static bool eapol_sm_get_bool(void *ctx, enum eapol_bool_var variable) 1873 { 1874 struct eapol_sm *sm = ctx; 1875 if (sm == NULL) 1876 return false; 1877 switch (variable) { 1878 case EAPOL_eapSuccess: 1879 return sm->eapSuccess; 1880 case EAPOL_eapRestart: 1881 return sm->eapRestart; 1882 case EAPOL_eapFail: 1883 return sm->eapFail; 1884 case EAPOL_eapResp: 1885 return sm->eapResp; 1886 case EAPOL_eapNoResp: 1887 return sm->eapNoResp; 1888 case EAPOL_eapReq: 1889 return sm->eapReq; 1890 case EAPOL_portEnabled: 1891 return sm->portEnabled; 1892 case EAPOL_altAccept: 1893 return sm->altAccept; 1894 case EAPOL_altReject: 1895 return sm->altReject; 1896 case EAPOL_eapTriggerStart: 1897 return sm->eapTriggerStart; 1898 } 1899 return false; 1900 } 1901 1902 1903 static void eapol_sm_set_bool(void *ctx, enum eapol_bool_var variable, 1904 bool value) 1905 { 1906 struct eapol_sm *sm = ctx; 1907 if (sm == NULL) 1908 return; 1909 switch (variable) { 1910 case EAPOL_eapSuccess: 1911 sm->eapSuccess = value; 1912 break; 1913 case EAPOL_eapRestart: 1914 sm->eapRestart = value; 1915 break; 1916 case EAPOL_eapFail: 1917 sm->eapFail = value; 1918 break; 1919 case EAPOL_eapResp: 1920 sm->eapResp = value; 1921 break; 1922 case EAPOL_eapNoResp: 1923 sm->eapNoResp = value; 1924 break; 1925 case EAPOL_eapReq: 1926 sm->eapReq = value; 1927 break; 1928 case EAPOL_portEnabled: 1929 sm->portEnabled = value; 1930 break; 1931 case EAPOL_altAccept: 1932 sm->altAccept = value; 1933 break; 1934 case EAPOL_altReject: 1935 sm->altReject = value; 1936 break; 1937 case EAPOL_eapTriggerStart: 1938 sm->eapTriggerStart = value; 1939 break; 1940 } 1941 } 1942 1943 1944 static unsigned int eapol_sm_get_int(void *ctx, enum eapol_int_var variable) 1945 { 1946 struct eapol_sm *sm = ctx; 1947 if (sm == NULL) 1948 return 0; 1949 switch (variable) { 1950 case EAPOL_idleWhile: 1951 return sm->idleWhile; 1952 } 1953 return 0; 1954 } 1955 1956 1957 static void eapol_sm_set_int(void *ctx, enum eapol_int_var variable, 1958 unsigned int value) 1959 { 1960 struct eapol_sm *sm = ctx; 1961 if (sm == NULL) 1962 return; 1963 switch (variable) { 1964 case EAPOL_idleWhile: 1965 sm->idleWhile = value; 1966 if (sm->idleWhile > 0) 1967 eapol_enable_timer_tick(sm); 1968 break; 1969 } 1970 } 1971 1972 1973 static void eapol_sm_set_config_blob(void *ctx, struct wpa_config_blob *blob) 1974 { 1975 #ifndef CONFIG_NO_CONFIG_BLOBS 1976 struct eapol_sm *sm = ctx; 1977 if (sm && sm->ctx && sm->ctx->set_config_blob) 1978 sm->ctx->set_config_blob(sm->ctx->ctx, blob); 1979 #endif /* CONFIG_NO_CONFIG_BLOBS */ 1980 } 1981 1982 1983 static const struct wpa_config_blob * 1984 eapol_sm_get_config_blob(void *ctx, const char *name) 1985 { 1986 #ifndef CONFIG_NO_CONFIG_BLOBS 1987 struct eapol_sm *sm = ctx; 1988 if (sm && sm->ctx && sm->ctx->get_config_blob) 1989 return sm->ctx->get_config_blob(sm->ctx->ctx, name); 1990 else 1991 return NULL; 1992 #else /* CONFIG_NO_CONFIG_BLOBS */ 1993 return NULL; 1994 #endif /* CONFIG_NO_CONFIG_BLOBS */ 1995 } 1996 1997 1998 static void eapol_sm_notify_pending(void *ctx) 1999 { 2000 struct eapol_sm *sm = ctx; 2001 if (sm == NULL) 2002 return; 2003 if (sm->eapReqData && !sm->eapReq) { 2004 wpa_printf(MSG_DEBUG, "EAPOL: received notification from EAP " 2005 "state machine - retrying pending EAP Request"); 2006 sm->eapolEap = true; 2007 sm->eapReq = true; 2008 eapol_sm_step(sm); 2009 } 2010 } 2011 2012 2013 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 2014 static void eapol_sm_eap_param_needed(void *ctx, enum wpa_ctrl_req_type field, 2015 const char *txt) 2016 { 2017 struct eapol_sm *sm = ctx; 2018 wpa_printf(MSG_DEBUG, "EAPOL: EAP parameter needed"); 2019 if (sm->ctx->eap_param_needed) 2020 sm->ctx->eap_param_needed(sm->ctx->ctx, field, txt); 2021 } 2022 #else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 2023 #define eapol_sm_eap_param_needed NULL 2024 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 2025 2026 static void eapol_sm_notify_cert(void *ctx, struct tls_cert_data *cert, 2027 const char *cert_hash) 2028 { 2029 struct eapol_sm *sm = ctx; 2030 if (sm->ctx->cert_cb) 2031 sm->ctx->cert_cb(sm->ctx->ctx, cert, cert_hash); 2032 } 2033 2034 2035 static void eapol_sm_notify_status(void *ctx, const char *status, 2036 const char *parameter) 2037 { 2038 struct eapol_sm *sm = ctx; 2039 2040 if (sm->ctx->status_cb) 2041 sm->ctx->status_cb(sm->ctx->ctx, status, parameter); 2042 } 2043 2044 2045 static void eapol_sm_notify_eap_error(void *ctx, int error_code) 2046 { 2047 struct eapol_sm *sm = ctx; 2048 2049 if (sm->ctx->eap_error_cb) 2050 sm->ctx->eap_error_cb(sm->ctx->ctx, error_code); 2051 } 2052 2053 2054 #ifdef CONFIG_EAP_PROXY 2055 2056 static void eapol_sm_eap_proxy_cb(void *ctx) 2057 { 2058 struct eapol_sm *sm = ctx; 2059 2060 if (sm->ctx->eap_proxy_cb) 2061 sm->ctx->eap_proxy_cb(sm->ctx->ctx); 2062 } 2063 2064 2065 static void 2066 eapol_sm_eap_proxy_notify_sim_status(void *ctx, 2067 enum eap_proxy_sim_state sim_state) 2068 { 2069 struct eapol_sm *sm = ctx; 2070 2071 if (sm->ctx->eap_proxy_notify_sim_status) 2072 sm->ctx->eap_proxy_notify_sim_status(sm->ctx->ctx, sim_state); 2073 } 2074 2075 #endif /* CONFIG_EAP_PROXY */ 2076 2077 2078 static void eapol_sm_set_anon_id(void *ctx, const u8 *id, size_t len) 2079 { 2080 struct eapol_sm *sm = ctx; 2081 2082 if (sm->ctx->set_anon_id) 2083 sm->ctx->set_anon_id(sm->ctx->ctx, id, len); 2084 } 2085 2086 2087 static const struct eapol_callbacks eapol_cb = 2088 { 2089 eapol_sm_get_config, 2090 eapol_sm_get_bool, 2091 eapol_sm_set_bool, 2092 eapol_sm_get_int, 2093 eapol_sm_set_int, 2094 eapol_sm_get_eapReqData, 2095 eapol_sm_set_config_blob, 2096 eapol_sm_get_config_blob, 2097 eapol_sm_notify_pending, 2098 eapol_sm_eap_param_needed, 2099 eapol_sm_notify_cert, 2100 eapol_sm_notify_status, 2101 eapol_sm_notify_eap_error, 2102 #ifdef CONFIG_EAP_PROXY 2103 eapol_sm_eap_proxy_cb, 2104 eapol_sm_eap_proxy_notify_sim_status, 2105 eapol_sm_get_eap_proxy_imsi, 2106 #endif /* CONFIG_EAP_PROXY */ 2107 eapol_sm_set_anon_id 2108 }; 2109 2110 2111 /** 2112 * eapol_sm_init - Initialize EAPOL state machine 2113 * @ctx: Pointer to EAPOL context data; this needs to be an allocated buffer 2114 * and EAPOL state machine will free it in eapol_sm_deinit() 2115 * Returns: Pointer to the allocated EAPOL state machine or %NULL on failure 2116 * 2117 * Allocate and initialize an EAPOL state machine. 2118 */ 2119 struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx) 2120 { 2121 struct eapol_sm *sm; 2122 struct eap_config conf; 2123 sm = os_zalloc(sizeof(*sm)); 2124 if (sm == NULL) 2125 return NULL; 2126 sm->ctx = ctx; 2127 2128 sm->portControl = Auto; 2129 2130 /* Supplicant PAE state machine */ 2131 sm->heldPeriod = 60; 2132 sm->startPeriod = 30; 2133 sm->maxStart = 3; 2134 2135 /* Supplicant Backend state machine */ 2136 sm->authPeriod = 30; 2137 2138 os_memset(&conf, 0, sizeof(conf)); 2139 #ifndef CONFIG_OPENSC_ENGINE_PATH 2140 conf.opensc_engine_path = ctx->opensc_engine_path; 2141 #endif /* CONFIG_OPENSC_ENGINE_PATH */ 2142 #ifndef CONFIG_PKCS11_ENGINE_PATH 2143 conf.pkcs11_engine_path = ctx->pkcs11_engine_path; 2144 #endif /* CONFIG_PKCS11_ENGINE_PATH */ 2145 #ifndef CONFIG_PKCS11_MODULE_PATH 2146 conf.pkcs11_module_path = ctx->pkcs11_module_path; 2147 #endif /* CONFIG_PKCS11_MODULE_PATH */ 2148 conf.openssl_ciphers = ctx->openssl_ciphers; 2149 conf.wps = ctx->wps; 2150 conf.cert_in_cb = ctx->cert_in_cb; 2151 2152 sm->eap = eap_peer_sm_init(sm, &eapol_cb, sm->ctx->msg_ctx, &conf); 2153 if (sm->eap == NULL) { 2154 os_free(sm); 2155 return NULL; 2156 } 2157 2158 #ifdef CONFIG_EAP_PROXY 2159 sm->use_eap_proxy = false; 2160 sm->eap_proxy = eap_proxy_init(sm, &eapol_cb, sm->ctx->msg_ctx); 2161 if (sm->eap_proxy == NULL) { 2162 wpa_printf(MSG_ERROR, "Unable to initialize EAP Proxy"); 2163 } 2164 #endif /* CONFIG_EAP_PROXY */ 2165 2166 /* Initialize EAPOL state machines */ 2167 sm->force_authorized_update = true; 2168 sm->initialize = true; 2169 eapol_sm_step(sm); 2170 sm->initialize = false; 2171 eapol_sm_step(sm); 2172 2173 if (eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm) == 0) 2174 sm->timer_tick_enabled = 1; 2175 2176 return sm; 2177 } 2178 2179 2180 /** 2181 * eapol_sm_deinit - Deinitialize EAPOL state machine 2182 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init() 2183 * 2184 * Deinitialize and free EAPOL state machine. 2185 */ 2186 void eapol_sm_deinit(struct eapol_sm *sm) 2187 { 2188 if (sm == NULL) 2189 return; 2190 eloop_cancel_timeout(eapol_sm_step_timeout, NULL, sm); 2191 eloop_cancel_timeout(eapol_port_timers_tick, NULL, sm); 2192 eap_peer_sm_deinit(sm->eap); 2193 #ifdef CONFIG_EAP_PROXY 2194 eap_proxy_deinit(sm->eap_proxy); 2195 #endif /* CONFIG_EAP_PROXY */ 2196 os_free(sm->last_rx_key); 2197 wpabuf_free(sm->eapReqData); 2198 os_free(sm->ctx); 2199 os_free(sm); 2200 } 2201 2202 2203 void eapol_sm_set_ext_pw_ctx(struct eapol_sm *sm, 2204 struct ext_password_data *ext) 2205 { 2206 if (sm && sm->eap) 2207 eap_sm_set_ext_pw_ctx(sm->eap, ext); 2208 } 2209 2210 2211 int eapol_sm_failed(struct eapol_sm *sm) 2212 { 2213 if (sm == NULL) 2214 return 0; 2215 return !sm->eapSuccess && sm->eapFail; 2216 } 2217 2218 2219 #ifdef CONFIG_EAP_PROXY 2220 int eapol_sm_get_eap_proxy_imsi(void *ctx, int sim_num, char *imsi, size_t *len) 2221 { 2222 struct eapol_sm *sm = ctx; 2223 2224 if (sm->eap_proxy == NULL) 2225 return -1; 2226 return eap_proxy_get_imsi(sm->eap_proxy, sim_num, imsi, len); 2227 } 2228 #endif /* CONFIG_EAP_PROXY */ 2229 2230 2231 void eapol_sm_erp_flush(struct eapol_sm *sm) 2232 { 2233 if (sm) 2234 eap_peer_erp_free_keys(sm->eap); 2235 } 2236 2237 2238 struct wpabuf * eapol_sm_build_erp_reauth_start(struct eapol_sm *sm) 2239 { 2240 #ifdef CONFIG_ERP 2241 if (!sm) 2242 return NULL; 2243 return eap_peer_build_erp_reauth_start(sm->eap, 0); 2244 #else /* CONFIG_ERP */ 2245 return NULL; 2246 #endif /* CONFIG_ERP */ 2247 } 2248 2249 2250 void eapol_sm_process_erp_finish(struct eapol_sm *sm, const u8 *buf, 2251 size_t len) 2252 { 2253 #ifdef CONFIG_ERP 2254 if (!sm) 2255 return; 2256 eap_peer_finish(sm->eap, (const struct eap_hdr *) buf, len); 2257 #endif /* CONFIG_ERP */ 2258 } 2259 2260 2261 int eapol_sm_update_erp_next_seq_num(struct eapol_sm *sm, u16 next_seq_num) 2262 { 2263 #ifdef CONFIG_ERP 2264 if (!sm) 2265 return -1; 2266 return eap_peer_update_erp_next_seq_num(sm->eap, next_seq_num); 2267 #else /* CONFIG_ERP */ 2268 return -1; 2269 #endif /* CONFIG_ERP */ 2270 } 2271 2272 2273 int eapol_sm_get_erp_info(struct eapol_sm *sm, struct eap_peer_config *config, 2274 const u8 **username, size_t *username_len, 2275 const u8 **realm, size_t *realm_len, 2276 u16 *erp_next_seq_num, const u8 **rrk, 2277 size_t *rrk_len) 2278 { 2279 #ifdef CONFIG_ERP 2280 if (!sm) 2281 return -1; 2282 return eap_peer_get_erp_info(sm->eap, config, username, username_len, 2283 realm, realm_len, erp_next_seq_num, rrk, 2284 rrk_len); 2285 #else /* CONFIG_ERP */ 2286 return -1; 2287 #endif /* CONFIG_ERP */ 2288 } 2289