xref: /freebsd/contrib/wpa/src/eap_peer/eap_aka.c (revision 884a2a699669ec61e2366e3e358342dbc94be24a)
1 /*
2  * EAP peer method: EAP-AKA (RFC 4187) and EAP-AKA' (draft-arkko-eap-aka-kdf)
3  * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14 
15 #include "includes.h"
16 
17 #include "common.h"
18 #include "pcsc_funcs.h"
19 #include "crypto/crypto.h"
20 #include "crypto/sha1.h"
21 #include "crypto/sha256.h"
22 #include "crypto/milenage.h"
23 #include "eap_common/eap_sim_common.h"
24 #include "eap_config.h"
25 #include "eap_i.h"
26 
27 
28 struct eap_aka_data {
29 	u8 ik[EAP_AKA_IK_LEN], ck[EAP_AKA_CK_LEN], res[EAP_AKA_RES_MAX_LEN];
30 	size_t res_len;
31 	u8 nonce_s[EAP_SIM_NONCE_S_LEN];
32 	u8 mk[EAP_SIM_MK_LEN];
33 	u8 k_aut[EAP_AKA_PRIME_K_AUT_LEN];
34 	u8 k_encr[EAP_SIM_K_ENCR_LEN];
35 	u8 k_re[EAP_AKA_PRIME_K_RE_LEN]; /* EAP-AKA' only */
36 	u8 msk[EAP_SIM_KEYING_DATA_LEN];
37 	u8 emsk[EAP_EMSK_LEN];
38 	u8 rand[EAP_AKA_RAND_LEN], autn[EAP_AKA_AUTN_LEN];
39 	u8 auts[EAP_AKA_AUTS_LEN];
40 
41 	int num_id_req, num_notification;
42 	u8 *pseudonym;
43 	size_t pseudonym_len;
44 	u8 *reauth_id;
45 	size_t reauth_id_len;
46 	int reauth;
47 	unsigned int counter, counter_too_small;
48 	u8 *last_eap_identity;
49 	size_t last_eap_identity_len;
50 	enum {
51 		CONTINUE, RESULT_SUCCESS, RESULT_FAILURE, SUCCESS, FAILURE
52 	} state;
53 
54 	struct wpabuf *id_msgs;
55 	int prev_id;
56 	int result_ind, use_result_ind;
57 	u8 eap_method;
58 	u8 *network_name;
59 	size_t network_name_len;
60 	u16 kdf;
61 	int kdf_negotiation;
62 };
63 
64 
65 #ifndef CONFIG_NO_STDOUT_DEBUG
66 static const char * eap_aka_state_txt(int state)
67 {
68 	switch (state) {
69 	case CONTINUE:
70 		return "CONTINUE";
71 	case RESULT_SUCCESS:
72 		return "RESULT_SUCCESS";
73 	case RESULT_FAILURE:
74 		return "RESULT_FAILURE";
75 	case SUCCESS:
76 		return "SUCCESS";
77 	case FAILURE:
78 		return "FAILURE";
79 	default:
80 		return "?";
81 	}
82 }
83 #endif /* CONFIG_NO_STDOUT_DEBUG */
84 
85 
86 static void eap_aka_state(struct eap_aka_data *data, int state)
87 {
88 	wpa_printf(MSG_DEBUG, "EAP-AKA: %s -> %s",
89 		   eap_aka_state_txt(data->state),
90 		   eap_aka_state_txt(state));
91 	data->state = state;
92 }
93 
94 
95 static void * eap_aka_init(struct eap_sm *sm)
96 {
97 	struct eap_aka_data *data;
98 	const char *phase1 = eap_get_config_phase1(sm);
99 
100 	data = os_zalloc(sizeof(*data));
101 	if (data == NULL)
102 		return NULL;
103 
104 	data->eap_method = EAP_TYPE_AKA;
105 
106 	eap_aka_state(data, CONTINUE);
107 	data->prev_id = -1;
108 
109 	data->result_ind = phase1 && os_strstr(phase1, "result_ind=1") != NULL;
110 
111 	return data;
112 }
113 
114 
115 #ifdef EAP_AKA_PRIME
116 static void * eap_aka_prime_init(struct eap_sm *sm)
117 {
118 	struct eap_aka_data *data = eap_aka_init(sm);
119 	if (data == NULL)
120 		return NULL;
121 	data->eap_method = EAP_TYPE_AKA_PRIME;
122 	return data;
123 }
124 #endif /* EAP_AKA_PRIME */
125 
126 
127 static void eap_aka_deinit(struct eap_sm *sm, void *priv)
128 {
129 	struct eap_aka_data *data = priv;
130 	if (data) {
131 		os_free(data->pseudonym);
132 		os_free(data->reauth_id);
133 		os_free(data->last_eap_identity);
134 		wpabuf_free(data->id_msgs);
135 		os_free(data->network_name);
136 		os_free(data);
137 	}
138 }
139 
140 
141 static int eap_aka_umts_auth(struct eap_sm *sm, struct eap_aka_data *data)
142 {
143 	struct eap_peer_config *conf;
144 
145 	wpa_printf(MSG_DEBUG, "EAP-AKA: UMTS authentication algorithm");
146 
147 	conf = eap_get_config(sm);
148 	if (conf == NULL)
149 		return -1;
150 	if (conf->pcsc) {
151 		return scard_umts_auth(sm->scard_ctx, data->rand,
152 				       data->autn, data->res, &data->res_len,
153 				       data->ik, data->ck, data->auts);
154 	}
155 
156 #ifdef CONFIG_USIM_SIMULATOR
157 	if (conf->password) {
158 		u8 opc[16], k[16], sqn[6];
159 		const char *pos;
160 		wpa_printf(MSG_DEBUG, "EAP-AKA: Use internal Milenage "
161 			   "implementation for UMTS authentication");
162 		if (conf->password_len < 78) {
163 			wpa_printf(MSG_DEBUG, "EAP-AKA: invalid Milenage "
164 				   "password");
165 			return -1;
166 		}
167 		pos = (const char *) conf->password;
168 		if (hexstr2bin(pos, k, 16))
169 			return -1;
170 		pos += 32;
171 		if (*pos != ':')
172 			return -1;
173 		pos++;
174 
175 		if (hexstr2bin(pos, opc, 16))
176 			return -1;
177 		pos += 32;
178 		if (*pos != ':')
179 			return -1;
180 		pos++;
181 
182 		if (hexstr2bin(pos, sqn, 6))
183 			return -1;
184 
185 		return milenage_check(opc, k, sqn, data->rand, data->autn,
186 				      data->ik, data->ck,
187 				      data->res, &data->res_len, data->auts);
188 	}
189 #endif /* CONFIG_USIM_SIMULATOR */
190 
191 #ifdef CONFIG_USIM_HARDCODED
192 	wpa_printf(MSG_DEBUG, "EAP-AKA: Use hardcoded Kc and SRES values for "
193 		   "testing");
194 
195 	/* These hardcoded Kc and SRES values are used for testing.
196 	 * Could consider making them configurable. */
197 	os_memset(data->res, '2', EAP_AKA_RES_MAX_LEN);
198 	data->res_len = EAP_AKA_RES_MAX_LEN;
199 	os_memset(data->ik, '3', EAP_AKA_IK_LEN);
200 	os_memset(data->ck, '4', EAP_AKA_CK_LEN);
201 	{
202 		u8 autn[EAP_AKA_AUTN_LEN];
203 		os_memset(autn, '1', EAP_AKA_AUTN_LEN);
204 		if (os_memcmp(autn, data->autn, EAP_AKA_AUTN_LEN) != 0) {
205 			wpa_printf(MSG_WARNING, "EAP-AKA: AUTN did not match "
206 				   "with expected value");
207 			return -1;
208 		}
209 	}
210 #if 0
211 	{
212 		static int test_resync = 1;
213 		if (test_resync) {
214 			/* Test Resynchronization */
215 			test_resync = 0;
216 			return -2;
217 		}
218 	}
219 #endif
220 	return 0;
221 
222 #else /* CONFIG_USIM_HARDCODED */
223 
224 	wpa_printf(MSG_DEBUG, "EAP-AKA: No UMTS authentication algorith "
225 		   "enabled");
226 	return -1;
227 
228 #endif /* CONFIG_USIM_HARDCODED */
229 }
230 
231 
232 #define CLEAR_PSEUDONYM	0x01
233 #define CLEAR_REAUTH_ID	0x02
234 #define CLEAR_EAP_ID	0x04
235 
236 static void eap_aka_clear_identities(struct eap_aka_data *data, int id)
237 {
238 	wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old%s%s%s",
239 		   id & CLEAR_PSEUDONYM ? " pseudonym" : "",
240 		   id & CLEAR_REAUTH_ID ? " reauth_id" : "",
241 		   id & CLEAR_EAP_ID ? " eap_id" : "");
242 	if (id & CLEAR_PSEUDONYM) {
243 		os_free(data->pseudonym);
244 		data->pseudonym = NULL;
245 		data->pseudonym_len = 0;
246 	}
247 	if (id & CLEAR_REAUTH_ID) {
248 		os_free(data->reauth_id);
249 		data->reauth_id = NULL;
250 		data->reauth_id_len = 0;
251 	}
252 	if (id & CLEAR_EAP_ID) {
253 		os_free(data->last_eap_identity);
254 		data->last_eap_identity = NULL;
255 		data->last_eap_identity_len = 0;
256 	}
257 }
258 
259 
260 static int eap_aka_learn_ids(struct eap_aka_data *data,
261 			     struct eap_sim_attrs *attr)
262 {
263 	if (attr->next_pseudonym) {
264 		os_free(data->pseudonym);
265 		data->pseudonym = os_malloc(attr->next_pseudonym_len);
266 		if (data->pseudonym == NULL) {
267 			wpa_printf(MSG_INFO, "EAP-AKA: (encr) No memory for "
268 				   "next pseudonym");
269 			return -1;
270 		}
271 		os_memcpy(data->pseudonym, attr->next_pseudonym,
272 			  attr->next_pseudonym_len);
273 		data->pseudonym_len = attr->next_pseudonym_len;
274 		wpa_hexdump_ascii(MSG_DEBUG,
275 				  "EAP-AKA: (encr) AT_NEXT_PSEUDONYM",
276 				  data->pseudonym,
277 				  data->pseudonym_len);
278 	}
279 
280 	if (attr->next_reauth_id) {
281 		os_free(data->reauth_id);
282 		data->reauth_id = os_malloc(attr->next_reauth_id_len);
283 		if (data->reauth_id == NULL) {
284 			wpa_printf(MSG_INFO, "EAP-AKA: (encr) No memory for "
285 				   "next reauth_id");
286 			return -1;
287 		}
288 		os_memcpy(data->reauth_id, attr->next_reauth_id,
289 			  attr->next_reauth_id_len);
290 		data->reauth_id_len = attr->next_reauth_id_len;
291 		wpa_hexdump_ascii(MSG_DEBUG,
292 				  "EAP-AKA: (encr) AT_NEXT_REAUTH_ID",
293 				  data->reauth_id,
294 				  data->reauth_id_len);
295 	}
296 
297 	return 0;
298 }
299 
300 
301 static int eap_aka_add_id_msg(struct eap_aka_data *data,
302 			      const struct wpabuf *msg)
303 {
304 	if (msg == NULL)
305 		return -1;
306 
307 	if (data->id_msgs == NULL) {
308 		data->id_msgs = wpabuf_dup(msg);
309 		return data->id_msgs == NULL ? -1 : 0;
310 	}
311 
312 	if (wpabuf_resize(&data->id_msgs, wpabuf_len(msg)) < 0)
313 		return -1;
314 	wpabuf_put_buf(data->id_msgs, msg);
315 
316 	return 0;
317 }
318 
319 
320 static void eap_aka_add_checkcode(struct eap_aka_data *data,
321 				  struct eap_sim_msg *msg)
322 {
323 	const u8 *addr;
324 	size_t len;
325 	u8 hash[SHA256_MAC_LEN];
326 
327 	wpa_printf(MSG_DEBUG, "   AT_CHECKCODE");
328 
329 	if (data->id_msgs == NULL) {
330 		/*
331 		 * No EAP-AKA/Identity packets were exchanged - send empty
332 		 * checkcode.
333 		 */
334 		eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, NULL, 0);
335 		return;
336 	}
337 
338 	/* Checkcode is SHA1/SHA256 hash over all EAP-AKA/Identity packets. */
339 	addr = wpabuf_head(data->id_msgs);
340 	len = wpabuf_len(data->id_msgs);
341 	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA: AT_CHECKCODE data", addr, len);
342 #ifdef EAP_AKA_PRIME
343 	if (data->eap_method == EAP_TYPE_AKA_PRIME)
344 		sha256_vector(1, &addr, &len, hash);
345 	else
346 #endif /* EAP_AKA_PRIME */
347 		sha1_vector(1, &addr, &len, hash);
348 
349 	eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, hash,
350 			data->eap_method == EAP_TYPE_AKA_PRIME ?
351 			EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN);
352 }
353 
354 
355 static int eap_aka_verify_checkcode(struct eap_aka_data *data,
356 				    const u8 *checkcode, size_t checkcode_len)
357 {
358 	const u8 *addr;
359 	size_t len;
360 	u8 hash[SHA256_MAC_LEN];
361 	size_t hash_len;
362 
363 	if (checkcode == NULL)
364 		return -1;
365 
366 	if (data->id_msgs == NULL) {
367 		if (checkcode_len != 0) {
368 			wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from server "
369 				   "indicates that AKA/Identity messages were "
370 				   "used, but they were not");
371 			return -1;
372 		}
373 		return 0;
374 	}
375 
376 	hash_len = data->eap_method == EAP_TYPE_AKA_PRIME ?
377 		EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN;
378 
379 	if (checkcode_len != hash_len) {
380 		wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from server "
381 			   "indicates that AKA/Identity message were not "
382 			   "used, but they were");
383 		return -1;
384 	}
385 
386 	/* Checkcode is SHA1/SHA256 hash over all EAP-AKA/Identity packets. */
387 	addr = wpabuf_head(data->id_msgs);
388 	len = wpabuf_len(data->id_msgs);
389 #ifdef EAP_AKA_PRIME
390 	if (data->eap_method == EAP_TYPE_AKA_PRIME)
391 		sha256_vector(1, &addr, &len, hash);
392 	else
393 #endif /* EAP_AKA_PRIME */
394 		sha1_vector(1, &addr, &len, hash);
395 
396 	if (os_memcmp(hash, checkcode, hash_len) != 0) {
397 		wpa_printf(MSG_DEBUG, "EAP-AKA: Mismatch in AT_CHECKCODE");
398 		return -1;
399 	}
400 
401 	return 0;
402 }
403 
404 
405 static struct wpabuf * eap_aka_client_error(struct eap_aka_data *data, u8 id,
406 					    int err)
407 {
408 	struct eap_sim_msg *msg;
409 
410 	eap_aka_state(data, FAILURE);
411 	data->num_id_req = 0;
412 	data->num_notification = 0;
413 
414 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
415 			       EAP_AKA_SUBTYPE_CLIENT_ERROR);
416 	eap_sim_msg_add(msg, EAP_SIM_AT_CLIENT_ERROR_CODE, err, NULL, 0);
417 	return eap_sim_msg_finish(msg, NULL, NULL, 0);
418 }
419 
420 
421 static struct wpabuf * eap_aka_authentication_reject(struct eap_aka_data *data,
422 						     u8 id)
423 {
424 	struct eap_sim_msg *msg;
425 
426 	eap_aka_state(data, FAILURE);
427 	data->num_id_req = 0;
428 	data->num_notification = 0;
429 
430 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Authentication-Reject "
431 		   "(id=%d)", id);
432 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
433 			       EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT);
434 	return eap_sim_msg_finish(msg, NULL, NULL, 0);
435 }
436 
437 
438 static struct wpabuf * eap_aka_synchronization_failure(
439 	struct eap_aka_data *data, u8 id)
440 {
441 	struct eap_sim_msg *msg;
442 
443 	data->num_id_req = 0;
444 	data->num_notification = 0;
445 
446 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Synchronization-Failure "
447 		   "(id=%d)", id);
448 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
449 			       EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE);
450 	wpa_printf(MSG_DEBUG, "   AT_AUTS");
451 	eap_sim_msg_add_full(msg, EAP_SIM_AT_AUTS, data->auts,
452 			     EAP_AKA_AUTS_LEN);
453 	return eap_sim_msg_finish(msg, NULL, NULL, 0);
454 }
455 
456 
457 static struct wpabuf * eap_aka_response_identity(struct eap_sm *sm,
458 						 struct eap_aka_data *data,
459 						 u8 id,
460 						 enum eap_sim_id_req id_req)
461 {
462 	const u8 *identity = NULL;
463 	size_t identity_len = 0;
464 	struct eap_sim_msg *msg;
465 
466 	data->reauth = 0;
467 	if (id_req == ANY_ID && data->reauth_id) {
468 		identity = data->reauth_id;
469 		identity_len = data->reauth_id_len;
470 		data->reauth = 1;
471 	} else if ((id_req == ANY_ID || id_req == FULLAUTH_ID) &&
472 		   data->pseudonym) {
473 		identity = data->pseudonym;
474 		identity_len = data->pseudonym_len;
475 		eap_aka_clear_identities(data, CLEAR_REAUTH_ID);
476 	} else if (id_req != NO_ID_REQ) {
477 		identity = eap_get_config_identity(sm, &identity_len);
478 		if (identity) {
479 			eap_aka_clear_identities(data, CLEAR_PSEUDONYM |
480 						 CLEAR_REAUTH_ID);
481 		}
482 	}
483 	if (id_req != NO_ID_REQ)
484 		eap_aka_clear_identities(data, CLEAR_EAP_ID);
485 
486 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Identity (id=%d)", id);
487 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
488 			       EAP_AKA_SUBTYPE_IDENTITY);
489 
490 	if (identity) {
491 		wpa_hexdump_ascii(MSG_DEBUG, "   AT_IDENTITY",
492 				  identity, identity_len);
493 		eap_sim_msg_add(msg, EAP_SIM_AT_IDENTITY, identity_len,
494 				identity, identity_len);
495 	}
496 
497 	return eap_sim_msg_finish(msg, NULL, NULL, 0);
498 }
499 
500 
501 static struct wpabuf * eap_aka_response_challenge(struct eap_aka_data *data,
502 						  u8 id)
503 {
504 	struct eap_sim_msg *msg;
505 
506 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Challenge (id=%d)", id);
507 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
508 			       EAP_AKA_SUBTYPE_CHALLENGE);
509 	wpa_printf(MSG_DEBUG, "   AT_RES");
510 	eap_sim_msg_add(msg, EAP_SIM_AT_RES, data->res_len * 8,
511 			data->res, data->res_len);
512 	eap_aka_add_checkcode(data, msg);
513 	if (data->use_result_ind) {
514 		wpa_printf(MSG_DEBUG, "   AT_RESULT_IND");
515 		eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
516 	}
517 	wpa_printf(MSG_DEBUG, "   AT_MAC");
518 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
519 	return eap_sim_msg_finish(msg, data->k_aut, (u8 *) "", 0);
520 }
521 
522 
523 static struct wpabuf * eap_aka_response_reauth(struct eap_aka_data *data,
524 					       u8 id, int counter_too_small,
525 					       const u8 *nonce_s)
526 {
527 	struct eap_sim_msg *msg;
528 	unsigned int counter;
529 
530 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Reauthentication (id=%d)",
531 		   id);
532 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
533 			       EAP_AKA_SUBTYPE_REAUTHENTICATION);
534 	wpa_printf(MSG_DEBUG, "   AT_IV");
535 	wpa_printf(MSG_DEBUG, "   AT_ENCR_DATA");
536 	eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, EAP_SIM_AT_ENCR_DATA);
537 
538 	if (counter_too_small) {
539 		wpa_printf(MSG_DEBUG, "   *AT_COUNTER_TOO_SMALL");
540 		eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER_TOO_SMALL, 0, NULL, 0);
541 		counter = data->counter_too_small;
542 	} else
543 		counter = data->counter;
544 
545 	wpa_printf(MSG_DEBUG, "   *AT_COUNTER %d", counter);
546 	eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, counter, NULL, 0);
547 
548 	if (eap_sim_msg_add_encr_end(msg, data->k_encr, EAP_SIM_AT_PADDING)) {
549 		wpa_printf(MSG_WARNING, "EAP-AKA: Failed to encrypt "
550 			   "AT_ENCR_DATA");
551 		eap_sim_msg_free(msg);
552 		return NULL;
553 	}
554 	eap_aka_add_checkcode(data, msg);
555 	if (data->use_result_ind) {
556 		wpa_printf(MSG_DEBUG, "   AT_RESULT_IND");
557 		eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
558 	}
559 	wpa_printf(MSG_DEBUG, "   AT_MAC");
560 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
561 	return eap_sim_msg_finish(msg, data->k_aut, nonce_s,
562 				  EAP_SIM_NONCE_S_LEN);
563 }
564 
565 
566 static struct wpabuf * eap_aka_response_notification(struct eap_aka_data *data,
567 						     u8 id, u16 notification)
568 {
569 	struct eap_sim_msg *msg;
570 	u8 *k_aut = (notification & 0x4000) == 0 ? data->k_aut : NULL;
571 
572 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Notification (id=%d)", id);
573 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
574 			       EAP_AKA_SUBTYPE_NOTIFICATION);
575 	if (k_aut && data->reauth) {
576 		wpa_printf(MSG_DEBUG, "   AT_IV");
577 		wpa_printf(MSG_DEBUG, "   AT_ENCR_DATA");
578 		eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV,
579 					   EAP_SIM_AT_ENCR_DATA);
580 		wpa_printf(MSG_DEBUG, "   *AT_COUNTER %d", data->counter);
581 		eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, data->counter,
582 				NULL, 0);
583 		if (eap_sim_msg_add_encr_end(msg, data->k_encr,
584 					     EAP_SIM_AT_PADDING)) {
585 			wpa_printf(MSG_WARNING, "EAP-AKA: Failed to encrypt "
586 				   "AT_ENCR_DATA");
587 			eap_sim_msg_free(msg);
588 			return NULL;
589 		}
590 	}
591 	if (k_aut) {
592 		wpa_printf(MSG_DEBUG, "   AT_MAC");
593 		eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
594 	}
595 	return eap_sim_msg_finish(msg, k_aut, (u8 *) "", 0);
596 }
597 
598 
599 static struct wpabuf * eap_aka_process_identity(struct eap_sm *sm,
600 						struct eap_aka_data *data,
601 						u8 id,
602 						const struct wpabuf *reqData,
603 						struct eap_sim_attrs *attr)
604 {
605 	int id_error;
606 	struct wpabuf *buf;
607 
608 	wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Identity");
609 
610 	id_error = 0;
611 	switch (attr->id_req) {
612 	case NO_ID_REQ:
613 		break;
614 	case ANY_ID:
615 		if (data->num_id_req > 0)
616 			id_error++;
617 		data->num_id_req++;
618 		break;
619 	case FULLAUTH_ID:
620 		if (data->num_id_req > 1)
621 			id_error++;
622 		data->num_id_req++;
623 		break;
624 	case PERMANENT_ID:
625 		if (data->num_id_req > 2)
626 			id_error++;
627 		data->num_id_req++;
628 		break;
629 	}
630 	if (id_error) {
631 		wpa_printf(MSG_INFO, "EAP-AKA: Too many ID requests "
632 			   "used within one authentication");
633 		return eap_aka_client_error(data, id,
634 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
635 	}
636 
637 	buf = eap_aka_response_identity(sm, data, id, attr->id_req);
638 
639 	if (data->prev_id != id) {
640 		eap_aka_add_id_msg(data, reqData);
641 		eap_aka_add_id_msg(data, buf);
642 		data->prev_id = id;
643 	}
644 
645 	return buf;
646 }
647 
648 
649 static int eap_aka_verify_mac(struct eap_aka_data *data,
650 			      const struct wpabuf *req,
651 			      const u8 *mac, const u8 *extra,
652 			      size_t extra_len)
653 {
654 	if (data->eap_method == EAP_TYPE_AKA_PRIME)
655 		return eap_sim_verify_mac_sha256(data->k_aut, req, mac, extra,
656 						 extra_len);
657 	return eap_sim_verify_mac(data->k_aut, req, mac, extra, extra_len);
658 }
659 
660 
661 #ifdef EAP_AKA_PRIME
662 static struct wpabuf * eap_aka_prime_kdf_select(struct eap_aka_data *data,
663 						u8 id, u16 kdf)
664 {
665 	struct eap_sim_msg *msg;
666 
667 	data->kdf_negotiation = 1;
668 	data->kdf = kdf;
669 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Challenge (id=%d) (KDF "
670 		   "select)", id);
671 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
672 			       EAP_AKA_SUBTYPE_CHALLENGE);
673 	wpa_printf(MSG_DEBUG, "   AT_KDF");
674 	eap_sim_msg_add(msg, EAP_SIM_AT_KDF, kdf, NULL, 0);
675 	return eap_sim_msg_finish(msg, NULL, NULL, 0);
676 }
677 
678 
679 static struct wpabuf * eap_aka_prime_kdf_neg(struct eap_aka_data *data,
680 					     u8 id, struct eap_sim_attrs *attr)
681 {
682 	size_t i;
683 
684 	for (i = 0; i < attr->kdf_count; i++) {
685 		if (attr->kdf[i] == EAP_AKA_PRIME_KDF)
686 			return eap_aka_prime_kdf_select(data, id,
687 							EAP_AKA_PRIME_KDF);
688 	}
689 
690 	/* No matching KDF found - fail authentication as if AUTN had been
691 	 * incorrect */
692 	return eap_aka_authentication_reject(data, id);
693 }
694 
695 
696 static int eap_aka_prime_kdf_valid(struct eap_aka_data *data,
697 				   struct eap_sim_attrs *attr)
698 {
699 	size_t i, j;
700 
701 	if (attr->kdf_count == 0)
702 		return 0;
703 
704 	/* The only allowed (and required) duplication of a KDF is the addition
705 	 * of the selected KDF into the beginning of the list. */
706 
707 	if (data->kdf_negotiation) {
708 		if (attr->kdf[0] != data->kdf) {
709 			wpa_printf(MSG_WARNING, "EAP-AKA': The server did not "
710 				   "accept the selected KDF");
711 			return 0;
712 		}
713 
714 		for (i = 1; i < attr->kdf_count; i++) {
715 			if (attr->kdf[i] == data->kdf)
716 				break;
717 		}
718 		if (i == attr->kdf_count &&
719 		    attr->kdf_count < EAP_AKA_PRIME_KDF_MAX) {
720 			wpa_printf(MSG_WARNING, "EAP-AKA': The server did not "
721 				   "duplicate the selected KDF");
722 			return 0;
723 		}
724 
725 		/* TODO: should check that the list is identical to the one
726 		 * used in the previous Challenge message apart from the added
727 		 * entry in the beginning. */
728 	}
729 
730 	for (i = data->kdf ? 1 : 0; i < attr->kdf_count; i++) {
731 		for (j = i + 1; j < attr->kdf_count; j++) {
732 			if (attr->kdf[i] == attr->kdf[j]) {
733 				wpa_printf(MSG_WARNING, "EAP-AKA': The server "
734 					   "included a duplicated KDF");
735 				return 0;
736 			}
737 		}
738 	}
739 
740 	return 1;
741 }
742 #endif /* EAP_AKA_PRIME */
743 
744 
745 static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm,
746 						 struct eap_aka_data *data,
747 						 u8 id,
748 						 const struct wpabuf *reqData,
749 						 struct eap_sim_attrs *attr)
750 {
751 	const u8 *identity;
752 	size_t identity_len;
753 	int res;
754 	struct eap_sim_attrs eattr;
755 
756 	wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Challenge");
757 
758 	if (attr->checkcode &&
759 	    eap_aka_verify_checkcode(data, attr->checkcode,
760 				     attr->checkcode_len)) {
761 		wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the "
762 			   "message");
763 		return eap_aka_client_error(data, id,
764 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
765 	}
766 
767 #ifdef EAP_AKA_PRIME
768 	if (data->eap_method == EAP_TYPE_AKA_PRIME) {
769 		if (!attr->kdf_input || attr->kdf_input_len == 0) {
770 			wpa_printf(MSG_WARNING, "EAP-AKA': Challenge message "
771 				   "did not include non-empty AT_KDF_INPUT");
772 			/* Fail authentication as if AUTN had been incorrect */
773 			return eap_aka_authentication_reject(data, id);
774 		}
775 		os_free(data->network_name);
776 		data->network_name = os_malloc(attr->kdf_input_len);
777 		if (data->network_name == NULL) {
778 			wpa_printf(MSG_WARNING, "EAP-AKA': No memory for "
779 				   "storing Network Name");
780 			return eap_aka_authentication_reject(data, id);
781 		}
782 		os_memcpy(data->network_name, attr->kdf_input,
783 			  attr->kdf_input_len);
784 		data->network_name_len = attr->kdf_input_len;
785 		wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA': Network Name "
786 				  "(AT_KDF_INPUT)",
787 				  data->network_name, data->network_name_len);
788 		/* TODO: check Network Name per 3GPP.33.402 */
789 
790 		if (!eap_aka_prime_kdf_valid(data, attr))
791 			return eap_aka_authentication_reject(data, id);
792 
793 		if (attr->kdf[0] != EAP_AKA_PRIME_KDF)
794 			return eap_aka_prime_kdf_neg(data, id, attr);
795 
796 		data->kdf = EAP_AKA_PRIME_KDF;
797 		wpa_printf(MSG_DEBUG, "EAP-AKA': KDF %d selected", data->kdf);
798 	}
799 
800 	if (data->eap_method == EAP_TYPE_AKA && attr->bidding) {
801 		u16 flags = WPA_GET_BE16(attr->bidding);
802 		if ((flags & EAP_AKA_BIDDING_FLAG_D) &&
803 		    eap_allowed_method(sm, EAP_VENDOR_IETF,
804 				       EAP_TYPE_AKA_PRIME)) {
805 			wpa_printf(MSG_WARNING, "EAP-AKA: Bidding down from "
806 				   "AKA' to AKA detected");
807 			/* Fail authentication as if AUTN had been incorrect */
808 			return eap_aka_authentication_reject(data, id);
809 		}
810 	}
811 #endif /* EAP_AKA_PRIME */
812 
813 	data->reauth = 0;
814 	if (!attr->mac || !attr->rand || !attr->autn) {
815 		wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
816 			   "did not include%s%s%s",
817 			   !attr->mac ? " AT_MAC" : "",
818 			   !attr->rand ? " AT_RAND" : "",
819 			   !attr->autn ? " AT_AUTN" : "");
820 		return eap_aka_client_error(data, id,
821 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
822 	}
823 	os_memcpy(data->rand, attr->rand, EAP_AKA_RAND_LEN);
824 	os_memcpy(data->autn, attr->autn, EAP_AKA_AUTN_LEN);
825 
826 	res = eap_aka_umts_auth(sm, data);
827 	if (res == -1) {
828 		wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication "
829 			   "failed (AUTN)");
830 		return eap_aka_authentication_reject(data, id);
831 	} else if (res == -2) {
832 		wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication "
833 			   "failed (AUTN seq# -> AUTS)");
834 		return eap_aka_synchronization_failure(data, id);
835 	} else if (res) {
836 		wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication failed");
837 		return eap_aka_client_error(data, id,
838 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
839 	}
840 #ifdef EAP_AKA_PRIME
841 	if (data->eap_method == EAP_TYPE_AKA_PRIME) {
842 		/* Note: AUTN = (SQN ^ AK) || AMF || MAC which gives us the
843 		 * needed 6-octet SQN ^ AK for CK',IK' derivation */
844 		u16 amf = WPA_GET_BE16(data->autn + 6);
845 		if (!(amf & 0x8000)) {
846 			wpa_printf(MSG_WARNING, "EAP-AKA': AMF separation bit "
847 				   "not set (AMF=0x%4x)", amf);
848 			return eap_aka_authentication_reject(data, id);
849 		}
850 		eap_aka_prime_derive_ck_ik_prime(data->ck, data->ik,
851 						 data->autn,
852 						 data->network_name,
853 						 data->network_name_len);
854 	}
855 #endif /* EAP_AKA_PRIME */
856 	if (data->last_eap_identity) {
857 		identity = data->last_eap_identity;
858 		identity_len = data->last_eap_identity_len;
859 	} else if (data->pseudonym) {
860 		identity = data->pseudonym;
861 		identity_len = data->pseudonym_len;
862 	} else
863 		identity = eap_get_config_identity(sm, &identity_len);
864 	wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Selected identity for MK "
865 			  "derivation", identity, identity_len);
866 	if (data->eap_method == EAP_TYPE_AKA_PRIME) {
867 		eap_aka_prime_derive_keys(identity, identity_len, data->ik,
868 					  data->ck, data->k_encr, data->k_aut,
869 					  data->k_re, data->msk, data->emsk);
870 	} else {
871 		eap_aka_derive_mk(identity, identity_len, data->ik, data->ck,
872 				  data->mk);
873 		eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut,
874 				    data->msk, data->emsk);
875 	}
876 	if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) {
877 		wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
878 			   "used invalid AT_MAC");
879 		return eap_aka_client_error(data, id,
880 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
881 	}
882 
883 	/* Old reauthentication and pseudonym identities must not be used
884 	 * anymore. In other words, if no new identities are received, full
885 	 * authentication will be used on next reauthentication. */
886 	eap_aka_clear_identities(data, CLEAR_PSEUDONYM | CLEAR_REAUTH_ID |
887 				 CLEAR_EAP_ID);
888 
889 	if (attr->encr_data) {
890 		u8 *decrypted;
891 		decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
892 					       attr->encr_data_len, attr->iv,
893 					       &eattr, 0);
894 		if (decrypted == NULL) {
895 			return eap_aka_client_error(
896 				data, id, EAP_AKA_UNABLE_TO_PROCESS_PACKET);
897 		}
898 		eap_aka_learn_ids(data, &eattr);
899 		os_free(decrypted);
900 	}
901 
902 	if (data->result_ind && attr->result_ind)
903 		data->use_result_ind = 1;
904 
905 	if (data->state != FAILURE && data->state != RESULT_FAILURE) {
906 		eap_aka_state(data, data->use_result_ind ?
907 			      RESULT_SUCCESS : SUCCESS);
908 	}
909 
910 	data->num_id_req = 0;
911 	data->num_notification = 0;
912 	/* RFC 4187 specifies that counter is initialized to one after
913 	 * fullauth, but initializing it to zero makes it easier to implement
914 	 * reauth verification. */
915 	data->counter = 0;
916 	return eap_aka_response_challenge(data, id);
917 }
918 
919 
920 static int eap_aka_process_notification_reauth(struct eap_aka_data *data,
921 					       struct eap_sim_attrs *attr)
922 {
923 	struct eap_sim_attrs eattr;
924 	u8 *decrypted;
925 
926 	if (attr->encr_data == NULL || attr->iv == NULL) {
927 		wpa_printf(MSG_WARNING, "EAP-AKA: Notification message after "
928 			   "reauth did not include encrypted data");
929 		return -1;
930 	}
931 
932 	decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
933 				       attr->encr_data_len, attr->iv, &eattr,
934 				       0);
935 	if (decrypted == NULL) {
936 		wpa_printf(MSG_WARNING, "EAP-AKA: Failed to parse encrypted "
937 			   "data from notification message");
938 		return -1;
939 	}
940 
941 	if (eattr.counter < 0 || (size_t) eattr.counter != data->counter) {
942 		wpa_printf(MSG_WARNING, "EAP-AKA: Counter in notification "
943 			   "message does not match with counter in reauth "
944 			   "message");
945 		os_free(decrypted);
946 		return -1;
947 	}
948 
949 	os_free(decrypted);
950 	return 0;
951 }
952 
953 
954 static int eap_aka_process_notification_auth(struct eap_aka_data *data,
955 					     const struct wpabuf *reqData,
956 					     struct eap_sim_attrs *attr)
957 {
958 	if (attr->mac == NULL) {
959 		wpa_printf(MSG_INFO, "EAP-AKA: no AT_MAC in after_auth "
960 			   "Notification message");
961 		return -1;
962 	}
963 
964 	if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) {
965 		wpa_printf(MSG_WARNING, "EAP-AKA: Notification message "
966 			   "used invalid AT_MAC");
967 		return -1;
968 	}
969 
970 	if (data->reauth &&
971 	    eap_aka_process_notification_reauth(data, attr)) {
972 		wpa_printf(MSG_WARNING, "EAP-AKA: Invalid notification "
973 			   "message after reauth");
974 		return -1;
975 	}
976 
977 	return 0;
978 }
979 
980 
981 static struct wpabuf * eap_aka_process_notification(
982 	struct eap_sm *sm, struct eap_aka_data *data, u8 id,
983 	const struct wpabuf *reqData, struct eap_sim_attrs *attr)
984 {
985 	wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Notification");
986 	if (data->num_notification > 0) {
987 		wpa_printf(MSG_INFO, "EAP-AKA: too many notification "
988 			   "rounds (only one allowed)");
989 		return eap_aka_client_error(data, id,
990 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
991 	}
992 	data->num_notification++;
993 	if (attr->notification == -1) {
994 		wpa_printf(MSG_INFO, "EAP-AKA: no AT_NOTIFICATION in "
995 			   "Notification message");
996 		return eap_aka_client_error(data, id,
997 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
998 	}
999 
1000 	if ((attr->notification & 0x4000) == 0 &&
1001 	    eap_aka_process_notification_auth(data, reqData, attr)) {
1002 		return eap_aka_client_error(data, id,
1003 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1004 	}
1005 
1006 	eap_sim_report_notification(sm->msg_ctx, attr->notification, 1);
1007 	if (attr->notification >= 0 && attr->notification < 32768) {
1008 		eap_aka_state(data, FAILURE);
1009 	} else if (attr->notification == EAP_SIM_SUCCESS &&
1010 		   data->state == RESULT_SUCCESS)
1011 		eap_aka_state(data, SUCCESS);
1012 	return eap_aka_response_notification(data, id, attr->notification);
1013 }
1014 
1015 
1016 static struct wpabuf * eap_aka_process_reauthentication(
1017 	struct eap_sm *sm, struct eap_aka_data *data, u8 id,
1018 	const struct wpabuf *reqData, struct eap_sim_attrs *attr)
1019 {
1020 	struct eap_sim_attrs eattr;
1021 	u8 *decrypted;
1022 
1023 	wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Reauthentication");
1024 
1025 	if (attr->checkcode &&
1026 	    eap_aka_verify_checkcode(data, attr->checkcode,
1027 				     attr->checkcode_len)) {
1028 		wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the "
1029 			   "message");
1030 		return eap_aka_client_error(data, id,
1031 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1032 	}
1033 
1034 	if (data->reauth_id == NULL) {
1035 		wpa_printf(MSG_WARNING, "EAP-AKA: Server is trying "
1036 			   "reauthentication, but no reauth_id available");
1037 		return eap_aka_client_error(data, id,
1038 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1039 	}
1040 
1041 	data->reauth = 1;
1042 	if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) {
1043 		wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication "
1044 			   "did not have valid AT_MAC");
1045 		return eap_aka_client_error(data, id,
1046 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1047 	}
1048 
1049 	if (attr->encr_data == NULL || attr->iv == NULL) {
1050 		wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication "
1051 			   "message did not include encrypted data");
1052 		return eap_aka_client_error(data, id,
1053 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1054 	}
1055 
1056 	decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
1057 				       attr->encr_data_len, attr->iv, &eattr,
1058 				       0);
1059 	if (decrypted == NULL) {
1060 		wpa_printf(MSG_WARNING, "EAP-AKA: Failed to parse encrypted "
1061 			   "data from reauthentication message");
1062 		return eap_aka_client_error(data, id,
1063 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1064 	}
1065 
1066 	if (eattr.nonce_s == NULL || eattr.counter < 0) {
1067 		wpa_printf(MSG_INFO, "EAP-AKA: (encr) No%s%s in reauth packet",
1068 			   !eattr.nonce_s ? " AT_NONCE_S" : "",
1069 			   eattr.counter < 0 ? " AT_COUNTER" : "");
1070 		os_free(decrypted);
1071 		return eap_aka_client_error(data, id,
1072 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1073 	}
1074 
1075 	if (eattr.counter < 0 || (size_t) eattr.counter <= data->counter) {
1076 		struct wpabuf *res;
1077 		wpa_printf(MSG_INFO, "EAP-AKA: (encr) Invalid counter "
1078 			   "(%d <= %d)", eattr.counter, data->counter);
1079 		data->counter_too_small = eattr.counter;
1080 
1081 		/* Reply using Re-auth w/ AT_COUNTER_TOO_SMALL. The current
1082 		 * reauth_id must not be used to start a new reauthentication.
1083 		 * However, since it was used in the last EAP-Response-Identity
1084 		 * packet, it has to saved for the following fullauth to be
1085 		 * used in MK derivation. */
1086 		os_free(data->last_eap_identity);
1087 		data->last_eap_identity = data->reauth_id;
1088 		data->last_eap_identity_len = data->reauth_id_len;
1089 		data->reauth_id = NULL;
1090 		data->reauth_id_len = 0;
1091 
1092 		res = eap_aka_response_reauth(data, id, 1, eattr.nonce_s);
1093 		os_free(decrypted);
1094 
1095 		return res;
1096 	}
1097 	data->counter = eattr.counter;
1098 
1099 	os_memcpy(data->nonce_s, eattr.nonce_s, EAP_SIM_NONCE_S_LEN);
1100 	wpa_hexdump(MSG_DEBUG, "EAP-AKA: (encr) AT_NONCE_S",
1101 		    data->nonce_s, EAP_SIM_NONCE_S_LEN);
1102 
1103 	if (data->eap_method == EAP_TYPE_AKA_PRIME) {
1104 		eap_aka_prime_derive_keys_reauth(data->k_re, data->counter,
1105 						 data->reauth_id,
1106 						 data->reauth_id_len,
1107 						 data->nonce_s,
1108 						 data->msk, data->emsk);
1109 	} else {
1110 		eap_sim_derive_keys_reauth(data->counter, data->reauth_id,
1111 					   data->reauth_id_len,
1112 					   data->nonce_s, data->mk,
1113 					   data->msk, data->emsk);
1114 	}
1115 	eap_aka_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
1116 	eap_aka_learn_ids(data, &eattr);
1117 
1118 	if (data->result_ind && attr->result_ind)
1119 		data->use_result_ind = 1;
1120 
1121 	if (data->state != FAILURE && data->state != RESULT_FAILURE) {
1122 		eap_aka_state(data, data->use_result_ind ?
1123 			      RESULT_SUCCESS : SUCCESS);
1124 	}
1125 
1126 	data->num_id_req = 0;
1127 	data->num_notification = 0;
1128 	if (data->counter > EAP_AKA_MAX_FAST_REAUTHS) {
1129 		wpa_printf(MSG_DEBUG, "EAP-AKA: Maximum number of "
1130 			   "fast reauths performed - force fullauth");
1131 		eap_aka_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
1132 	}
1133 	os_free(decrypted);
1134 	return eap_aka_response_reauth(data, id, 0, data->nonce_s);
1135 }
1136 
1137 
1138 static struct wpabuf * eap_aka_process(struct eap_sm *sm, void *priv,
1139 				       struct eap_method_ret *ret,
1140 				       const struct wpabuf *reqData)
1141 {
1142 	struct eap_aka_data *data = priv;
1143 	const struct eap_hdr *req;
1144 	u8 subtype, id;
1145 	struct wpabuf *res;
1146 	const u8 *pos;
1147 	struct eap_sim_attrs attr;
1148 	size_t len;
1149 
1150 	wpa_hexdump_buf(MSG_DEBUG, "EAP-AKA: EAP data", reqData);
1151 	if (eap_get_config_identity(sm, &len) == NULL) {
1152 		wpa_printf(MSG_INFO, "EAP-AKA: Identity not configured");
1153 		eap_sm_request_identity(sm);
1154 		ret->ignore = TRUE;
1155 		return NULL;
1156 	}
1157 
1158 	pos = eap_hdr_validate(EAP_VENDOR_IETF, data->eap_method, reqData,
1159 			       &len);
1160 	if (pos == NULL || len < 1) {
1161 		ret->ignore = TRUE;
1162 		return NULL;
1163 	}
1164 	req = wpabuf_head(reqData);
1165 	id = req->identifier;
1166 	len = be_to_host16(req->length);
1167 
1168 	ret->ignore = FALSE;
1169 	ret->methodState = METHOD_MAY_CONT;
1170 	ret->decision = DECISION_FAIL;
1171 	ret->allowNotifications = TRUE;
1172 
1173 	subtype = *pos++;
1174 	wpa_printf(MSG_DEBUG, "EAP-AKA: Subtype=%d", subtype);
1175 	pos += 2; /* Reserved */
1176 
1177 	if (eap_sim_parse_attr(pos, wpabuf_head_u8(reqData) + len, &attr,
1178 			       data->eap_method == EAP_TYPE_AKA_PRIME ? 2 : 1,
1179 			       0)) {
1180 		res = eap_aka_client_error(data, id,
1181 					   EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1182 		goto done;
1183 	}
1184 
1185 	switch (subtype) {
1186 	case EAP_AKA_SUBTYPE_IDENTITY:
1187 		res = eap_aka_process_identity(sm, data, id, reqData, &attr);
1188 		break;
1189 	case EAP_AKA_SUBTYPE_CHALLENGE:
1190 		res = eap_aka_process_challenge(sm, data, id, reqData, &attr);
1191 		break;
1192 	case EAP_AKA_SUBTYPE_NOTIFICATION:
1193 		res = eap_aka_process_notification(sm, data, id, reqData,
1194 						   &attr);
1195 		break;
1196 	case EAP_AKA_SUBTYPE_REAUTHENTICATION:
1197 		res = eap_aka_process_reauthentication(sm, data, id, reqData,
1198 						       &attr);
1199 		break;
1200 	case EAP_AKA_SUBTYPE_CLIENT_ERROR:
1201 		wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Client-Error");
1202 		res = eap_aka_client_error(data, id,
1203 					   EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1204 		break;
1205 	default:
1206 		wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown subtype=%d", subtype);
1207 		res = eap_aka_client_error(data, id,
1208 					   EAP_AKA_UNABLE_TO_PROCESS_PACKET);
1209 		break;
1210 	}
1211 
1212 done:
1213 	if (data->state == FAILURE) {
1214 		ret->decision = DECISION_FAIL;
1215 		ret->methodState = METHOD_DONE;
1216 	} else if (data->state == SUCCESS) {
1217 		ret->decision = data->use_result_ind ?
1218 			DECISION_UNCOND_SUCC : DECISION_COND_SUCC;
1219 		/*
1220 		 * It is possible for the server to reply with AKA
1221 		 * Notification, so we must allow the method to continue and
1222 		 * not only accept EAP-Success at this point.
1223 		 */
1224 		ret->methodState = data->use_result_ind ?
1225 			METHOD_DONE : METHOD_MAY_CONT;
1226 	} else if (data->state == RESULT_FAILURE)
1227 		ret->methodState = METHOD_CONT;
1228 	else if (data->state == RESULT_SUCCESS)
1229 		ret->methodState = METHOD_CONT;
1230 
1231 	if (ret->methodState == METHOD_DONE) {
1232 		ret->allowNotifications = FALSE;
1233 	}
1234 
1235 	return res;
1236 }
1237 
1238 
1239 static Boolean eap_aka_has_reauth_data(struct eap_sm *sm, void *priv)
1240 {
1241 	struct eap_aka_data *data = priv;
1242 	return data->pseudonym || data->reauth_id;
1243 }
1244 
1245 
1246 static void eap_aka_deinit_for_reauth(struct eap_sm *sm, void *priv)
1247 {
1248 	struct eap_aka_data *data = priv;
1249 	eap_aka_clear_identities(data, CLEAR_EAP_ID);
1250 	data->prev_id = -1;
1251 	wpabuf_free(data->id_msgs);
1252 	data->id_msgs = NULL;
1253 	data->use_result_ind = 0;
1254 	data->kdf_negotiation = 0;
1255 }
1256 
1257 
1258 static void * eap_aka_init_for_reauth(struct eap_sm *sm, void *priv)
1259 {
1260 	struct eap_aka_data *data = priv;
1261 	data->num_id_req = 0;
1262 	data->num_notification = 0;
1263 	eap_aka_state(data, CONTINUE);
1264 	return priv;
1265 }
1266 
1267 
1268 static const u8 * eap_aka_get_identity(struct eap_sm *sm, void *priv,
1269 				       size_t *len)
1270 {
1271 	struct eap_aka_data *data = priv;
1272 
1273 	if (data->reauth_id) {
1274 		*len = data->reauth_id_len;
1275 		return data->reauth_id;
1276 	}
1277 
1278 	if (data->pseudonym) {
1279 		*len = data->pseudonym_len;
1280 		return data->pseudonym;
1281 	}
1282 
1283 	return NULL;
1284 }
1285 
1286 
1287 static Boolean eap_aka_isKeyAvailable(struct eap_sm *sm, void *priv)
1288 {
1289 	struct eap_aka_data *data = priv;
1290 	return data->state == SUCCESS;
1291 }
1292 
1293 
1294 static u8 * eap_aka_getKey(struct eap_sm *sm, void *priv, size_t *len)
1295 {
1296 	struct eap_aka_data *data = priv;
1297 	u8 *key;
1298 
1299 	if (data->state != SUCCESS)
1300 		return NULL;
1301 
1302 	key = os_malloc(EAP_SIM_KEYING_DATA_LEN);
1303 	if (key == NULL)
1304 		return NULL;
1305 
1306 	*len = EAP_SIM_KEYING_DATA_LEN;
1307 	os_memcpy(key, data->msk, EAP_SIM_KEYING_DATA_LEN);
1308 
1309 	return key;
1310 }
1311 
1312 
1313 static u8 * eap_aka_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
1314 {
1315 	struct eap_aka_data *data = priv;
1316 	u8 *key;
1317 
1318 	if (data->state != SUCCESS)
1319 		return NULL;
1320 
1321 	key = os_malloc(EAP_EMSK_LEN);
1322 	if (key == NULL)
1323 		return NULL;
1324 
1325 	*len = EAP_EMSK_LEN;
1326 	os_memcpy(key, data->emsk, EAP_EMSK_LEN);
1327 
1328 	return key;
1329 }
1330 
1331 
1332 int eap_peer_aka_register(void)
1333 {
1334 	struct eap_method *eap;
1335 	int ret;
1336 
1337 	eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
1338 				    EAP_VENDOR_IETF, EAP_TYPE_AKA, "AKA");
1339 	if (eap == NULL)
1340 		return -1;
1341 
1342 	eap->init = eap_aka_init;
1343 	eap->deinit = eap_aka_deinit;
1344 	eap->process = eap_aka_process;
1345 	eap->isKeyAvailable = eap_aka_isKeyAvailable;
1346 	eap->getKey = eap_aka_getKey;
1347 	eap->has_reauth_data = eap_aka_has_reauth_data;
1348 	eap->deinit_for_reauth = eap_aka_deinit_for_reauth;
1349 	eap->init_for_reauth = eap_aka_init_for_reauth;
1350 	eap->get_identity = eap_aka_get_identity;
1351 	eap->get_emsk = eap_aka_get_emsk;
1352 
1353 	ret = eap_peer_method_register(eap);
1354 	if (ret)
1355 		eap_peer_method_free(eap);
1356 	return ret;
1357 }
1358 
1359 
1360 #ifdef EAP_AKA_PRIME
1361 int eap_peer_aka_prime_register(void)
1362 {
1363 	struct eap_method *eap;
1364 	int ret;
1365 
1366 	eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
1367 				    EAP_VENDOR_IETF, EAP_TYPE_AKA_PRIME,
1368 				    "AKA'");
1369 	if (eap == NULL)
1370 		return -1;
1371 
1372 	eap->init = eap_aka_prime_init;
1373 	eap->deinit = eap_aka_deinit;
1374 	eap->process = eap_aka_process;
1375 	eap->isKeyAvailable = eap_aka_isKeyAvailable;
1376 	eap->getKey = eap_aka_getKey;
1377 	eap->has_reauth_data = eap_aka_has_reauth_data;
1378 	eap->deinit_for_reauth = eap_aka_deinit_for_reauth;
1379 	eap->init_for_reauth = eap_aka_init_for_reauth;
1380 	eap->get_identity = eap_aka_get_identity;
1381 	eap->get_emsk = eap_aka_get_emsk;
1382 
1383 	ret = eap_peer_method_register(eap);
1384 	if (ret)
1385 		eap_peer_method_free(eap);
1386 
1387 	return ret;
1388 }
1389 #endif /* EAP_AKA_PRIME */
1390