eap_server.c revision fe31a9a8fff325bfddbf06fc3e9edaf480824bee
1/*
2 * hostapd / EAP Full Authenticator state machine (RFC 4137)
3 * Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 *
8 * This state machine is based on the full authenticator state machine defined
9 * in RFC 4137. However, to support backend authentication in RADIUS
10 * authentication server functionality, parts of backend authenticator (also
11 * from RFC 4137) are mixed in. This functionality is enabled by setting
12 * backend_auth configuration variable to TRUE.
13 */
14
15#include "includes.h"
16
17#include "common.h"
18#include "crypto/sha256.h"
19#include "eap_i.h"
20#include "state_machine.h"
21#include "common/wpa_ctrl.h"
22
23#define STATE_MACHINE_DATA struct eap_sm
24#define STATE_MACHINE_DEBUG_PREFIX "EAP"
25
26#define EAP_MAX_AUTH_ROUNDS 50
27
28static void eap_user_free(struct eap_user *user);
29
30
31/* EAP state machines are described in RFC 4137 */
32
33static int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount,
34				   int eapSRTT, int eapRTTVAR,
35				   int methodTimeout);
36static void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp);
37static int eap_sm_getId(const struct wpabuf *data);
38static struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id);
39static struct wpabuf * eap_sm_buildFailure(struct eap_sm *sm, u8 id);
40static int eap_sm_nextId(struct eap_sm *sm, int id);
41static void eap_sm_Policy_update(struct eap_sm *sm, const u8 *nak_list,
42				 size_t len);
43static EapType eap_sm_Policy_getNextMethod(struct eap_sm *sm, int *vendor);
44static int eap_sm_Policy_getDecision(struct eap_sm *sm);
45static Boolean eap_sm_Policy_doPickUp(struct eap_sm *sm, EapType method);
46
47
48static int eap_get_erp_send_reauth_start(struct eap_sm *sm)
49{
50	if (sm->eapol_cb->get_erp_send_reauth_start)
51		return sm->eapol_cb->get_erp_send_reauth_start(sm->eapol_ctx);
52	return 0;
53}
54
55
56static const char * eap_get_erp_domain(struct eap_sm *sm)
57{
58	if (sm->eapol_cb->get_erp_domain)
59		return sm->eapol_cb->get_erp_domain(sm->eapol_ctx);
60	return NULL;
61}
62
63
64#ifdef CONFIG_ERP
65
66static struct eap_server_erp_key * eap_erp_get_key(struct eap_sm *sm,
67						   const char *keyname)
68{
69	if (sm->eapol_cb->erp_get_key)
70		return sm->eapol_cb->erp_get_key(sm->eapol_ctx, keyname);
71	return NULL;
72}
73
74
75static int eap_erp_add_key(struct eap_sm *sm, struct eap_server_erp_key *erp)
76{
77	if (sm->eapol_cb->erp_add_key)
78		return sm->eapol_cb->erp_add_key(sm->eapol_ctx, erp);
79	return -1;
80}
81
82#endif /* CONFIG_ERP */
83
84
85static struct wpabuf * eap_sm_buildInitiateReauthStart(struct eap_sm *sm,
86						       u8 id)
87{
88	const char *domain;
89	size_t plen = 1;
90	struct wpabuf *msg;
91	size_t domain_len = 0;
92
93	domain = eap_get_erp_domain(sm);
94	if (domain) {
95		domain_len = os_strlen(domain);
96		plen += 2 + domain_len;
97	}
98
99	msg = eap_msg_alloc(EAP_VENDOR_IETF,
100			    (EapType) EAP_ERP_TYPE_REAUTH_START, plen,
101			    EAP_CODE_INITIATE, id);
102	if (msg == NULL)
103		return NULL;
104	wpabuf_put_u8(msg, 0); /* Reserved */
105	if (domain) {
106		/* Domain name TLV */
107		wpabuf_put_u8(msg, EAP_ERP_TLV_DOMAIN_NAME);
108		wpabuf_put_u8(msg, domain_len);
109		wpabuf_put_data(msg, domain, domain_len);
110	}
111
112	return msg;
113}
114
115
116static int eap_copy_buf(struct wpabuf **dst, const struct wpabuf *src)
117{
118	if (src == NULL)
119		return -1;
120
121	wpabuf_free(*dst);
122	*dst = wpabuf_dup(src);
123	return *dst ? 0 : -1;
124}
125
126
127static int eap_copy_data(u8 **dst, size_t *dst_len,
128			 const u8 *src, size_t src_len)
129{
130	if (src == NULL)
131		return -1;
132
133	os_free(*dst);
134	*dst = os_malloc(src_len);
135	if (*dst) {
136		os_memcpy(*dst, src, src_len);
137		*dst_len = src_len;
138		return 0;
139	} else {
140		*dst_len = 0;
141		return -1;
142	}
143}
144
145#define EAP_COPY(dst, src) \
146	eap_copy_data((dst), (dst ## Len), (src), (src ## Len))
147
148
149/**
150 * eap_user_get - Fetch user information from the database
151 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
152 * @identity: Identity (User-Name) of the user
153 * @identity_len: Length of identity in bytes
154 * @phase2: 0 = EAP phase1 user, 1 = EAP phase2 (tunneled) user
155 * Returns: 0 on success, or -1 on failure
156 *
157 * This function is used to fetch user information for EAP. The user will be
158 * selected based on the specified identity. sm->user and
159 * sm->user_eap_method_index are updated for the new user when a matching user
160 * is found. sm->user can be used to get user information (e.g., password).
161 */
162int eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len,
163		 int phase2)
164{
165	struct eap_user *user;
166
167	if (sm == NULL || sm->eapol_cb == NULL ||
168	    sm->eapol_cb->get_eap_user == NULL)
169		return -1;
170
171	eap_user_free(sm->user);
172	sm->user = NULL;
173
174	user = os_zalloc(sizeof(*user));
175	if (user == NULL)
176	    return -1;
177
178	if (sm->eapol_cb->get_eap_user(sm->eapol_ctx, identity,
179				       identity_len, phase2, user) != 0) {
180		eap_user_free(user);
181		return -1;
182	}
183
184	sm->user = user;
185	sm->user_eap_method_index = 0;
186
187	return 0;
188}
189
190
191void eap_log_msg(struct eap_sm *sm, const char *fmt, ...)
192{
193	va_list ap;
194	char *buf;
195	int buflen;
196
197	if (sm == NULL || sm->eapol_cb == NULL || sm->eapol_cb->log_msg == NULL)
198		return;
199
200	va_start(ap, fmt);
201	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
202	va_end(ap);
203
204	buf = os_malloc(buflen);
205	if (buf == NULL)
206		return;
207	va_start(ap, fmt);
208	vsnprintf(buf, buflen, fmt, ap);
209	va_end(ap);
210
211	sm->eapol_cb->log_msg(sm->eapol_ctx, buf);
212
213	os_free(buf);
214}
215
216
217SM_STATE(EAP, DISABLED)
218{
219	SM_ENTRY(EAP, DISABLED);
220	sm->num_rounds = 0;
221}
222
223
224SM_STATE(EAP, INITIALIZE)
225{
226	SM_ENTRY(EAP, INITIALIZE);
227
228	if (sm->eap_if.eapRestart && !sm->eap_server && sm->identity) {
229		/*
230		 * Need to allow internal Identity method to be used instead
231		 * of passthrough at the beginning of reauthentication.
232		 */
233		eap_server_clear_identity(sm);
234	}
235
236	sm->try_initiate_reauth = FALSE;
237	sm->currentId = -1;
238	sm->eap_if.eapSuccess = FALSE;
239	sm->eap_if.eapFail = FALSE;
240	sm->eap_if.eapTimeout = FALSE;
241	bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
242	sm->eap_if.eapKeyData = NULL;
243	sm->eap_if.eapKeyDataLen = 0;
244	os_free(sm->eap_if.eapSessionId);
245	sm->eap_if.eapSessionId = NULL;
246	sm->eap_if.eapSessionIdLen = 0;
247	sm->eap_if.eapKeyAvailable = FALSE;
248	sm->eap_if.eapRestart = FALSE;
249
250	/*
251	 * This is not defined in RFC 4137, but method state needs to be
252	 * reseted here so that it does not remain in success state when
253	 * re-authentication starts.
254	 */
255	if (sm->m && sm->eap_method_priv) {
256		sm->m->reset(sm, sm->eap_method_priv);
257		sm->eap_method_priv = NULL;
258	}
259	sm->m = NULL;
260	sm->user_eap_method_index = 0;
261
262	if (sm->backend_auth) {
263		sm->currentMethod = EAP_TYPE_NONE;
264		/* parse rxResp, respId, respMethod */
265		eap_sm_parseEapResp(sm, sm->eap_if.eapRespData);
266		if (sm->rxResp) {
267			sm->currentId = sm->respId;
268		}
269	}
270	sm->num_rounds = 0;
271	sm->method_pending = METHOD_PENDING_NONE;
272
273	wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_STARTED
274		MACSTR, MAC2STR(sm->peer_addr));
275}
276
277
278SM_STATE(EAP, PICK_UP_METHOD)
279{
280	SM_ENTRY(EAP, PICK_UP_METHOD);
281
282	if (eap_sm_Policy_doPickUp(sm, sm->respMethod)) {
283		sm->currentMethod = sm->respMethod;
284		if (sm->m && sm->eap_method_priv) {
285			sm->m->reset(sm, sm->eap_method_priv);
286			sm->eap_method_priv = NULL;
287		}
288		sm->m = eap_server_get_eap_method(EAP_VENDOR_IETF,
289						  sm->currentMethod);
290		if (sm->m && sm->m->initPickUp) {
291			sm->eap_method_priv = sm->m->initPickUp(sm);
292			if (sm->eap_method_priv == NULL) {
293				wpa_printf(MSG_DEBUG, "EAP: Failed to "
294					   "initialize EAP method %d",
295					   sm->currentMethod);
296				sm->m = NULL;
297				sm->currentMethod = EAP_TYPE_NONE;
298			}
299		} else {
300			sm->m = NULL;
301			sm->currentMethod = EAP_TYPE_NONE;
302		}
303	}
304
305	wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD
306		"method=%u", sm->currentMethod);
307}
308
309
310SM_STATE(EAP, IDLE)
311{
312	SM_ENTRY(EAP, IDLE);
313
314	sm->eap_if.retransWhile = eap_sm_calculateTimeout(
315		sm, sm->retransCount, sm->eap_if.eapSRTT, sm->eap_if.eapRTTVAR,
316		sm->methodTimeout);
317}
318
319
320SM_STATE(EAP, RETRANSMIT)
321{
322	SM_ENTRY(EAP, RETRANSMIT);
323
324	sm->retransCount++;
325	if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) {
326		if (eap_copy_buf(&sm->eap_if.eapReqData, sm->lastReqData) == 0)
327			sm->eap_if.eapReq = TRUE;
328	}
329}
330
331
332SM_STATE(EAP, RECEIVED)
333{
334	SM_ENTRY(EAP, RECEIVED);
335
336	/* parse rxResp, respId, respMethod */
337	eap_sm_parseEapResp(sm, sm->eap_if.eapRespData);
338	sm->num_rounds++;
339}
340
341
342SM_STATE(EAP, DISCARD)
343{
344	SM_ENTRY(EAP, DISCARD);
345	sm->eap_if.eapResp = FALSE;
346	sm->eap_if.eapNoReq = TRUE;
347}
348
349
350SM_STATE(EAP, SEND_REQUEST)
351{
352	SM_ENTRY(EAP, SEND_REQUEST);
353
354	sm->retransCount = 0;
355	if (sm->eap_if.eapReqData) {
356		if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0)
357		{
358			sm->eap_if.eapResp = FALSE;
359			sm->eap_if.eapReq = TRUE;
360		} else {
361			sm->eap_if.eapResp = FALSE;
362			sm->eap_if.eapReq = FALSE;
363		}
364	} else {
365		wpa_printf(MSG_INFO, "EAP: SEND_REQUEST - no eapReqData");
366		sm->eap_if.eapResp = FALSE;
367		sm->eap_if.eapReq = FALSE;
368		sm->eap_if.eapNoReq = TRUE;
369	}
370}
371
372
373SM_STATE(EAP, INTEGRITY_CHECK)
374{
375	SM_ENTRY(EAP, INTEGRITY_CHECK);
376
377	if (!eap_hdr_len_valid(sm->eap_if.eapRespData, 1)) {
378		sm->ignore = TRUE;
379		return;
380	}
381
382	if (sm->m->check) {
383		sm->ignore = sm->m->check(sm, sm->eap_method_priv,
384					  sm->eap_if.eapRespData);
385	}
386}
387
388
389SM_STATE(EAP, METHOD_REQUEST)
390{
391	SM_ENTRY(EAP, METHOD_REQUEST);
392
393	if (sm->m == NULL) {
394		wpa_printf(MSG_DEBUG, "EAP: method not initialized");
395		return;
396	}
397
398	sm->currentId = eap_sm_nextId(sm, sm->currentId);
399	wpa_printf(MSG_DEBUG, "EAP: building EAP-Request: Identifier %d",
400		   sm->currentId);
401	sm->lastId = sm->currentId;
402	wpabuf_free(sm->eap_if.eapReqData);
403	sm->eap_if.eapReqData = sm->m->buildReq(sm, sm->eap_method_priv,
404						sm->currentId);
405	if (sm->m->getTimeout)
406		sm->methodTimeout = sm->m->getTimeout(sm, sm->eap_method_priv);
407	else
408		sm->methodTimeout = 0;
409}
410
411
412static void eap_server_erp_init(struct eap_sm *sm)
413{
414#ifdef CONFIG_ERP
415	u8 *emsk = NULL;
416	size_t emsk_len = 0;
417	u8 EMSKname[EAP_EMSK_NAME_LEN];
418	u8 len[2];
419	const char *domain;
420	size_t domain_len, nai_buf_len;
421	struct eap_server_erp_key *erp = NULL;
422	int pos;
423
424	domain = eap_get_erp_domain(sm);
425	if (!domain)
426		return;
427
428	domain_len = os_strlen(domain);
429
430	nai_buf_len = 2 * EAP_EMSK_NAME_LEN + 1 + domain_len;
431	if (nai_buf_len > 253) {
432		/*
433		 * keyName-NAI has a maximum length of 253 octet to fit in
434		 * RADIUS attributes.
435		 */
436		wpa_printf(MSG_DEBUG,
437			   "EAP: Too long realm for ERP keyName-NAI maximum length");
438		return;
439	}
440	nai_buf_len++; /* null termination */
441	erp = os_zalloc(sizeof(*erp) + nai_buf_len);
442	if (erp == NULL)
443		goto fail;
444	erp->recv_seq = (u32) -1;
445
446	emsk = sm->m->get_emsk(sm, sm->eap_method_priv, &emsk_len);
447	if (!emsk || emsk_len == 0 || emsk_len > ERP_MAX_KEY_LEN) {
448		wpa_printf(MSG_DEBUG,
449			   "EAP: No suitable EMSK available for ERP");
450		goto fail;
451	}
452
453	wpa_hexdump_key(MSG_DEBUG, "EAP: EMSK", emsk, emsk_len);
454
455	WPA_PUT_BE16(len, 8);
456	if (hmac_sha256_kdf(sm->eap_if.eapSessionId, sm->eap_if.eapSessionIdLen,
457			    "EMSK", len, sizeof(len),
458			    EMSKname, EAP_EMSK_NAME_LEN) < 0) {
459		wpa_printf(MSG_DEBUG, "EAP: Could not derive EMSKname");
460		goto fail;
461	}
462	wpa_hexdump(MSG_DEBUG, "EAP: EMSKname", EMSKname, EAP_EMSK_NAME_LEN);
463
464	pos = wpa_snprintf_hex(erp->keyname_nai, nai_buf_len,
465			       EMSKname, EAP_EMSK_NAME_LEN);
466	erp->keyname_nai[pos] = '@';
467	os_memcpy(&erp->keyname_nai[pos + 1], domain, domain_len);
468
469	WPA_PUT_BE16(len, emsk_len);
470	if (hmac_sha256_kdf(emsk, emsk_len,
471			    "EAP Re-authentication Root Key@ietf.org",
472			    len, sizeof(len), erp->rRK, emsk_len) < 0) {
473		wpa_printf(MSG_DEBUG, "EAP: Could not derive rRK for ERP");
474		goto fail;
475	}
476	erp->rRK_len = emsk_len;
477	wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rRK", erp->rRK, erp->rRK_len);
478
479	if (hmac_sha256_kdf(erp->rRK, erp->rRK_len,
480			    "EAP Re-authentication Integrity Key@ietf.org",
481			    len, sizeof(len), erp->rIK, erp->rRK_len) < 0) {
482		wpa_printf(MSG_DEBUG, "EAP: Could not derive rIK for ERP");
483		goto fail;
484	}
485	erp->rIK_len = erp->rRK_len;
486	wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rIK", erp->rIK, erp->rIK_len);
487
488	if (eap_erp_add_key(sm, erp) == 0) {
489		wpa_printf(MSG_DEBUG, "EAP: Stored ERP keys %s",
490			   erp->keyname_nai);
491		erp = NULL;
492	}
493
494fail:
495	bin_clear_free(emsk, emsk_len);
496	bin_clear_free(erp, sizeof(*erp));
497#endif /* CONFIG_ERP */
498}
499
500
501SM_STATE(EAP, METHOD_RESPONSE)
502{
503	SM_ENTRY(EAP, METHOD_RESPONSE);
504
505	if (!eap_hdr_len_valid(sm->eap_if.eapRespData, 1))
506		return;
507
508	sm->m->process(sm, sm->eap_method_priv, sm->eap_if.eapRespData);
509	if (sm->m->isDone(sm, sm->eap_method_priv)) {
510		eap_sm_Policy_update(sm, NULL, 0);
511		bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
512		if (sm->m->getKey) {
513			sm->eap_if.eapKeyData = sm->m->getKey(
514				sm, sm->eap_method_priv,
515				&sm->eap_if.eapKeyDataLen);
516		} else {
517			sm->eap_if.eapKeyData = NULL;
518			sm->eap_if.eapKeyDataLen = 0;
519		}
520		os_free(sm->eap_if.eapSessionId);
521		sm->eap_if.eapSessionId = NULL;
522		if (sm->m->getSessionId) {
523			sm->eap_if.eapSessionId = sm->m->getSessionId(
524				sm, sm->eap_method_priv,
525				&sm->eap_if.eapSessionIdLen);
526			wpa_hexdump(MSG_DEBUG, "EAP: Session-Id",
527				    sm->eap_if.eapSessionId,
528				    sm->eap_if.eapSessionIdLen);
529		}
530		if (sm->erp && sm->m->get_emsk && sm->eap_if.eapSessionId)
531			eap_server_erp_init(sm);
532		sm->methodState = METHOD_END;
533	} else {
534		sm->methodState = METHOD_CONTINUE;
535	}
536}
537
538
539SM_STATE(EAP, PROPOSE_METHOD)
540{
541	int vendor;
542	EapType type;
543
544	SM_ENTRY(EAP, PROPOSE_METHOD);
545
546	sm->try_initiate_reauth = FALSE;
547try_another_method:
548	type = eap_sm_Policy_getNextMethod(sm, &vendor);
549	if (vendor == EAP_VENDOR_IETF)
550		sm->currentMethod = type;
551	else
552		sm->currentMethod = EAP_TYPE_EXPANDED;
553	if (sm->m && sm->eap_method_priv) {
554		sm->m->reset(sm, sm->eap_method_priv);
555		sm->eap_method_priv = NULL;
556	}
557	sm->m = eap_server_get_eap_method(vendor, type);
558	if (sm->m) {
559		sm->eap_method_priv = sm->m->init(sm);
560		if (sm->eap_method_priv == NULL) {
561			wpa_printf(MSG_DEBUG, "EAP: Failed to initialize EAP "
562				   "method %d", sm->currentMethod);
563			sm->m = NULL;
564			sm->currentMethod = EAP_TYPE_NONE;
565			goto try_another_method;
566		}
567	}
568	if (sm->m == NULL) {
569		wpa_printf(MSG_DEBUG, "EAP: Could not find suitable EAP method");
570		eap_log_msg(sm, "Could not find suitable EAP method");
571		sm->decision = DECISION_FAILURE;
572		return;
573	}
574	if (sm->currentMethod == EAP_TYPE_IDENTITY ||
575	    sm->currentMethod == EAP_TYPE_NOTIFICATION)
576		sm->methodState = METHOD_CONTINUE;
577	else
578		sm->methodState = METHOD_PROPOSED;
579
580	wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD
581		"vendor=%u method=%u", vendor, sm->currentMethod);
582	eap_log_msg(sm, "Propose EAP method vendor=%u method=%u",
583		    vendor, sm->currentMethod);
584}
585
586
587SM_STATE(EAP, NAK)
588{
589	const struct eap_hdr *nak;
590	size_t len = 0;
591	const u8 *pos;
592	const u8 *nak_list = NULL;
593
594	SM_ENTRY(EAP, NAK);
595
596	if (sm->eap_method_priv) {
597		sm->m->reset(sm, sm->eap_method_priv);
598		sm->eap_method_priv = NULL;
599	}
600	sm->m = NULL;
601
602	if (!eap_hdr_len_valid(sm->eap_if.eapRespData, 1))
603		return;
604
605	nak = wpabuf_head(sm->eap_if.eapRespData);
606	if (nak && wpabuf_len(sm->eap_if.eapRespData) > sizeof(*nak)) {
607		len = be_to_host16(nak->length);
608		if (len > wpabuf_len(sm->eap_if.eapRespData))
609			len = wpabuf_len(sm->eap_if.eapRespData);
610		pos = (const u8 *) (nak + 1);
611		len -= sizeof(*nak);
612		if (*pos == EAP_TYPE_NAK) {
613			pos++;
614			len--;
615			nak_list = pos;
616		}
617	}
618	eap_sm_Policy_update(sm, nak_list, len);
619}
620
621
622SM_STATE(EAP, SELECT_ACTION)
623{
624	SM_ENTRY(EAP, SELECT_ACTION);
625
626	sm->decision = eap_sm_Policy_getDecision(sm);
627}
628
629
630SM_STATE(EAP, TIMEOUT_FAILURE)
631{
632	SM_ENTRY(EAP, TIMEOUT_FAILURE);
633
634	sm->eap_if.eapTimeout = TRUE;
635}
636
637
638SM_STATE(EAP, FAILURE)
639{
640	SM_ENTRY(EAP, FAILURE);
641
642	wpabuf_free(sm->eap_if.eapReqData);
643	sm->eap_if.eapReqData = eap_sm_buildFailure(sm, sm->currentId);
644	wpabuf_free(sm->lastReqData);
645	sm->lastReqData = NULL;
646	sm->eap_if.eapFail = TRUE;
647
648	wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE
649		MACSTR, MAC2STR(sm->peer_addr));
650}
651
652
653SM_STATE(EAP, SUCCESS)
654{
655	SM_ENTRY(EAP, SUCCESS);
656
657	wpabuf_free(sm->eap_if.eapReqData);
658	sm->eap_if.eapReqData = eap_sm_buildSuccess(sm, sm->currentId);
659	wpabuf_free(sm->lastReqData);
660	sm->lastReqData = NULL;
661	if (sm->eap_if.eapKeyData)
662		sm->eap_if.eapKeyAvailable = TRUE;
663	sm->eap_if.eapSuccess = TRUE;
664
665	wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS
666		MACSTR, MAC2STR(sm->peer_addr));
667}
668
669
670SM_STATE(EAP, INITIATE_REAUTH_START)
671{
672	SM_ENTRY(EAP, INITIATE_REAUTH_START);
673
674	sm->initiate_reauth_start_sent = TRUE;
675	sm->try_initiate_reauth = TRUE;
676	sm->currentId = eap_sm_nextId(sm, sm->currentId);
677	wpa_printf(MSG_DEBUG,
678		   "EAP: building EAP-Initiate-Re-auth-Start: Identifier %d",
679		   sm->currentId);
680	sm->lastId = sm->currentId;
681	wpabuf_free(sm->eap_if.eapReqData);
682	sm->eap_if.eapReqData = eap_sm_buildInitiateReauthStart(sm,
683								sm->currentId);
684	wpabuf_free(sm->lastReqData);
685	sm->lastReqData = NULL;
686}
687
688
689#ifdef CONFIG_ERP
690
691static void erp_send_finish_reauth(struct eap_sm *sm,
692				   struct eap_server_erp_key *erp, u8 id,
693				   u8 flags, u16 seq, const char *nai)
694{
695	size_t plen;
696	struct wpabuf *msg;
697	u8 hash[SHA256_MAC_LEN];
698	size_t hash_len;
699	u8 seed[4];
700
701	if (erp) {
702		switch (erp->cryptosuite) {
703		case EAP_ERP_CS_HMAC_SHA256_256:
704			hash_len = 32;
705			break;
706		case EAP_ERP_CS_HMAC_SHA256_128:
707			hash_len = 16;
708			break;
709		default:
710			return;
711		}
712	} else
713		hash_len = 0;
714
715	plen = 1 + 2 + 2 + os_strlen(nai);
716	if (hash_len)
717		plen += 1 + hash_len;
718	msg = eap_msg_alloc(EAP_VENDOR_IETF, (EapType) EAP_ERP_TYPE_REAUTH,
719			    plen, EAP_CODE_FINISH, id);
720	if (msg == NULL)
721		return;
722	wpabuf_put_u8(msg, flags);
723	wpabuf_put_be16(msg, seq);
724
725	wpabuf_put_u8(msg, EAP_ERP_TLV_KEYNAME_NAI);
726	wpabuf_put_u8(msg, os_strlen(nai));
727	wpabuf_put_str(msg, nai);
728
729	if (erp) {
730		wpabuf_put_u8(msg, erp->cryptosuite);
731		if (hmac_sha256(erp->rIK, erp->rIK_len,
732				wpabuf_head(msg), wpabuf_len(msg), hash) < 0) {
733			wpabuf_free(msg);
734			return;
735		}
736		wpabuf_put_data(msg, hash, hash_len);
737	}
738
739	wpa_printf(MSG_DEBUG, "EAP: Send EAP-Finish/Re-auth (%s)",
740		   flags & 0x80 ? "failure" : "success");
741
742	sm->lastId = sm->currentId;
743	sm->currentId = id;
744	wpabuf_free(sm->eap_if.eapReqData);
745	sm->eap_if.eapReqData = msg;
746	wpabuf_free(sm->lastReqData);
747	sm->lastReqData = NULL;
748
749	if ((flags & 0x80) || !erp) {
750		sm->eap_if.eapFail = TRUE;
751		wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE
752			MACSTR, MAC2STR(sm->peer_addr));
753		return;
754	}
755
756	bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
757	sm->eap_if.eapKeyDataLen = 0;
758	sm->eap_if.eapKeyData = os_malloc(erp->rRK_len);
759	if (!sm->eap_if.eapKeyData)
760		return;
761
762	WPA_PUT_BE16(seed, seq);
763	WPA_PUT_BE16(&seed[2], erp->rRK_len);
764	if (hmac_sha256_kdf(erp->rRK, erp->rRK_len,
765			    "Re-authentication Master Session Key@ietf.org",
766			    seed, sizeof(seed),
767			    sm->eap_if.eapKeyData, erp->rRK_len) < 0) {
768		wpa_printf(MSG_DEBUG, "EAP: Could not derive rMSK for ERP");
769		bin_clear_free(sm->eap_if.eapKeyData, erp->rRK_len);
770		sm->eap_if.eapKeyData = NULL;
771		return;
772	}
773	sm->eap_if.eapKeyDataLen = erp->rRK_len;
774	sm->eap_if.eapKeyAvailable = TRUE;
775	wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rMSK",
776			sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
777	sm->eap_if.eapSuccess = TRUE;
778
779	wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS
780		MACSTR, MAC2STR(sm->peer_addr));
781}
782
783
784SM_STATE(EAP, INITIATE_RECEIVED)
785{
786	const u8 *pos, *end, *start, *tlvs, *hdr;
787	const struct eap_hdr *ehdr;
788	size_t len;
789	u8 flags;
790	u16 seq;
791	char nai[254];
792	struct eap_server_erp_key *erp;
793	int max_len;
794	u8 hash[SHA256_MAC_LEN];
795	size_t hash_len;
796	struct erp_tlvs parse;
797	u8 resp_flags = 0x80; /* default to failure; cleared on success */
798
799	SM_ENTRY(EAP, INITIATE_RECEIVED);
800
801	sm->rxInitiate = FALSE;
802
803	pos = eap_hdr_validate(EAP_VENDOR_IETF, (EapType) EAP_ERP_TYPE_REAUTH,
804			       sm->eap_if.eapRespData, &len);
805	if (pos == NULL) {
806		wpa_printf(MSG_INFO, "EAP-Initiate: Invalid frame");
807		goto fail;
808	}
809	hdr = wpabuf_head(sm->eap_if.eapRespData);
810	ehdr = wpabuf_head(sm->eap_if.eapRespData);
811
812	wpa_hexdump(MSG_DEBUG, "EAP: EAP-Initiate/Re-Auth", pos, len);
813	if (len < 4) {
814		wpa_printf(MSG_INFO, "EAP: Too short EAP-Initiate/Re-auth");
815		goto fail;
816	}
817	end = pos + len;
818
819	flags = *pos++;
820	seq = WPA_GET_BE16(pos);
821	pos += 2;
822	wpa_printf(MSG_DEBUG, "EAP: Flags=0x%x SEQ=%u", flags, seq);
823	tlvs = pos;
824
825	/*
826	 * Parse TVs/TLVs. Since we do not yet know the length of the
827	 * Authentication Tag, stop parsing if an unknown TV/TLV is seen and
828	 * just try to find the keyName-NAI first so that we can check the
829	 * Authentication Tag.
830	 */
831	if (erp_parse_tlvs(tlvs, end, &parse, 1) < 0)
832		goto fail;
833
834	if (!parse.keyname) {
835		wpa_printf(MSG_DEBUG,
836			   "EAP: No keyName-NAI in EAP-Initiate/Re-auth Packet");
837		goto fail;
838	}
839
840	wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Initiate/Re-auth - keyName-NAI",
841			  parse.keyname, parse.keyname_len);
842	if (parse.keyname_len > 253) {
843		wpa_printf(MSG_DEBUG,
844			   "EAP: Too long keyName-NAI in EAP-Initiate/Re-auth");
845		goto fail;
846	}
847	os_memcpy(nai, parse.keyname, parse.keyname_len);
848	nai[parse.keyname_len] = '\0';
849
850	if (!sm->eap_server) {
851		/*
852		 * In passthrough case, EAP-Initiate/Re-auth replaces
853		 * EAP Identity exchange. Use keyName-NAI as the user identity
854		 * and forward EAP-Initiate/Re-auth to the backend
855		 * authentication server.
856		 */
857		wpa_printf(MSG_DEBUG,
858			   "EAP: Use keyName-NAI as user identity for backend authentication");
859		eap_server_clear_identity(sm);
860		sm->identity = (u8 *) dup_binstr(parse.keyname,
861						 parse.keyname_len);
862		if (!sm->identity)
863			goto fail;
864		sm->identity_len = parse.keyname_len;
865		return;
866	}
867
868	erp = eap_erp_get_key(sm, nai);
869	if (!erp) {
870		wpa_printf(MSG_DEBUG, "EAP: No matching ERP key found for %s",
871			   nai);
872		goto report_error;
873	}
874
875	if (erp->recv_seq != (u32) -1 && erp->recv_seq >= seq) {
876		wpa_printf(MSG_DEBUG,
877			   "EAP: SEQ=%u replayed (already received SEQ=%u)",
878			   seq, erp->recv_seq);
879		goto fail;
880	}
881
882	/* Is there enough room for Cryptosuite and Authentication Tag? */
883	start = parse.keyname + parse.keyname_len;
884	max_len = end - start;
885	if (max_len <
886	    1 + (erp->cryptosuite == EAP_ERP_CS_HMAC_SHA256_256 ? 32 : 16)) {
887		wpa_printf(MSG_DEBUG,
888			   "EAP: Not enough room for Authentication Tag");
889		goto fail;
890	}
891
892	switch (erp->cryptosuite) {
893	case EAP_ERP_CS_HMAC_SHA256_256:
894		if (end[-33] != erp->cryptosuite) {
895			wpa_printf(MSG_DEBUG,
896				   "EAP: Different Cryptosuite used");
897			goto fail;
898		}
899		hash_len = 32;
900		break;
901	case EAP_ERP_CS_HMAC_SHA256_128:
902		if (end[-17] != erp->cryptosuite) {
903			wpa_printf(MSG_DEBUG,
904				   "EAP: Different Cryptosuite used");
905			goto fail;
906		}
907		hash_len = 16;
908		break;
909	default:
910		hash_len = 0;
911		break;
912	}
913
914	if (hash_len) {
915		if (hmac_sha256(erp->rIK, erp->rIK_len, hdr,
916				end - hdr - hash_len, hash) < 0)
917			goto fail;
918		if (os_memcmp(end - hash_len, hash, hash_len) != 0) {
919			wpa_printf(MSG_DEBUG,
920				   "EAP: Authentication Tag mismatch");
921			goto fail;
922		}
923	}
924
925	/* Check if any supported CS results in matching tag */
926	if (!hash_len && max_len >= 1 + 32 &&
927	    end[-33] == EAP_ERP_CS_HMAC_SHA256_256) {
928		if (hmac_sha256(erp->rIK, erp->rIK_len, hdr,
929				end - hdr - 32, hash) < 0)
930			goto fail;
931		if (os_memcmp(end - 32, hash, 32) == 0) {
932			wpa_printf(MSG_DEBUG,
933				   "EAP: Authentication Tag match using HMAC-SHA256-256");
934			hash_len = 32;
935			erp->cryptosuite = EAP_ERP_CS_HMAC_SHA256_256;
936		}
937	}
938
939	if (!hash_len && end[-17] == EAP_ERP_CS_HMAC_SHA256_128) {
940		if (hmac_sha256(erp->rIK, erp->rIK_len, hdr,
941				end - hdr - 16, hash) < 0)
942			goto fail;
943		if (os_memcmp(end - 16, hash, 16) == 0) {
944			wpa_printf(MSG_DEBUG,
945				   "EAP: Authentication Tag match using HMAC-SHA256-128");
946			hash_len = 16;
947			erp->cryptosuite = EAP_ERP_CS_HMAC_SHA256_128;
948		}
949	}
950
951	if (!hash_len) {
952		wpa_printf(MSG_DEBUG,
953			   "EAP: No supported cryptosuite matched Authentication Tag");
954		goto fail;
955	}
956	end -= 1 + hash_len;
957
958	/*
959	 * Parse TVs/TLVs again now that we know the exact part of the buffer
960	 * that contains them.
961	 */
962	wpa_hexdump(MSG_DEBUG, "EAP: EAP-Initiate/Re-Auth TVs/TLVs",
963		    tlvs, end - tlvs);
964	if (erp_parse_tlvs(tlvs, end, &parse, 0) < 0)
965		goto fail;
966
967	wpa_printf(MSG_DEBUG, "EAP: ERP key %s SEQ updated to %u",
968		   erp->keyname_nai, seq);
969	erp->recv_seq = seq;
970	resp_flags &= ~0x80; /* R=0 - success */
971
972report_error:
973	erp_send_finish_reauth(sm, erp, ehdr->identifier, resp_flags, seq, nai);
974	return;
975
976fail:
977	sm->ignore = TRUE;
978}
979
980#endif /* CONFIG_ERP */
981
982
983SM_STATE(EAP, INITIALIZE_PASSTHROUGH)
984{
985	SM_ENTRY(EAP, INITIALIZE_PASSTHROUGH);
986
987	wpabuf_free(sm->eap_if.aaaEapRespData);
988	sm->eap_if.aaaEapRespData = NULL;
989	sm->try_initiate_reauth = FALSE;
990}
991
992
993SM_STATE(EAP, IDLE2)
994{
995	SM_ENTRY(EAP, IDLE2);
996
997	sm->eap_if.retransWhile = eap_sm_calculateTimeout(
998		sm, sm->retransCount, sm->eap_if.eapSRTT, sm->eap_if.eapRTTVAR,
999		sm->methodTimeout);
1000}
1001
1002
1003SM_STATE(EAP, RETRANSMIT2)
1004{
1005	SM_ENTRY(EAP, RETRANSMIT2);
1006
1007	sm->retransCount++;
1008	if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) {
1009		if (eap_copy_buf(&sm->eap_if.eapReqData, sm->lastReqData) == 0)
1010			sm->eap_if.eapReq = TRUE;
1011	}
1012}
1013
1014
1015SM_STATE(EAP, RECEIVED2)
1016{
1017	SM_ENTRY(EAP, RECEIVED2);
1018
1019	/* parse rxResp, respId, respMethod */
1020	eap_sm_parseEapResp(sm, sm->eap_if.eapRespData);
1021}
1022
1023
1024SM_STATE(EAP, DISCARD2)
1025{
1026	SM_ENTRY(EAP, DISCARD2);
1027	sm->eap_if.eapResp = FALSE;
1028	sm->eap_if.eapNoReq = TRUE;
1029}
1030
1031
1032SM_STATE(EAP, SEND_REQUEST2)
1033{
1034	SM_ENTRY(EAP, SEND_REQUEST2);
1035
1036	sm->retransCount = 0;
1037	if (sm->eap_if.eapReqData) {
1038		if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0)
1039		{
1040			sm->eap_if.eapResp = FALSE;
1041			sm->eap_if.eapReq = TRUE;
1042		} else {
1043			sm->eap_if.eapResp = FALSE;
1044			sm->eap_if.eapReq = FALSE;
1045		}
1046	} else {
1047		wpa_printf(MSG_INFO, "EAP: SEND_REQUEST2 - no eapReqData");
1048		sm->eap_if.eapResp = FALSE;
1049		sm->eap_if.eapReq = FALSE;
1050		sm->eap_if.eapNoReq = TRUE;
1051	}
1052}
1053
1054
1055SM_STATE(EAP, AAA_REQUEST)
1056{
1057	SM_ENTRY(EAP, AAA_REQUEST);
1058
1059	if (sm->eap_if.eapRespData == NULL) {
1060		wpa_printf(MSG_INFO, "EAP: AAA_REQUEST - no eapRespData");
1061		return;
1062	}
1063
1064	/*
1065	 * if (respMethod == IDENTITY)
1066	 *	aaaIdentity = eapRespData
1067	 * This is already taken care of by the EAP-Identity method which
1068	 * stores the identity into sm->identity.
1069	 */
1070
1071	eap_copy_buf(&sm->eap_if.aaaEapRespData, sm->eap_if.eapRespData);
1072}
1073
1074
1075SM_STATE(EAP, AAA_RESPONSE)
1076{
1077	SM_ENTRY(EAP, AAA_RESPONSE);
1078
1079	eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData);
1080	sm->currentId = eap_sm_getId(sm->eap_if.eapReqData);
1081	sm->methodTimeout = sm->eap_if.aaaMethodTimeout;
1082}
1083
1084
1085SM_STATE(EAP, AAA_IDLE)
1086{
1087	SM_ENTRY(EAP, AAA_IDLE);
1088
1089	sm->eap_if.aaaFail = FALSE;
1090	sm->eap_if.aaaSuccess = FALSE;
1091	sm->eap_if.aaaEapReq = FALSE;
1092	sm->eap_if.aaaEapNoReq = FALSE;
1093	sm->eap_if.aaaEapResp = TRUE;
1094}
1095
1096
1097SM_STATE(EAP, TIMEOUT_FAILURE2)
1098{
1099	SM_ENTRY(EAP, TIMEOUT_FAILURE2);
1100
1101	sm->eap_if.eapTimeout = TRUE;
1102}
1103
1104
1105SM_STATE(EAP, FAILURE2)
1106{
1107	SM_ENTRY(EAP, FAILURE2);
1108
1109	eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData);
1110	sm->eap_if.eapFail = TRUE;
1111}
1112
1113
1114SM_STATE(EAP, SUCCESS2)
1115{
1116	SM_ENTRY(EAP, SUCCESS2);
1117
1118	eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData);
1119
1120	sm->eap_if.eapKeyAvailable = sm->eap_if.aaaEapKeyAvailable;
1121	if (sm->eap_if.aaaEapKeyAvailable) {
1122		EAP_COPY(&sm->eap_if.eapKeyData, sm->eap_if.aaaEapKeyData);
1123	} else {
1124		bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
1125		sm->eap_if.eapKeyData = NULL;
1126		sm->eap_if.eapKeyDataLen = 0;
1127	}
1128
1129	sm->eap_if.eapSuccess = TRUE;
1130
1131	/*
1132	 * Start reauthentication with identity request even though we know the
1133	 * previously used identity. This is needed to get reauthentication
1134	 * started properly.
1135	 */
1136	sm->start_reauth = TRUE;
1137}
1138
1139
1140SM_STEP(EAP)
1141{
1142	if (sm->eap_if.eapRestart && sm->eap_if.portEnabled)
1143		SM_ENTER_GLOBAL(EAP, INITIALIZE);
1144	else if (!sm->eap_if.portEnabled)
1145		SM_ENTER_GLOBAL(EAP, DISABLED);
1146	else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) {
1147		if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) {
1148			wpa_printf(MSG_DEBUG, "EAP: more than %d "
1149				   "authentication rounds - abort",
1150				   EAP_MAX_AUTH_ROUNDS);
1151			sm->num_rounds++;
1152			SM_ENTER_GLOBAL(EAP, FAILURE);
1153		}
1154	} else switch (sm->EAP_state) {
1155	case EAP_INITIALIZE:
1156		if (sm->backend_auth) {
1157			if (!sm->rxResp)
1158				SM_ENTER(EAP, SELECT_ACTION);
1159			else if (sm->rxResp &&
1160				 (sm->respMethod == EAP_TYPE_NAK ||
1161				  (sm->respMethod == EAP_TYPE_EXPANDED &&
1162				   sm->respVendor == EAP_VENDOR_IETF &&
1163				   sm->respVendorMethod == EAP_TYPE_NAK)))
1164				SM_ENTER(EAP, NAK);
1165			else
1166				SM_ENTER(EAP, PICK_UP_METHOD);
1167		} else {
1168			SM_ENTER(EAP, SELECT_ACTION);
1169		}
1170		break;
1171	case EAP_PICK_UP_METHOD:
1172		if (sm->currentMethod == EAP_TYPE_NONE) {
1173			SM_ENTER(EAP, SELECT_ACTION);
1174		} else {
1175			SM_ENTER(EAP, METHOD_RESPONSE);
1176		}
1177		break;
1178	case EAP_DISABLED:
1179		if (sm->eap_if.portEnabled)
1180			SM_ENTER(EAP, INITIALIZE);
1181		break;
1182	case EAP_IDLE:
1183		if (sm->eap_if.retransWhile == 0) {
1184			if (sm->try_initiate_reauth) {
1185				sm->try_initiate_reauth = FALSE;
1186				SM_ENTER(EAP, SELECT_ACTION);
1187			} else {
1188				SM_ENTER(EAP, RETRANSMIT);
1189			}
1190		} else if (sm->eap_if.eapResp)
1191			SM_ENTER(EAP, RECEIVED);
1192		break;
1193	case EAP_RETRANSMIT:
1194		if (sm->retransCount > sm->MaxRetrans)
1195			SM_ENTER(EAP, TIMEOUT_FAILURE);
1196		else
1197			SM_ENTER(EAP, IDLE);
1198		break;
1199	case EAP_RECEIVED:
1200		if (sm->rxResp && (sm->respId == sm->currentId) &&
1201		    (sm->respMethod == EAP_TYPE_NAK ||
1202		     (sm->respMethod == EAP_TYPE_EXPANDED &&
1203		      sm->respVendor == EAP_VENDOR_IETF &&
1204		      sm->respVendorMethod == EAP_TYPE_NAK))
1205		    && (sm->methodState == METHOD_PROPOSED))
1206			SM_ENTER(EAP, NAK);
1207		else if (sm->rxResp && (sm->respId == sm->currentId) &&
1208			 ((sm->respMethod == sm->currentMethod) ||
1209			  (sm->respMethod == EAP_TYPE_EXPANDED &&
1210			   sm->respVendor == EAP_VENDOR_IETF &&
1211			   sm->respVendorMethod == sm->currentMethod)))
1212			SM_ENTER(EAP, INTEGRITY_CHECK);
1213#ifdef CONFIG_ERP
1214		else if (sm->rxInitiate)
1215			SM_ENTER(EAP, INITIATE_RECEIVED);
1216#endif /* CONFIG_ERP */
1217		else {
1218			wpa_printf(MSG_DEBUG, "EAP: RECEIVED->DISCARD: "
1219				   "rxResp=%d respId=%d currentId=%d "
1220				   "respMethod=%d currentMethod=%d",
1221				   sm->rxResp, sm->respId, sm->currentId,
1222				   sm->respMethod, sm->currentMethod);
1223			eap_log_msg(sm, "Discard received EAP message");
1224			SM_ENTER(EAP, DISCARD);
1225		}
1226		break;
1227	case EAP_DISCARD:
1228		SM_ENTER(EAP, IDLE);
1229		break;
1230	case EAP_SEND_REQUEST:
1231		SM_ENTER(EAP, IDLE);
1232		break;
1233	case EAP_INTEGRITY_CHECK:
1234		if (sm->ignore)
1235			SM_ENTER(EAP, DISCARD);
1236		else
1237			SM_ENTER(EAP, METHOD_RESPONSE);
1238		break;
1239	case EAP_METHOD_REQUEST:
1240		if (sm->m == NULL) {
1241			/*
1242			 * This transition is not mentioned in RFC 4137, but it
1243			 * is needed to handle cleanly a case where EAP method
1244			 * initialization fails.
1245			 */
1246			SM_ENTER(EAP, FAILURE);
1247			break;
1248		}
1249		SM_ENTER(EAP, SEND_REQUEST);
1250		if (sm->eap_if.eapNoReq && !sm->eap_if.eapReq) {
1251			/*
1252			 * This transition is not mentioned in RFC 4137, but it
1253			 * is needed to handle cleanly a case where EAP method
1254			 * buildReq fails.
1255			 */
1256			wpa_printf(MSG_DEBUG,
1257				   "EAP: Method did not return a request");
1258			SM_ENTER(EAP, FAILURE);
1259			break;
1260		}
1261		break;
1262	case EAP_METHOD_RESPONSE:
1263		/*
1264		 * Note: Mechanism to allow EAP methods to wait while going
1265		 * through pending processing is an extension to RFC 4137
1266		 * which only defines the transits to SELECT_ACTION and
1267		 * METHOD_REQUEST from this METHOD_RESPONSE state.
1268		 */
1269		if (sm->methodState == METHOD_END)
1270			SM_ENTER(EAP, SELECT_ACTION);
1271		else if (sm->method_pending == METHOD_PENDING_WAIT) {
1272			wpa_printf(MSG_DEBUG, "EAP: Method has pending "
1273				   "processing - wait before proceeding to "
1274				   "METHOD_REQUEST state");
1275		} else if (sm->method_pending == METHOD_PENDING_CONT) {
1276			wpa_printf(MSG_DEBUG, "EAP: Method has completed "
1277				   "pending processing - reprocess pending "
1278				   "EAP message");
1279			sm->method_pending = METHOD_PENDING_NONE;
1280			SM_ENTER(EAP, METHOD_RESPONSE);
1281		} else
1282			SM_ENTER(EAP, METHOD_REQUEST);
1283		break;
1284	case EAP_PROPOSE_METHOD:
1285		/*
1286		 * Note: Mechanism to allow EAP methods to wait while going
1287		 * through pending processing is an extension to RFC 4137
1288		 * which only defines the transit to METHOD_REQUEST from this
1289		 * PROPOSE_METHOD state.
1290		 */
1291		if (sm->method_pending == METHOD_PENDING_WAIT) {
1292			wpa_printf(MSG_DEBUG, "EAP: Method has pending "
1293				   "processing - wait before proceeding to "
1294				   "METHOD_REQUEST state");
1295			if (sm->user_eap_method_index > 0)
1296				sm->user_eap_method_index--;
1297		} else if (sm->method_pending == METHOD_PENDING_CONT) {
1298			wpa_printf(MSG_DEBUG, "EAP: Method has completed "
1299				   "pending processing - reprocess pending "
1300				   "EAP message");
1301			sm->method_pending = METHOD_PENDING_NONE;
1302			SM_ENTER(EAP, PROPOSE_METHOD);
1303		} else
1304			SM_ENTER(EAP, METHOD_REQUEST);
1305		break;
1306	case EAP_NAK:
1307		SM_ENTER(EAP, SELECT_ACTION);
1308		break;
1309	case EAP_SELECT_ACTION:
1310		if (sm->decision == DECISION_FAILURE)
1311			SM_ENTER(EAP, FAILURE);
1312		else if (sm->decision == DECISION_SUCCESS)
1313			SM_ENTER(EAP, SUCCESS);
1314		else if (sm->decision == DECISION_PASSTHROUGH)
1315			SM_ENTER(EAP, INITIALIZE_PASSTHROUGH);
1316		else if (sm->decision == DECISION_INITIATE_REAUTH_START)
1317			SM_ENTER(EAP, INITIATE_REAUTH_START);
1318#ifdef CONFIG_ERP
1319		else if (sm->eap_server && sm->erp && sm->rxInitiate)
1320			SM_ENTER(EAP, INITIATE_RECEIVED);
1321#endif /* CONFIG_ERP */
1322		else
1323			SM_ENTER(EAP, PROPOSE_METHOD);
1324		break;
1325	case EAP_INITIATE_REAUTH_START:
1326		SM_ENTER(EAP, SEND_REQUEST);
1327		break;
1328	case EAP_INITIATE_RECEIVED:
1329		if (!sm->eap_server)
1330			SM_ENTER(EAP, SELECT_ACTION);
1331		break;
1332	case EAP_TIMEOUT_FAILURE:
1333		break;
1334	case EAP_FAILURE:
1335		break;
1336	case EAP_SUCCESS:
1337		break;
1338
1339	case EAP_INITIALIZE_PASSTHROUGH:
1340		if (sm->currentId == -1)
1341			SM_ENTER(EAP, AAA_IDLE);
1342		else
1343			SM_ENTER(EAP, AAA_REQUEST);
1344		break;
1345	case EAP_IDLE2:
1346		if (sm->eap_if.eapResp)
1347			SM_ENTER(EAP, RECEIVED2);
1348		else if (sm->eap_if.retransWhile == 0)
1349			SM_ENTER(EAP, RETRANSMIT2);
1350		break;
1351	case EAP_RETRANSMIT2:
1352		if (sm->retransCount > sm->MaxRetrans)
1353			SM_ENTER(EAP, TIMEOUT_FAILURE2);
1354		else
1355			SM_ENTER(EAP, IDLE2);
1356		break;
1357	case EAP_RECEIVED2:
1358		if (sm->rxResp && (sm->respId == sm->currentId))
1359			SM_ENTER(EAP, AAA_REQUEST);
1360		else
1361			SM_ENTER(EAP, DISCARD2);
1362		break;
1363	case EAP_DISCARD2:
1364		SM_ENTER(EAP, IDLE2);
1365		break;
1366	case EAP_SEND_REQUEST2:
1367		SM_ENTER(EAP, IDLE2);
1368		break;
1369	case EAP_AAA_REQUEST:
1370		SM_ENTER(EAP, AAA_IDLE);
1371		break;
1372	case EAP_AAA_RESPONSE:
1373		SM_ENTER(EAP, SEND_REQUEST2);
1374		break;
1375	case EAP_AAA_IDLE:
1376		if (sm->eap_if.aaaFail)
1377			SM_ENTER(EAP, FAILURE2);
1378		else if (sm->eap_if.aaaSuccess)
1379			SM_ENTER(EAP, SUCCESS2);
1380		else if (sm->eap_if.aaaEapReq)
1381			SM_ENTER(EAP, AAA_RESPONSE);
1382		else if (sm->eap_if.aaaTimeout)
1383			SM_ENTER(EAP, TIMEOUT_FAILURE2);
1384		break;
1385	case EAP_TIMEOUT_FAILURE2:
1386		break;
1387	case EAP_FAILURE2:
1388		break;
1389	case EAP_SUCCESS2:
1390		break;
1391	}
1392}
1393
1394
1395static int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount,
1396				   int eapSRTT, int eapRTTVAR,
1397				   int methodTimeout)
1398{
1399	int rto, i;
1400
1401	if (sm->try_initiate_reauth) {
1402		wpa_printf(MSG_DEBUG,
1403			   "EAP: retransmit timeout 1 second for EAP-Initiate-Re-auth-Start");
1404		return 1;
1405	}
1406
1407	if (methodTimeout) {
1408		/*
1409		 * EAP method (either internal or through AAA server, provided
1410		 * timeout hint. Use that as-is as a timeout for retransmitting
1411		 * the EAP request if no response is received.
1412		 */
1413		wpa_printf(MSG_DEBUG, "EAP: retransmit timeout %d seconds "
1414			   "(from EAP method hint)", methodTimeout);
1415		return methodTimeout;
1416	}
1417
1418	/*
1419	 * RFC 3748 recommends algorithms described in RFC 2988 for estimation
1420	 * of the retransmission timeout. This should be implemented once
1421	 * round-trip time measurements are available. For nowm a simple
1422	 * backoff mechanism is used instead if there are no EAP method
1423	 * specific hints.
1424	 *
1425	 * SRTT = smoothed round-trip time
1426	 * RTTVAR = round-trip time variation
1427	 * RTO = retransmission timeout
1428	 */
1429
1430	/*
1431	 * RFC 2988, 2.1: before RTT measurement, set RTO to 3 seconds for
1432	 * initial retransmission and then double the RTO to provide back off
1433	 * per 5.5. Limit the maximum RTO to 20 seconds per RFC 3748, 4.3
1434	 * modified RTOmax.
1435	 */
1436	rto = 3;
1437	for (i = 0; i < retransCount; i++) {
1438		rto *= 2;
1439		if (rto >= 20) {
1440			rto = 20;
1441			break;
1442		}
1443	}
1444
1445	wpa_printf(MSG_DEBUG, "EAP: retransmit timeout %d seconds "
1446		   "(from dynamic back off; retransCount=%d)",
1447		   rto, retransCount);
1448
1449	return rto;
1450}
1451
1452
1453static void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp)
1454{
1455	const struct eap_hdr *hdr;
1456	size_t plen;
1457
1458	/* parse rxResp, respId, respMethod */
1459	sm->rxResp = FALSE;
1460	sm->rxInitiate = FALSE;
1461	sm->respId = -1;
1462	sm->respMethod = EAP_TYPE_NONE;
1463	sm->respVendor = EAP_VENDOR_IETF;
1464	sm->respVendorMethod = EAP_TYPE_NONE;
1465
1466	if (resp == NULL || wpabuf_len(resp) < sizeof(*hdr)) {
1467		wpa_printf(MSG_DEBUG, "EAP: parseEapResp: invalid resp=%p "
1468			   "len=%lu", resp,
1469			   resp ? (unsigned long) wpabuf_len(resp) : 0);
1470		return;
1471	}
1472
1473	hdr = wpabuf_head(resp);
1474	plen = be_to_host16(hdr->length);
1475	if (plen > wpabuf_len(resp)) {
1476		wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet "
1477			   "(len=%lu plen=%lu)",
1478			   (unsigned long) wpabuf_len(resp),
1479			   (unsigned long) plen);
1480		return;
1481	}
1482
1483	sm->respId = hdr->identifier;
1484
1485	if (hdr->code == EAP_CODE_RESPONSE)
1486		sm->rxResp = TRUE;
1487	else if (hdr->code == EAP_CODE_INITIATE)
1488		sm->rxInitiate = TRUE;
1489
1490	if (plen > sizeof(*hdr)) {
1491		u8 *pos = (u8 *) (hdr + 1);
1492		sm->respMethod = *pos++;
1493		if (sm->respMethod == EAP_TYPE_EXPANDED) {
1494			if (plen < sizeof(*hdr) + 8) {
1495				wpa_printf(MSG_DEBUG, "EAP: Ignored truncated "
1496					   "expanded EAP-Packet (plen=%lu)",
1497					   (unsigned long) plen);
1498				return;
1499			}
1500			sm->respVendor = WPA_GET_BE24(pos);
1501			pos += 3;
1502			sm->respVendorMethod = WPA_GET_BE32(pos);
1503		}
1504	}
1505
1506	wpa_printf(MSG_DEBUG,
1507		   "EAP: parseEapResp: rxResp=%d rxInitiate=%d respId=%d respMethod=%u respVendor=%u respVendorMethod=%u",
1508		   sm->rxResp, sm->rxInitiate, sm->respId, sm->respMethod,
1509		   sm->respVendor, sm->respVendorMethod);
1510}
1511
1512
1513static int eap_sm_getId(const struct wpabuf *data)
1514{
1515	const struct eap_hdr *hdr;
1516
1517	if (data == NULL || wpabuf_len(data) < sizeof(*hdr))
1518		return -1;
1519
1520	hdr = wpabuf_head(data);
1521	wpa_printf(MSG_DEBUG, "EAP: getId: id=%d", hdr->identifier);
1522	return hdr->identifier;
1523}
1524
1525
1526static struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id)
1527{
1528	struct wpabuf *msg;
1529	struct eap_hdr *resp;
1530	wpa_printf(MSG_DEBUG, "EAP: Building EAP-Success (id=%d)", id);
1531
1532	msg = wpabuf_alloc(sizeof(*resp));
1533	if (msg == NULL)
1534		return NULL;
1535	resp = wpabuf_put(msg, sizeof(*resp));
1536	resp->code = EAP_CODE_SUCCESS;
1537	resp->identifier = id;
1538	resp->length = host_to_be16(sizeof(*resp));
1539
1540	return msg;
1541}
1542
1543
1544static struct wpabuf * eap_sm_buildFailure(struct eap_sm *sm, u8 id)
1545{
1546	struct wpabuf *msg;
1547	struct eap_hdr *resp;
1548	wpa_printf(MSG_DEBUG, "EAP: Building EAP-Failure (id=%d)", id);
1549
1550	msg = wpabuf_alloc(sizeof(*resp));
1551	if (msg == NULL)
1552		return NULL;
1553	resp = wpabuf_put(msg, sizeof(*resp));
1554	resp->code = EAP_CODE_FAILURE;
1555	resp->identifier = id;
1556	resp->length = host_to_be16(sizeof(*resp));
1557
1558	return msg;
1559}
1560
1561
1562static int eap_sm_nextId(struct eap_sm *sm, int id)
1563{
1564	if (id < 0) {
1565		/* RFC 3748 Ch 4.1: recommended to initialize Identifier with a
1566		 * random number */
1567		id = rand() & 0xff;
1568		if (id != sm->lastId)
1569			return id;
1570	}
1571	return (id + 1) & 0xff;
1572}
1573
1574
1575/**
1576 * eap_sm_process_nak - Process EAP-Response/Nak
1577 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1578 * @nak_list: Nak list (allowed methods) from the supplicant
1579 * @len: Length of nak_list in bytes
1580 *
1581 * This function is called when EAP-Response/Nak is received from the
1582 * supplicant. This can happen for both phase 1 and phase 2 authentications.
1583 */
1584void eap_sm_process_nak(struct eap_sm *sm, const u8 *nak_list, size_t len)
1585{
1586	int i;
1587	size_t j;
1588
1589	if (sm->user == NULL)
1590		return;
1591
1592	wpa_printf(MSG_MSGDUMP, "EAP: processing NAK (current EAP method "
1593		   "index %d)", sm->user_eap_method_index);
1594
1595	wpa_hexdump(MSG_MSGDUMP, "EAP: configured methods",
1596		    (u8 *) sm->user->methods,
1597		    EAP_MAX_METHODS * sizeof(sm->user->methods[0]));
1598	wpa_hexdump(MSG_MSGDUMP, "EAP: list of methods supported by the peer",
1599		    nak_list, len);
1600
1601	i = sm->user_eap_method_index;
1602	while (i < EAP_MAX_METHODS &&
1603	       (sm->user->methods[i].vendor != EAP_VENDOR_IETF ||
1604		sm->user->methods[i].method != EAP_TYPE_NONE)) {
1605		if (sm->user->methods[i].vendor != EAP_VENDOR_IETF)
1606			goto not_found;
1607		for (j = 0; j < len; j++) {
1608			if (nak_list[j] == sm->user->methods[i].method) {
1609				break;
1610			}
1611		}
1612
1613		if (j < len) {
1614			/* found */
1615			i++;
1616			continue;
1617		}
1618
1619	not_found:
1620		/* not found - remove from the list */
1621		if (i + 1 < EAP_MAX_METHODS) {
1622			os_memmove(&sm->user->methods[i],
1623				   &sm->user->methods[i + 1],
1624				   (EAP_MAX_METHODS - i - 1) *
1625				   sizeof(sm->user->methods[0]));
1626		}
1627		sm->user->methods[EAP_MAX_METHODS - 1].vendor =
1628			EAP_VENDOR_IETF;
1629		sm->user->methods[EAP_MAX_METHODS - 1].method = EAP_TYPE_NONE;
1630	}
1631
1632	wpa_hexdump(MSG_MSGDUMP, "EAP: new list of configured methods",
1633		    (u8 *) sm->user->methods, EAP_MAX_METHODS *
1634		    sizeof(sm->user->methods[0]));
1635}
1636
1637
1638static void eap_sm_Policy_update(struct eap_sm *sm, const u8 *nak_list,
1639				 size_t len)
1640{
1641	if (nak_list == NULL || sm == NULL || sm->user == NULL)
1642		return;
1643
1644	if (sm->user->phase2) {
1645		wpa_printf(MSG_DEBUG, "EAP: EAP-Nak received after Phase2 user"
1646			   " info was selected - reject");
1647		sm->decision = DECISION_FAILURE;
1648		return;
1649	}
1650
1651	eap_sm_process_nak(sm, nak_list, len);
1652}
1653
1654
1655static EapType eap_sm_Policy_getNextMethod(struct eap_sm *sm, int *vendor)
1656{
1657	EapType next;
1658	int idx = sm->user_eap_method_index;
1659
1660	/* In theory, there should be no problems with starting
1661	 * re-authentication with something else than EAP-Request/Identity and
1662	 * this does indeed work with wpa_supplicant. However, at least Funk
1663	 * Supplicant seemed to ignore re-auth if it skipped
1664	 * EAP-Request/Identity.
1665	 * Re-auth sets currentId == -1, so that can be used here to select
1666	 * whether Identity needs to be requested again. */
1667	if (sm->identity == NULL || sm->currentId == -1) {
1668		*vendor = EAP_VENDOR_IETF;
1669		next = EAP_TYPE_IDENTITY;
1670		sm->update_user = TRUE;
1671	} else if (sm->user && idx < EAP_MAX_METHODS &&
1672		   (sm->user->methods[idx].vendor != EAP_VENDOR_IETF ||
1673		    sm->user->methods[idx].method != EAP_TYPE_NONE)) {
1674		*vendor = sm->user->methods[idx].vendor;
1675		next = sm->user->methods[idx].method;
1676		sm->user_eap_method_index++;
1677	} else {
1678		*vendor = EAP_VENDOR_IETF;
1679		next = EAP_TYPE_NONE;
1680	}
1681	wpa_printf(MSG_DEBUG, "EAP: getNextMethod: vendor %d type %d",
1682		   *vendor, next);
1683	return next;
1684}
1685
1686
1687static int eap_sm_Policy_getDecision(struct eap_sm *sm)
1688{
1689	if (!sm->eap_server && sm->identity && !sm->start_reauth) {
1690		wpa_printf(MSG_DEBUG, "EAP: getDecision: -> PASSTHROUGH");
1691		return DECISION_PASSTHROUGH;
1692	}
1693
1694	if (sm->m && sm->currentMethod != EAP_TYPE_IDENTITY &&
1695	    sm->m->isSuccess(sm, sm->eap_method_priv)) {
1696		wpa_printf(MSG_DEBUG, "EAP: getDecision: method succeeded -> "
1697			   "SUCCESS");
1698		sm->update_user = TRUE;
1699		return DECISION_SUCCESS;
1700	}
1701
1702	if (sm->m && sm->m->isDone(sm, sm->eap_method_priv) &&
1703	    !sm->m->isSuccess(sm, sm->eap_method_priv)) {
1704		wpa_printf(MSG_DEBUG, "EAP: getDecision: method failed -> "
1705			   "FAILURE");
1706		sm->update_user = TRUE;
1707		return DECISION_FAILURE;
1708	}
1709
1710	if ((sm->user == NULL || sm->update_user) && sm->identity &&
1711	    !sm->start_reauth) {
1712		/*
1713		 * Allow Identity method to be started once to allow identity
1714		 * selection hint to be sent from the authentication server,
1715		 * but prevent a loop of Identity requests by only allowing
1716		 * this to happen once.
1717		 */
1718		int id_req = 0;
1719		if (sm->user && sm->currentMethod == EAP_TYPE_IDENTITY &&
1720		    sm->user->methods[0].vendor == EAP_VENDOR_IETF &&
1721		    sm->user->methods[0].method == EAP_TYPE_IDENTITY)
1722			id_req = 1;
1723		if (eap_user_get(sm, sm->identity, sm->identity_len, 0) != 0) {
1724			wpa_printf(MSG_DEBUG, "EAP: getDecision: user not "
1725				   "found from database -> FAILURE");
1726			return DECISION_FAILURE;
1727		}
1728		if (id_req && sm->user &&
1729		    sm->user->methods[0].vendor == EAP_VENDOR_IETF &&
1730		    sm->user->methods[0].method == EAP_TYPE_IDENTITY) {
1731			wpa_printf(MSG_DEBUG, "EAP: getDecision: stop "
1732				   "identity request loop -> FAILURE");
1733			sm->update_user = TRUE;
1734			return DECISION_FAILURE;
1735		}
1736		sm->update_user = FALSE;
1737	}
1738	sm->start_reauth = FALSE;
1739
1740	if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
1741	    (sm->user->methods[sm->user_eap_method_index].vendor !=
1742	     EAP_VENDOR_IETF ||
1743	     sm->user->methods[sm->user_eap_method_index].method !=
1744	     EAP_TYPE_NONE)) {
1745		wpa_printf(MSG_DEBUG, "EAP: getDecision: another method "
1746			   "available -> CONTINUE");
1747		return DECISION_CONTINUE;
1748	}
1749
1750	if (!sm->identity && eap_get_erp_send_reauth_start(sm) &&
1751	    !sm->initiate_reauth_start_sent) {
1752		wpa_printf(MSG_DEBUG,
1753			   "EAP: getDecision: send EAP-Initiate/Re-auth-Start");
1754		return DECISION_INITIATE_REAUTH_START;
1755	}
1756
1757	if (sm->identity == NULL || sm->currentId == -1) {
1758		wpa_printf(MSG_DEBUG, "EAP: getDecision: no identity known "
1759			   "yet -> CONTINUE");
1760		return DECISION_CONTINUE;
1761	}
1762
1763	wpa_printf(MSG_DEBUG, "EAP: getDecision: no more methods available -> "
1764		   "FAILURE");
1765	return DECISION_FAILURE;
1766}
1767
1768
1769static Boolean eap_sm_Policy_doPickUp(struct eap_sm *sm, EapType method)
1770{
1771	return method == EAP_TYPE_IDENTITY ? TRUE : FALSE;
1772}
1773
1774
1775/**
1776 * eap_server_sm_step - Step EAP server state machine
1777 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1778 * Returns: 1 if EAP state was changed or 0 if not
1779 *
1780 * This function advances EAP state machine to a new state to match with the
1781 * current variables. This should be called whenever variables used by the EAP
1782 * state machine have changed.
1783 */
1784int eap_server_sm_step(struct eap_sm *sm)
1785{
1786	int res = 0;
1787	do {
1788		sm->changed = FALSE;
1789		SM_STEP_RUN(EAP);
1790		if (sm->changed)
1791			res = 1;
1792	} while (sm->changed);
1793	return res;
1794}
1795
1796
1797static void eap_user_free(struct eap_user *user)
1798{
1799	if (user == NULL)
1800		return;
1801	bin_clear_free(user->password, user->password_len);
1802	user->password = NULL;
1803	os_free(user);
1804}
1805
1806
1807/**
1808 * eap_server_sm_init - Allocate and initialize EAP server state machine
1809 * @eapol_ctx: Context data to be used with eapol_cb calls
1810 * @eapol_cb: Pointer to EAPOL callback functions
1811 * @conf: EAP configuration
1812 * Returns: Pointer to the allocated EAP state machine or %NULL on failure
1813 *
1814 * This function allocates and initializes an EAP state machine.
1815 */
1816struct eap_sm * eap_server_sm_init(void *eapol_ctx,
1817				   const struct eapol_callbacks *eapol_cb,
1818				   struct eap_config *conf)
1819{
1820	struct eap_sm *sm;
1821
1822	sm = os_zalloc(sizeof(*sm));
1823	if (sm == NULL)
1824		return NULL;
1825	sm->eapol_ctx = eapol_ctx;
1826	sm->eapol_cb = eapol_cb;
1827	sm->MaxRetrans = 5; /* RFC 3748: max 3-5 retransmissions suggested */
1828	sm->ssl_ctx = conf->ssl_ctx;
1829	sm->msg_ctx = conf->msg_ctx;
1830	sm->eap_sim_db_priv = conf->eap_sim_db_priv;
1831	sm->backend_auth = conf->backend_auth;
1832	sm->eap_server = conf->eap_server;
1833	if (conf->pac_opaque_encr_key) {
1834		sm->pac_opaque_encr_key = os_malloc(16);
1835		if (sm->pac_opaque_encr_key) {
1836			os_memcpy(sm->pac_opaque_encr_key,
1837				  conf->pac_opaque_encr_key, 16);
1838		}
1839	}
1840	if (conf->eap_fast_a_id) {
1841		sm->eap_fast_a_id = os_malloc(conf->eap_fast_a_id_len);
1842		if (sm->eap_fast_a_id) {
1843			os_memcpy(sm->eap_fast_a_id, conf->eap_fast_a_id,
1844				  conf->eap_fast_a_id_len);
1845			sm->eap_fast_a_id_len = conf->eap_fast_a_id_len;
1846		}
1847	}
1848	if (conf->eap_fast_a_id_info)
1849		sm->eap_fast_a_id_info = os_strdup(conf->eap_fast_a_id_info);
1850	sm->eap_fast_prov = conf->eap_fast_prov;
1851	sm->pac_key_lifetime = conf->pac_key_lifetime;
1852	sm->pac_key_refresh_time = conf->pac_key_refresh_time;
1853	sm->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
1854	sm->tnc = conf->tnc;
1855	sm->wps = conf->wps;
1856	if (conf->assoc_wps_ie)
1857		sm->assoc_wps_ie = wpabuf_dup(conf->assoc_wps_ie);
1858	if (conf->assoc_p2p_ie)
1859		sm->assoc_p2p_ie = wpabuf_dup(conf->assoc_p2p_ie);
1860	if (conf->peer_addr)
1861		os_memcpy(sm->peer_addr, conf->peer_addr, ETH_ALEN);
1862	sm->fragment_size = conf->fragment_size;
1863	sm->pwd_group = conf->pwd_group;
1864	sm->pbc_in_m1 = conf->pbc_in_m1;
1865	sm->server_id = conf->server_id;
1866	sm->server_id_len = conf->server_id_len;
1867	sm->erp = conf->erp;
1868	sm->tls_session_lifetime = conf->tls_session_lifetime;
1869
1870#ifdef CONFIG_TESTING_OPTIONS
1871	sm->tls_test_flags = conf->tls_test_flags;
1872#endif /* CONFIG_TESTING_OPTIONS */
1873
1874	wpa_printf(MSG_DEBUG, "EAP: Server state machine created");
1875
1876	return sm;
1877}
1878
1879
1880/**
1881 * eap_server_sm_deinit - Deinitialize and free an EAP server state machine
1882 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1883 *
1884 * This function deinitializes EAP state machine and frees all allocated
1885 * resources.
1886 */
1887void eap_server_sm_deinit(struct eap_sm *sm)
1888{
1889	if (sm == NULL)
1890		return;
1891	wpa_printf(MSG_DEBUG, "EAP: Server state machine removed");
1892	if (sm->m && sm->eap_method_priv)
1893		sm->m->reset(sm, sm->eap_method_priv);
1894	wpabuf_free(sm->eap_if.eapReqData);
1895	bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
1896	os_free(sm->eap_if.eapSessionId);
1897	wpabuf_free(sm->lastReqData);
1898	wpabuf_free(sm->eap_if.eapRespData);
1899	os_free(sm->identity);
1900	os_free(sm->pac_opaque_encr_key);
1901	os_free(sm->eap_fast_a_id);
1902	os_free(sm->eap_fast_a_id_info);
1903	wpabuf_free(sm->eap_if.aaaEapReqData);
1904	wpabuf_free(sm->eap_if.aaaEapRespData);
1905	bin_clear_free(sm->eap_if.aaaEapKeyData, sm->eap_if.aaaEapKeyDataLen);
1906	eap_user_free(sm->user);
1907	wpabuf_free(sm->assoc_wps_ie);
1908	wpabuf_free(sm->assoc_p2p_ie);
1909	os_free(sm);
1910}
1911
1912
1913/**
1914 * eap_sm_notify_cached - Notify EAP state machine of cached PMK
1915 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1916 *
1917 * This function is called when PMKSA caching is used to skip EAP
1918 * authentication.
1919 */
1920void eap_sm_notify_cached(struct eap_sm *sm)
1921{
1922	if (sm == NULL)
1923		return;
1924
1925	sm->EAP_state = EAP_SUCCESS;
1926}
1927
1928
1929/**
1930 * eap_sm_pending_cb - EAP state machine callback for a pending EAP request
1931 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1932 *
1933 * This function is called when data for a pending EAP-Request is received.
1934 */
1935void eap_sm_pending_cb(struct eap_sm *sm)
1936{
1937	if (sm == NULL)
1938		return;
1939	wpa_printf(MSG_DEBUG, "EAP: Callback for pending request received");
1940	if (sm->method_pending == METHOD_PENDING_WAIT)
1941		sm->method_pending = METHOD_PENDING_CONT;
1942}
1943
1944
1945/**
1946 * eap_sm_method_pending - Query whether EAP method is waiting for pending data
1947 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1948 * Returns: 1 if method is waiting for pending data or 0 if not
1949 */
1950int eap_sm_method_pending(struct eap_sm *sm)
1951{
1952	if (sm == NULL)
1953		return 0;
1954	return sm->method_pending == METHOD_PENDING_WAIT;
1955}
1956
1957
1958/**
1959 * eap_get_identity - Get the user identity (from EAP-Response/Identity)
1960 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1961 * @len: Buffer for returning identity length
1962 * Returns: Pointer to the user identity or %NULL if not available
1963 */
1964const u8 * eap_get_identity(struct eap_sm *sm, size_t *len)
1965{
1966	*len = sm->identity_len;
1967	return sm->identity;
1968}
1969
1970
1971/**
1972 * eap_get_interface - Get pointer to EAP-EAPOL interface data
1973 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1974 * Returns: Pointer to the EAP-EAPOL interface data
1975 */
1976struct eap_eapol_interface * eap_get_interface(struct eap_sm *sm)
1977{
1978	return &sm->eap_if;
1979}
1980
1981
1982/**
1983 * eap_server_clear_identity - Clear EAP identity information
1984 * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
1985 *
1986 * This function can be used to clear the EAP identity information in the EAP
1987 * server context. This allows the EAP/Identity method to be used again after
1988 * EAPOL-Start or EAPOL-Logoff.
1989 */
1990void eap_server_clear_identity(struct eap_sm *sm)
1991{
1992	os_free(sm->identity);
1993	sm->identity = NULL;
1994}
1995
1996
1997#ifdef CONFIG_TESTING_OPTIONS
1998void eap_server_mschap_rx_callback(struct eap_sm *sm, const char *source,
1999				   const u8 *username, size_t username_len,
2000				   const u8 *challenge, const u8 *response)
2001{
2002	char hex_challenge[30], hex_response[90], user[100];
2003
2004	/* Print out Challenge and Response in format supported by asleap. */
2005	if (username)
2006		printf_encode(user, sizeof(user), username, username_len);
2007	else
2008		user[0] = '\0';
2009	wpa_snprintf_hex_sep(hex_challenge, sizeof(hex_challenge),
2010			     challenge, sizeof(challenge), ':');
2011	wpa_snprintf_hex_sep(hex_response, sizeof(hex_response), response, 24,
2012			     ':');
2013	wpa_printf(MSG_DEBUG, "[%s/user=%s] asleap -C %s -R %s",
2014		   source, user, hex_challenge, hex_response);
2015}
2016#endif /* CONFIG_TESTING_OPTIONS */
2017