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