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