xref: /netbsd-src/external/bsd/wpa/dist/src/eap_peer/eap_sim.c (revision ba65fde2d7fefa7d39838fa5fa855e62bd606b5e)
1 /*
2  * EAP peer method: EAP-SIM (RFC 4186)
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/milenage.h"
20 #include "crypto/random.h"
21 #include "eap_peer/eap_i.h"
22 #include "eap_config.h"
23 #include "eap_common/eap_sim_common.h"
24 
25 
26 struct eap_sim_data {
27 	u8 *ver_list;
28 	size_t ver_list_len;
29 	int selected_version;
30 	size_t min_num_chal, num_chal;
31 
32 	u8 kc[3][EAP_SIM_KC_LEN];
33 	u8 sres[3][EAP_SIM_SRES_LEN];
34 	u8 nonce_mt[EAP_SIM_NONCE_MT_LEN], nonce_s[EAP_SIM_NONCE_S_LEN];
35 	u8 mk[EAP_SIM_MK_LEN];
36 	u8 k_aut[EAP_SIM_K_AUT_LEN];
37 	u8 k_encr[EAP_SIM_K_ENCR_LEN];
38 	u8 msk[EAP_SIM_KEYING_DATA_LEN];
39 	u8 emsk[EAP_EMSK_LEN];
40 	u8 rand[3][GSM_RAND_LEN];
41 
42 	int num_id_req, num_notification;
43 	u8 *pseudonym;
44 	size_t pseudonym_len;
45 	u8 *reauth_id;
46 	size_t reauth_id_len;
47 	int reauth;
48 	unsigned int counter, counter_too_small;
49 	u8 *last_eap_identity;
50 	size_t last_eap_identity_len;
51 	enum {
52 		CONTINUE, RESULT_SUCCESS, RESULT_FAILURE, SUCCESS, FAILURE
53 	} state;
54 	int result_ind, use_result_ind;
55 };
56 
57 
58 #ifndef CONFIG_NO_STDOUT_DEBUG
59 static const char * eap_sim_state_txt(int state)
60 {
61 	switch (state) {
62 	case CONTINUE:
63 		return "CONTINUE";
64 	case RESULT_SUCCESS:
65 		return "RESULT_SUCCESS";
66 	case RESULT_FAILURE:
67 		return "RESULT_FAILURE";
68 	case SUCCESS:
69 		return "SUCCESS";
70 	case FAILURE:
71 		return "FAILURE";
72 	default:
73 		return "?";
74 	}
75 }
76 #endif /* CONFIG_NO_STDOUT_DEBUG */
77 
78 
79 static void eap_sim_state(struct eap_sim_data *data, int state)
80 {
81 	wpa_printf(MSG_DEBUG, "EAP-SIM: %s -> %s",
82 		   eap_sim_state_txt(data->state),
83 		   eap_sim_state_txt(state));
84 	data->state = state;
85 }
86 
87 
88 static void * eap_sim_init(struct eap_sm *sm)
89 {
90 	struct eap_sim_data *data;
91 	struct eap_peer_config *config = eap_get_config(sm);
92 
93 	data = os_zalloc(sizeof(*data));
94 	if (data == NULL)
95 		return NULL;
96 
97 	if (random_get_bytes(data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) {
98 		wpa_printf(MSG_WARNING, "EAP-SIM: Failed to get random data "
99 			   "for NONCE_MT");
100 		os_free(data);
101 		return NULL;
102 	}
103 
104 	data->min_num_chal = 2;
105 	if (config && config->phase1) {
106 		char *pos = os_strstr(config->phase1, "sim_min_num_chal=");
107 		if (pos) {
108 			data->min_num_chal = atoi(pos + 17);
109 			if (data->min_num_chal < 2 || data->min_num_chal > 3) {
110 				wpa_printf(MSG_WARNING, "EAP-SIM: Invalid "
111 					   "sim_min_num_chal configuration "
112 					   "(%lu, expected 2 or 3)",
113 					   (unsigned long) data->min_num_chal);
114 				os_free(data);
115 				return NULL;
116 			}
117 			wpa_printf(MSG_DEBUG, "EAP-SIM: Set minimum number of "
118 				   "challenges to %lu",
119 				   (unsigned long) data->min_num_chal);
120 		}
121 
122 		data->result_ind = os_strstr(config->phase1, "result_ind=1") !=
123 			NULL;
124 	}
125 
126 	eap_sim_state(data, CONTINUE);
127 
128 	return data;
129 }
130 
131 
132 static void eap_sim_deinit(struct eap_sm *sm, void *priv)
133 {
134 	struct eap_sim_data *data = priv;
135 	if (data) {
136 		os_free(data->ver_list);
137 		os_free(data->pseudonym);
138 		os_free(data->reauth_id);
139 		os_free(data->last_eap_identity);
140 		os_free(data);
141 	}
142 }
143 
144 
145 static int eap_sim_gsm_auth(struct eap_sm *sm, struct eap_sim_data *data)
146 {
147 	struct eap_peer_config *conf;
148 
149 	wpa_printf(MSG_DEBUG, "EAP-SIM: GSM authentication algorithm");
150 
151 	conf = eap_get_config(sm);
152 	if (conf == NULL)
153 		return -1;
154 	if (conf->pcsc) {
155 		if (scard_gsm_auth(sm->scard_ctx, data->rand[0],
156 				   data->sres[0], data->kc[0]) ||
157 		    scard_gsm_auth(sm->scard_ctx, data->rand[1],
158 				   data->sres[1], data->kc[1]) ||
159 		    (data->num_chal > 2 &&
160 		     scard_gsm_auth(sm->scard_ctx, data->rand[2],
161 				    data->sres[2], data->kc[2]))) {
162 			wpa_printf(MSG_DEBUG, "EAP-SIM: GSM SIM "
163 				   "authentication could not be completed");
164 			return -1;
165 		}
166 		return 0;
167 	}
168 
169 #ifdef CONFIG_SIM_SIMULATOR
170 	if (conf->password) {
171 		u8 opc[16], k[16];
172 		const char *pos;
173 		size_t i;
174 		wpa_printf(MSG_DEBUG, "EAP-SIM: Use internal GSM-Milenage "
175 			   "implementation for authentication");
176 		if (conf->password_len < 65) {
177 			wpa_printf(MSG_DEBUG, "EAP-SIM: invalid GSM-Milenage "
178 				   "password");
179 			return -1;
180 		}
181 		pos = (const char *) conf->password;
182 		if (hexstr2bin(pos, k, 16))
183 			return -1;
184 		pos += 32;
185 		if (*pos != ':')
186 			return -1;
187 		pos++;
188 
189 		if (hexstr2bin(pos, opc, 16))
190 			return -1;
191 
192 		for (i = 0; i < data->num_chal; i++) {
193 			if (gsm_milenage(opc, k, data->rand[i],
194 					 data->sres[i], data->kc[i])) {
195 				wpa_printf(MSG_DEBUG, "EAP-SIM: "
196 					   "GSM-Milenage authentication "
197 					   "could not be completed");
198 				return -1;
199 			}
200 			wpa_hexdump(MSG_DEBUG, "EAP-SIM: RAND",
201 				    data->rand[i], GSM_RAND_LEN);
202 			wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: SRES",
203 					data->sres[i], EAP_SIM_SRES_LEN);
204 			wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: Kc",
205 					data->kc[i], EAP_SIM_KC_LEN);
206 		}
207 		return 0;
208 	}
209 #endif /* CONFIG_SIM_SIMULATOR */
210 
211 #ifdef CONFIG_SIM_HARDCODED
212 	/* These hardcoded Kc and SRES values are used for testing. RAND to
213 	 * KC/SREC mapping is very bogus as far as real authentication is
214 	 * concerned, but it is quite useful for cases where the AS is rotating
215 	 * the order of pre-configured values. */
216 	{
217 		size_t i;
218 
219 		wpa_printf(MSG_DEBUG, "EAP-SIM: Use hardcoded Kc and SRES "
220 			   "values for testing");
221 
222 		for (i = 0; i < data->num_chal; i++) {
223 			if (data->rand[i][0] == 0xaa) {
224 				os_memcpy(data->kc[i],
225 					  "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7",
226 					  EAP_SIM_KC_LEN);
227 				os_memcpy(data->sres[i], "\xd1\xd2\xd3\xd4",
228 					  EAP_SIM_SRES_LEN);
229 			} else if (data->rand[i][0] == 0xbb) {
230 				os_memcpy(data->kc[i],
231 					  "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7",
232 					  EAP_SIM_KC_LEN);
233 				os_memcpy(data->sres[i], "\xe1\xe2\xe3\xe4",
234 					  EAP_SIM_SRES_LEN);
235 			} else {
236 				os_memcpy(data->kc[i],
237 					  "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7",
238 					  EAP_SIM_KC_LEN);
239 				os_memcpy(data->sres[i], "\xf1\xf2\xf3\xf4",
240 					  EAP_SIM_SRES_LEN);
241 			}
242 		}
243 	}
244 
245 	return 0;
246 
247 #else /* CONFIG_SIM_HARDCODED */
248 
249 	wpa_printf(MSG_DEBUG, "EAP-SIM: No GSM authentication algorithm "
250 		   "enabled");
251 	return -1;
252 
253 #endif /* CONFIG_SIM_HARDCODED */
254 }
255 
256 
257 static int eap_sim_supported_ver(int version)
258 {
259 	return version == EAP_SIM_VERSION;
260 }
261 
262 
263 #define CLEAR_PSEUDONYM	0x01
264 #define CLEAR_REAUTH_ID	0x02
265 #define CLEAR_EAP_ID	0x04
266 
267 static void eap_sim_clear_identities(struct eap_sim_data *data, int id)
268 {
269 	if ((id & CLEAR_PSEUDONYM) && data->pseudonym) {
270 		wpa_printf(MSG_DEBUG, "EAP-SIM: forgetting old pseudonym");
271 		os_free(data->pseudonym);
272 		data->pseudonym = NULL;
273 		data->pseudonym_len = 0;
274 	}
275 	if ((id & CLEAR_REAUTH_ID) && data->reauth_id) {
276 		wpa_printf(MSG_DEBUG, "EAP-SIM: forgetting old reauth_id");
277 		os_free(data->reauth_id);
278 		data->reauth_id = NULL;
279 		data->reauth_id_len = 0;
280 	}
281 	if ((id & CLEAR_EAP_ID) && data->last_eap_identity) {
282 		wpa_printf(MSG_DEBUG, "EAP-SIM: forgetting old eap_id");
283 		os_free(data->last_eap_identity);
284 		data->last_eap_identity = NULL;
285 		data->last_eap_identity_len = 0;
286 	}
287 }
288 
289 
290 static int eap_sim_learn_ids(struct eap_sm *sm, struct eap_sim_data *data,
291 			     struct eap_sim_attrs *attr)
292 {
293 	if (attr->next_pseudonym) {
294 		const u8 *identity = NULL;
295 		size_t identity_len = 0;
296 		const u8 *realm = NULL;
297 		size_t realm_len = 0;
298 
299 		wpa_hexdump_ascii(MSG_DEBUG,
300 				  "EAP-SIM: (encr) AT_NEXT_PSEUDONYM",
301 				  attr->next_pseudonym,
302 				  attr->next_pseudonym_len);
303 		os_free(data->pseudonym);
304 		/* Look for the realm of the permanent identity */
305 		identity = eap_get_config_identity(sm, &identity_len);
306 		if (identity) {
307 			for (realm = identity, realm_len = identity_len;
308 			     realm_len > 0; realm_len--, realm++) {
309 				if (*realm == '@')
310 					break;
311 			}
312 		}
313 		data->pseudonym = os_malloc(attr->next_pseudonym_len +
314 					    realm_len);
315 		if (data->pseudonym == NULL) {
316 			wpa_printf(MSG_INFO, "EAP-SIM: (encr) No memory for "
317 				   "next pseudonym");
318 			data->pseudonym_len = 0;
319 			return -1;
320 		}
321 		os_memcpy(data->pseudonym, attr->next_pseudonym,
322 			  attr->next_pseudonym_len);
323 		if (realm_len) {
324 			os_memcpy(data->pseudonym + attr->next_pseudonym_len,
325 				  realm, realm_len);
326 		}
327 		data->pseudonym_len = attr->next_pseudonym_len + realm_len;
328 	}
329 
330 	if (attr->next_reauth_id) {
331 		os_free(data->reauth_id);
332 		data->reauth_id = os_malloc(attr->next_reauth_id_len);
333 		if (data->reauth_id == NULL) {
334 			wpa_printf(MSG_INFO, "EAP-SIM: (encr) No memory for "
335 				   "next reauth_id");
336 			data->reauth_id_len = 0;
337 			return -1;
338 		}
339 		os_memcpy(data->reauth_id, attr->next_reauth_id,
340 			  attr->next_reauth_id_len);
341 		data->reauth_id_len = attr->next_reauth_id_len;
342 		wpa_hexdump_ascii(MSG_DEBUG,
343 				  "EAP-SIM: (encr) AT_NEXT_REAUTH_ID",
344 				  data->reauth_id,
345 				  data->reauth_id_len);
346 	}
347 
348 	return 0;
349 }
350 
351 
352 static struct wpabuf * eap_sim_client_error(struct eap_sim_data *data, u8 id,
353 					    int err)
354 {
355 	struct eap_sim_msg *msg;
356 
357 	eap_sim_state(data, FAILURE);
358 	data->num_id_req = 0;
359 	data->num_notification = 0;
360 
361 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_SIM,
362 			       EAP_SIM_SUBTYPE_CLIENT_ERROR);
363 	eap_sim_msg_add(msg, EAP_SIM_AT_CLIENT_ERROR_CODE, err, NULL, 0);
364 	return eap_sim_msg_finish(msg, NULL, NULL, 0);
365 }
366 
367 
368 static struct wpabuf * eap_sim_response_start(struct eap_sm *sm,
369 					      struct eap_sim_data *data, u8 id,
370 					      enum eap_sim_id_req id_req)
371 {
372 	const u8 *identity = NULL;
373 	size_t identity_len = 0;
374 	struct eap_sim_msg *msg;
375 
376 	data->reauth = 0;
377 	if (id_req == ANY_ID && data->reauth_id) {
378 		identity = data->reauth_id;
379 		identity_len = data->reauth_id_len;
380 		data->reauth = 1;
381 	} else if ((id_req == ANY_ID || id_req == FULLAUTH_ID) &&
382 		   data->pseudonym) {
383 		identity = data->pseudonym;
384 		identity_len = data->pseudonym_len;
385 		eap_sim_clear_identities(data, CLEAR_REAUTH_ID);
386 	} else if (id_req != NO_ID_REQ) {
387 		identity = eap_get_config_identity(sm, &identity_len);
388 		if (identity) {
389 			eap_sim_clear_identities(data, CLEAR_PSEUDONYM |
390 						 CLEAR_REAUTH_ID);
391 		}
392 	}
393 	if (id_req != NO_ID_REQ)
394 		eap_sim_clear_identities(data, CLEAR_EAP_ID);
395 
396 	wpa_printf(MSG_DEBUG, "Generating EAP-SIM Start (id=%d)", id);
397 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id,
398 			       EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START);
399 	if (!data->reauth) {
400 		wpa_hexdump(MSG_DEBUG, "   AT_NONCE_MT",
401 			    data->nonce_mt, EAP_SIM_NONCE_MT_LEN);
402 		eap_sim_msg_add(msg, EAP_SIM_AT_NONCE_MT, 0,
403 				data->nonce_mt, EAP_SIM_NONCE_MT_LEN);
404 		wpa_printf(MSG_DEBUG, "   AT_SELECTED_VERSION %d",
405 			   data->selected_version);
406 		eap_sim_msg_add(msg, EAP_SIM_AT_SELECTED_VERSION,
407 				data->selected_version, NULL, 0);
408 	}
409 
410 	if (identity) {
411 		wpa_hexdump_ascii(MSG_DEBUG, "   AT_IDENTITY",
412 				  identity, identity_len);
413 		eap_sim_msg_add(msg, EAP_SIM_AT_IDENTITY, identity_len,
414 				identity, identity_len);
415 	}
416 
417 	return eap_sim_msg_finish(msg, NULL, NULL, 0);
418 }
419 
420 
421 static struct wpabuf * eap_sim_response_challenge(struct eap_sim_data *data,
422 						  u8 id)
423 {
424 	struct eap_sim_msg *msg;
425 
426 	wpa_printf(MSG_DEBUG, "Generating EAP-SIM Challenge (id=%d)", id);
427 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_SIM,
428 			       EAP_SIM_SUBTYPE_CHALLENGE);
429 	if (data->use_result_ind) {
430 		wpa_printf(MSG_DEBUG, "   AT_RESULT_IND");
431 		eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
432 	}
433 	wpa_printf(MSG_DEBUG, "   AT_MAC");
434 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
435 	return eap_sim_msg_finish(msg, data->k_aut, (u8 *) data->sres,
436 				  data->num_chal * EAP_SIM_SRES_LEN);
437 }
438 
439 
440 static struct wpabuf * eap_sim_response_reauth(struct eap_sim_data *data,
441 					       u8 id, int counter_too_small)
442 {
443 	struct eap_sim_msg *msg;
444 	unsigned int counter;
445 
446 	wpa_printf(MSG_DEBUG, "Generating EAP-SIM Reauthentication (id=%d)",
447 		   id);
448 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_SIM,
449 			       EAP_SIM_SUBTYPE_REAUTHENTICATION);
450 	wpa_printf(MSG_DEBUG, "   AT_IV");
451 	wpa_printf(MSG_DEBUG, "   AT_ENCR_DATA");
452 	eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, EAP_SIM_AT_ENCR_DATA);
453 
454 	if (counter_too_small) {
455 		wpa_printf(MSG_DEBUG, "   *AT_COUNTER_TOO_SMALL");
456 		eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER_TOO_SMALL, 0, NULL, 0);
457 		counter = data->counter_too_small;
458 	} else
459 		counter = data->counter;
460 
461 	wpa_printf(MSG_DEBUG, "   *AT_COUNTER %d", counter);
462 	eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, counter, NULL, 0);
463 
464 	if (eap_sim_msg_add_encr_end(msg, data->k_encr, EAP_SIM_AT_PADDING)) {
465 		wpa_printf(MSG_WARNING, "EAP-SIM: Failed to encrypt "
466 			   "AT_ENCR_DATA");
467 		eap_sim_msg_free(msg);
468 		return NULL;
469 	}
470 	if (data->use_result_ind) {
471 		wpa_printf(MSG_DEBUG, "   AT_RESULT_IND");
472 		eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
473 	}
474 	wpa_printf(MSG_DEBUG, "   AT_MAC");
475 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
476 	return eap_sim_msg_finish(msg, data->k_aut, data->nonce_s,
477 				  EAP_SIM_NONCE_S_LEN);
478 }
479 
480 
481 static struct wpabuf * eap_sim_response_notification(struct eap_sim_data *data,
482 						     u8 id, u16 notification)
483 {
484 	struct eap_sim_msg *msg;
485 	u8 *k_aut = (notification & 0x4000) == 0 ? data->k_aut : NULL;
486 
487 	wpa_printf(MSG_DEBUG, "Generating EAP-SIM Notification (id=%d)", id);
488 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id,
489 			       EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION);
490 	if (k_aut && data->reauth) {
491 		wpa_printf(MSG_DEBUG, "   AT_IV");
492 		wpa_printf(MSG_DEBUG, "   AT_ENCR_DATA");
493 		eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV,
494 					   EAP_SIM_AT_ENCR_DATA);
495 		wpa_printf(MSG_DEBUG, "   *AT_COUNTER %d", data->counter);
496 		eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, data->counter,
497 				NULL, 0);
498 		if (eap_sim_msg_add_encr_end(msg, data->k_encr,
499 					     EAP_SIM_AT_PADDING)) {
500 			wpa_printf(MSG_WARNING, "EAP-SIM: Failed to encrypt "
501 				   "AT_ENCR_DATA");
502 			eap_sim_msg_free(msg);
503 			return NULL;
504 		}
505 	}
506 	if (k_aut) {
507 		wpa_printf(MSG_DEBUG, "   AT_MAC");
508 		eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
509 	}
510 	return eap_sim_msg_finish(msg, k_aut, (u8 *) "", 0);
511 }
512 
513 
514 static struct wpabuf * eap_sim_process_start(struct eap_sm *sm,
515 					     struct eap_sim_data *data, u8 id,
516 					     struct eap_sim_attrs *attr)
517 {
518 	int selected_version = -1, id_error;
519 	size_t i;
520 	u8 *pos;
521 
522 	wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Start");
523 	if (attr->version_list == NULL) {
524 		wpa_printf(MSG_INFO, "EAP-SIM: No AT_VERSION_LIST in "
525 			   "SIM/Start");
526 		return eap_sim_client_error(data, id,
527 					    EAP_SIM_UNSUPPORTED_VERSION);
528 	}
529 
530 	os_free(data->ver_list);
531 	data->ver_list = os_malloc(attr->version_list_len);
532 	if (data->ver_list == NULL) {
533 		wpa_printf(MSG_DEBUG, "EAP-SIM: Failed to allocate "
534 			   "memory for version list");
535 		return eap_sim_client_error(data, id,
536 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
537 	}
538 	os_memcpy(data->ver_list, attr->version_list, attr->version_list_len);
539 	data->ver_list_len = attr->version_list_len;
540 	pos = data->ver_list;
541 	for (i = 0; i < data->ver_list_len / 2; i++) {
542 		int ver = pos[0] * 256 + pos[1];
543 		pos += 2;
544 		if (eap_sim_supported_ver(ver)) {
545 			selected_version = ver;
546 			break;
547 		}
548 	}
549 	if (selected_version < 0) {
550 		wpa_printf(MSG_INFO, "EAP-SIM: Could not find a supported "
551 			   "version");
552 		return eap_sim_client_error(data, id,
553 					    EAP_SIM_UNSUPPORTED_VERSION);
554 	}
555 	wpa_printf(MSG_DEBUG, "EAP-SIM: Selected Version %d",
556 		   selected_version);
557 	data->selected_version = selected_version;
558 
559 	id_error = 0;
560 	switch (attr->id_req) {
561 	case NO_ID_REQ:
562 		break;
563 	case ANY_ID:
564 		if (data->num_id_req > 0)
565 			id_error++;
566 		data->num_id_req++;
567 		break;
568 	case FULLAUTH_ID:
569 		if (data->num_id_req > 1)
570 			id_error++;
571 		data->num_id_req++;
572 		break;
573 	case PERMANENT_ID:
574 		if (data->num_id_req > 2)
575 			id_error++;
576 		data->num_id_req++;
577 		break;
578 	}
579 	if (id_error) {
580 		wpa_printf(MSG_INFO, "EAP-SIM: Too many ID requests "
581 			   "used within one authentication");
582 		return eap_sim_client_error(data, id,
583 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
584 	}
585 
586 	return eap_sim_response_start(sm, data, id, attr->id_req);
587 }
588 
589 
590 static struct wpabuf * eap_sim_process_challenge(struct eap_sm *sm,
591 						 struct eap_sim_data *data,
592 						 u8 id,
593 						 const struct wpabuf *reqData,
594 						 struct eap_sim_attrs *attr)
595 {
596 	const u8 *identity;
597 	size_t identity_len;
598 	struct eap_sim_attrs eattr;
599 
600 	wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Challenge");
601 	data->reauth = 0;
602 	if (!attr->mac || !attr->rand) {
603 		wpa_printf(MSG_WARNING, "EAP-SIM: Challenge message "
604 			   "did not include%s%s",
605 			   !attr->mac ? " AT_MAC" : "",
606 			   !attr->rand ? " AT_RAND" : "");
607 		return eap_sim_client_error(data, id,
608 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
609 	}
610 
611 	wpa_printf(MSG_DEBUG, "EAP-SIM: %lu challenges",
612 		   (unsigned long) attr->num_chal);
613 	if (attr->num_chal < data->min_num_chal) {
614 		wpa_printf(MSG_INFO, "EAP-SIM: Insufficient number of "
615 			   "challenges (%lu)", (unsigned long) attr->num_chal);
616 		return eap_sim_client_error(data, id,
617 					    EAP_SIM_INSUFFICIENT_NUM_OF_CHAL);
618 	}
619 	if (attr->num_chal > 3) {
620 		wpa_printf(MSG_INFO, "EAP-SIM: Too many challenges "
621 			   "(%lu)", (unsigned long) attr->num_chal);
622 		return eap_sim_client_error(data, id,
623 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
624 	}
625 
626 	/* Verify that RANDs are different */
627 	if (os_memcmp(attr->rand, attr->rand + GSM_RAND_LEN,
628 		   GSM_RAND_LEN) == 0 ||
629 	    (attr->num_chal > 2 &&
630 	     (os_memcmp(attr->rand, attr->rand + 2 * GSM_RAND_LEN,
631 			GSM_RAND_LEN) == 0 ||
632 	      os_memcmp(attr->rand + GSM_RAND_LEN,
633 			attr->rand + 2 * GSM_RAND_LEN,
634 			GSM_RAND_LEN) == 0))) {
635 		wpa_printf(MSG_INFO, "EAP-SIM: Same RAND used multiple times");
636 		return eap_sim_client_error(data, id,
637 					    EAP_SIM_RAND_NOT_FRESH);
638 	}
639 
640 	os_memcpy(data->rand, attr->rand, attr->num_chal * GSM_RAND_LEN);
641 	data->num_chal = attr->num_chal;
642 
643 	if (eap_sim_gsm_auth(sm, data)) {
644 		wpa_printf(MSG_WARNING, "EAP-SIM: GSM authentication failed");
645 		return eap_sim_client_error(data, id,
646 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
647 	}
648 	if (data->last_eap_identity) {
649 		identity = data->last_eap_identity;
650 		identity_len = data->last_eap_identity_len;
651 	} else if (data->pseudonym) {
652 		identity = data->pseudonym;
653 		identity_len = data->pseudonym_len;
654 	} else
655 		identity = eap_get_config_identity(sm, &identity_len);
656 	wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Selected identity for MK "
657 			  "derivation", identity, identity_len);
658 	eap_sim_derive_mk(identity, identity_len, data->nonce_mt,
659 			  data->selected_version, data->ver_list,
660 			  data->ver_list_len, data->num_chal,
661 			  (const u8 *) data->kc, data->mk);
662 	eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,
663 			    data->emsk);
664 	if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, data->nonce_mt,
665 			       EAP_SIM_NONCE_MT_LEN)) {
666 		wpa_printf(MSG_WARNING, "EAP-SIM: Challenge message "
667 			   "used invalid AT_MAC");
668 		return eap_sim_client_error(data, id,
669 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
670 	}
671 
672 	/* Old reauthentication identity must not be used anymore. In
673 	 * other words, if no new reauth identity is received, full
674 	 * authentication will be used on next reauthentication (using
675 	 * pseudonym identity or permanent identity). */
676 	eap_sim_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
677 
678 	if (attr->encr_data) {
679 		u8 *decrypted;
680 		decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
681 					       attr->encr_data_len, attr->iv,
682 					       &eattr, 0);
683 		if (decrypted == NULL) {
684 			return eap_sim_client_error(
685 				data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET);
686 		}
687 		eap_sim_learn_ids(sm, data, &eattr);
688 		os_free(decrypted);
689 	}
690 
691 	if (data->result_ind && attr->result_ind)
692 		data->use_result_ind = 1;
693 
694 	if (data->state != FAILURE && data->state != RESULT_FAILURE) {
695 		eap_sim_state(data, data->use_result_ind ?
696 			      RESULT_SUCCESS : SUCCESS);
697 	}
698 
699 	data->num_id_req = 0;
700 	data->num_notification = 0;
701 	/* RFC 4186 specifies that counter is initialized to one after
702 	 * fullauth, but initializing it to zero makes it easier to implement
703 	 * reauth verification. */
704 	data->counter = 0;
705 	return eap_sim_response_challenge(data, id);
706 }
707 
708 
709 static int eap_sim_process_notification_reauth(struct eap_sim_data *data,
710 					       struct eap_sim_attrs *attr)
711 {
712 	struct eap_sim_attrs eattr;
713 	u8 *decrypted;
714 
715 	if (attr->encr_data == NULL || attr->iv == NULL) {
716 		wpa_printf(MSG_WARNING, "EAP-SIM: Notification message after "
717 			   "reauth did not include encrypted data");
718 		return -1;
719 	}
720 
721 	decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
722 				       attr->encr_data_len, attr->iv, &eattr,
723 				       0);
724 	if (decrypted == NULL) {
725 		wpa_printf(MSG_WARNING, "EAP-SIM: Failed to parse encrypted "
726 			   "data from notification message");
727 		return -1;
728 	}
729 
730 	if (eattr.counter < 0 || (size_t) eattr.counter != data->counter) {
731 		wpa_printf(MSG_WARNING, "EAP-SIM: Counter in notification "
732 			   "message does not match with counter in reauth "
733 			   "message");
734 		os_free(decrypted);
735 		return -1;
736 	}
737 
738 	os_free(decrypted);
739 	return 0;
740 }
741 
742 
743 static int eap_sim_process_notification_auth(struct eap_sim_data *data,
744 					     const struct wpabuf *reqData,
745 					     struct eap_sim_attrs *attr)
746 {
747 	if (attr->mac == NULL) {
748 		wpa_printf(MSG_INFO, "EAP-SIM: no AT_MAC in after_auth "
749 			   "Notification message");
750 		return -1;
751 	}
752 
753 	if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0))
754 	{
755 		wpa_printf(MSG_WARNING, "EAP-SIM: Notification message "
756 			   "used invalid AT_MAC");
757 		return -1;
758 	}
759 
760 	if (data->reauth &&
761 	    eap_sim_process_notification_reauth(data, attr)) {
762 		wpa_printf(MSG_WARNING, "EAP-SIM: Invalid notification "
763 			   "message after reauth");
764 		return -1;
765 	}
766 
767 	return 0;
768 }
769 
770 
771 static struct wpabuf * eap_sim_process_notification(
772 	struct eap_sm *sm, struct eap_sim_data *data, u8 id,
773 	const struct wpabuf *reqData, struct eap_sim_attrs *attr)
774 {
775 	wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Notification");
776 	if (data->num_notification > 0) {
777 		wpa_printf(MSG_INFO, "EAP-SIM: too many notification "
778 			   "rounds (only one allowed)");
779 		return eap_sim_client_error(data, id,
780 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
781 	}
782 	data->num_notification++;
783 	if (attr->notification == -1) {
784 		wpa_printf(MSG_INFO, "EAP-SIM: no AT_NOTIFICATION in "
785 			   "Notification message");
786 		return eap_sim_client_error(data, id,
787 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
788 	}
789 
790 	if ((attr->notification & 0x4000) == 0 &&
791 	    eap_sim_process_notification_auth(data, reqData, attr)) {
792 		return eap_sim_client_error(data, id,
793 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
794 	}
795 
796 	eap_sim_report_notification(sm->msg_ctx, attr->notification, 0);
797 	if (attr->notification >= 0 && attr->notification < 32768) {
798 		eap_sim_state(data, FAILURE);
799 	} else if (attr->notification == EAP_SIM_SUCCESS &&
800 		   data->state == RESULT_SUCCESS)
801 		eap_sim_state(data, SUCCESS);
802 	return eap_sim_response_notification(data, id, attr->notification);
803 }
804 
805 
806 static struct wpabuf * eap_sim_process_reauthentication(
807 	struct eap_sm *sm, struct eap_sim_data *data, u8 id,
808 	const struct wpabuf *reqData, struct eap_sim_attrs *attr)
809 {
810 	struct eap_sim_attrs eattr;
811 	u8 *decrypted;
812 
813 	wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Reauthentication");
814 
815 	if (data->reauth_id == NULL) {
816 		wpa_printf(MSG_WARNING, "EAP-SIM: Server is trying "
817 			   "reauthentication, but no reauth_id available");
818 		return eap_sim_client_error(data, id,
819 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
820 	}
821 
822 	data->reauth = 1;
823 	if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0))
824 	{
825 		wpa_printf(MSG_WARNING, "EAP-SIM: Reauthentication "
826 			   "did not have valid AT_MAC");
827 		return eap_sim_client_error(data, id,
828 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
829 	}
830 
831 	if (attr->encr_data == NULL || attr->iv == NULL) {
832 		wpa_printf(MSG_WARNING, "EAP-SIM: Reauthentication "
833 			   "message did not include encrypted data");
834 		return eap_sim_client_error(data, id,
835 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
836 	}
837 
838 	decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
839 				       attr->encr_data_len, attr->iv, &eattr,
840 				       0);
841 	if (decrypted == NULL) {
842 		wpa_printf(MSG_WARNING, "EAP-SIM: Failed to parse encrypted "
843 			   "data from reauthentication message");
844 		return eap_sim_client_error(data, id,
845 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
846 	}
847 
848 	if (eattr.nonce_s == NULL || eattr.counter < 0) {
849 		wpa_printf(MSG_INFO, "EAP-SIM: (encr) No%s%s in reauth packet",
850 			   !eattr.nonce_s ? " AT_NONCE_S" : "",
851 			   eattr.counter < 0 ? " AT_COUNTER" : "");
852 		os_free(decrypted);
853 		return eap_sim_client_error(data, id,
854 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
855 	}
856 
857 	if (eattr.counter < 0 || (size_t) eattr.counter <= data->counter) {
858 		wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid counter "
859 			   "(%d <= %d)", eattr.counter, data->counter);
860 		data->counter_too_small = eattr.counter;
861 		/* Reply using Re-auth w/ AT_COUNTER_TOO_SMALL. The current
862 		 * reauth_id must not be used to start a new reauthentication.
863 		 * However, since it was used in the last EAP-Response-Identity
864 		 * packet, it has to saved for the following fullauth to be
865 		 * used in MK derivation. */
866 		os_free(data->last_eap_identity);
867 		data->last_eap_identity = data->reauth_id;
868 		data->last_eap_identity_len = data->reauth_id_len;
869 		data->reauth_id = NULL;
870 		data->reauth_id_len = 0;
871 		os_free(decrypted);
872 		return eap_sim_response_reauth(data, id, 1);
873 	}
874 	data->counter = eattr.counter;
875 
876 	os_memcpy(data->nonce_s, eattr.nonce_s, EAP_SIM_NONCE_S_LEN);
877 	wpa_hexdump(MSG_DEBUG, "EAP-SIM: (encr) AT_NONCE_S",
878 		    data->nonce_s, EAP_SIM_NONCE_S_LEN);
879 
880 	eap_sim_derive_keys_reauth(data->counter,
881 				   data->reauth_id, data->reauth_id_len,
882 				   data->nonce_s, data->mk, data->msk,
883 				   data->emsk);
884 	eap_sim_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
885 	eap_sim_learn_ids(sm, data, &eattr);
886 
887 	if (data->result_ind && attr->result_ind)
888 		data->use_result_ind = 1;
889 
890 	if (data->state != FAILURE && data->state != RESULT_FAILURE) {
891 		eap_sim_state(data, data->use_result_ind ?
892 			      RESULT_SUCCESS : SUCCESS);
893 	}
894 
895 	data->num_id_req = 0;
896 	data->num_notification = 0;
897 	if (data->counter > EAP_SIM_MAX_FAST_REAUTHS) {
898 		wpa_printf(MSG_DEBUG, "EAP-SIM: Maximum number of "
899 			   "fast reauths performed - force fullauth");
900 		eap_sim_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
901 	}
902 	os_free(decrypted);
903 	return eap_sim_response_reauth(data, id, 0);
904 }
905 
906 
907 static struct wpabuf * eap_sim_process(struct eap_sm *sm, void *priv,
908 				       struct eap_method_ret *ret,
909 				       const struct wpabuf *reqData)
910 {
911 	struct eap_sim_data *data = priv;
912 	const struct eap_hdr *req;
913 	u8 subtype, id;
914 	struct wpabuf *res;
915 	const u8 *pos;
916 	struct eap_sim_attrs attr;
917 	size_t len;
918 
919 	wpa_hexdump_buf(MSG_DEBUG, "EAP-SIM: EAP data", reqData);
920 	if (eap_get_config_identity(sm, &len) == NULL) {
921 		wpa_printf(MSG_INFO, "EAP-SIM: Identity not configured");
922 		eap_sm_request_identity(sm);
923 		ret->ignore = TRUE;
924 		return NULL;
925 	}
926 
927 	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SIM, reqData, &len);
928 	if (pos == NULL || len < 1) {
929 		ret->ignore = TRUE;
930 		return NULL;
931 	}
932 	req = wpabuf_head(reqData);
933 	id = req->identifier;
934 	len = be_to_host16(req->length);
935 
936 	ret->ignore = FALSE;
937 	ret->methodState = METHOD_MAY_CONT;
938 	ret->decision = DECISION_FAIL;
939 	ret->allowNotifications = TRUE;
940 
941 	subtype = *pos++;
942 	wpa_printf(MSG_DEBUG, "EAP-SIM: Subtype=%d", subtype);
943 	pos += 2; /* Reserved */
944 
945 	if (eap_sim_parse_attr(pos, wpabuf_head_u8(reqData) + len, &attr, 0,
946 			       0)) {
947 		res = eap_sim_client_error(data, id,
948 					   EAP_SIM_UNABLE_TO_PROCESS_PACKET);
949 		goto done;
950 	}
951 
952 	switch (subtype) {
953 	case EAP_SIM_SUBTYPE_START:
954 		res = eap_sim_process_start(sm, data, id, &attr);
955 		break;
956 	case EAP_SIM_SUBTYPE_CHALLENGE:
957 		res = eap_sim_process_challenge(sm, data, id, reqData, &attr);
958 		break;
959 	case EAP_SIM_SUBTYPE_NOTIFICATION:
960 		res = eap_sim_process_notification(sm, data, id, reqData,
961 						   &attr);
962 		break;
963 	case EAP_SIM_SUBTYPE_REAUTHENTICATION:
964 		res = eap_sim_process_reauthentication(sm, data, id, reqData,
965 						       &attr);
966 		break;
967 	case EAP_SIM_SUBTYPE_CLIENT_ERROR:
968 		wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Client-Error");
969 		res = eap_sim_client_error(data, id,
970 					   EAP_SIM_UNABLE_TO_PROCESS_PACKET);
971 		break;
972 	default:
973 		wpa_printf(MSG_DEBUG, "EAP-SIM: Unknown subtype=%d", subtype);
974 		res = eap_sim_client_error(data, id,
975 					   EAP_SIM_UNABLE_TO_PROCESS_PACKET);
976 		break;
977 	}
978 
979 done:
980 	if (data->state == FAILURE) {
981 		ret->decision = DECISION_FAIL;
982 		ret->methodState = METHOD_DONE;
983 	} else if (data->state == SUCCESS) {
984 		ret->decision = data->use_result_ind ?
985 			DECISION_UNCOND_SUCC : DECISION_COND_SUCC;
986 		ret->methodState = data->use_result_ind ?
987 			METHOD_DONE : METHOD_MAY_CONT;
988 	} else if (data->state == RESULT_FAILURE)
989 		ret->methodState = METHOD_CONT;
990 	else if (data->state == RESULT_SUCCESS)
991 		ret->methodState = METHOD_CONT;
992 
993 	if (ret->methodState == METHOD_DONE) {
994 		ret->allowNotifications = FALSE;
995 	}
996 
997 	return res;
998 }
999 
1000 
1001 static Boolean eap_sim_has_reauth_data(struct eap_sm *sm, void *priv)
1002 {
1003 	struct eap_sim_data *data = priv;
1004 	return data->pseudonym || data->reauth_id;
1005 }
1006 
1007 
1008 static void eap_sim_deinit_for_reauth(struct eap_sm *sm, void *priv)
1009 {
1010 	struct eap_sim_data *data = priv;
1011 	eap_sim_clear_identities(data, CLEAR_EAP_ID);
1012 	data->use_result_ind = 0;
1013 }
1014 
1015 
1016 static void * eap_sim_init_for_reauth(struct eap_sm *sm, void *priv)
1017 {
1018 	struct eap_sim_data *data = priv;
1019 	if (random_get_bytes(data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) {
1020 		wpa_printf(MSG_WARNING, "EAP-SIM: Failed to get random data "
1021 			   "for NONCE_MT");
1022 		os_free(data);
1023 		return NULL;
1024 	}
1025 	data->num_id_req = 0;
1026 	data->num_notification = 0;
1027 	eap_sim_state(data, CONTINUE);
1028 	return priv;
1029 }
1030 
1031 
1032 static const u8 * eap_sim_get_identity(struct eap_sm *sm, void *priv,
1033 				       size_t *len)
1034 {
1035 	struct eap_sim_data *data = priv;
1036 
1037 	if (data->reauth_id) {
1038 		*len = data->reauth_id_len;
1039 		return data->reauth_id;
1040 	}
1041 
1042 	if (data->pseudonym) {
1043 		*len = data->pseudonym_len;
1044 		return data->pseudonym;
1045 	}
1046 
1047 	return NULL;
1048 }
1049 
1050 
1051 static Boolean eap_sim_isKeyAvailable(struct eap_sm *sm, void *priv)
1052 {
1053 	struct eap_sim_data *data = priv;
1054 	return data->state == SUCCESS;
1055 }
1056 
1057 
1058 static u8 * eap_sim_getKey(struct eap_sm *sm, void *priv, size_t *len)
1059 {
1060 	struct eap_sim_data *data = priv;
1061 	u8 *key;
1062 
1063 	if (data->state != SUCCESS)
1064 		return NULL;
1065 
1066 	key = os_malloc(EAP_SIM_KEYING_DATA_LEN);
1067 	if (key == NULL)
1068 		return NULL;
1069 
1070 	*len = EAP_SIM_KEYING_DATA_LEN;
1071 	os_memcpy(key, data->msk, EAP_SIM_KEYING_DATA_LEN);
1072 
1073 	return key;
1074 }
1075 
1076 
1077 static u8 * eap_sim_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
1078 {
1079 	struct eap_sim_data *data = priv;
1080 	u8 *key;
1081 
1082 	if (data->state != SUCCESS)
1083 		return NULL;
1084 
1085 	key = os_malloc(EAP_EMSK_LEN);
1086 	if (key == NULL)
1087 		return NULL;
1088 
1089 	*len = EAP_EMSK_LEN;
1090 	os_memcpy(key, data->emsk, EAP_EMSK_LEN);
1091 
1092 	return key;
1093 }
1094 
1095 
1096 int eap_peer_sim_register(void)
1097 {
1098 	struct eap_method *eap;
1099 	int ret;
1100 
1101 	eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
1102 				    EAP_VENDOR_IETF, EAP_TYPE_SIM, "SIM");
1103 	if (eap == NULL)
1104 		return -1;
1105 
1106 	eap->init = eap_sim_init;
1107 	eap->deinit = eap_sim_deinit;
1108 	eap->process = eap_sim_process;
1109 	eap->isKeyAvailable = eap_sim_isKeyAvailable;
1110 	eap->getKey = eap_sim_getKey;
1111 	eap->has_reauth_data = eap_sim_has_reauth_data;
1112 	eap->deinit_for_reauth = eap_sim_deinit_for_reauth;
1113 	eap->init_for_reauth = eap_sim_init_for_reauth;
1114 	eap->get_identity = eap_sim_get_identity;
1115 	eap->get_emsk = eap_sim_get_emsk;
1116 
1117 	ret = eap_peer_method_register(eap);
1118 	if (ret)
1119 		eap_peer_method_free(eap);
1120 	return ret;
1121 }
1122