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