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