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