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