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