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