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