2 * EAPOL supplicant state machines
3 * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
12 #include "state_machine.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"
22 #define STATE_MACHINE_DATA struct eapol_sm
23 #define STATE_MACHINE_DEBUG_PREFIX "EAPOL"
26 /* IEEE 802.1X-2004 - Supplicant - EAPOL state machines */
29 * struct eapol_sm - Internal data for EAPOL state machines
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;
39 /* Global variables */
46 PortControl portControl;
48 PortStatus suppPortStatus; /* dot1xSuppControlledPortStatus */
56 /* Supplicant PAE state machine */
59 SUPP_PAE_DISCONNECTED = 1,
61 SUPP_PAE_CONNECTING = 3,
62 SUPP_PAE_AUTHENTICATING = 4,
63 SUPP_PAE_AUTHENTICATED = 5,
67 SUPP_PAE_S_FORCE_AUTH = 9,
68 SUPP_PAE_S_FORCE_UNAUTH = 10
69 } SUPP_PAE_state; /* dot1xSuppPaeState */
73 unsigned int startCount;
75 PortControl sPortMode;
77 unsigned int heldPeriod; /* dot1xSuppHeldPeriod */
78 unsigned int startPeriod; /* dot1xSuppStartPeriod */
79 unsigned int maxStart; /* dot1xSuppMaxStart */
81 /* Key Receive state machine */
84 KEY_RX_NO_KEY_RECEIVE, KEY_RX_KEY_RECEIVE
89 /* Supplicant Backend state machine */
92 SUPP_BE_INITIALIZE = 1,
100 } SUPP_BE_state; /* dot1xSuppBackendPaeState */
106 unsigned int authPeriod; /* dot1xSuppAuthPeriod */
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];
121 /* Miscellaneous variables (not defined in IEEE 802.1X-2004) */
124 struct eap_peer_config *config;
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 }
140 Boolean unicast_key_received, broadcast_key_received;
142 Boolean force_authorized_update;
144 #ifdef CONFIG_EAP_PROXY
145 Boolean use_eap_proxy;
146 struct eap_proxy_sm *eap_proxy;
147 #endif /* CONFIG_EAP_PROXY */
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);
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)
167 struct eapol_sm *sm = timeout_ctx;
169 if (sm->authWhile > 0) {
171 if (sm->authWhile == 0)
172 wpa_printf(MSG_DEBUG, "EAPOL: authWhile --> 0");
174 if (sm->heldWhile > 0) {
176 if (sm->heldWhile == 0)
177 wpa_printf(MSG_DEBUG, "EAPOL: heldWhile --> 0");
179 if (sm->startWhen > 0) {
181 if (sm->startWhen == 0)
182 wpa_printf(MSG_DEBUG, "EAPOL: startWhen --> 0");
184 if (sm->idleWhile > 0) {
186 if (sm->idleWhile == 0)
187 wpa_printf(MSG_DEBUG, "EAPOL: idleWhile --> 0");
190 if (sm->authWhile | sm->heldWhile | sm->startWhen | sm->idleWhile) {
191 eloop_register_timeout(1, 0, eapol_port_timers_tick, eloop_ctx,
194 wpa_printf(MSG_DEBUG, "EAPOL: disable timer tick");
195 sm->timer_tick_enabled = 0;
201 static void eapol_enable_timer_tick(struct eapol_sm *sm)
203 if (sm->timer_tick_enabled)
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);
212 SM_STATE(SUPP_PAE, LOGOFF)
214 SM_ENTRY(SUPP_PAE, LOGOFF);
215 eapol_sm_txLogoff(sm);
216 sm->logoffSent = TRUE;
217 eapol_sm_set_port_unauthorized(sm);
221 SM_STATE(SUPP_PAE, DISCONNECTED)
223 SM_ENTRY(SUPP_PAE, DISCONNECTED);
224 sm->sPortMode = Auto;
226 sm->eapTriggerStart = FALSE;
227 sm->logoffSent = FALSE;
228 eapol_sm_set_port_unauthorized(sm);
229 sm->suppAbort = TRUE;
231 sm->unicast_key_received = FALSE;
232 sm->broadcast_key_received = FALSE;
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
245 SM_STATE(SUPP_PAE, CONNECTING)
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);
251 if (sm->eapTriggerStart)
253 sm->eapTriggerStart = FALSE;
256 sm->startWhen = sm->startPeriod;
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.
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");
275 eapol_enable_timer_tick(sm);
276 sm->eapolEap = FALSE;
278 eapol_sm_txStart(sm);
282 SM_STATE(SUPP_PAE, AUTHENTICATING)
284 SM_ENTRY(SUPP_PAE, AUTHENTICATING);
286 sm->suppSuccess = FALSE;
287 sm->suppFail = FALSE;
288 sm->suppTimeout = FALSE;
291 sm->suppStart = TRUE;
295 SM_STATE(SUPP_PAE, HELD)
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;
305 SM_STATE(SUPP_PAE, AUTHENTICATED)
307 SM_ENTRY(SUPP_PAE, AUTHENTICATED);
308 eapol_sm_set_port_authorized(sm);
309 sm->cb_status = EAPOL_CB_SUCCESS;
313 SM_STATE(SUPP_PAE, RESTART)
315 SM_ENTRY(SUPP_PAE, RESTART);
316 sm->eapRestart = TRUE;
320 SM_STATE(SUPP_PAE, S_FORCE_AUTH)
322 SM_ENTRY(SUPP_PAE, S_FORCE_AUTH);
323 eapol_sm_set_port_authorized(sm);
324 sm->sPortMode = ForceAuthorized;
328 SM_STATE(SUPP_PAE, S_FORCE_UNAUTH)
330 SM_ENTRY(SUPP_PAE, S_FORCE_UNAUTH);
331 eapol_sm_set_port_unauthorized(sm);
332 sm->sPortMode = ForceUnauthorized;
333 eapol_sm_txLogoff(sm);
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:
357 case SUPP_PAE_LOGOFF:
359 SM_ENTER(SUPP_PAE, DISCONNECTED);
361 case SUPP_PAE_DISCONNECTED:
362 SM_ENTER(SUPP_PAE, CONNECTING);
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 &&
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 &&
378 SM_ENTER(SUPP_PAE, HELD);
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 "
387 sm->portValid = TRUE;
388 if (sm->ctx->eapol_done_cb)
389 sm->ctx->eapol_done_cb(sm->ctx->ctx);
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);
401 if (sm->heldWhile == 0)
402 SM_ENTER(SUPP_PAE, CONNECTING);
403 else if (sm->eapolEap)
404 SM_ENTER(SUPP_PAE, RESTART);
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);
412 case SUPP_PAE_RESTART:
414 SM_ENTER(SUPP_PAE, AUTHENTICATING);
416 case SUPP_PAE_S_FORCE_AUTH:
418 case SUPP_PAE_S_FORCE_UNAUTH:
424 SM_STATE(KEY_RX, NO_KEY_RECEIVE)
426 SM_ENTRY(KEY_RX, NO_KEY_RECEIVE);
430 SM_STATE(KEY_RX, KEY_RECEIVE)
432 SM_ENTRY(KEY_RX, KEY_RECEIVE);
433 eapol_sm_processKey(sm);
440 if (sm->initialize || !sm->portEnabled)
441 SM_ENTER_GLOBAL(KEY_RX, NO_KEY_RECEIVE);
442 switch (sm->KEY_RX_state) {
445 case KEY_RX_NO_KEY_RECEIVE:
447 SM_ENTER(KEY_RX, KEY_RECEIVE);
449 case KEY_RX_KEY_RECEIVE:
451 SM_ENTER(KEY_RX, KEY_RECEIVE);
457 SM_STATE(SUPP_BE, REQUEST)
459 SM_ENTRY(SUPP_BE, REQUEST);
462 eapol_sm_getSuppRsp(sm);
466 SM_STATE(SUPP_BE, RESPONSE)
468 SM_ENTRY(SUPP_BE, RESPONSE);
469 eapol_sm_txSuppRsp(sm);
474 SM_STATE(SUPP_BE, SUCCESS)
476 SM_ENTRY(SUPP_BE, SUCCESS);
478 sm->suppSuccess = TRUE;
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
485 sm->replay_counter_valid = FALSE;
489 #endif /* CONFIG_EAP_PROXY */
491 if (eap_key_available(sm->eap)) {
492 /* New key received - clear IEEE 802.1X EAPOL-Key replay
494 sm->replay_counter_valid = FALSE;
499 SM_STATE(SUPP_BE, FAIL)
501 SM_ENTRY(SUPP_BE, FAIL);
506 SM_STATE(SUPP_BE, TIMEOUT)
508 SM_ENTRY(SUPP_BE, TIMEOUT);
509 sm->suppTimeout = TRUE;
513 SM_STATE(SUPP_BE, IDLE)
515 SM_ENTRY(SUPP_BE, IDLE);
516 sm->suppStart = FALSE;
517 sm->initial_req = TRUE;
521 SM_STATE(SUPP_BE, INITIALIZE)
523 SM_ENTRY(SUPP_BE, INITIALIZE);
524 eapol_sm_abortSupp(sm);
525 sm->suppAbort = FALSE;
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
538 SM_STATE(SUPP_BE, RECEIVE)
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;
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:
556 case SUPP_BE_REQUEST:
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.
571 if (sm->eapResp && sm->eapNoResp) {
572 wpa_printf(MSG_DEBUG, "EAPOL: SUPP_BE REQUEST: both "
573 "eapResp and eapNoResp set?!");
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);
584 case SUPP_BE_RESPONSE:
585 SM_ENTER(SUPP_BE, RECEIVE);
587 case SUPP_BE_SUCCESS:
588 SM_ENTER(SUPP_BE, IDLE);
591 SM_ENTER(SUPP_BE, IDLE);
593 case SUPP_BE_TIMEOUT:
594 SM_ENTER(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);
604 case SUPP_BE_INITIALIZE:
605 SM_ENTER(SUPP_BE, IDLE);
607 case SUPP_BE_RECEIVE:
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);
621 static void eapol_sm_txLogoff(struct eapol_sm *sm)
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++;
631 static void eapol_sm_txStart(struct eapol_sm *sm)
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++;
641 #define IEEE8021X_ENCR_KEY_LEN 32
642 #define IEEE8021X_SIGN_KEY_LEN 32
644 struct eap_key_data {
645 u8 encr_key[IEEE8021X_ENCR_KEY_LEN];
646 u8 sign_key[IEEE8021X_SIGN_KEY_LEN];
650 static void eapol_sm_processKey(struct eapol_sm *sm)
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;
664 wpa_printf(MSG_DEBUG, "EAPOL: processKey");
665 if (sm->last_rx_key == NULL)
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");
675 if (sm->last_rx_key_len < sizeof(*hdr) + sizeof(*key))
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");
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);
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));
695 wpa_printf(MSG_DEBUG, "EAPOL: Could not get master key for "
696 "decrypting EAPOL-Key keys");
700 /* LEAP derives only 16 bytes of keying material. */
701 res = eapol_sm_get_key(sm, (u8 *) &keydata, 16);
703 wpa_printf(MSG_DEBUG, "EAPOL: Could not get LEAP "
704 "master key for decrypting EAPOL-Key keys");
709 os_memcpy(keydata.sign_key, keydata.encr_key, 16);
711 wpa_printf(MSG_DEBUG, "EAPOL: Could not get enough master key "
712 "data for decrypting EAPOL-Key keys (res=%d)", res);
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);
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),
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 "
740 os_memcpy(key->key_signature, orig_key_sign,
741 IEEE8021X_KEY_SIGN_LEN);
744 wpa_printf(MSG_DEBUG, "EAPOL: EAPOL-Key key signature verified");
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);
752 if (key_len == rx_key_length) {
755 /* otherwise unused */
757 wpa_printf(MSG_ERROR, "EAPOL: RC4 not supported in the build");
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,
763 os_memcpy(datakey, key + 1, key_len);
764 rc4_skip(ekey, IEEE8021X_KEY_IV_LEN + encr_key_len, 0,
766 wpa_hexdump_key(MSG_DEBUG, "EAPOL: Decrypted(RC4) key",
768 #endif /* CONFIG_NO_RC4 */
769 } else if (key_len == 0) {
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.
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",
785 wpa_printf(MSG_DEBUG, "EAPOL: Invalid key data length %d "
786 "(key_length=%d)", key_len, rx_key_length);
790 sm->replay_counter_valid = TRUE;
791 os_memcpy(sm->last_replay_counter, key->replay_counter,
792 IEEE8021X_REPLAY_COUNTER_LEN);
794 wpa_printf(MSG_DEBUG, "EAPOL: Setting dynamic WEP key: %s keyidx %d "
796 key->key_index & IEEE8021X_KEY_INDEX_FLAG ?
797 "unicast" : "broadcast",
798 key->key_index & IEEE8021X_KEY_INDEX_MASK, key_len);
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 "
808 if (key->key_index & IEEE8021X_KEY_INDEX_FLAG)
809 sm->unicast_key_received = TRUE;
811 sm->broadcast_key_received = TRUE;
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)))
818 wpa_printf(MSG_DEBUG, "EAPOL: all required EAPOL-Key "
820 sm->portValid = TRUE;
821 if (sm->ctx->eapol_done_cb)
822 sm->ctx->eapol_done_cb(sm->ctx->ctx);
825 #endif /* CONFIG_FIPS */
829 static void eapol_sm_getSuppRsp(struct eapol_sm *sm)
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
839 static void eapol_sm_txSuppRsp(struct eapol_sm *sm)
843 wpa_printf(MSG_DEBUG, "EAPOL: txSuppRsp");
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);
850 wpa_printf(MSG_WARNING, "EAPOL: txSuppRsp - EAP Proxy "
851 "response data not available");
855 #endif /* CONFIG_EAP_PROXY */
857 resp = eap_get_eapRespData(sm->eap);
859 wpa_printf(MSG_WARNING, "EAPOL: txSuppRsp - EAP response data "
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),
869 /* eapRespData is not used anymore, so free it here */
873 sm->dot1xSuppEapolReqIdFramesRx++;
875 sm->dot1xSuppEapolReqFramesRx++;
876 sm->dot1xSuppEapolRespFramesTx++;
877 sm->dot1xSuppEapolFramesTx++;
881 static void eapol_sm_abortSupp(struct eapol_sm *sm)
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);
893 static void eapol_sm_step_timeout(void *eloop_ctx, void *timeout_ctx)
895 eapol_sm_step(timeout_ctx);
899 static void eapol_sm_set_port_authorized(struct eapol_sm *sm)
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);
911 static void eapol_sm_set_port_unauthorized(struct eapol_sm *sm)
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);
924 * eapol_sm_step - EAPOL state machine step function
925 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
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.
931 void eapol_sm_step(struct eapol_sm *sm)
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++) {
941 SM_STEP_RUN(SUPP_PAE);
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))
950 #endif /* CONFIG_EAP_PROXY */
951 if (eap_peer_sm_step(sm->eap))
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);
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;
971 result = EAPOL_SUPP_RESULT_FAILURE;
972 sm->cb_status = EAPOL_CB_IN_PROGRESS;
973 sm->ctx->cb(sm, result, sm->ctx->cb_ctx);
978 #ifdef CONFIG_CTRL_IFACE
979 static const char *eapol_supp_pae_state(int state)
982 case SUPP_PAE_LOGOFF:
984 case SUPP_PAE_DISCONNECTED:
985 return "DISCONNECTED";
986 case SUPP_PAE_CONNECTING:
988 case SUPP_PAE_AUTHENTICATING:
989 return "AUTHENTICATING";
992 case SUPP_PAE_AUTHENTICATED:
993 return "AUTHENTICATED";
994 case SUPP_PAE_RESTART:
1002 static const char *eapol_supp_be_state(int state)
1005 case SUPP_BE_REQUEST:
1007 case SUPP_BE_RESPONSE:
1009 case SUPP_BE_SUCCESS:
1013 case SUPP_BE_TIMEOUT:
1017 case SUPP_BE_INITIALIZE:
1018 return "INITIALIZE";
1019 case SUPP_BE_RECEIVE:
1027 static const char * eapol_port_status(PortStatus status)
1029 if (status == Authorized)
1030 return "Authorized";
1032 return "Unauthorized";
1034 #endif /* CONFIG_CTRL_IFACE */
1037 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
1038 static const char * eapol_port_control(PortControl ctrl)
1043 case ForceUnauthorized:
1044 return "ForceUnauthorized";
1045 case ForceAuthorized:
1046 return "ForceAuthorized";
1051 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
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
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).
1065 void eapol_sm_configure(struct eapol_sm *sm, int heldPeriod, int authPeriod,
1066 int startPeriod, int maxStart)
1070 if (heldPeriod >= 0)
1071 sm->heldPeriod = heldPeriod;
1072 if (authPeriod >= 0)
1073 sm->authPeriod = authPeriod;
1074 if (startPeriod >= 0)
1075 sm->startPeriod = startPeriod;
1077 sm->maxStart = maxStart;
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
1086 const char * eapol_sm_get_method_name(struct eapol_sm *sm)
1088 if (sm->SUPP_PAE_state != SUPP_PAE_AUTHENTICATED ||
1089 sm->suppPortStatus != Authorized)
1092 return eap_sm_get_method_name(sm->eap);
1096 #ifdef CONFIG_CTRL_IFACE
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.
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.
1110 int eapol_sm_get_status(struct eapol_sm *sm, char *buf, size_t buflen,
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))
1126 ret = os_snprintf(buf + len, buflen - len,
1132 "Supplicant Backend state=%s\n",
1137 eapol_port_control(sm->portControl),
1138 eapol_supp_be_state(sm->SUPP_BE_state));
1139 if (os_snprintf_error(buflen - len, ret))
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,
1150 #endif /* CONFIG_EAP_PROXY */
1151 len += eap_sm_get_status(sm->eap, buf + len, buflen - len, verbose);
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.
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
1169 int eapol_sm_get_mib(struct eapol_sm *sm, char *buf, size_t buflen)
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",
1189 sm->suppPortStatus == Authorized ?
1190 "Authorized" : "Unauthorized",
1193 if (os_snprintf_error(buflen, ret))
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));
1221 if (os_snprintf_error(buflen - len, ret))
1227 #endif /* CONFIG_CTRL_IFACE */
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,
1239 int eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src, const u8 *buf,
1242 const struct ieee802_1x_hdr *hdr;
1243 const struct ieee802_1x_eapol_key *key;
1250 sm->dot1xSuppEapolFramesRx++;
1251 if (len < sizeof(*hdr)) {
1252 sm->dot1xSuppInvalidEapolFramesRx++;
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 */
1261 plen = be_to_host16(hdr->length);
1262 if (plen > len - sizeof(*hdr)) {
1263 sm->dot1xSuppEapLengthErrorFramesRx++;
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);
1275 elen = be_to_host16(ehdr->length);
1276 if (elen > plen && elen <= len - sizeof(*hdr)) {
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.
1284 wpa_printf(MSG_DEBUG, "EAPOL: Workaround - fix EAPOL "
1285 "payload length based on EAP header: "
1286 "%d -> %d", (int) plen, elen);
1290 #endif /* CONFIG_WPS */
1291 data_len = plen + sizeof(*hdr);
1293 switch (hdr->type) {
1294 case IEEE802_1X_TYPE_EAP_PACKET:
1295 if (sm->conf.workaround) {
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
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");
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.
1318 eapol_sm_abort_cached(sm);
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 "
1325 sm->eapolEap = TRUE;
1326 #ifdef CONFIG_EAP_PROXY
1327 if (sm->use_eap_proxy) {
1328 eap_proxy_packet_update(
1330 wpabuf_mhead_u8(sm->eapReqData),
1331 wpabuf_len(sm->eapReqData));
1332 wpa_printf(MSG_DEBUG, "EAPOL: eap_proxy "
1335 #endif /* CONFIG_EAP_PROXY */
1339 case IEEE802_1X_TYPE_EAPOL_KEY:
1340 if (plen < sizeof(*key)) {
1341 wpa_printf(MSG_DEBUG, "EAPOL: Too short EAPOL-Key "
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");
1354 if (key->type != EAPOL_KEY_TYPE_RC4) {
1355 wpa_printf(MSG_DEBUG, "EAPOL: Ignored unknown "
1356 "EAPOL-Key type %d", key->type);
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 "
1364 os_memcpy(sm->last_rx_key, buf, data_len);
1365 sm->last_rx_key_len = data_len;
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",
1376 #endif /* CONFIG_MACSEC */
1378 wpa_printf(MSG_DEBUG, "EAPOL: Received unknown EAPOL type %d",
1380 sm->dot1xSuppInvalidEapolFramesRx++;
1389 * eapol_sm_notify_tx_eapol_key - Notification about transmitted EAPOL packet
1390 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1392 * Notify EAPOL state machine about transmitted EAPOL packet from an external
1393 * component, e.g., WPA. This will update the statistics.
1395 void eapol_sm_notify_tx_eapol_key(struct eapol_sm *sm)
1398 sm->dot1xSuppEapolFramesTx++;
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
1407 * Notify EAPOL state machine about new portEnabled value.
1409 void eapol_sm_notify_portEnabled(struct eapol_sm *sm, Boolean enabled)
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;
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
1427 * Notify EAPOL state machine about new portValid value.
1429 void eapol_sm_notify_portValid(struct eapol_sm *sm, Boolean valid)
1433 wpa_printf(MSG_DEBUG, "EAPOL: External notification - "
1434 "portValid=%d", valid);
1435 sm->portValid = valid;
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
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.
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.
1451 void eapol_sm_notify_eap_success(struct eapol_sm *sm, Boolean success)
1455 wpa_printf(MSG_DEBUG, "EAPOL: External notification - "
1456 "EAP success=%d", success);
1457 sm->eapSuccess = success;
1458 sm->altAccept = success;
1460 eap_notify_success(sm->eap);
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
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.
1473 void eapol_sm_notify_eap_fail(struct eapol_sm *sm, Boolean fail)
1477 wpa_printf(MSG_DEBUG, "EAPOL: External notification - "
1478 "EAP fail=%d", fail);
1480 sm->altReject = fail;
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
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
1497 void eapol_sm_notify_config(struct eapol_sm *sm,
1498 struct eap_peer_config *config,
1499 const struct eapol_config *conf)
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 */
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 */
1522 #endif /* CONFIG_EAP_PROXY */
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);
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.
1540 * Fetch EAP keying material (MSK, eapKeyData) from EAP state machine. The key
1541 * is available only after a successful authentication.
1543 int eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len)
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");
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 "
1563 #endif /* CONFIG_EAP_PROXY */
1564 if (sm == NULL || !eap_key_available(sm->eap)) {
1565 wpa_printf(MSG_DEBUG, "EAPOL: EAP key not available");
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");
1573 #ifdef CONFIG_EAP_PROXY
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);
1582 os_memcpy(key, eap_key, len);
1583 wpa_printf(MSG_DEBUG, "EAPOL: Successfully fetched key (len=%lu)",
1584 (unsigned long) len);
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
1595 * The Session-Id is available only after a successful authentication.
1597 const u8 * eapol_sm_get_session_id(struct eapol_sm *sm, size_t *len)
1599 if (sm == NULL || !eap_key_available(sm->eap)) {
1600 wpa_printf(MSG_DEBUG, "EAPOL: EAP Session-Id not available");
1603 return eap_get_eapSessionId(sm->eap, len);
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
1612 * Notify EAPOL state machines that user requested logon/logoff.
1614 void eapol_sm_notify_logoff(struct eapol_sm *sm, Boolean logoff)
1617 sm->userLogoff = logoff;
1619 /* If there is a delayed txStart queued, start now. */
1628 * eapol_sm_notify_pmkid_attempt - Notification of successful PMKSA caching
1629 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
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.
1634 void eapol_sm_notify_cached(struct eapol_sm *sm)
1638 wpa_printf(MSG_DEBUG, "EAPOL: PMKSA caching was used - skip EAPOL");
1639 sm->eapSuccess = TRUE;
1640 eap_notify_success(sm->eap);
1646 * eapol_sm_notify_pmkid_attempt - Notification of PMKSA caching
1647 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1649 * Notify EAPOL state machines if PMKSA caching is used.
1651 void eapol_sm_notify_pmkid_attempt(struct eapol_sm *sm)
1655 wpa_printf(MSG_DEBUG, "RSN: Trying to use cached PMKSA");
1656 sm->cached_pmk = TRUE;
1660 static void eapol_sm_abort_cached(struct eapol_sm *sm)
1662 wpa_printf(MSG_DEBUG, "RSN: Authenticator did not accept PMKID, "
1663 "doing full EAP authentication");
1666 sm->cached_pmk = FALSE;
1667 sm->SUPP_PAE_state = SUPP_PAE_CONNECTING;
1668 eapol_sm_set_port_unauthorized(sm);
1670 /* Make sure we do not start sending EAPOL-Start frames first, but
1671 * instead move to RESTART state to start EAPOL authentication. */
1673 eapol_enable_timer_tick(sm);
1675 if (sm->ctx->aborted_cached)
1676 sm->ctx->aborted_cached(sm->ctx->ctx);
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
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.
1688 void eapol_sm_register_scard_ctx(struct eapol_sm *sm, void *ctx)
1691 sm->ctx->scard_ctx = ctx;
1692 eap_register_scard_ctx(sm->eap, ctx);
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
1702 * Notify EAPOL state machines that portControl variable has changed.
1704 void eapol_sm_notify_portControl(struct eapol_sm *sm, PortControl portControl)
1708 wpa_printf(MSG_DEBUG, "EAPOL: External notification - "
1709 "portControl=%s", eapol_port_control(portControl));
1710 sm->portControl = portControl;
1716 * eapol_sm_notify_ctrl_attached - Notification of attached monitor
1717 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
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.
1722 void eapol_sm_notify_ctrl_attached(struct eapol_sm *sm)
1726 eap_sm_notify_ctrl_attached(sm->eap);
1731 * eapol_sm_notify_ctrl_response - Notification of received user input
1732 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
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.
1737 void eapol_sm_notify_ctrl_response(struct eapol_sm *sm)
1741 if (sm->eapReqData && !sm->eapReq) {
1742 wpa_printf(MSG_DEBUG, "EAPOL: received control response (user "
1743 "input) notification - retrying pending EAP "
1745 sm->eapolEap = TRUE;
1753 * eapol_sm_request_reauth - Request reauthentication
1754 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1756 * This function can be used to request EAPOL reauthentication, e.g., when the
1757 * current PMKSA entry is nearing expiration.
1759 void eapol_sm_request_reauth(struct eapol_sm *sm)
1761 if (sm == NULL || sm->SUPP_PAE_state != SUPP_PAE_AUTHENTICATED)
1763 eapol_sm_txStart(sm);
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())
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
1777 void eapol_sm_notify_lower_layer_success(struct eapol_sm *sm, int in_eapol_sm)
1781 eap_notify_lower_layer_success(sm->eap);
1788 * eapol_sm_invalidate_cached_session - Mark cached EAP session data invalid
1789 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1791 void eapol_sm_invalidate_cached_session(struct eapol_sm *sm)
1794 eap_invalidate_cached_session(sm->eap);
1798 static struct eap_peer_config * eapol_sm_get_config(void *ctx)
1800 struct eapol_sm *sm = ctx;
1801 return sm ? sm->config : NULL;
1805 static struct wpabuf * eapol_sm_get_eapReqData(void *ctx)
1807 struct eapol_sm *sm = ctx;
1808 if (sm == NULL || sm->eapReqData == NULL)
1811 return sm->eapReqData;
1815 static Boolean eapol_sm_get_bool(void *ctx, enum eapol_bool_var variable)
1817 struct eapol_sm *sm = ctx;
1821 case EAPOL_eapSuccess:
1822 return sm->eapSuccess;
1823 case EAPOL_eapRestart:
1824 return sm->eapRestart;
1829 case EAPOL_eapNoResp:
1830 return sm->eapNoResp;
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;
1846 static void eapol_sm_set_bool(void *ctx, enum eapol_bool_var variable,
1849 struct eapol_sm *sm = ctx;
1853 case EAPOL_eapSuccess:
1854 sm->eapSuccess = value;
1856 case EAPOL_eapRestart:
1857 sm->eapRestart = value;
1860 sm->eapFail = value;
1863 sm->eapResp = value;
1865 case EAPOL_eapNoResp:
1866 sm->eapNoResp = value;
1871 case EAPOL_portEnabled:
1872 sm->portEnabled = value;
1874 case EAPOL_altAccept:
1875 sm->altAccept = value;
1877 case EAPOL_altReject:
1878 sm->altReject = value;
1880 case EAPOL_eapTriggerStart:
1881 sm->eapTriggerStart = value;
1887 static unsigned int eapol_sm_get_int(void *ctx, enum eapol_int_var variable)
1889 struct eapol_sm *sm = ctx;
1893 case EAPOL_idleWhile:
1894 return sm->idleWhile;
1900 static void eapol_sm_set_int(void *ctx, enum eapol_int_var variable,
1903 struct eapol_sm *sm = ctx;
1907 case EAPOL_idleWhile:
1908 sm->idleWhile = value;
1909 if (sm->idleWhile > 0)
1910 eapol_enable_timer_tick(sm);
1916 static void eapol_sm_set_config_blob(void *ctx, struct wpa_config_blob *blob)
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 */
1926 static const struct wpa_config_blob *
1927 eapol_sm_get_config_blob(void *ctx, const char *name)
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);
1935 #else /* CONFIG_NO_CONFIG_BLOBS */
1937 #endif /* CONFIG_NO_CONFIG_BLOBS */
1941 static void eapol_sm_notify_pending(void *ctx)
1943 struct eapol_sm *sm = ctx;
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;
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,
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);
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 */
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)
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);
1981 static void eapol_sm_notify_status(void *ctx, const char *status,
1982 const char *parameter)
1984 struct eapol_sm *sm = ctx;
1986 if (sm->ctx->status_cb)
1987 sm->ctx->status_cb(sm->ctx->ctx, status, parameter);
1991 #ifdef CONFIG_EAP_PROXY
1992 static void eapol_sm_eap_proxy_cb(void *ctx)
1994 struct eapol_sm *sm = ctx;
1996 if (sm->ctx->eap_proxy_cb)
1997 sm->ctx->eap_proxy_cb(sm->ctx->ctx);
1999 #endif /* CONFIG_EAP_PROXY */
2002 static void eapol_sm_set_anon_id(void *ctx, const u8 *id, size_t len)
2004 struct eapol_sm *sm = ctx;
2006 if (sm->ctx->set_anon_id)
2007 sm->ctx->set_anon_id(sm->ctx->ctx, id, len);
2011 static const struct eapol_callbacks eapol_cb =
2013 eapol_sm_get_config,
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
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
2038 * Allocate and initialize an EAPOL state machine.
2040 struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx)
2042 struct eapol_sm *sm;
2043 struct eap_config conf;
2044 sm = os_zalloc(sizeof(*sm));
2049 sm->portControl = Auto;
2051 /* Supplicant PAE state machine */
2052 sm->heldPeriod = 60;
2053 sm->startPeriod = 30;
2056 /* Supplicant Backend state machine */
2057 sm->authPeriod = 30;
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;
2067 sm->eap = eap_peer_sm_init(sm, &eapol_cb, sm->ctx->msg_ctx, &conf);
2068 if (sm->eap == NULL) {
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");
2079 #endif /* CONFIG_EAP_PROXY */
2081 /* Initialize EAPOL state machines */
2082 sm->force_authorized_update = TRUE;
2083 sm->initialize = TRUE;
2085 sm->initialize = FALSE;
2088 sm->timer_tick_enabled = 1;
2089 eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm);
2096 * eapol_sm_deinit - Deinitialize EAPOL state machine
2097 * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
2099 * Deinitialize and free EAPOL state machine.
2101 void eapol_sm_deinit(struct eapol_sm *sm)
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);
2118 void eapol_sm_set_ext_pw_ctx(struct eapol_sm *sm,
2119 struct ext_password_data *ext)
2122 eap_sm_set_ext_pw_ctx(sm->eap, ext);
2126 int eapol_sm_failed(struct eapol_sm *sm)
2130 return !sm->eapSuccess && sm->eapFail;
2134 int eapol_sm_get_eap_proxy_imsi(struct eapol_sm *sm, char *imsi, size_t *len)
2136 #ifdef CONFIG_EAP_PROXY
2137 if (sm->eap_proxy == NULL)
2139 return eap_proxy_get_imsi(sm->eap_proxy, imsi, len);
2140 #else /* CONFIG_EAP_PROXY */
2142 #endif /* CONFIG_EAP_PROXY */
2146 void eapol_sm_erp_flush(struct eapol_sm *sm)
2149 eap_peer_erp_free_keys(sm->eap);