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