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 "crypto/md5.h"
23#include "crypto/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 */
36struct 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
159struct 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
188static void eapol_sm_txLogoff(struct eapol_sm *sm);
189static void eapol_sm_txStart(struct eapol_sm *sm);
190static void eapol_sm_processKey(struct eapol_sm *sm);
191static void eapol_sm_getSuppRsp(struct eapol_sm *sm);
192static void eapol_sm_txSuppRsp(struct eapol_sm *sm);
193static void eapol_sm_abortSupp(struct eapol_sm *sm);
194static void eapol_sm_abort_cached(struct eapol_sm *sm);
195static 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 */
200static 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
236static 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
247SM_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
256SM_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
270SM_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
299SM_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
312SM_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
322SM_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
330SM_STATE(SUPP_PAE, RESTART)
331{
332	SM_ENTRY(SUPP_PAE, RESTART);
333	sm->eapRestart = TRUE;
334}
335
336
337SM_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
345SM_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
354SM_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
439SM_STATE(KEY_RX, NO_KEY_RECEIVE)
440{
441	SM_ENTRY(KEY_RX, NO_KEY_RECEIVE);
442}
443
444
445SM_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
453SM_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
472SM_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
481SM_STATE(SUPP_BE, RESPONSE)
482{
483	SM_ENTRY(SUPP_BE, RESPONSE);
484	eapol_sm_txSuppRsp(sm);
485	sm->eapResp = FALSE;
486}
487
488
489SM_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
503SM_STATE(SUPP_BE, FAIL)
504{
505	SM_ENTRY(SUPP_BE, FAIL);
506	sm->suppFail = TRUE;
507}
508
509
510SM_STATE(SUPP_BE, TIMEOUT)
511{
512	SM_ENTRY(SUPP_BE, TIMEOUT);
513	sm->suppTimeout = TRUE;
514}
515
516
517SM_STATE(SUPP_BE, IDLE)
518{
519	SM_ENTRY(SUPP_BE, IDLE);
520	sm->suppStart = FALSE;
521	sm->initial_req = TRUE;
522}
523
524
525SM_STATE(SUPP_BE, INITIALIZE)
526{
527	SM_ENTRY(SUPP_BE, INITIALIZE);
528	eapol_sm_abortSupp(sm);
529	sm->suppAbort = FALSE;
530}
531
532
533SM_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
544SM_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
616static 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
626static 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
639struct eap_key_data {
640	u8 encr_key[IEEE8021X_ENCR_KEY_LEN];
641	u8 sign_key[IEEE8021X_SIGN_KEY_LEN];
642};
643
644
645static 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
808static 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
818static 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
847static 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
859static 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 */
873void 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
908static 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
931static 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
956static 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)
967static 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 */
994void 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 */
1024int 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 */
1076int 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 */
1146int 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 */
1267void 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 */
1281void 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 */
1299void 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 */
1321void 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 */
1343void 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 */
1367void 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 */
1402int 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 */
1436void 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 */
1452void 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 */
1472void 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
1486static 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 */
1514void 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 */
1530void 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 */
1548void 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 */
1563void 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 */
1585void 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 */
1603void 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 */
1617void eapol_sm_invalidate_cached_session(struct eapol_sm *sm)
1618{
1619	if (sm)
1620		eap_invalidate_cached_session(sm->eap);
1621}
1622
1623
1624static 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
1631static 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
1641static 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
1670static 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
1708static 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
1721static 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
1736static 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
1746static const struct wpa_config_blob *
1747eapol_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
1761static 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)
1777static 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
1790static 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 */
1813struct 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 */
1865void 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