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