]> git.ipfire.org Git - thirdparty/hostap.git/blob - src/eap_peer/eap.c
Replace EapType typedef with enum eap_type
[thirdparty/hostap.git] / src / eap_peer / eap.c
1 /*
2 * EAP peer state machines (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 file implements the Peer State Machine as defined in RFC 4137. The used
9 * states and state transitions match mostly with the RFC. However, there are
10 * couple of additional transitions for working around small issues noticed
11 * during testing. These exceptions are explained in comments within the
12 * functions in this file. The method functions, m.func(), are similar to the
13 * ones used in RFC 4137, but some small changes have used here to optimize
14 * operations and to add functionality needed for fast re-authentication
15 * (session resumption).
16 */
17
18 #include "includes.h"
19
20 #include "common.h"
21 #include "pcsc_funcs.h"
22 #include "state_machine.h"
23 #include "ext_password.h"
24 #include "crypto/crypto.h"
25 #include "crypto/tls.h"
26 #include "crypto/sha256.h"
27 #include "common/wpa_ctrl.h"
28 #include "eap_common/eap_wsc_common.h"
29 #include "eap_i.h"
30 #include "eap_config.h"
31
32 #define STATE_MACHINE_DATA struct eap_sm
33 #define STATE_MACHINE_DEBUG_PREFIX "EAP"
34
35 #define EAP_MAX_AUTH_ROUNDS 50
36 #define EAP_CLIENT_TIMEOUT_DEFAULT 60
37
38
39 static Boolean eap_sm_allowMethod(struct eap_sm *sm, int vendor,
40 enum eap_type method);
41 static struct wpabuf * eap_sm_buildNak(struct eap_sm *sm, int id);
42 static void eap_sm_processIdentity(struct eap_sm *sm,
43 const struct wpabuf *req);
44 static void eap_sm_processNotify(struct eap_sm *sm, const struct wpabuf *req);
45 static struct wpabuf * eap_sm_buildNotify(int id);
46 static void eap_sm_parseEapReq(struct eap_sm *sm, const struct wpabuf *req);
47 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
48 static const char * eap_sm_method_state_txt(EapMethodState state);
49 static const char * eap_sm_decision_txt(EapDecision decision);
50 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
51 static void eap_sm_request(struct eap_sm *sm, enum wpa_ctrl_req_type field,
52 const char *msg, size_t msglen);
53
54
55
56 static Boolean eapol_get_bool(struct eap_sm *sm, enum eapol_bool_var var)
57 {
58 return sm->eapol_cb->get_bool(sm->eapol_ctx, var);
59 }
60
61
62 static void eapol_set_bool(struct eap_sm *sm, enum eapol_bool_var var,
63 Boolean value)
64 {
65 sm->eapol_cb->set_bool(sm->eapol_ctx, var, value);
66 }
67
68
69 static unsigned int eapol_get_int(struct eap_sm *sm, enum eapol_int_var var)
70 {
71 return sm->eapol_cb->get_int(sm->eapol_ctx, var);
72 }
73
74
75 static void eapol_set_int(struct eap_sm *sm, enum eapol_int_var var,
76 unsigned int value)
77 {
78 sm->eapol_cb->set_int(sm->eapol_ctx, var, value);
79 }
80
81
82 static struct wpabuf * eapol_get_eapReqData(struct eap_sm *sm)
83 {
84 return sm->eapol_cb->get_eapReqData(sm->eapol_ctx);
85 }
86
87
88 static void eap_notify_status(struct eap_sm *sm, const char *status,
89 const char *parameter)
90 {
91 wpa_printf(MSG_DEBUG, "EAP: Status notification: %s (param=%s)",
92 status, parameter);
93 if (sm->eapol_cb->notify_status)
94 sm->eapol_cb->notify_status(sm->eapol_ctx, status, parameter);
95 }
96
97
98 static void eap_report_error(struct eap_sm *sm, int error_code)
99 {
100 wpa_printf(MSG_DEBUG, "EAP: Error notification: %d", error_code);
101 if (sm->eapol_cb->notify_eap_error)
102 sm->eapol_cb->notify_eap_error(sm->eapol_ctx, error_code);
103 }
104
105
106 static void eap_sm_free_key(struct eap_sm *sm)
107 {
108 if (sm->eapKeyData) {
109 bin_clear_free(sm->eapKeyData, sm->eapKeyDataLen);
110 sm->eapKeyData = NULL;
111 }
112 }
113
114
115 static void eap_deinit_prev_method(struct eap_sm *sm, const char *txt)
116 {
117 ext_password_free(sm->ext_pw_buf);
118 sm->ext_pw_buf = NULL;
119
120 if (sm->m == NULL || sm->eap_method_priv == NULL)
121 return;
122
123 wpa_printf(MSG_DEBUG, "EAP: deinitialize previously used EAP method "
124 "(%d, %s) at %s", sm->selectedMethod, sm->m->name, txt);
125 sm->m->deinit(sm, sm->eap_method_priv);
126 sm->eap_method_priv = NULL;
127 sm->m = NULL;
128 }
129
130
131 /**
132 * eap_config_allowed_method - Check whether EAP method is allowed
133 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
134 * @config: EAP configuration
135 * @vendor: Vendor-Id for expanded types or 0 = IETF for legacy types
136 * @method: EAP type
137 * Returns: 1 = allowed EAP method, 0 = not allowed
138 */
139 static int eap_config_allowed_method(struct eap_sm *sm,
140 struct eap_peer_config *config,
141 int vendor, u32 method)
142 {
143 int i;
144 struct eap_method_type *m;
145
146 if (config == NULL || config->eap_methods == NULL)
147 return 1;
148
149 m = config->eap_methods;
150 for (i = 0; m[i].vendor != EAP_VENDOR_IETF ||
151 m[i].method != EAP_TYPE_NONE; i++) {
152 if (m[i].vendor == vendor && m[i].method == method)
153 return 1;
154 }
155 return 0;
156 }
157
158
159 /**
160 * eap_allowed_method - Check whether EAP method is allowed
161 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
162 * @vendor: Vendor-Id for expanded types or 0 = IETF for legacy types
163 * @method: EAP type
164 * Returns: 1 = allowed EAP method, 0 = not allowed
165 */
166 int eap_allowed_method(struct eap_sm *sm, int vendor, u32 method)
167 {
168 return eap_config_allowed_method(sm, eap_get_config(sm), vendor,
169 method);
170 }
171
172
173 #if defined(PCSC_FUNCS) || defined(CONFIG_EAP_PROXY)
174 static int eap_sm_append_3gpp_realm(struct eap_sm *sm, char *imsi,
175 size_t max_len, size_t *imsi_len,
176 int mnc_len)
177 {
178 char *pos, mnc[4];
179
180 if (*imsi_len + 36 > max_len) {
181 wpa_printf(MSG_WARNING, "No room for realm in IMSI buffer");
182 return -1;
183 }
184
185 if (mnc_len != 2 && mnc_len != 3)
186 mnc_len = 3;
187
188 if (mnc_len == 2) {
189 mnc[0] = '0';
190 mnc[1] = imsi[3];
191 mnc[2] = imsi[4];
192 } else if (mnc_len == 3) {
193 mnc[0] = imsi[3];
194 mnc[1] = imsi[4];
195 mnc[2] = imsi[5];
196 }
197 mnc[3] = '\0';
198
199 pos = imsi + *imsi_len;
200 pos += os_snprintf(pos, imsi + max_len - pos,
201 "@wlan.mnc%s.mcc%c%c%c.3gppnetwork.org",
202 mnc, imsi[0], imsi[1], imsi[2]);
203 *imsi_len = pos - imsi;
204
205 return 0;
206 }
207 #endif /* PCSC_FUNCS || CONFIG_EAP_PROXY */
208
209
210 /*
211 * This state initializes state machine variables when the machine is
212 * activated (portEnabled = TRUE). This is also used when re-starting
213 * authentication (eapRestart == TRUE).
214 */
215 SM_STATE(EAP, INITIALIZE)
216 {
217 SM_ENTRY(EAP, INITIALIZE);
218 if (sm->fast_reauth && sm->m && sm->m->has_reauth_data &&
219 sm->m->has_reauth_data(sm, sm->eap_method_priv) &&
220 !sm->prev_failure &&
221 sm->last_config == eap_get_config(sm)) {
222 wpa_printf(MSG_DEBUG, "EAP: maintaining EAP method data for "
223 "fast reauthentication");
224 sm->m->deinit_for_reauth(sm, sm->eap_method_priv);
225 } else {
226 sm->last_config = eap_get_config(sm);
227 eap_deinit_prev_method(sm, "INITIALIZE");
228 }
229 sm->selectedMethod = EAP_TYPE_NONE;
230 sm->methodState = METHOD_NONE;
231 sm->allowNotifications = TRUE;
232 sm->decision = DECISION_FAIL;
233 sm->ClientTimeout = EAP_CLIENT_TIMEOUT_DEFAULT;
234 eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout);
235 eapol_set_bool(sm, EAPOL_eapSuccess, FALSE);
236 eapol_set_bool(sm, EAPOL_eapFail, FALSE);
237 eap_sm_free_key(sm);
238 os_free(sm->eapSessionId);
239 sm->eapSessionId = NULL;
240 sm->eapKeyAvailable = FALSE;
241 eapol_set_bool(sm, EAPOL_eapRestart, FALSE);
242 sm->lastId = -1; /* new session - make sure this does not match with
243 * the first EAP-Packet */
244 /*
245 * RFC 4137 does not reset eapResp and eapNoResp here. However, this
246 * seemed to be able to trigger cases where both were set and if EAPOL
247 * state machine uses eapNoResp first, it may end up not sending a real
248 * reply correctly. This occurred when the workaround in FAIL state set
249 * eapNoResp = TRUE.. Maybe that workaround needs to be fixed to do
250 * something else(?)
251 */
252 eapol_set_bool(sm, EAPOL_eapResp, FALSE);
253 eapol_set_bool(sm, EAPOL_eapNoResp, FALSE);
254 /*
255 * RFC 4137 does not reset ignore here, but since it is possible for
256 * some method code paths to end up not setting ignore=FALSE, clear the
257 * value here to avoid issues if a previous authentication attempt
258 * failed with ignore=TRUE being left behind in the last
259 * m.check(eapReqData) operation.
260 */
261 sm->ignore = 0;
262 sm->num_rounds = 0;
263 sm->prev_failure = 0;
264 sm->expected_failure = 0;
265 sm->reauthInit = FALSE;
266 sm->erp_seq = (u32) -1;
267 }
268
269
270 /*
271 * This state is reached whenever service from the lower layer is interrupted
272 * or unavailable (portEnabled == FALSE). Immediate transition to INITIALIZE
273 * occurs when the port becomes enabled.
274 */
275 SM_STATE(EAP, DISABLED)
276 {
277 SM_ENTRY(EAP, DISABLED);
278 sm->num_rounds = 0;
279 /*
280 * RFC 4137 does not describe clearing of idleWhile here, but doing so
281 * allows the timer tick to be stopped more quickly when EAP is not in
282 * use.
283 */
284 eapol_set_int(sm, EAPOL_idleWhile, 0);
285 }
286
287
288 /*
289 * The state machine spends most of its time here, waiting for something to
290 * happen. This state is entered unconditionally from INITIALIZE, DISCARD, and
291 * SEND_RESPONSE states.
292 */
293 SM_STATE(EAP, IDLE)
294 {
295 SM_ENTRY(EAP, IDLE);
296 }
297
298
299 /*
300 * This state is entered when an EAP packet is received (eapReq == TRUE) to
301 * parse the packet header.
302 */
303 SM_STATE(EAP, RECEIVED)
304 {
305 const struct wpabuf *eapReqData;
306
307 SM_ENTRY(EAP, RECEIVED);
308 eapReqData = eapol_get_eapReqData(sm);
309 /* parse rxReq, rxSuccess, rxFailure, reqId, reqMethod */
310 eap_sm_parseEapReq(sm, eapReqData);
311 sm->num_rounds++;
312 }
313
314
315 /*
316 * This state is entered when a request for a new type comes in. Either the
317 * correct method is started, or a Nak response is built.
318 */
319 SM_STATE(EAP, GET_METHOD)
320 {
321 int reinit;
322 enum eap_type method;
323 const struct eap_method *eap_method;
324
325 SM_ENTRY(EAP, GET_METHOD);
326
327 if (sm->reqMethod == EAP_TYPE_EXPANDED)
328 method = sm->reqVendorMethod;
329 else
330 method = sm->reqMethod;
331
332 eap_method = eap_peer_get_eap_method(sm->reqVendor, method);
333
334 if (!eap_sm_allowMethod(sm, sm->reqVendor, method)) {
335 wpa_printf(MSG_DEBUG, "EAP: vendor %u method %u not allowed",
336 sm->reqVendor, method);
337 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD
338 "vendor=%u method=%u -> NAK",
339 sm->reqVendor, method);
340 eap_notify_status(sm, "refuse proposed method",
341 eap_method ? eap_method->name : "unknown");
342 goto nak;
343 }
344
345 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD
346 "vendor=%u method=%u", sm->reqVendor, method);
347
348 eap_notify_status(sm, "accept proposed method",
349 eap_method ? eap_method->name : "unknown");
350 /*
351 * RFC 4137 does not define specific operation for fast
352 * re-authentication (session resumption). The design here is to allow
353 * the previously used method data to be maintained for
354 * re-authentication if the method support session resumption.
355 * Otherwise, the previously used method data is freed and a new method
356 * is allocated here.
357 */
358 if (sm->fast_reauth &&
359 sm->m && sm->m->vendor == sm->reqVendor &&
360 sm->m->method == method &&
361 sm->m->has_reauth_data &&
362 sm->m->has_reauth_data(sm, sm->eap_method_priv)) {
363 wpa_printf(MSG_DEBUG, "EAP: Using previous method data"
364 " for fast re-authentication");
365 reinit = 1;
366 } else {
367 eap_deinit_prev_method(sm, "GET_METHOD");
368 reinit = 0;
369 }
370
371 sm->selectedMethod = sm->reqMethod;
372 if (sm->m == NULL)
373 sm->m = eap_method;
374 if (!sm->m) {
375 wpa_printf(MSG_DEBUG, "EAP: Could not find selected method: "
376 "vendor %d method %d",
377 sm->reqVendor, method);
378 goto nak;
379 }
380
381 sm->ClientTimeout = EAP_CLIENT_TIMEOUT_DEFAULT;
382
383 wpa_printf(MSG_DEBUG, "EAP: Initialize selected EAP method: "
384 "vendor %u method %u (%s)",
385 sm->reqVendor, method, sm->m->name);
386 if (reinit) {
387 sm->eap_method_priv = sm->m->init_for_reauth(
388 sm, sm->eap_method_priv);
389 } else {
390 sm->waiting_ext_cert_check = 0;
391 sm->ext_cert_check = 0;
392 sm->eap_method_priv = sm->m->init(sm);
393 }
394
395 if (sm->eap_method_priv == NULL) {
396 struct eap_peer_config *config = eap_get_config(sm);
397 wpa_msg(sm->msg_ctx, MSG_INFO,
398 "EAP: Failed to initialize EAP method: vendor %u "
399 "method %u (%s)",
400 sm->reqVendor, method, sm->m->name);
401 sm->m = NULL;
402 sm->methodState = METHOD_NONE;
403 sm->selectedMethod = EAP_TYPE_NONE;
404 if (sm->reqMethod == EAP_TYPE_TLS && config &&
405 (config->pending_req_pin ||
406 config->pending_req_passphrase)) {
407 /*
408 * Return without generating Nak in order to allow
409 * entering of PIN code or passphrase to retry the
410 * current EAP packet.
411 */
412 wpa_printf(MSG_DEBUG, "EAP: Pending PIN/passphrase "
413 "request - skip Nak");
414 return;
415 }
416
417 goto nak;
418 }
419
420 sm->methodState = METHOD_INIT;
421 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_METHOD
422 "EAP vendor %u method %u (%s) selected",
423 sm->reqVendor, method, sm->m->name);
424 return;
425
426 nak:
427 wpabuf_free(sm->eapRespData);
428 sm->eapRespData = NULL;
429 sm->eapRespData = eap_sm_buildNak(sm, sm->reqId);
430 }
431
432
433 #ifdef CONFIG_ERP
434
435 static char * eap_get_realm(struct eap_sm *sm, struct eap_peer_config *config)
436 {
437 char *realm;
438 size_t i, realm_len;
439
440 if (!config)
441 return NULL;
442
443 if (config->identity) {
444 for (i = 0; i < config->identity_len; i++) {
445 if (config->identity[i] == '@')
446 break;
447 }
448 if (i < config->identity_len) {
449 realm_len = config->identity_len - i - 1;
450 realm = os_malloc(realm_len + 1);
451 if (realm == NULL)
452 return NULL;
453 os_memcpy(realm, &config->identity[i + 1], realm_len);
454 realm[realm_len] = '\0';
455 return realm;
456 }
457 }
458
459 if (config->anonymous_identity) {
460 for (i = 0; i < config->anonymous_identity_len; i++) {
461 if (config->anonymous_identity[i] == '@')
462 break;
463 }
464 if (i < config->anonymous_identity_len) {
465 realm_len = config->anonymous_identity_len - i - 1;
466 realm = os_malloc(realm_len + 1);
467 if (realm == NULL)
468 return NULL;
469 os_memcpy(realm, &config->anonymous_identity[i + 1],
470 realm_len);
471 realm[realm_len] = '\0';
472 return realm;
473 }
474 }
475
476 #ifdef CONFIG_EAP_PROXY
477 /* When identity is not provided in the config, build the realm from
478 * IMSI for eap_proxy based methods.
479 */
480 if (!config->identity && !config->anonymous_identity &&
481 sm->eapol_cb->get_imsi &&
482 (eap_config_allowed_method(sm, config, EAP_VENDOR_IETF,
483 EAP_TYPE_SIM) ||
484 eap_config_allowed_method(sm, config, EAP_VENDOR_IETF,
485 EAP_TYPE_AKA) ||
486 eap_config_allowed_method(sm, config, EAP_VENDOR_IETF,
487 EAP_TYPE_AKA_PRIME))) {
488 char imsi[100];
489 size_t imsi_len;
490 int mnc_len, pos;
491
492 wpa_printf(MSG_DEBUG, "EAP: Build realm from IMSI (eap_proxy)");
493 mnc_len = sm->eapol_cb->get_imsi(sm->eapol_ctx, config->sim_num,
494 imsi, &imsi_len);
495 if (mnc_len < 0)
496 return NULL;
497
498 pos = imsi_len + 1; /* points to the beginning of the realm */
499 if (eap_sm_append_3gpp_realm(sm, imsi, sizeof(imsi), &imsi_len,
500 mnc_len) < 0) {
501 wpa_printf(MSG_WARNING, "Could not append realm");
502 return NULL;
503 }
504
505 realm = os_strdup(&imsi[pos]);
506 if (!realm)
507 return NULL;
508
509 wpa_printf(MSG_DEBUG, "EAP: Generated realm '%s'", realm);
510 return realm;
511 }
512 #endif /* CONFIG_EAP_PROXY */
513
514 return NULL;
515 }
516
517
518 static char * eap_home_realm(struct eap_sm *sm)
519 {
520 return eap_get_realm(sm, eap_get_config(sm));
521 }
522
523
524 static struct eap_erp_key *
525 eap_erp_get_key(struct eap_sm *sm, const char *realm)
526 {
527 struct eap_erp_key *erp;
528
529 dl_list_for_each(erp, &sm->erp_keys, struct eap_erp_key, list) {
530 char *pos;
531
532 pos = os_strchr(erp->keyname_nai, '@');
533 if (!pos)
534 continue;
535 pos++;
536 if (os_strcmp(pos, realm) == 0)
537 return erp;
538 }
539
540 return NULL;
541 }
542
543
544 static struct eap_erp_key *
545 eap_erp_get_key_nai(struct eap_sm *sm, const char *nai)
546 {
547 struct eap_erp_key *erp;
548
549 dl_list_for_each(erp, &sm->erp_keys, struct eap_erp_key, list) {
550 if (os_strcmp(erp->keyname_nai, nai) == 0)
551 return erp;
552 }
553
554 return NULL;
555 }
556
557
558 static void eap_peer_erp_free_key(struct eap_erp_key *erp)
559 {
560 dl_list_del(&erp->list);
561 bin_clear_free(erp, sizeof(*erp));
562 }
563
564
565 static void eap_erp_remove_keys_realm(struct eap_sm *sm, const char *realm)
566 {
567 struct eap_erp_key *erp;
568
569 while ((erp = eap_erp_get_key(sm, realm)) != NULL) {
570 wpa_printf(MSG_DEBUG, "EAP: Delete old ERP key %s",
571 erp->keyname_nai);
572 eap_peer_erp_free_key(erp);
573 }
574 }
575
576
577 int eap_peer_update_erp_next_seq_num(struct eap_sm *sm, u16 next_seq_num)
578 {
579 struct eap_erp_key *erp;
580 char *home_realm;
581
582 home_realm = eap_home_realm(sm);
583 if (!home_realm || os_strlen(home_realm) == 0) {
584 os_free(home_realm);
585 return -1;
586 }
587
588 erp = eap_erp_get_key(sm, home_realm);
589 if (!erp) {
590 wpa_printf(MSG_DEBUG,
591 "EAP: Failed to find ERP key for realm: %s",
592 home_realm);
593 os_free(home_realm);
594 return -1;
595 }
596
597 if ((u32) next_seq_num < erp->next_seq) {
598 /* Sequence number has wrapped around, clear this ERP
599 * info and do a full auth next time.
600 */
601 eap_peer_erp_free_key(erp);
602 } else {
603 erp->next_seq = (u32) next_seq_num;
604 }
605
606 os_free(home_realm);
607 return 0;
608 }
609
610
611 int eap_peer_get_erp_info(struct eap_sm *sm, struct eap_peer_config *config,
612 const u8 **username, size_t *username_len,
613 const u8 **realm, size_t *realm_len,
614 u16 *erp_next_seq_num, const u8 **rrk,
615 size_t *rrk_len)
616 {
617 struct eap_erp_key *erp;
618 char *home_realm;
619 char *pos;
620
621 if (config)
622 home_realm = eap_get_realm(sm, config);
623 else
624 home_realm = eap_home_realm(sm);
625 if (!home_realm || os_strlen(home_realm) == 0) {
626 os_free(home_realm);
627 return -1;
628 }
629
630 erp = eap_erp_get_key(sm, home_realm);
631 os_free(home_realm);
632 if (!erp)
633 return -1;
634
635 if (erp->next_seq >= 65536)
636 return -1; /* SEQ has range of 0..65535 */
637
638 pos = os_strchr(erp->keyname_nai, '@');
639 if (!pos)
640 return -1; /* this cannot really happen */
641 *username_len = pos - erp->keyname_nai;
642 *username = (u8 *) erp->keyname_nai;
643
644 pos++;
645 *realm_len = os_strlen(pos);
646 *realm = (u8 *) pos;
647
648 *erp_next_seq_num = (u16) erp->next_seq;
649
650 *rrk_len = erp->rRK_len;
651 *rrk = erp->rRK;
652
653 if (*username_len == 0 || *realm_len == 0 || *rrk_len == 0)
654 return -1;
655
656 return 0;
657 }
658
659 #endif /* CONFIG_ERP */
660
661
662 void eap_peer_erp_free_keys(struct eap_sm *sm)
663 {
664 #ifdef CONFIG_ERP
665 struct eap_erp_key *erp, *tmp;
666
667 dl_list_for_each_safe(erp, tmp, &sm->erp_keys, struct eap_erp_key, list)
668 eap_peer_erp_free_key(erp);
669 #endif /* CONFIG_ERP */
670 }
671
672
673 /* Note: If ext_session and/or ext_emsk are passed to this function, they are
674 * expected to point to allocated memory and those allocations will be freed
675 * unconditionally. */
676 void eap_peer_erp_init(struct eap_sm *sm, u8 *ext_session_id,
677 size_t ext_session_id_len, u8 *ext_emsk,
678 size_t ext_emsk_len)
679 {
680 #ifdef CONFIG_ERP
681 u8 *emsk = NULL;
682 size_t emsk_len = 0;
683 u8 *session_id = NULL;
684 size_t session_id_len = 0;
685 u8 EMSKname[EAP_EMSK_NAME_LEN];
686 u8 len[2], ctx[3];
687 char *realm;
688 size_t realm_len, nai_buf_len;
689 struct eap_erp_key *erp = NULL;
690 int pos;
691
692 realm = eap_home_realm(sm);
693 if (!realm)
694 goto fail;
695 realm_len = os_strlen(realm);
696 wpa_printf(MSG_DEBUG, "EAP: Realm for ERP keyName-NAI: %s", realm);
697 eap_erp_remove_keys_realm(sm, realm);
698
699 nai_buf_len = 2 * EAP_EMSK_NAME_LEN + 1 + realm_len;
700 if (nai_buf_len > 253) {
701 /*
702 * keyName-NAI has a maximum length of 253 octet to fit in
703 * RADIUS attributes.
704 */
705 wpa_printf(MSG_DEBUG,
706 "EAP: Too long realm for ERP keyName-NAI maximum length");
707 goto fail;
708 }
709 nai_buf_len++; /* null termination */
710 erp = os_zalloc(sizeof(*erp) + nai_buf_len);
711 if (erp == NULL)
712 goto fail;
713
714 if (ext_emsk) {
715 emsk = ext_emsk;
716 emsk_len = ext_emsk_len;
717 } else {
718 emsk = sm->m->get_emsk(sm, sm->eap_method_priv, &emsk_len);
719 }
720
721 if (!emsk || emsk_len == 0 || emsk_len > ERP_MAX_KEY_LEN) {
722 wpa_printf(MSG_DEBUG,
723 "EAP: No suitable EMSK available for ERP");
724 goto fail;
725 }
726
727 wpa_hexdump_key(MSG_DEBUG, "EAP: EMSK", emsk, emsk_len);
728
729 if (ext_session_id) {
730 session_id = ext_session_id;
731 session_id_len = ext_session_id_len;
732 } else {
733 session_id = sm->eapSessionId;
734 session_id_len = sm->eapSessionIdLen;
735 }
736
737 if (!session_id || session_id_len == 0) {
738 wpa_printf(MSG_DEBUG,
739 "EAP: No suitable session id available for ERP");
740 goto fail;
741 }
742
743 WPA_PUT_BE16(len, EAP_EMSK_NAME_LEN);
744 if (hmac_sha256_kdf(session_id, session_id_len, "EMSK", len,
745 sizeof(len), EMSKname, EAP_EMSK_NAME_LEN) < 0) {
746 wpa_printf(MSG_DEBUG, "EAP: Could not derive EMSKname");
747 goto fail;
748 }
749 wpa_hexdump(MSG_DEBUG, "EAP: EMSKname", EMSKname, EAP_EMSK_NAME_LEN);
750
751 pos = wpa_snprintf_hex(erp->keyname_nai, nai_buf_len,
752 EMSKname, EAP_EMSK_NAME_LEN);
753 erp->keyname_nai[pos] = '@';
754 os_memcpy(&erp->keyname_nai[pos + 1], realm, realm_len);
755
756 WPA_PUT_BE16(len, emsk_len);
757 if (hmac_sha256_kdf(emsk, emsk_len,
758 "EAP Re-authentication Root Key@ietf.org",
759 len, sizeof(len), erp->rRK, emsk_len) < 0) {
760 wpa_printf(MSG_DEBUG, "EAP: Could not derive rRK for ERP");
761 goto fail;
762 }
763 erp->rRK_len = emsk_len;
764 wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rRK", erp->rRK, erp->rRK_len);
765
766 ctx[0] = EAP_ERP_CS_HMAC_SHA256_128;
767 WPA_PUT_BE16(&ctx[1], erp->rRK_len);
768 if (hmac_sha256_kdf(erp->rRK, erp->rRK_len,
769 "Re-authentication Integrity Key@ietf.org",
770 ctx, sizeof(ctx), erp->rIK, erp->rRK_len) < 0) {
771 wpa_printf(MSG_DEBUG, "EAP: Could not derive rIK for ERP");
772 goto fail;
773 }
774 erp->rIK_len = erp->rRK_len;
775 wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rIK", erp->rIK, erp->rIK_len);
776
777 wpa_printf(MSG_DEBUG, "EAP: Stored ERP keys %s", erp->keyname_nai);
778 dl_list_add(&sm->erp_keys, &erp->list);
779 erp = NULL;
780 fail:
781 if (ext_emsk)
782 bin_clear_free(ext_emsk, ext_emsk_len);
783 else
784 bin_clear_free(emsk, emsk_len);
785 bin_clear_free(ext_session_id, ext_session_id_len);
786 bin_clear_free(erp, sizeof(*erp));
787 os_free(realm);
788 #endif /* CONFIG_ERP */
789 }
790
791
792 #ifdef CONFIG_ERP
793 struct wpabuf * eap_peer_build_erp_reauth_start(struct eap_sm *sm, u8 eap_id)
794 {
795 char *realm;
796 struct eap_erp_key *erp;
797 struct wpabuf *msg;
798 u8 hash[SHA256_MAC_LEN];
799
800 realm = eap_home_realm(sm);
801 if (!realm)
802 return NULL;
803
804 erp = eap_erp_get_key(sm, realm);
805 os_free(realm);
806 realm = NULL;
807 if (!erp)
808 return NULL;
809
810 if (erp->next_seq >= 65536)
811 return NULL; /* SEQ has range of 0..65535 */
812
813 /* TODO: check rRK lifetime expiration */
814
815 wpa_printf(MSG_DEBUG, "EAP: Valid ERP key found %s (SEQ=%u)",
816 erp->keyname_nai, erp->next_seq);
817
818 msg = eap_msg_alloc(EAP_VENDOR_IETF,
819 (enum eap_type) EAP_ERP_TYPE_REAUTH,
820 1 + 2 + 2 + os_strlen(erp->keyname_nai) + 1 + 16,
821 EAP_CODE_INITIATE, eap_id);
822 if (msg == NULL)
823 return NULL;
824
825 wpabuf_put_u8(msg, 0x20); /* Flags: R=0 B=0 L=1 */
826 wpabuf_put_be16(msg, erp->next_seq);
827
828 wpabuf_put_u8(msg, EAP_ERP_TLV_KEYNAME_NAI);
829 wpabuf_put_u8(msg, os_strlen(erp->keyname_nai));
830 wpabuf_put_str(msg, erp->keyname_nai);
831
832 wpabuf_put_u8(msg, EAP_ERP_CS_HMAC_SHA256_128); /* Cryptosuite */
833
834 if (hmac_sha256(erp->rIK, erp->rIK_len,
835 wpabuf_head(msg), wpabuf_len(msg), hash) < 0) {
836 wpabuf_free(msg);
837 return NULL;
838 }
839 wpabuf_put_data(msg, hash, 16);
840
841 sm->erp_seq = erp->next_seq;
842 erp->next_seq++;
843
844 wpa_hexdump_buf(MSG_DEBUG, "ERP: EAP-Initiate/Re-auth", msg);
845
846 return msg;
847 }
848
849
850 static int eap_peer_erp_reauth_start(struct eap_sm *sm, u8 eap_id)
851 {
852 struct wpabuf *msg;
853
854 msg = eap_peer_build_erp_reauth_start(sm, eap_id);
855 if (!msg)
856 return -1;
857
858 wpa_printf(MSG_DEBUG, "EAP: Sending EAP-Initiate/Re-auth");
859 wpabuf_free(sm->eapRespData);
860 sm->eapRespData = msg;
861 sm->reauthInit = TRUE;
862 return 0;
863 }
864 #endif /* CONFIG_ERP */
865
866
867 /*
868 * The method processing happens here. The request from the authenticator is
869 * processed, and an appropriate response packet is built.
870 */
871 SM_STATE(EAP, METHOD)
872 {
873 struct wpabuf *eapReqData;
874 struct eap_method_ret ret;
875 int min_len = 1;
876
877 SM_ENTRY(EAP, METHOD);
878 if (sm->m == NULL) {
879 wpa_printf(MSG_WARNING, "EAP::METHOD - method not selected");
880 return;
881 }
882
883 eapReqData = eapol_get_eapReqData(sm);
884 if (sm->m->vendor == EAP_VENDOR_IETF && sm->m->method == EAP_TYPE_LEAP)
885 min_len = 0; /* LEAP uses EAP-Success without payload */
886 if (!eap_hdr_len_valid(eapReqData, min_len))
887 return;
888
889 /*
890 * Get ignore, methodState, decision, allowNotifications, and
891 * eapRespData. RFC 4137 uses three separate method procedure (check,
892 * process, and buildResp) in this state. These have been combined into
893 * a single function call to m->process() in order to optimize EAP
894 * method implementation interface a bit. These procedures are only
895 * used from within this METHOD state, so there is no need to keep
896 * these as separate C functions.
897 *
898 * The RFC 4137 procedures return values as follows:
899 * ignore = m.check(eapReqData)
900 * (methodState, decision, allowNotifications) = m.process(eapReqData)
901 * eapRespData = m.buildResp(reqId)
902 */
903 os_memset(&ret, 0, sizeof(ret));
904 ret.ignore = sm->ignore;
905 ret.methodState = sm->methodState;
906 ret.decision = sm->decision;
907 ret.allowNotifications = sm->allowNotifications;
908 wpabuf_free(sm->eapRespData);
909 sm->eapRespData = NULL;
910 sm->eapRespData = sm->m->process(sm, sm->eap_method_priv, &ret,
911 eapReqData);
912 wpa_printf(MSG_DEBUG, "EAP: method process -> ignore=%s "
913 "methodState=%s decision=%s eapRespData=%p",
914 ret.ignore ? "TRUE" : "FALSE",
915 eap_sm_method_state_txt(ret.methodState),
916 eap_sm_decision_txt(ret.decision),
917 sm->eapRespData);
918
919 sm->ignore = ret.ignore;
920 if (sm->ignore)
921 return;
922 sm->methodState = ret.methodState;
923 sm->decision = ret.decision;
924 sm->allowNotifications = ret.allowNotifications;
925
926 if (sm->m->isKeyAvailable && sm->m->getKey &&
927 sm->m->isKeyAvailable(sm, sm->eap_method_priv)) {
928 eap_sm_free_key(sm);
929 sm->eapKeyData = sm->m->getKey(sm, sm->eap_method_priv,
930 &sm->eapKeyDataLen);
931 os_free(sm->eapSessionId);
932 sm->eapSessionId = NULL;
933 if (sm->m->getSessionId) {
934 sm->eapSessionId = sm->m->getSessionId(
935 sm, sm->eap_method_priv,
936 &sm->eapSessionIdLen);
937 wpa_hexdump(MSG_DEBUG, "EAP: Session-Id",
938 sm->eapSessionId, sm->eapSessionIdLen);
939 }
940 }
941 }
942
943
944 /*
945 * This state signals the lower layer that a response packet is ready to be
946 * sent.
947 */
948 SM_STATE(EAP, SEND_RESPONSE)
949 {
950 SM_ENTRY(EAP, SEND_RESPONSE);
951 wpabuf_free(sm->lastRespData);
952 if (sm->eapRespData) {
953 if (sm->workaround)
954 os_memcpy(sm->last_sha1, sm->req_sha1, 20);
955 sm->lastId = sm->reqId;
956 sm->lastRespData = wpabuf_dup(sm->eapRespData);
957 eapol_set_bool(sm, EAPOL_eapResp, TRUE);
958 } else {
959 wpa_printf(MSG_DEBUG, "EAP: No eapRespData available");
960 sm->lastRespData = NULL;
961 }
962 eapol_set_bool(sm, EAPOL_eapReq, FALSE);
963 eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout);
964 sm->reauthInit = FALSE;
965 }
966
967
968 /*
969 * This state signals the lower layer that the request was discarded, and no
970 * response packet will be sent at this time.
971 */
972 SM_STATE(EAP, DISCARD)
973 {
974 SM_ENTRY(EAP, DISCARD);
975 eapol_set_bool(sm, EAPOL_eapReq, FALSE);
976 eapol_set_bool(sm, EAPOL_eapNoResp, TRUE);
977 }
978
979
980 /*
981 * Handles requests for Identity method and builds a response.
982 */
983 SM_STATE(EAP, IDENTITY)
984 {
985 const struct wpabuf *eapReqData;
986
987 SM_ENTRY(EAP, IDENTITY);
988 eapReqData = eapol_get_eapReqData(sm);
989 if (!eap_hdr_len_valid(eapReqData, 1))
990 return;
991 eap_sm_processIdentity(sm, eapReqData);
992 wpabuf_free(sm->eapRespData);
993 sm->eapRespData = NULL;
994 sm->eapRespData = eap_sm_buildIdentity(sm, sm->reqId, 0);
995 }
996
997
998 /*
999 * Handles requests for Notification method and builds a response.
1000 */
1001 SM_STATE(EAP, NOTIFICATION)
1002 {
1003 const struct wpabuf *eapReqData;
1004
1005 SM_ENTRY(EAP, NOTIFICATION);
1006 eapReqData = eapol_get_eapReqData(sm);
1007 if (!eap_hdr_len_valid(eapReqData, 1))
1008 return;
1009 eap_sm_processNotify(sm, eapReqData);
1010 wpabuf_free(sm->eapRespData);
1011 sm->eapRespData = NULL;
1012 sm->eapRespData = eap_sm_buildNotify(sm->reqId);
1013 }
1014
1015
1016 /*
1017 * This state retransmits the previous response packet.
1018 */
1019 SM_STATE(EAP, RETRANSMIT)
1020 {
1021 SM_ENTRY(EAP, RETRANSMIT);
1022 wpabuf_free(sm->eapRespData);
1023 if (sm->lastRespData)
1024 sm->eapRespData = wpabuf_dup(sm->lastRespData);
1025 else
1026 sm->eapRespData = NULL;
1027 }
1028
1029
1030 /*
1031 * This state is entered in case of a successful completion of authentication
1032 * and state machine waits here until port is disabled or EAP authentication is
1033 * restarted.
1034 */
1035 SM_STATE(EAP, SUCCESS)
1036 {
1037 struct eap_peer_config *config = eap_get_config(sm);
1038
1039 SM_ENTRY(EAP, SUCCESS);
1040 if (sm->eapKeyData != NULL)
1041 sm->eapKeyAvailable = TRUE;
1042 eapol_set_bool(sm, EAPOL_eapSuccess, TRUE);
1043
1044 /*
1045 * RFC 4137 does not clear eapReq here, but this seems to be required
1046 * to avoid processing the same request twice when state machine is
1047 * initialized.
1048 */
1049 eapol_set_bool(sm, EAPOL_eapReq, FALSE);
1050
1051 /*
1052 * RFC 4137 does not set eapNoResp here, but this seems to be required
1053 * to get EAPOL Supplicant backend state machine into SUCCESS state. In
1054 * addition, either eapResp or eapNoResp is required to be set after
1055 * processing the received EAP frame.
1056 */
1057 eapol_set_bool(sm, EAPOL_eapNoResp, TRUE);
1058
1059 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS
1060 "EAP authentication completed successfully");
1061
1062 if (config->erp && sm->m->get_emsk && sm->eapSessionId &&
1063 sm->m->isKeyAvailable &&
1064 sm->m->isKeyAvailable(sm, sm->eap_method_priv))
1065 eap_peer_erp_init(sm, NULL, 0, NULL, 0);
1066 }
1067
1068
1069 /*
1070 * This state is entered in case of a failure and state machine waits here
1071 * until port is disabled or EAP authentication is restarted.
1072 */
1073 SM_STATE(EAP, FAILURE)
1074 {
1075 SM_ENTRY(EAP, FAILURE);
1076 eapol_set_bool(sm, EAPOL_eapFail, TRUE);
1077
1078 /*
1079 * RFC 4137 does not clear eapReq here, but this seems to be required
1080 * to avoid processing the same request twice when state machine is
1081 * initialized.
1082 */
1083 eapol_set_bool(sm, EAPOL_eapReq, FALSE);
1084
1085 /*
1086 * RFC 4137 does not set eapNoResp here. However, either eapResp or
1087 * eapNoResp is required to be set after processing the received EAP
1088 * frame.
1089 */
1090 eapol_set_bool(sm, EAPOL_eapNoResp, TRUE);
1091
1092 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE
1093 "EAP authentication failed");
1094
1095 sm->prev_failure = 1;
1096 }
1097
1098
1099 static int eap_success_workaround(struct eap_sm *sm, int reqId, int lastId)
1100 {
1101 /*
1102 * At least Microsoft IAS and Meetinghouse Aegis seem to be sending
1103 * EAP-Success/Failure with lastId + 1 even though RFC 3748 and
1104 * RFC 4137 require that reqId == lastId. In addition, it looks like
1105 * Ringmaster v2.1.2.0 would be using lastId + 2 in EAP-Success.
1106 *
1107 * Accept this kind of Id if EAP workarounds are enabled. These are
1108 * unauthenticated plaintext messages, so this should have minimal
1109 * security implications (bit easier to fake EAP-Success/Failure).
1110 */
1111 if (sm->workaround && (reqId == ((lastId + 1) & 0xff) ||
1112 reqId == ((lastId + 2) & 0xff))) {
1113 wpa_printf(MSG_DEBUG, "EAP: Workaround for unexpected "
1114 "identifier field in EAP Success: "
1115 "reqId=%d lastId=%d (these are supposed to be "
1116 "same)", reqId, lastId);
1117 return 1;
1118 }
1119 wpa_printf(MSG_DEBUG, "EAP: EAP-Success Id mismatch - reqId=%d "
1120 "lastId=%d", reqId, lastId);
1121 return 0;
1122 }
1123
1124
1125 /*
1126 * RFC 4137 - Appendix A.1: EAP Peer State Machine - State transitions
1127 */
1128
1129 static void eap_peer_sm_step_idle(struct eap_sm *sm)
1130 {
1131 /*
1132 * The first three transitions are from RFC 4137. The last two are
1133 * local additions to handle special cases with LEAP and PEAP server
1134 * not sending EAP-Success in some cases.
1135 */
1136 if (eapol_get_bool(sm, EAPOL_eapReq))
1137 SM_ENTER(EAP, RECEIVED);
1138 else if ((eapol_get_bool(sm, EAPOL_altAccept) &&
1139 sm->decision != DECISION_FAIL) ||
1140 (eapol_get_int(sm, EAPOL_idleWhile) == 0 &&
1141 sm->decision == DECISION_UNCOND_SUCC))
1142 SM_ENTER(EAP, SUCCESS);
1143 else if (eapol_get_bool(sm, EAPOL_altReject) ||
1144 (eapol_get_int(sm, EAPOL_idleWhile) == 0 &&
1145 sm->decision != DECISION_UNCOND_SUCC) ||
1146 (eapol_get_bool(sm, EAPOL_altAccept) &&
1147 sm->methodState != METHOD_CONT &&
1148 sm->decision == DECISION_FAIL))
1149 SM_ENTER(EAP, FAILURE);
1150 else if (sm->selectedMethod == EAP_TYPE_LEAP &&
1151 sm->leap_done && sm->decision != DECISION_FAIL &&
1152 sm->methodState == METHOD_DONE)
1153 SM_ENTER(EAP, SUCCESS);
1154 else if (sm->selectedMethod == EAP_TYPE_PEAP &&
1155 sm->peap_done && sm->decision != DECISION_FAIL &&
1156 sm->methodState == METHOD_DONE)
1157 SM_ENTER(EAP, SUCCESS);
1158 }
1159
1160
1161 static int eap_peer_req_is_duplicate(struct eap_sm *sm)
1162 {
1163 int duplicate;
1164
1165 duplicate = (sm->reqId == sm->lastId) && sm->rxReq;
1166 if (sm->workaround && duplicate &&
1167 os_memcmp(sm->req_sha1, sm->last_sha1, 20) != 0) {
1168 /*
1169 * RFC 4137 uses (reqId == lastId) as the only verification for
1170 * duplicate EAP requests. However, this misses cases where the
1171 * AS is incorrectly using the same id again; and
1172 * unfortunately, such implementations exist. Use SHA1 hash as
1173 * an extra verification for the packets being duplicate to
1174 * workaround these issues.
1175 */
1176 wpa_printf(MSG_DEBUG, "EAP: AS used the same Id again, but "
1177 "EAP packets were not identical");
1178 wpa_printf(MSG_DEBUG, "EAP: workaround - assume this is not a "
1179 "duplicate packet");
1180 duplicate = 0;
1181 }
1182
1183 return duplicate;
1184 }
1185
1186
1187 static int eap_peer_sm_allow_canned(struct eap_sm *sm)
1188 {
1189 struct eap_peer_config *config = eap_get_config(sm);
1190
1191 return config && config->phase1 &&
1192 os_strstr(config->phase1, "allow_canned_success=1");
1193 }
1194
1195
1196 static void eap_peer_sm_step_received(struct eap_sm *sm)
1197 {
1198 int duplicate = eap_peer_req_is_duplicate(sm);
1199
1200 /*
1201 * Two special cases below for LEAP are local additions to work around
1202 * odd LEAP behavior (EAP-Success in the middle of authentication and
1203 * then swapped roles). Other transitions are based on RFC 4137.
1204 */
1205 if (sm->rxSuccess && sm->decision != DECISION_FAIL &&
1206 (sm->reqId == sm->lastId ||
1207 eap_success_workaround(sm, sm->reqId, sm->lastId)))
1208 SM_ENTER(EAP, SUCCESS);
1209 else if (sm->workaround && sm->lastId == -1 && sm->rxSuccess &&
1210 !sm->rxFailure && !sm->rxReq && eap_peer_sm_allow_canned(sm))
1211 SM_ENTER(EAP, SUCCESS); /* EAP-Success prior any EAP method */
1212 else if (sm->workaround && sm->lastId == -1 && sm->rxFailure &&
1213 !sm->rxReq && sm->methodState != METHOD_CONT &&
1214 eap_peer_sm_allow_canned(sm))
1215 SM_ENTER(EAP, FAILURE); /* EAP-Failure prior any EAP method */
1216 else if (sm->workaround && sm->rxSuccess && !sm->rxFailure &&
1217 !sm->rxReq && sm->methodState != METHOD_CONT &&
1218 eap_peer_sm_allow_canned(sm))
1219 SM_ENTER(EAP, SUCCESS); /* EAP-Success after Identity */
1220 else if (sm->methodState != METHOD_CONT &&
1221 ((sm->rxFailure &&
1222 sm->decision != DECISION_UNCOND_SUCC) ||
1223 (sm->rxSuccess && sm->decision == DECISION_FAIL &&
1224 (sm->selectedMethod != EAP_TYPE_LEAP ||
1225 sm->methodState != METHOD_MAY_CONT))) &&
1226 (sm->reqId == sm->lastId ||
1227 eap_success_workaround(sm, sm->reqId, sm->lastId)))
1228 SM_ENTER(EAP, FAILURE);
1229 else if (sm->rxReq && duplicate)
1230 SM_ENTER(EAP, RETRANSMIT);
1231 else if (sm->rxReq && !duplicate &&
1232 sm->reqMethod == EAP_TYPE_NOTIFICATION &&
1233 sm->allowNotifications)
1234 SM_ENTER(EAP, NOTIFICATION);
1235 else if (sm->rxReq && !duplicate &&
1236 sm->selectedMethod == EAP_TYPE_NONE &&
1237 sm->reqMethod == EAP_TYPE_IDENTITY)
1238 SM_ENTER(EAP, IDENTITY);
1239 else if (sm->rxReq && !duplicate &&
1240 sm->selectedMethod == EAP_TYPE_NONE &&
1241 sm->reqMethod != EAP_TYPE_IDENTITY &&
1242 sm->reqMethod != EAP_TYPE_NOTIFICATION)
1243 SM_ENTER(EAP, GET_METHOD);
1244 else if (sm->rxReq && !duplicate &&
1245 sm->reqMethod == sm->selectedMethod &&
1246 sm->methodState != METHOD_DONE)
1247 SM_ENTER(EAP, METHOD);
1248 else if (sm->selectedMethod == EAP_TYPE_LEAP &&
1249 (sm->rxSuccess || sm->rxResp))
1250 SM_ENTER(EAP, METHOD);
1251 else if (sm->reauthInit)
1252 SM_ENTER(EAP, SEND_RESPONSE);
1253 else
1254 SM_ENTER(EAP, DISCARD);
1255 }
1256
1257
1258 static void eap_peer_sm_step_local(struct eap_sm *sm)
1259 {
1260 switch (sm->EAP_state) {
1261 case EAP_INITIALIZE:
1262 SM_ENTER(EAP, IDLE);
1263 break;
1264 case EAP_DISABLED:
1265 if (eapol_get_bool(sm, EAPOL_portEnabled) &&
1266 !sm->force_disabled)
1267 SM_ENTER(EAP, INITIALIZE);
1268 break;
1269 case EAP_IDLE:
1270 eap_peer_sm_step_idle(sm);
1271 break;
1272 case EAP_RECEIVED:
1273 eap_peer_sm_step_received(sm);
1274 break;
1275 case EAP_GET_METHOD:
1276 if (sm->selectedMethod == sm->reqMethod)
1277 SM_ENTER(EAP, METHOD);
1278 else
1279 SM_ENTER(EAP, SEND_RESPONSE);
1280 break;
1281 case EAP_METHOD:
1282 /*
1283 * Note: RFC 4137 uses methodState == DONE && decision == FAIL
1284 * as the condition. eapRespData == NULL here is used to allow
1285 * final EAP method response to be sent without having to change
1286 * all methods to either use methodState MAY_CONT or leaving
1287 * decision to something else than FAIL in cases where the only
1288 * expected response is EAP-Failure.
1289 */
1290 if (sm->ignore)
1291 SM_ENTER(EAP, DISCARD);
1292 else if (sm->methodState == METHOD_DONE &&
1293 sm->decision == DECISION_FAIL && !sm->eapRespData)
1294 SM_ENTER(EAP, FAILURE);
1295 else
1296 SM_ENTER(EAP, SEND_RESPONSE);
1297 break;
1298 case EAP_SEND_RESPONSE:
1299 SM_ENTER(EAP, IDLE);
1300 break;
1301 case EAP_DISCARD:
1302 SM_ENTER(EAP, IDLE);
1303 break;
1304 case EAP_IDENTITY:
1305 SM_ENTER(EAP, SEND_RESPONSE);
1306 break;
1307 case EAP_NOTIFICATION:
1308 SM_ENTER(EAP, SEND_RESPONSE);
1309 break;
1310 case EAP_RETRANSMIT:
1311 SM_ENTER(EAP, SEND_RESPONSE);
1312 break;
1313 case EAP_SUCCESS:
1314 break;
1315 case EAP_FAILURE:
1316 break;
1317 }
1318 }
1319
1320
1321 SM_STEP(EAP)
1322 {
1323 /* Global transitions */
1324 if (eapol_get_bool(sm, EAPOL_eapRestart) &&
1325 eapol_get_bool(sm, EAPOL_portEnabled))
1326 SM_ENTER_GLOBAL(EAP, INITIALIZE);
1327 else if (!eapol_get_bool(sm, EAPOL_portEnabled) || sm->force_disabled)
1328 SM_ENTER_GLOBAL(EAP, DISABLED);
1329 else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) {
1330 /* RFC 4137 does not place any limit on number of EAP messages
1331 * in an authentication session. However, some error cases have
1332 * ended up in a state were EAP messages were sent between the
1333 * peer and server in a loop (e.g., TLS ACK frame in both
1334 * direction). Since this is quite undesired outcome, limit the
1335 * total number of EAP round-trips and abort authentication if
1336 * this limit is exceeded.
1337 */
1338 if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) {
1339 wpa_msg(sm->msg_ctx, MSG_INFO, "EAP: more than %d "
1340 "authentication rounds - abort",
1341 EAP_MAX_AUTH_ROUNDS);
1342 sm->num_rounds++;
1343 SM_ENTER_GLOBAL(EAP, FAILURE);
1344 }
1345 } else {
1346 /* Local transitions */
1347 eap_peer_sm_step_local(sm);
1348 }
1349 }
1350
1351
1352 static Boolean eap_sm_allowMethod(struct eap_sm *sm, int vendor,
1353 enum eap_type method)
1354 {
1355 if (!eap_allowed_method(sm, vendor, method)) {
1356 wpa_printf(MSG_DEBUG, "EAP: configuration does not allow: "
1357 "vendor %u method %u", vendor, method);
1358 return FALSE;
1359 }
1360 if (eap_peer_get_eap_method(vendor, method))
1361 return TRUE;
1362 wpa_printf(MSG_DEBUG, "EAP: not included in build: "
1363 "vendor %u method %u", vendor, method);
1364 return FALSE;
1365 }
1366
1367
1368 static struct wpabuf * eap_sm_build_expanded_nak(
1369 struct eap_sm *sm, int id, const struct eap_method *methods,
1370 size_t count)
1371 {
1372 struct wpabuf *resp;
1373 int found = 0;
1374 const struct eap_method *m;
1375
1376 wpa_printf(MSG_DEBUG, "EAP: Building expanded EAP-Nak");
1377
1378 /* RFC 3748 - 5.3.2: Expanded Nak */
1379 resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_EXPANDED,
1380 8 + 8 * (count + 1), EAP_CODE_RESPONSE, id);
1381 if (resp == NULL)
1382 return NULL;
1383
1384 wpabuf_put_be24(resp, EAP_VENDOR_IETF);
1385 wpabuf_put_be32(resp, EAP_TYPE_NAK);
1386
1387 for (m = methods; m; m = m->next) {
1388 if (sm->reqVendor == m->vendor &&
1389 sm->reqVendorMethod == m->method)
1390 continue; /* do not allow the current method again */
1391 if (eap_allowed_method(sm, m->vendor, m->method)) {
1392 wpa_printf(MSG_DEBUG, "EAP: allowed type: "
1393 "vendor=%u method=%u",
1394 m->vendor, m->method);
1395 wpabuf_put_u8(resp, EAP_TYPE_EXPANDED);
1396 wpabuf_put_be24(resp, m->vendor);
1397 wpabuf_put_be32(resp, m->method);
1398
1399 found++;
1400 }
1401 }
1402 if (!found) {
1403 wpa_printf(MSG_DEBUG, "EAP: no more allowed methods");
1404 wpabuf_put_u8(resp, EAP_TYPE_EXPANDED);
1405 wpabuf_put_be24(resp, EAP_VENDOR_IETF);
1406 wpabuf_put_be32(resp, EAP_TYPE_NONE);
1407 }
1408
1409 eap_update_len(resp);
1410
1411 return resp;
1412 }
1413
1414
1415 static struct wpabuf * eap_sm_buildNak(struct eap_sm *sm, int id)
1416 {
1417 struct wpabuf *resp;
1418 u8 *start;
1419 int found = 0, expanded_found = 0;
1420 size_t count;
1421 const struct eap_method *methods, *m;
1422
1423 wpa_printf(MSG_DEBUG, "EAP: Building EAP-Nak (requested type %u "
1424 "vendor=%u method=%u not allowed)", sm->reqMethod,
1425 sm->reqVendor, sm->reqVendorMethod);
1426 methods = eap_peer_get_methods(&count);
1427 if (methods == NULL)
1428 return NULL;
1429 if (sm->reqMethod == EAP_TYPE_EXPANDED)
1430 return eap_sm_build_expanded_nak(sm, id, methods, count);
1431
1432 /* RFC 3748 - 5.3.1: Legacy Nak */
1433 resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_NAK,
1434 sizeof(struct eap_hdr) + 1 + count + 1,
1435 EAP_CODE_RESPONSE, id);
1436 if (resp == NULL)
1437 return NULL;
1438
1439 start = wpabuf_put(resp, 0);
1440 for (m = methods; m; m = m->next) {
1441 if (m->vendor == EAP_VENDOR_IETF && m->method == sm->reqMethod)
1442 continue; /* do not allow the current method again */
1443 if (eap_allowed_method(sm, m->vendor, m->method)) {
1444 if (m->vendor != EAP_VENDOR_IETF) {
1445 if (expanded_found)
1446 continue;
1447 expanded_found = 1;
1448 wpabuf_put_u8(resp, EAP_TYPE_EXPANDED);
1449 } else
1450 wpabuf_put_u8(resp, m->method);
1451 found++;
1452 }
1453 }
1454 if (!found)
1455 wpabuf_put_u8(resp, EAP_TYPE_NONE);
1456 wpa_hexdump(MSG_DEBUG, "EAP: allowed methods", start, found);
1457
1458 eap_update_len(resp);
1459
1460 return resp;
1461 }
1462
1463
1464 static void eap_sm_processIdentity(struct eap_sm *sm, const struct wpabuf *req)
1465 {
1466 const u8 *pos;
1467 size_t msg_len;
1468
1469 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_STARTED
1470 "EAP authentication started");
1471 eap_notify_status(sm, "started", "");
1472
1473 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, req,
1474 &msg_len);
1475 if (pos == NULL)
1476 return;
1477
1478 /*
1479 * RFC 3748 - 5.1: Identity
1480 * Data field may contain a displayable message in UTF-8. If this
1481 * includes NUL-character, only the data before that should be
1482 * displayed. Some EAP implementasitons may piggy-back additional
1483 * options after the NUL.
1484 */
1485 /* TODO: could save displayable message so that it can be shown to the
1486 * user in case of interaction is required */
1487 wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Identity data",
1488 pos, msg_len);
1489 }
1490
1491
1492 #ifdef PCSC_FUNCS
1493
1494 /*
1495 * Rules for figuring out MNC length based on IMSI for SIM cards that do not
1496 * include MNC length field.
1497 */
1498 static int mnc_len_from_imsi(const char *imsi)
1499 {
1500 char mcc_str[4];
1501 unsigned int mcc;
1502
1503 os_memcpy(mcc_str, imsi, 3);
1504 mcc_str[3] = '\0';
1505 mcc = atoi(mcc_str);
1506
1507 if (mcc == 228)
1508 return 2; /* Networks in Switzerland use 2-digit MNC */
1509 if (mcc == 244)
1510 return 2; /* Networks in Finland use 2-digit MNC */
1511
1512 return -1;
1513 }
1514
1515
1516 static int eap_sm_imsi_identity(struct eap_sm *sm,
1517 struct eap_peer_config *conf)
1518 {
1519 enum { EAP_SM_SIM, EAP_SM_AKA, EAP_SM_AKA_PRIME } method = EAP_SM_SIM;
1520 char imsi[100];
1521 size_t imsi_len;
1522 struct eap_method_type *m = conf->eap_methods;
1523 int i, mnc_len;
1524
1525 imsi_len = sizeof(imsi);
1526 if (scard_get_imsi(sm->scard_ctx, imsi, &imsi_len)) {
1527 wpa_printf(MSG_WARNING, "Failed to get IMSI from SIM");
1528 return -1;
1529 }
1530
1531 wpa_hexdump_ascii(MSG_DEBUG, "IMSI", (u8 *) imsi, imsi_len);
1532
1533 if (imsi_len < 7) {
1534 wpa_printf(MSG_WARNING, "Too short IMSI for SIM identity");
1535 return -1;
1536 }
1537
1538 /* MNC (2 or 3 digits) */
1539 mnc_len = scard_get_mnc_len(sm->scard_ctx);
1540 if (mnc_len < 0)
1541 mnc_len = mnc_len_from_imsi(imsi);
1542 if (mnc_len < 0) {
1543 wpa_printf(MSG_INFO, "Failed to get MNC length from (U)SIM "
1544 "assuming 3");
1545 mnc_len = 3;
1546 }
1547
1548 if (eap_sm_append_3gpp_realm(sm, imsi, sizeof(imsi), &imsi_len,
1549 mnc_len) < 0) {
1550 wpa_printf(MSG_WARNING, "Could not add realm to SIM identity");
1551 return -1;
1552 }
1553 wpa_hexdump_ascii(MSG_DEBUG, "IMSI + realm", (u8 *) imsi, imsi_len);
1554
1555 for (i = 0; m && (m[i].vendor != EAP_VENDOR_IETF ||
1556 m[i].method != EAP_TYPE_NONE); i++) {
1557 if (m[i].vendor == EAP_VENDOR_IETF &&
1558 m[i].method == EAP_TYPE_AKA_PRIME) {
1559 method = EAP_SM_AKA_PRIME;
1560 break;
1561 }
1562
1563 if (m[i].vendor == EAP_VENDOR_IETF &&
1564 m[i].method == EAP_TYPE_AKA) {
1565 method = EAP_SM_AKA;
1566 break;
1567 }
1568 }
1569
1570 os_free(conf->identity);
1571 conf->identity = os_malloc(1 + imsi_len);
1572 if (conf->identity == NULL) {
1573 wpa_printf(MSG_WARNING, "Failed to allocate buffer for "
1574 "IMSI-based identity");
1575 return -1;
1576 }
1577
1578 switch (method) {
1579 case EAP_SM_SIM:
1580 conf->identity[0] = '1';
1581 break;
1582 case EAP_SM_AKA:
1583 conf->identity[0] = '0';
1584 break;
1585 case EAP_SM_AKA_PRIME:
1586 conf->identity[0] = '6';
1587 break;
1588 }
1589 os_memcpy(conf->identity + 1, imsi, imsi_len);
1590 conf->identity_len = 1 + imsi_len;
1591
1592 return 0;
1593 }
1594
1595
1596 static int eap_sm_set_scard_pin(struct eap_sm *sm,
1597 struct eap_peer_config *conf)
1598 {
1599 if (scard_set_pin(sm->scard_ctx, conf->pin)) {
1600 /*
1601 * Make sure the same PIN is not tried again in order to avoid
1602 * blocking SIM.
1603 */
1604 os_free(conf->pin);
1605 conf->pin = NULL;
1606
1607 wpa_printf(MSG_WARNING, "PIN validation failed");
1608 eap_sm_request_pin(sm);
1609 return -1;
1610 }
1611 return 0;
1612 }
1613
1614
1615 static int eap_sm_get_scard_identity(struct eap_sm *sm,
1616 struct eap_peer_config *conf)
1617 {
1618 if (eap_sm_set_scard_pin(sm, conf))
1619 return -1;
1620
1621 return eap_sm_imsi_identity(sm, conf);
1622 }
1623
1624 #endif /* PCSC_FUNCS */
1625
1626
1627 /**
1628 * eap_sm_buildIdentity - Build EAP-Identity/Response for the current network
1629 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
1630 * @id: EAP identifier for the packet
1631 * @encrypted: Whether the packet is for encrypted tunnel (EAP phase 2)
1632 * Returns: Pointer to the allocated EAP-Identity/Response packet or %NULL on
1633 * failure
1634 *
1635 * This function allocates and builds an EAP-Identity/Response packet for the
1636 * current network. The caller is responsible for freeing the returned data.
1637 */
1638 struct wpabuf * eap_sm_buildIdentity(struct eap_sm *sm, int id, int encrypted)
1639 {
1640 struct eap_peer_config *config = eap_get_config(sm);
1641 struct wpabuf *resp;
1642 const u8 *identity;
1643 size_t identity_len;
1644
1645 if (config == NULL) {
1646 wpa_printf(MSG_WARNING, "EAP: buildIdentity: configuration "
1647 "was not available");
1648 return NULL;
1649 }
1650
1651 if (sm->m && sm->m->get_identity &&
1652 (identity = sm->m->get_identity(sm, sm->eap_method_priv,
1653 &identity_len)) != NULL) {
1654 wpa_hexdump_ascii(MSG_DEBUG, "EAP: using method re-auth "
1655 "identity", identity, identity_len);
1656 } else if (!encrypted && config->anonymous_identity) {
1657 identity = config->anonymous_identity;
1658 identity_len = config->anonymous_identity_len;
1659 wpa_hexdump_ascii(MSG_DEBUG, "EAP: using anonymous identity",
1660 identity, identity_len);
1661 } else {
1662 identity = config->identity;
1663 identity_len = config->identity_len;
1664 wpa_hexdump_ascii(MSG_DEBUG, "EAP: using real identity",
1665 identity, identity_len);
1666 }
1667
1668 if (config->pcsc) {
1669 #ifdef PCSC_FUNCS
1670 if (!identity) {
1671 if (eap_sm_get_scard_identity(sm, config) < 0)
1672 return NULL;
1673 identity = config->identity;
1674 identity_len = config->identity_len;
1675 wpa_hexdump_ascii(MSG_DEBUG,
1676 "permanent identity from IMSI",
1677 identity, identity_len);
1678 } else if (eap_sm_set_scard_pin(sm, config) < 0) {
1679 return NULL;
1680 }
1681 #else /* PCSC_FUNCS */
1682 return NULL;
1683 #endif /* PCSC_FUNCS */
1684 } else if (!identity) {
1685 wpa_printf(MSG_WARNING,
1686 "EAP: buildIdentity: identity configuration was not available");
1687 eap_sm_request_identity(sm);
1688 return NULL;
1689 }
1690
1691 resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, identity_len,
1692 EAP_CODE_RESPONSE, id);
1693 if (resp == NULL)
1694 return NULL;
1695
1696 wpabuf_put_data(resp, identity, identity_len);
1697
1698 return resp;
1699 }
1700
1701
1702 static void eap_sm_processNotify(struct eap_sm *sm, const struct wpabuf *req)
1703 {
1704 const u8 *pos;
1705 char *msg;
1706 size_t i, msg_len;
1707
1708 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_NOTIFICATION, req,
1709 &msg_len);
1710 if (pos == NULL)
1711 return;
1712 wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Notification data",
1713 pos, msg_len);
1714
1715 msg = os_malloc(msg_len + 1);
1716 if (msg == NULL)
1717 return;
1718 for (i = 0; i < msg_len; i++)
1719 msg[i] = isprint(pos[i]) ? (char) pos[i] : '_';
1720 msg[msg_len] = '\0';
1721 wpa_msg(sm->msg_ctx, MSG_INFO, "%s%s",
1722 WPA_EVENT_EAP_NOTIFICATION, msg);
1723 os_free(msg);
1724 }
1725
1726
1727 static struct wpabuf * eap_sm_buildNotify(int id)
1728 {
1729 wpa_printf(MSG_DEBUG, "EAP: Generating EAP-Response Notification");
1730 return eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_NOTIFICATION, 0,
1731 EAP_CODE_RESPONSE, id);
1732 }
1733
1734
1735 static void eap_peer_initiate(struct eap_sm *sm, const struct eap_hdr *hdr,
1736 size_t len)
1737 {
1738 #ifdef CONFIG_ERP
1739 const u8 *pos = (const u8 *) (hdr + 1);
1740 const u8 *end = ((const u8 *) hdr) + len;
1741 struct erp_tlvs parse;
1742
1743 if (len < sizeof(*hdr) + 1) {
1744 wpa_printf(MSG_DEBUG, "EAP: Ignored too short EAP-Initiate");
1745 return;
1746 }
1747
1748 if (*pos != EAP_ERP_TYPE_REAUTH_START) {
1749 wpa_printf(MSG_DEBUG,
1750 "EAP: Ignored unexpected EAP-Initiate Type=%u",
1751 *pos);
1752 return;
1753 }
1754
1755 pos++;
1756 if (pos >= end) {
1757 wpa_printf(MSG_DEBUG,
1758 "EAP: Too short EAP-Initiate/Re-auth-Start");
1759 return;
1760 }
1761 pos++; /* Reserved */
1762 wpa_hexdump(MSG_DEBUG, "EAP: EAP-Initiate/Re-auth-Start TVs/TLVs",
1763 pos, end - pos);
1764
1765 if (erp_parse_tlvs(pos, end, &parse, 0) < 0)
1766 goto invalid;
1767
1768 if (parse.domain) {
1769 wpa_hexdump_ascii(MSG_DEBUG,
1770 "EAP: EAP-Initiate/Re-auth-Start - Domain name",
1771 parse.domain, parse.domain_len);
1772 /* TODO: Derivation of domain specific keys for local ER */
1773 }
1774
1775 if (eap_peer_erp_reauth_start(sm, hdr->identifier) == 0)
1776 return;
1777
1778 invalid:
1779 #endif /* CONFIG_ERP */
1780 wpa_printf(MSG_DEBUG,
1781 "EAP: EAP-Initiate/Re-auth-Start - No suitable ERP keys available - try to start full EAP authentication");
1782 eapol_set_bool(sm, EAPOL_eapTriggerStart, TRUE);
1783 }
1784
1785
1786 void eap_peer_finish(struct eap_sm *sm, const struct eap_hdr *hdr, size_t len)
1787 {
1788 #ifdef CONFIG_ERP
1789 const u8 *pos = (const u8 *) (hdr + 1);
1790 const u8 *end = ((const u8 *) hdr) + len;
1791 const u8 *start;
1792 struct erp_tlvs parse;
1793 u8 flags;
1794 u16 seq;
1795 u8 hash[SHA256_MAC_LEN];
1796 size_t hash_len;
1797 struct eap_erp_key *erp;
1798 int max_len;
1799 char nai[254];
1800 u8 seed[4];
1801 int auth_tag_ok = 0;
1802
1803 if (len < sizeof(*hdr) + 1) {
1804 wpa_printf(MSG_DEBUG, "EAP: Ignored too short EAP-Finish");
1805 return;
1806 }
1807
1808 if (*pos != EAP_ERP_TYPE_REAUTH) {
1809 wpa_printf(MSG_DEBUG,
1810 "EAP: Ignored unexpected EAP-Finish Type=%u", *pos);
1811 return;
1812 }
1813
1814 if (len < sizeof(*hdr) + 4) {
1815 wpa_printf(MSG_DEBUG,
1816 "EAP: Ignored too short EAP-Finish/Re-auth");
1817 return;
1818 }
1819
1820 pos++;
1821 flags = *pos++;
1822 seq = WPA_GET_BE16(pos);
1823 pos += 2;
1824 wpa_printf(MSG_DEBUG, "EAP: Flags=0x%x SEQ=%u", flags, seq);
1825
1826 if (seq != sm->erp_seq) {
1827 wpa_printf(MSG_DEBUG,
1828 "EAP: Unexpected EAP-Finish/Re-auth SEQ=%u", seq);
1829 return;
1830 }
1831
1832 /*
1833 * Parse TVs/TLVs. Since we do not yet know the length of the
1834 * Authentication Tag, stop parsing if an unknown TV/TLV is seen and
1835 * just try to find the keyName-NAI first so that we can check the
1836 * Authentication Tag.
1837 */
1838 if (erp_parse_tlvs(pos, end, &parse, 1) < 0)
1839 return;
1840
1841 if (!parse.keyname) {
1842 wpa_printf(MSG_DEBUG,
1843 "EAP: No keyName-NAI in EAP-Finish/Re-auth Packet");
1844 return;
1845 }
1846
1847 wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Finish/Re-auth - keyName-NAI",
1848 parse.keyname, parse.keyname_len);
1849 if (parse.keyname_len > 253) {
1850 wpa_printf(MSG_DEBUG,
1851 "EAP: Too long keyName-NAI in EAP-Finish/Re-auth");
1852 return;
1853 }
1854 os_memcpy(nai, parse.keyname, parse.keyname_len);
1855 nai[parse.keyname_len] = '\0';
1856
1857 erp = eap_erp_get_key_nai(sm, nai);
1858 if (!erp) {
1859 wpa_printf(MSG_DEBUG, "EAP: No matching ERP key found for %s",
1860 nai);
1861 return;
1862 }
1863
1864 /* Is there enough room for Cryptosuite and Authentication Tag? */
1865 start = parse.keyname + parse.keyname_len;
1866 max_len = end - start;
1867 hash_len = 16;
1868 if (max_len < 1 + (int) hash_len) {
1869 wpa_printf(MSG_DEBUG,
1870 "EAP: Not enough room for Authentication Tag");
1871 if (flags & 0x80)
1872 goto no_auth_tag;
1873 return;
1874 }
1875 if (end[-17] != EAP_ERP_CS_HMAC_SHA256_128) {
1876 wpa_printf(MSG_DEBUG, "EAP: Different Cryptosuite used");
1877 if (flags & 0x80)
1878 goto no_auth_tag;
1879 return;
1880 }
1881
1882 if (hmac_sha256(erp->rIK, erp->rIK_len, (const u8 *) hdr,
1883 end - ((const u8 *) hdr) - hash_len, hash) < 0)
1884 return;
1885 if (os_memcmp(end - hash_len, hash, hash_len) != 0) {
1886 wpa_printf(MSG_DEBUG,
1887 "EAP: Authentication Tag mismatch");
1888 return;
1889 }
1890 auth_tag_ok = 1;
1891 end -= 1 + hash_len;
1892
1893 no_auth_tag:
1894 /*
1895 * Parse TVs/TLVs again now that we know the exact part of the buffer
1896 * that contains them.
1897 */
1898 wpa_hexdump(MSG_DEBUG, "EAP: EAP-Finish/Re-Auth TVs/TLVs",
1899 pos, end - pos);
1900 if (erp_parse_tlvs(pos, end, &parse, 0) < 0)
1901 return;
1902
1903 if (flags & 0x80 || !auth_tag_ok) {
1904 wpa_printf(MSG_DEBUG,
1905 "EAP: EAP-Finish/Re-auth indicated failure");
1906 eapol_set_bool(sm, EAPOL_eapFail, TRUE);
1907 eapol_set_bool(sm, EAPOL_eapReq, FALSE);
1908 eapol_set_bool(sm, EAPOL_eapNoResp, TRUE);
1909 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_FAILURE
1910 "EAP authentication failed");
1911 sm->prev_failure = 1;
1912 wpa_printf(MSG_DEBUG,
1913 "EAP: Drop ERP key to try full authentication on next attempt");
1914 eap_peer_erp_free_key(erp);
1915 return;
1916 }
1917
1918 eap_sm_free_key(sm);
1919 sm->eapKeyDataLen = 0;
1920 sm->eapKeyData = os_malloc(erp->rRK_len);
1921 if (!sm->eapKeyData)
1922 return;
1923 sm->eapKeyDataLen = erp->rRK_len;
1924
1925 WPA_PUT_BE16(seed, seq);
1926 WPA_PUT_BE16(&seed[2], erp->rRK_len);
1927 if (hmac_sha256_kdf(erp->rRK, erp->rRK_len,
1928 "Re-authentication Master Session Key@ietf.org",
1929 seed, sizeof(seed),
1930 sm->eapKeyData, erp->rRK_len) < 0) {
1931 wpa_printf(MSG_DEBUG, "EAP: Could not derive rMSK for ERP");
1932 eap_sm_free_key(sm);
1933 return;
1934 }
1935 wpa_hexdump_key(MSG_DEBUG, "EAP: ERP rMSK",
1936 sm->eapKeyData, sm->eapKeyDataLen);
1937 sm->eapKeyAvailable = TRUE;
1938 eapol_set_bool(sm, EAPOL_eapSuccess, TRUE);
1939 eapol_set_bool(sm, EAPOL_eapReq, FALSE);
1940 eapol_set_bool(sm, EAPOL_eapNoResp, TRUE);
1941 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS
1942 "EAP re-authentication completed successfully");
1943 #endif /* CONFIG_ERP */
1944 }
1945
1946
1947 static void eap_sm_parseEapReq(struct eap_sm *sm, const struct wpabuf *req)
1948 {
1949 const struct eap_hdr *hdr;
1950 size_t plen;
1951 const u8 *pos;
1952
1953 sm->rxReq = sm->rxResp = sm->rxSuccess = sm->rxFailure = FALSE;
1954 sm->reqId = 0;
1955 sm->reqMethod = EAP_TYPE_NONE;
1956 sm->reqVendor = EAP_VENDOR_IETF;
1957 sm->reqVendorMethod = EAP_TYPE_NONE;
1958
1959 if (req == NULL || wpabuf_len(req) < sizeof(*hdr))
1960 return;
1961
1962 hdr = wpabuf_head(req);
1963 plen = be_to_host16(hdr->length);
1964 if (plen > wpabuf_len(req)) {
1965 wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet "
1966 "(len=%lu plen=%lu)",
1967 (unsigned long) wpabuf_len(req),
1968 (unsigned long) plen);
1969 return;
1970 }
1971
1972 sm->reqId = hdr->identifier;
1973
1974 if (sm->workaround) {
1975 const u8 *addr[1];
1976 addr[0] = wpabuf_head(req);
1977 sha1_vector(1, addr, &plen, sm->req_sha1);
1978 }
1979
1980 switch (hdr->code) {
1981 case EAP_CODE_REQUEST:
1982 if (plen < sizeof(*hdr) + 1) {
1983 wpa_printf(MSG_DEBUG, "EAP: Too short EAP-Request - "
1984 "no Type field");
1985 return;
1986 }
1987 sm->rxReq = TRUE;
1988 pos = (const u8 *) (hdr + 1);
1989 sm->reqMethod = *pos++;
1990 if (sm->reqMethod == EAP_TYPE_EXPANDED) {
1991 if (plen < sizeof(*hdr) + 8) {
1992 wpa_printf(MSG_DEBUG, "EAP: Ignored truncated "
1993 "expanded EAP-Packet (plen=%lu)",
1994 (unsigned long) plen);
1995 return;
1996 }
1997 sm->reqVendor = WPA_GET_BE24(pos);
1998 pos += 3;
1999 sm->reqVendorMethod = WPA_GET_BE32(pos);
2000 }
2001 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Request id=%d "
2002 "method=%u vendor=%u vendorMethod=%u",
2003 sm->reqId, sm->reqMethod, sm->reqVendor,
2004 sm->reqVendorMethod);
2005 break;
2006 case EAP_CODE_RESPONSE:
2007 if (sm->selectedMethod == EAP_TYPE_LEAP) {
2008 /*
2009 * LEAP differs from RFC 4137 by using reversed roles
2010 * for mutual authentication and because of this, we
2011 * need to accept EAP-Response frames if LEAP is used.
2012 */
2013 if (plen < sizeof(*hdr) + 1) {
2014 wpa_printf(MSG_DEBUG, "EAP: Too short "
2015 "EAP-Response - no Type field");
2016 return;
2017 }
2018 sm->rxResp = TRUE;
2019 pos = (const u8 *) (hdr + 1);
2020 sm->reqMethod = *pos;
2021 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Response for "
2022 "LEAP method=%d id=%d",
2023 sm->reqMethod, sm->reqId);
2024 break;
2025 }
2026 wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Response");
2027 break;
2028 case EAP_CODE_SUCCESS:
2029 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Success");
2030 eap_notify_status(sm, "completion", "success");
2031 sm->rxSuccess = TRUE;
2032 break;
2033 case EAP_CODE_FAILURE:
2034 wpa_printf(MSG_DEBUG, "EAP: Received EAP-Failure");
2035 eap_notify_status(sm, "completion", "failure");
2036
2037 /* Get the error code from method */
2038 if (sm->m && sm->m->get_error_code) {
2039 int error_code;
2040
2041 error_code = sm->m->get_error_code(sm->eap_method_priv);
2042 if (error_code != NO_EAP_METHOD_ERROR)
2043 eap_report_error(sm, error_code);
2044 }
2045 sm->rxFailure = TRUE;
2046 break;
2047 case EAP_CODE_INITIATE:
2048 eap_peer_initiate(sm, hdr, plen);
2049 break;
2050 case EAP_CODE_FINISH:
2051 eap_peer_finish(sm, hdr, plen);
2052 break;
2053 default:
2054 wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Packet with unknown "
2055 "code %d", hdr->code);
2056 break;
2057 }
2058 }
2059
2060
2061 static void eap_peer_sm_tls_event(void *ctx, enum tls_event ev,
2062 union tls_event_data *data)
2063 {
2064 struct eap_sm *sm = ctx;
2065 char *hash_hex = NULL;
2066
2067 switch (ev) {
2068 case TLS_CERT_CHAIN_SUCCESS:
2069 eap_notify_status(sm, "remote certificate verification",
2070 "success");
2071 if (sm->ext_cert_check) {
2072 sm->waiting_ext_cert_check = 1;
2073 eap_sm_request(sm, WPA_CTRL_REQ_EXT_CERT_CHECK,
2074 NULL, 0);
2075 }
2076 break;
2077 case TLS_CERT_CHAIN_FAILURE:
2078 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_TLS_CERT_ERROR
2079 "reason=%d depth=%d subject='%s' err='%s'",
2080 data->cert_fail.reason,
2081 data->cert_fail.depth,
2082 data->cert_fail.subject,
2083 data->cert_fail.reason_txt);
2084 eap_notify_status(sm, "remote certificate verification",
2085 data->cert_fail.reason_txt);
2086 break;
2087 case TLS_PEER_CERTIFICATE:
2088 if (!sm->eapol_cb->notify_cert)
2089 break;
2090
2091 if (data->peer_cert.hash) {
2092 size_t len = data->peer_cert.hash_len * 2 + 1;
2093 hash_hex = os_malloc(len);
2094 if (hash_hex) {
2095 wpa_snprintf_hex(hash_hex, len,
2096 data->peer_cert.hash,
2097 data->peer_cert.hash_len);
2098 }
2099 }
2100
2101 sm->eapol_cb->notify_cert(sm->eapol_ctx, &data->peer_cert,
2102 hash_hex);
2103 break;
2104 case TLS_ALERT:
2105 if (data->alert.is_local)
2106 eap_notify_status(sm, "local TLS alert",
2107 data->alert.description);
2108 else
2109 eap_notify_status(sm, "remote TLS alert",
2110 data->alert.description);
2111 break;
2112 }
2113
2114 os_free(hash_hex);
2115 }
2116
2117
2118 /**
2119 * eap_peer_sm_init - Allocate and initialize EAP peer state machine
2120 * @eapol_ctx: Context data to be used with eapol_cb calls
2121 * @eapol_cb: Pointer to EAPOL callback functions
2122 * @msg_ctx: Context data for wpa_msg() calls
2123 * @conf: EAP configuration
2124 * Returns: Pointer to the allocated EAP state machine or %NULL on failure
2125 *
2126 * This function allocates and initializes an EAP state machine. In addition,
2127 * this initializes TLS library for the new EAP state machine. eapol_cb pointer
2128 * will be in use until eap_peer_sm_deinit() is used to deinitialize this EAP
2129 * state machine. Consequently, the caller must make sure that this data
2130 * structure remains alive while the EAP state machine is active.
2131 */
2132 struct eap_sm * eap_peer_sm_init(void *eapol_ctx,
2133 const struct eapol_callbacks *eapol_cb,
2134 void *msg_ctx, struct eap_config *conf)
2135 {
2136 struct eap_sm *sm;
2137 struct tls_config tlsconf;
2138
2139 sm = os_zalloc(sizeof(*sm));
2140 if (sm == NULL)
2141 return NULL;
2142 sm->eapol_ctx = eapol_ctx;
2143 sm->eapol_cb = eapol_cb;
2144 sm->msg_ctx = msg_ctx;
2145 sm->ClientTimeout = EAP_CLIENT_TIMEOUT_DEFAULT;
2146 sm->wps = conf->wps;
2147 dl_list_init(&sm->erp_keys);
2148
2149 os_memset(&tlsconf, 0, sizeof(tlsconf));
2150 tlsconf.opensc_engine_path = conf->opensc_engine_path;
2151 tlsconf.pkcs11_engine_path = conf->pkcs11_engine_path;
2152 tlsconf.pkcs11_module_path = conf->pkcs11_module_path;
2153 tlsconf.openssl_ciphers = conf->openssl_ciphers;
2154 #ifdef CONFIG_FIPS
2155 tlsconf.fips_mode = 1;
2156 #endif /* CONFIG_FIPS */
2157 tlsconf.event_cb = eap_peer_sm_tls_event;
2158 tlsconf.cb_ctx = sm;
2159 tlsconf.cert_in_cb = conf->cert_in_cb;
2160 sm->ssl_ctx = tls_init(&tlsconf);
2161 if (sm->ssl_ctx == NULL) {
2162 wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS "
2163 "context.");
2164 os_free(sm);
2165 return NULL;
2166 }
2167
2168 sm->ssl_ctx2 = tls_init(&tlsconf);
2169 if (sm->ssl_ctx2 == NULL) {
2170 wpa_printf(MSG_INFO, "SSL: Failed to initialize TLS "
2171 "context (2).");
2172 /* Run without separate TLS context within TLS tunnel */
2173 }
2174
2175 return sm;
2176 }
2177
2178
2179 /**
2180 * eap_peer_sm_deinit - Deinitialize and free an EAP peer state machine
2181 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2182 *
2183 * This function deinitializes EAP state machine and frees all allocated
2184 * resources.
2185 */
2186 void eap_peer_sm_deinit(struct eap_sm *sm)
2187 {
2188 if (sm == NULL)
2189 return;
2190 eap_deinit_prev_method(sm, "EAP deinit");
2191 eap_sm_abort(sm);
2192 if (sm->ssl_ctx2)
2193 tls_deinit(sm->ssl_ctx2);
2194 tls_deinit(sm->ssl_ctx);
2195 eap_peer_erp_free_keys(sm);
2196 os_free(sm);
2197 }
2198
2199
2200 /**
2201 * eap_peer_sm_step - Step EAP peer state machine
2202 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2203 * Returns: 1 if EAP state was changed or 0 if not
2204 *
2205 * This function advances EAP state machine to a new state to match with the
2206 * current variables. This should be called whenever variables used by the EAP
2207 * state machine have changed.
2208 */
2209 int eap_peer_sm_step(struct eap_sm *sm)
2210 {
2211 int res = 0;
2212 do {
2213 sm->changed = FALSE;
2214 SM_STEP_RUN(EAP);
2215 if (sm->changed)
2216 res = 1;
2217 } while (sm->changed);
2218 return res;
2219 }
2220
2221
2222 /**
2223 * eap_sm_abort - Abort EAP authentication
2224 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2225 *
2226 * Release system resources that have been allocated for the authentication
2227 * session without fully deinitializing the EAP state machine.
2228 */
2229 void eap_sm_abort(struct eap_sm *sm)
2230 {
2231 wpabuf_free(sm->lastRespData);
2232 sm->lastRespData = NULL;
2233 wpabuf_free(sm->eapRespData);
2234 sm->eapRespData = NULL;
2235 eap_sm_free_key(sm);
2236 os_free(sm->eapSessionId);
2237 sm->eapSessionId = NULL;
2238
2239 /* This is not clearly specified in the EAP statemachines draft, but
2240 * it seems necessary to make sure that some of the EAPOL variables get
2241 * cleared for the next authentication. */
2242 eapol_set_bool(sm, EAPOL_eapSuccess, FALSE);
2243 }
2244
2245
2246 #ifdef CONFIG_CTRL_IFACE
2247 static const char * eap_sm_state_txt(int state)
2248 {
2249 switch (state) {
2250 case EAP_INITIALIZE:
2251 return "INITIALIZE";
2252 case EAP_DISABLED:
2253 return "DISABLED";
2254 case EAP_IDLE:
2255 return "IDLE";
2256 case EAP_RECEIVED:
2257 return "RECEIVED";
2258 case EAP_GET_METHOD:
2259 return "GET_METHOD";
2260 case EAP_METHOD:
2261 return "METHOD";
2262 case EAP_SEND_RESPONSE:
2263 return "SEND_RESPONSE";
2264 case EAP_DISCARD:
2265 return "DISCARD";
2266 case EAP_IDENTITY:
2267 return "IDENTITY";
2268 case EAP_NOTIFICATION:
2269 return "NOTIFICATION";
2270 case EAP_RETRANSMIT:
2271 return "RETRANSMIT";
2272 case EAP_SUCCESS:
2273 return "SUCCESS";
2274 case EAP_FAILURE:
2275 return "FAILURE";
2276 default:
2277 return "UNKNOWN";
2278 }
2279 }
2280 #endif /* CONFIG_CTRL_IFACE */
2281
2282
2283 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
2284 static const char * eap_sm_method_state_txt(EapMethodState state)
2285 {
2286 switch (state) {
2287 case METHOD_NONE:
2288 return "NONE";
2289 case METHOD_INIT:
2290 return "INIT";
2291 case METHOD_CONT:
2292 return "CONT";
2293 case METHOD_MAY_CONT:
2294 return "MAY_CONT";
2295 case METHOD_DONE:
2296 return "DONE";
2297 default:
2298 return "UNKNOWN";
2299 }
2300 }
2301
2302
2303 static const char * eap_sm_decision_txt(EapDecision decision)
2304 {
2305 switch (decision) {
2306 case DECISION_FAIL:
2307 return "FAIL";
2308 case DECISION_COND_SUCC:
2309 return "COND_SUCC";
2310 case DECISION_UNCOND_SUCC:
2311 return "UNCOND_SUCC";
2312 default:
2313 return "UNKNOWN";
2314 }
2315 }
2316 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
2317
2318
2319 #ifdef CONFIG_CTRL_IFACE
2320
2321 /**
2322 * eap_sm_get_status - Get EAP state machine status
2323 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2324 * @buf: Buffer for status information
2325 * @buflen: Maximum buffer length
2326 * @verbose: Whether to include verbose status information
2327 * Returns: Number of bytes written to buf.
2328 *
2329 * Query EAP state machine for status information. This function fills in a
2330 * text area with current status information from the EAPOL state machine. If
2331 * the buffer (buf) is not large enough, status information will be truncated
2332 * to fit the buffer.
2333 */
2334 int eap_sm_get_status(struct eap_sm *sm, char *buf, size_t buflen, int verbose)
2335 {
2336 int len, ret;
2337
2338 if (sm == NULL)
2339 return 0;
2340
2341 len = os_snprintf(buf, buflen,
2342 "EAP state=%s\n",
2343 eap_sm_state_txt(sm->EAP_state));
2344 if (os_snprintf_error(buflen, len))
2345 return 0;
2346
2347 if (sm->selectedMethod != EAP_TYPE_NONE) {
2348 const char *name;
2349 if (sm->m) {
2350 name = sm->m->name;
2351 } else {
2352 const struct eap_method *m =
2353 eap_peer_get_eap_method(EAP_VENDOR_IETF,
2354 sm->selectedMethod);
2355 if (m)
2356 name = m->name;
2357 else
2358 name = "?";
2359 }
2360 ret = os_snprintf(buf + len, buflen - len,
2361 "selectedMethod=%d (EAP-%s)\n",
2362 sm->selectedMethod, name);
2363 if (os_snprintf_error(buflen - len, ret))
2364 return len;
2365 len += ret;
2366
2367 if (sm->m && sm->m->get_status) {
2368 len += sm->m->get_status(sm, sm->eap_method_priv,
2369 buf + len, buflen - len,
2370 verbose);
2371 }
2372 }
2373
2374 if (verbose) {
2375 ret = os_snprintf(buf + len, buflen - len,
2376 "reqMethod=%d\n"
2377 "methodState=%s\n"
2378 "decision=%s\n"
2379 "ClientTimeout=%d\n",
2380 sm->reqMethod,
2381 eap_sm_method_state_txt(sm->methodState),
2382 eap_sm_decision_txt(sm->decision),
2383 sm->ClientTimeout);
2384 if (os_snprintf_error(buflen - len, ret))
2385 return len;
2386 len += ret;
2387 }
2388
2389 return len;
2390 }
2391 #endif /* CONFIG_CTRL_IFACE */
2392
2393
2394 static void eap_sm_request(struct eap_sm *sm, enum wpa_ctrl_req_type field,
2395 const char *msg, size_t msglen)
2396 {
2397 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
2398 struct eap_peer_config *config;
2399 const char *txt = NULL;
2400 char *tmp;
2401
2402 if (sm == NULL)
2403 return;
2404 config = eap_get_config(sm);
2405 if (config == NULL)
2406 return;
2407
2408 switch (field) {
2409 case WPA_CTRL_REQ_EAP_IDENTITY:
2410 config->pending_req_identity++;
2411 break;
2412 case WPA_CTRL_REQ_EAP_PASSWORD:
2413 config->pending_req_password++;
2414 break;
2415 case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
2416 config->pending_req_new_password++;
2417 break;
2418 case WPA_CTRL_REQ_EAP_PIN:
2419 config->pending_req_pin++;
2420 break;
2421 case WPA_CTRL_REQ_EAP_OTP:
2422 if (msg) {
2423 tmp = os_malloc(msglen + 3);
2424 if (tmp == NULL)
2425 return;
2426 tmp[0] = '[';
2427 os_memcpy(tmp + 1, msg, msglen);
2428 tmp[msglen + 1] = ']';
2429 tmp[msglen + 2] = '\0';
2430 txt = tmp;
2431 os_free(config->pending_req_otp);
2432 config->pending_req_otp = tmp;
2433 config->pending_req_otp_len = msglen + 3;
2434 } else {
2435 if (config->pending_req_otp == NULL)
2436 return;
2437 txt = config->pending_req_otp;
2438 }
2439 break;
2440 case WPA_CTRL_REQ_EAP_PASSPHRASE:
2441 config->pending_req_passphrase++;
2442 break;
2443 case WPA_CTRL_REQ_SIM:
2444 config->pending_req_sim++;
2445 txt = msg;
2446 break;
2447 case WPA_CTRL_REQ_EXT_CERT_CHECK:
2448 break;
2449 default:
2450 return;
2451 }
2452
2453 if (sm->eapol_cb->eap_param_needed)
2454 sm->eapol_cb->eap_param_needed(sm->eapol_ctx, field, txt);
2455 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
2456 }
2457
2458
2459 const char * eap_sm_get_method_name(struct eap_sm *sm)
2460 {
2461 if (sm->m == NULL)
2462 return "UNKNOWN";
2463 return sm->m->name;
2464 }
2465
2466
2467 /**
2468 * eap_sm_request_identity - Request identity from user (ctrl_iface)
2469 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2470 *
2471 * EAP methods can call this function to request identity information for the
2472 * current network. This is normally called when the identity is not included
2473 * in the network configuration. The request will be sent to monitor programs
2474 * through the control interface.
2475 */
2476 void eap_sm_request_identity(struct eap_sm *sm)
2477 {
2478 eap_sm_request(sm, WPA_CTRL_REQ_EAP_IDENTITY, NULL, 0);
2479 }
2480
2481
2482 /**
2483 * eap_sm_request_password - Request password from user (ctrl_iface)
2484 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2485 *
2486 * EAP methods can call this function to request password information for the
2487 * current network. This is normally called when the password is not included
2488 * in the network configuration. The request will be sent to monitor programs
2489 * through the control interface.
2490 */
2491 void eap_sm_request_password(struct eap_sm *sm)
2492 {
2493 eap_sm_request(sm, WPA_CTRL_REQ_EAP_PASSWORD, NULL, 0);
2494 }
2495
2496
2497 /**
2498 * eap_sm_request_new_password - Request new password from user (ctrl_iface)
2499 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2500 *
2501 * EAP methods can call this function to request new password information for
2502 * the current network. This is normally called when the EAP method indicates
2503 * that the current password has expired and password change is required. The
2504 * request will be sent to monitor programs through the control interface.
2505 */
2506 void eap_sm_request_new_password(struct eap_sm *sm)
2507 {
2508 eap_sm_request(sm, WPA_CTRL_REQ_EAP_NEW_PASSWORD, NULL, 0);
2509 }
2510
2511
2512 /**
2513 * eap_sm_request_pin - Request SIM or smart card PIN from user (ctrl_iface)
2514 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2515 *
2516 * EAP methods can call this function to request SIM or smart card PIN
2517 * information for the current network. This is normally called when the PIN is
2518 * not included in the network configuration. The request will be sent to
2519 * monitor programs through the control interface.
2520 */
2521 void eap_sm_request_pin(struct eap_sm *sm)
2522 {
2523 eap_sm_request(sm, WPA_CTRL_REQ_EAP_PIN, NULL, 0);
2524 }
2525
2526
2527 /**
2528 * eap_sm_request_otp - Request one time password from user (ctrl_iface)
2529 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2530 * @msg: Message to be displayed to the user when asking for OTP
2531 * @msg_len: Length of the user displayable message
2532 *
2533 * EAP methods can call this function to request open time password (OTP) for
2534 * the current network. The request will be sent to monitor programs through
2535 * the control interface.
2536 */
2537 void eap_sm_request_otp(struct eap_sm *sm, const char *msg, size_t msg_len)
2538 {
2539 eap_sm_request(sm, WPA_CTRL_REQ_EAP_OTP, msg, msg_len);
2540 }
2541
2542
2543 /**
2544 * eap_sm_request_passphrase - Request passphrase from user (ctrl_iface)
2545 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2546 *
2547 * EAP methods can call this function to request passphrase for a private key
2548 * for the current network. This is normally called when the passphrase is not
2549 * included in the network configuration. The request will be sent to monitor
2550 * programs through the control interface.
2551 */
2552 void eap_sm_request_passphrase(struct eap_sm *sm)
2553 {
2554 eap_sm_request(sm, WPA_CTRL_REQ_EAP_PASSPHRASE, NULL, 0);
2555 }
2556
2557
2558 /**
2559 * eap_sm_request_sim - Request external SIM processing
2560 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2561 * @req: EAP method specific request
2562 */
2563 void eap_sm_request_sim(struct eap_sm *sm, const char *req)
2564 {
2565 eap_sm_request(sm, WPA_CTRL_REQ_SIM, req, os_strlen(req));
2566 }
2567
2568
2569 /**
2570 * eap_sm_notify_ctrl_attached - Notification of attached monitor
2571 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2572 *
2573 * Notify EAP state machines that a monitor was attached to the control
2574 * interface to trigger re-sending of pending requests for user input.
2575 */
2576 void eap_sm_notify_ctrl_attached(struct eap_sm *sm)
2577 {
2578 struct eap_peer_config *config = eap_get_config(sm);
2579
2580 if (config == NULL)
2581 return;
2582
2583 /* Re-send any pending requests for user data since a new control
2584 * interface was added. This handles cases where the EAP authentication
2585 * starts immediately after system startup when the user interface is
2586 * not yet running. */
2587 if (config->pending_req_identity)
2588 eap_sm_request_identity(sm);
2589 if (config->pending_req_password)
2590 eap_sm_request_password(sm);
2591 if (config->pending_req_new_password)
2592 eap_sm_request_new_password(sm);
2593 if (config->pending_req_otp)
2594 eap_sm_request_otp(sm, NULL, 0);
2595 if (config->pending_req_pin)
2596 eap_sm_request_pin(sm);
2597 if (config->pending_req_passphrase)
2598 eap_sm_request_passphrase(sm);
2599 }
2600
2601
2602 static int eap_allowed_phase2_type(int vendor, int type)
2603 {
2604 if (vendor != EAP_VENDOR_IETF)
2605 return 0;
2606 return type != EAP_TYPE_PEAP && type != EAP_TYPE_TTLS &&
2607 type != EAP_TYPE_FAST && type != EAP_TYPE_TEAP;
2608 }
2609
2610
2611 /**
2612 * eap_get_phase2_type - Get EAP type for the given EAP phase 2 method name
2613 * @name: EAP method name, e.g., MD5
2614 * @vendor: Buffer for returning EAP Vendor-Id
2615 * Returns: EAP method type or %EAP_TYPE_NONE if not found
2616 *
2617 * This function maps EAP type names into EAP type numbers that are allowed for
2618 * Phase 2, i.e., for tunneled authentication. Phase 2 is used, e.g., with
2619 * EAP-PEAP, EAP-TTLS, and EAP-FAST.
2620 */
2621 u32 eap_get_phase2_type(const char *name, int *vendor)
2622 {
2623 int v;
2624 u32 type = eap_peer_get_type(name, &v);
2625 if (eap_allowed_phase2_type(v, type)) {
2626 *vendor = v;
2627 return type;
2628 }
2629 *vendor = EAP_VENDOR_IETF;
2630 return EAP_TYPE_NONE;
2631 }
2632
2633
2634 /**
2635 * eap_get_phase2_types - Get list of allowed EAP phase 2 types
2636 * @config: Pointer to a network configuration
2637 * @count: Pointer to a variable to be filled with number of returned EAP types
2638 * Returns: Pointer to allocated type list or %NULL on failure
2639 *
2640 * This function generates an array of allowed EAP phase 2 (tunneled) types for
2641 * the given network configuration.
2642 */
2643 struct eap_method_type * eap_get_phase2_types(struct eap_peer_config *config,
2644 size_t *count)
2645 {
2646 struct eap_method_type *buf;
2647 u32 method;
2648 int vendor;
2649 size_t mcount;
2650 const struct eap_method *methods, *m;
2651
2652 methods = eap_peer_get_methods(&mcount);
2653 if (methods == NULL)
2654 return NULL;
2655 *count = 0;
2656 buf = os_malloc(mcount * sizeof(struct eap_method_type));
2657 if (buf == NULL)
2658 return NULL;
2659
2660 for (m = methods; m; m = m->next) {
2661 vendor = m->vendor;
2662 method = m->method;
2663 if (eap_allowed_phase2_type(vendor, method)) {
2664 if (vendor == EAP_VENDOR_IETF &&
2665 method == EAP_TYPE_TLS && config &&
2666 config->private_key2 == NULL)
2667 continue;
2668 buf[*count].vendor = vendor;
2669 buf[*count].method = method;
2670 (*count)++;
2671 }
2672 }
2673
2674 return buf;
2675 }
2676
2677
2678 /**
2679 * eap_set_fast_reauth - Update fast_reauth setting
2680 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2681 * @enabled: 1 = Fast reauthentication is enabled, 0 = Disabled
2682 */
2683 void eap_set_fast_reauth(struct eap_sm *sm, int enabled)
2684 {
2685 sm->fast_reauth = enabled;
2686 }
2687
2688
2689 /**
2690 * eap_set_workaround - Update EAP workarounds setting
2691 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2692 * @workaround: 1 = Enable EAP workarounds, 0 = Disable EAP workarounds
2693 */
2694 void eap_set_workaround(struct eap_sm *sm, unsigned int workaround)
2695 {
2696 sm->workaround = workaround;
2697 }
2698
2699
2700 /**
2701 * eap_get_config - Get current network configuration
2702 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2703 * Returns: Pointer to the current network configuration or %NULL if not found
2704 *
2705 * EAP peer methods should avoid using this function if they can use other
2706 * access functions, like eap_get_config_identity() and
2707 * eap_get_config_password(), that do not require direct access to
2708 * struct eap_peer_config.
2709 */
2710 struct eap_peer_config * eap_get_config(struct eap_sm *sm)
2711 {
2712 return sm->eapol_cb->get_config(sm->eapol_ctx);
2713 }
2714
2715
2716 /**
2717 * eap_get_config_identity - Get identity from the network configuration
2718 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2719 * @len: Buffer for the length of the identity
2720 * Returns: Pointer to the identity or %NULL if not found
2721 */
2722 const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len)
2723 {
2724 struct eap_peer_config *config = eap_get_config(sm);
2725 if (config == NULL)
2726 return NULL;
2727 *len = config->identity_len;
2728 return config->identity;
2729 }
2730
2731
2732 static int eap_get_ext_password(struct eap_sm *sm,
2733 struct eap_peer_config *config)
2734 {
2735 char *name;
2736
2737 if (config->password == NULL)
2738 return -1;
2739
2740 name = os_zalloc(config->password_len + 1);
2741 if (name == NULL)
2742 return -1;
2743 os_memcpy(name, config->password, config->password_len);
2744
2745 ext_password_free(sm->ext_pw_buf);
2746 sm->ext_pw_buf = ext_password_get(sm->ext_pw, name);
2747 os_free(name);
2748
2749 return sm->ext_pw_buf == NULL ? -1 : 0;
2750 }
2751
2752
2753 /**
2754 * eap_get_config_password - Get password from the network configuration
2755 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2756 * @len: Buffer for the length of the password
2757 * Returns: Pointer to the password or %NULL if not found
2758 */
2759 const u8 * eap_get_config_password(struct eap_sm *sm, size_t *len)
2760 {
2761 struct eap_peer_config *config = eap_get_config(sm);
2762 if (config == NULL)
2763 return NULL;
2764
2765 if (config->flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) {
2766 if (eap_get_ext_password(sm, config) < 0)
2767 return NULL;
2768 *len = wpabuf_len(sm->ext_pw_buf);
2769 return wpabuf_head(sm->ext_pw_buf);
2770 }
2771
2772 *len = config->password_len;
2773 return config->password;
2774 }
2775
2776
2777 /**
2778 * eap_get_config_password2 - Get password from the network configuration
2779 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2780 * @len: Buffer for the length of the password
2781 * @hash: Buffer for returning whether the password is stored as a
2782 * NtPasswordHash instead of plaintext password; can be %NULL if this
2783 * information is not needed
2784 * Returns: Pointer to the password or %NULL if not found
2785 */
2786 const u8 * eap_get_config_password2(struct eap_sm *sm, size_t *len, int *hash)
2787 {
2788 struct eap_peer_config *config = eap_get_config(sm);
2789 if (config == NULL)
2790 return NULL;
2791
2792 if (config->flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) {
2793 if (eap_get_ext_password(sm, config) < 0)
2794 return NULL;
2795 if (hash)
2796 *hash = 0;
2797 *len = wpabuf_len(sm->ext_pw_buf);
2798 return wpabuf_head(sm->ext_pw_buf);
2799 }
2800
2801 *len = config->password_len;
2802 if (hash)
2803 *hash = !!(config->flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH);
2804 return config->password;
2805 }
2806
2807
2808 /**
2809 * eap_get_config_new_password - Get new password from network configuration
2810 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2811 * @len: Buffer for the length of the new password
2812 * Returns: Pointer to the new password or %NULL if not found
2813 */
2814 const u8 * eap_get_config_new_password(struct eap_sm *sm, size_t *len)
2815 {
2816 struct eap_peer_config *config = eap_get_config(sm);
2817 if (config == NULL)
2818 return NULL;
2819 *len = config->new_password_len;
2820 return config->new_password;
2821 }
2822
2823
2824 /**
2825 * eap_get_config_otp - Get one-time password from the network configuration
2826 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2827 * @len: Buffer for the length of the one-time password
2828 * Returns: Pointer to the one-time password or %NULL if not found
2829 */
2830 const u8 * eap_get_config_otp(struct eap_sm *sm, size_t *len)
2831 {
2832 struct eap_peer_config *config = eap_get_config(sm);
2833 if (config == NULL)
2834 return NULL;
2835 *len = config->otp_len;
2836 return config->otp;
2837 }
2838
2839
2840 /**
2841 * eap_clear_config_otp - Clear used one-time password
2842 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2843 *
2844 * This function clears a used one-time password (OTP) from the current network
2845 * configuration. This should be called when the OTP has been used and is not
2846 * needed anymore.
2847 */
2848 void eap_clear_config_otp(struct eap_sm *sm)
2849 {
2850 struct eap_peer_config *config = eap_get_config(sm);
2851 if (config == NULL)
2852 return;
2853 os_memset(config->otp, 0, config->otp_len);
2854 os_free(config->otp);
2855 config->otp = NULL;
2856 config->otp_len = 0;
2857 }
2858
2859
2860 /**
2861 * eap_get_config_phase1 - Get phase1 data from the network configuration
2862 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2863 * Returns: Pointer to the phase1 data or %NULL if not found
2864 */
2865 const char * eap_get_config_phase1(struct eap_sm *sm)
2866 {
2867 struct eap_peer_config *config = eap_get_config(sm);
2868 if (config == NULL)
2869 return NULL;
2870 return config->phase1;
2871 }
2872
2873
2874 /**
2875 * eap_get_config_phase2 - Get phase2 data from the network configuration
2876 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2877 * Returns: Pointer to the phase1 data or %NULL if not found
2878 */
2879 const char * eap_get_config_phase2(struct eap_sm *sm)
2880 {
2881 struct eap_peer_config *config = eap_get_config(sm);
2882 if (config == NULL)
2883 return NULL;
2884 return config->phase2;
2885 }
2886
2887
2888 int eap_get_config_fragment_size(struct eap_sm *sm)
2889 {
2890 struct eap_peer_config *config = eap_get_config(sm);
2891 if (config == NULL)
2892 return -1;
2893 return config->fragment_size;
2894 }
2895
2896
2897 /**
2898 * eap_key_available - Get key availability (eapKeyAvailable variable)
2899 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2900 * Returns: 1 if EAP keying material is available, 0 if not
2901 */
2902 int eap_key_available(struct eap_sm *sm)
2903 {
2904 return sm ? sm->eapKeyAvailable : 0;
2905 }
2906
2907
2908 /**
2909 * eap_notify_success - Notify EAP state machine about external success trigger
2910 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2911 *
2912 * This function is called when external event, e.g., successful completion of
2913 * WPA-PSK key handshake, is indicating that EAP state machine should move to
2914 * success state. This is mainly used with security modes that do not use EAP
2915 * state machine (e.g., WPA-PSK).
2916 */
2917 void eap_notify_success(struct eap_sm *sm)
2918 {
2919 if (sm) {
2920 sm->decision = DECISION_COND_SUCC;
2921 sm->EAP_state = EAP_SUCCESS;
2922 }
2923 }
2924
2925
2926 /**
2927 * eap_notify_lower_layer_success - Notification of lower layer success
2928 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2929 *
2930 * Notify EAP state machines that a lower layer has detected a successful
2931 * authentication. This is used to recover from dropped EAP-Success messages.
2932 */
2933 void eap_notify_lower_layer_success(struct eap_sm *sm)
2934 {
2935 if (sm == NULL)
2936 return;
2937
2938 if (eapol_get_bool(sm, EAPOL_eapSuccess) ||
2939 sm->decision == DECISION_FAIL ||
2940 (sm->methodState != METHOD_MAY_CONT &&
2941 sm->methodState != METHOD_DONE))
2942 return;
2943
2944 if (sm->eapKeyData != NULL)
2945 sm->eapKeyAvailable = TRUE;
2946 eapol_set_bool(sm, EAPOL_eapSuccess, TRUE);
2947 wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS
2948 "EAP authentication completed successfully (based on lower "
2949 "layer success)");
2950 }
2951
2952
2953 /**
2954 * eap_get_eapSessionId - Get Session-Id from EAP state machine
2955 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2956 * @len: Pointer to variable that will be set to number of bytes in the session
2957 * Returns: Pointer to the EAP Session-Id or %NULL on failure
2958 *
2959 * Fetch EAP Session-Id from the EAP state machine. The Session-Id is available
2960 * only after a successful authentication. EAP state machine continues to manage
2961 * the Session-Id and the caller must not change or free the returned data.
2962 */
2963 const u8 * eap_get_eapSessionId(struct eap_sm *sm, size_t *len)
2964 {
2965 if (sm == NULL || sm->eapSessionId == NULL) {
2966 *len = 0;
2967 return NULL;
2968 }
2969
2970 *len = sm->eapSessionIdLen;
2971 return sm->eapSessionId;
2972 }
2973
2974
2975 /**
2976 * eap_get_eapKeyData - Get master session key (MSK) from EAP state machine
2977 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
2978 * @len: Pointer to variable that will be set to number of bytes in the key
2979 * Returns: Pointer to the EAP keying data or %NULL on failure
2980 *
2981 * Fetch EAP keying material (MSK, eapKeyData) from the EAP state machine. The
2982 * key is available only after a successful authentication. EAP state machine
2983 * continues to manage the key data and the caller must not change or free the
2984 * returned data.
2985 */
2986 const u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len)
2987 {
2988 if (sm == NULL || sm->eapKeyData == NULL) {
2989 *len = 0;
2990 return NULL;
2991 }
2992
2993 *len = sm->eapKeyDataLen;
2994 return sm->eapKeyData;
2995 }
2996
2997
2998 /**
2999 * eap_get_eapKeyData - Get EAP response data
3000 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3001 * Returns: Pointer to the EAP response (eapRespData) or %NULL on failure
3002 *
3003 * Fetch EAP response (eapRespData) from the EAP state machine. This data is
3004 * available when EAP state machine has processed an incoming EAP request. The
3005 * EAP state machine does not maintain a reference to the response after this
3006 * function is called and the caller is responsible for freeing the data.
3007 */
3008 struct wpabuf * eap_get_eapRespData(struct eap_sm *sm)
3009 {
3010 struct wpabuf *resp;
3011
3012 if (sm == NULL || sm->eapRespData == NULL)
3013 return NULL;
3014
3015 resp = sm->eapRespData;
3016 sm->eapRespData = NULL;
3017
3018 return resp;
3019 }
3020
3021
3022 /**
3023 * eap_sm_register_scard_ctx - Notification of smart card context
3024 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3025 * @ctx: Context data for smart card operations
3026 *
3027 * Notify EAP state machines of context data for smart card operations. This
3028 * context data will be used as a parameter for scard_*() functions.
3029 */
3030 void eap_register_scard_ctx(struct eap_sm *sm, void *ctx)
3031 {
3032 if (sm)
3033 sm->scard_ctx = ctx;
3034 }
3035
3036
3037 /**
3038 * eap_set_config_blob - Set or add a named configuration blob
3039 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3040 * @blob: New value for the blob
3041 *
3042 * Adds a new configuration blob or replaces the current value of an existing
3043 * blob.
3044 */
3045 void eap_set_config_blob(struct eap_sm *sm, struct wpa_config_blob *blob)
3046 {
3047 #ifndef CONFIG_NO_CONFIG_BLOBS
3048 sm->eapol_cb->set_config_blob(sm->eapol_ctx, blob);
3049 #endif /* CONFIG_NO_CONFIG_BLOBS */
3050 }
3051
3052
3053 /**
3054 * eap_get_config_blob - Get a named configuration blob
3055 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3056 * @name: Name of the blob
3057 * Returns: Pointer to blob data or %NULL if not found
3058 */
3059 const struct wpa_config_blob * eap_get_config_blob(struct eap_sm *sm,
3060 const char *name)
3061 {
3062 #ifndef CONFIG_NO_CONFIG_BLOBS
3063 return sm->eapol_cb->get_config_blob(sm->eapol_ctx, name);
3064 #else /* CONFIG_NO_CONFIG_BLOBS */
3065 return NULL;
3066 #endif /* CONFIG_NO_CONFIG_BLOBS */
3067 }
3068
3069
3070 /**
3071 * eap_set_force_disabled - Set force_disabled flag
3072 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3073 * @disabled: 1 = EAP disabled, 0 = EAP enabled
3074 *
3075 * This function is used to force EAP state machine to be disabled when it is
3076 * not in use (e.g., with WPA-PSK or plaintext connections).
3077 */
3078 void eap_set_force_disabled(struct eap_sm *sm, int disabled)
3079 {
3080 sm->force_disabled = disabled;
3081 }
3082
3083
3084 /**
3085 * eap_set_external_sim - Set external_sim flag
3086 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3087 * @external_sim: Whether external SIM/USIM processing is used
3088 */
3089 void eap_set_external_sim(struct eap_sm *sm, int external_sim)
3090 {
3091 sm->external_sim = external_sim;
3092 }
3093
3094
3095 /**
3096 * eap_notify_pending - Notify that EAP method is ready to re-process a request
3097 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3098 *
3099 * An EAP method can perform a pending operation (e.g., to get a response from
3100 * an external process). Once the response is available, this function can be
3101 * used to request EAPOL state machine to retry delivering the previously
3102 * received (and still unanswered) EAP request to EAP state machine.
3103 */
3104 void eap_notify_pending(struct eap_sm *sm)
3105 {
3106 sm->eapol_cb->notify_pending(sm->eapol_ctx);
3107 }
3108
3109
3110 /**
3111 * eap_invalidate_cached_session - Mark cached session data invalid
3112 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3113 */
3114 void eap_invalidate_cached_session(struct eap_sm *sm)
3115 {
3116 if (sm)
3117 eap_deinit_prev_method(sm, "invalidate");
3118 }
3119
3120
3121 int eap_is_wps_pbc_enrollee(struct eap_peer_config *conf)
3122 {
3123 if (conf->identity_len != WSC_ID_ENROLLEE_LEN ||
3124 os_memcmp(conf->identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN))
3125 return 0; /* Not a WPS Enrollee */
3126
3127 if (conf->phase1 == NULL || os_strstr(conf->phase1, "pbc=1") == NULL)
3128 return 0; /* Not using PBC */
3129
3130 return 1;
3131 }
3132
3133
3134 int eap_is_wps_pin_enrollee(struct eap_peer_config *conf)
3135 {
3136 if (conf->identity_len != WSC_ID_ENROLLEE_LEN ||
3137 os_memcmp(conf->identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN))
3138 return 0; /* Not a WPS Enrollee */
3139
3140 if (conf->phase1 == NULL || os_strstr(conf->phase1, "pin=") == NULL)
3141 return 0; /* Not using PIN */
3142
3143 return 1;
3144 }
3145
3146
3147 void eap_sm_set_ext_pw_ctx(struct eap_sm *sm, struct ext_password_data *ext)
3148 {
3149 ext_password_free(sm->ext_pw_buf);
3150 sm->ext_pw_buf = NULL;
3151 sm->ext_pw = ext;
3152 }
3153
3154
3155 /**
3156 * eap_set_anon_id - Set or add anonymous identity
3157 * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
3158 * @id: Anonymous identity (e.g., EAP-SIM pseudonym) or %NULL to clear
3159 * @len: Length of anonymous identity in octets
3160 */
3161 void eap_set_anon_id(struct eap_sm *sm, const u8 *id, size_t len)
3162 {
3163 if (sm->eapol_cb->set_anon_id)
3164 sm->eapol_cb->set_anon_id(sm->eapol_ctx, id, len);
3165 }
3166
3167
3168 int eap_peer_was_failure_expected(struct eap_sm *sm)
3169 {
3170 return sm->expected_failure;
3171 }