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