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