Home | History | Annotate | Download | only in wpa_supplicant
      1 /*
      2  * EAP peer method: EAP-AKA (RFC 4187)
      3  * Copyright (c) 2004-2006, Jouni Malinen <j (at) 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_i.h"
     19 #include "crypto.h"
     20 #include "pcsc_funcs.h"
     21 #include "eap_sim_common.h"
     22 
     23 
     24 struct eap_aka_data {
     25 	u8 ik[EAP_AKA_IK_LEN], ck[EAP_AKA_CK_LEN], res[EAP_AKA_RES_MAX_LEN];
     26 	size_t res_len;
     27 	u8 nonce_s[EAP_SIM_NONCE_S_LEN];
     28 	u8 mk[EAP_SIM_MK_LEN];
     29 	u8 k_aut[EAP_SIM_K_AUT_LEN];
     30 	u8 k_encr[EAP_SIM_K_ENCR_LEN];
     31 	u8 msk[EAP_SIM_KEYING_DATA_LEN];
     32 	u8 emsk[EAP_EMSK_LEN];
     33 	u8 rand[EAP_AKA_RAND_LEN], autn[EAP_AKA_AUTN_LEN];
     34 	u8 auts[EAP_AKA_AUTS_LEN];
     35 
     36 	int num_id_req, num_notification;
     37 	u8 *pseudonym;
     38 	size_t pseudonym_len;
     39 	u8 *reauth_id;
     40 	size_t reauth_id_len;
     41 	int reauth;
     42 	unsigned int counter, counter_too_small;
     43 	u8 *last_eap_identity;
     44 	size_t last_eap_identity_len;
     45 	enum { CONTINUE, SUCCESS, FAILURE } state;
     46 };
     47 
     48 
     49 static void * eap_aka_init(struct eap_sm *sm)
     50 {
     51 	struct eap_aka_data *data;
     52 	data = os_zalloc(sizeof(*data));
     53 	if (data == NULL)
     54 		return NULL;
     55 
     56 	data->state = CONTINUE;
     57 
     58 	return data;
     59 }
     60 
     61 
     62 static void eap_aka_deinit(struct eap_sm *sm, void *priv)
     63 {
     64 	struct eap_aka_data *data = priv;
     65 	if (data) {
     66 		os_free(data->pseudonym);
     67 		os_free(data->reauth_id);
     68 		os_free(data->last_eap_identity);
     69 		os_free(data);
     70 	}
     71 }
     72 
     73 
     74 static int eap_aka_umts_auth(struct eap_sm *sm, struct eap_aka_data *data)
     75 {
     76 	wpa_printf(MSG_DEBUG, "EAP-AKA: UMTS authentication algorithm");
     77 #ifdef PCSC_FUNCS
     78 	return scard_umts_auth(sm->scard_ctx, data->rand,
     79 			       data->autn, data->res, &data->res_len,
     80 			       data->ik, data->ck, data->auts);
     81 #else /* PCSC_FUNCS */
     82 	/* These hardcoded Kc and SRES values are used for testing.
     83 	 * Could consider making them configurable. */
     84 	os_memset(data->res, '2', EAP_AKA_RES_MAX_LEN);
     85 	data->res_len = EAP_AKA_RES_MAX_LEN;
     86 	os_memset(data->ik, '3', EAP_AKA_IK_LEN);
     87 	os_memset(data->ck, '4', EAP_AKA_CK_LEN);
     88 	{
     89 		u8 autn[EAP_AKA_AUTN_LEN];
     90 		os_memset(autn, '1', EAP_AKA_AUTN_LEN);
     91 		if (os_memcmp(autn, data->autn, EAP_AKA_AUTN_LEN) != 0) {
     92 			wpa_printf(MSG_WARNING, "EAP-AKA: AUTN did not match "
     93 				   "with expected value");
     94 			return -1;
     95 		}
     96 	}
     97 #if 0
     98 	{
     99 		static int test_resync = 1;
    100 		if (test_resync) {
    101 			/* Test Resynchronization */
    102 			test_resync = 0;
    103 			return -2;
    104 		}
    105 	}
    106 #endif
    107 	return 0;
    108 #endif /* PCSC_FUNCS */
    109 }
    110 
    111 
    112 #define CLEAR_PSEUDONYM	0x01
    113 #define CLEAR_REAUTH_ID	0x02
    114 #define CLEAR_EAP_ID	0x04
    115 
    116 static void eap_aka_clear_identities(struct eap_aka_data *data, int id)
    117 {
    118 	wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old%s%s%s",
    119 		   id & CLEAR_PSEUDONYM ? " pseudonym" : "",
    120 		   id & CLEAR_REAUTH_ID ? " reauth_id" : "",
    121 		   id & CLEAR_EAP_ID ? " eap_id" : "");
    122 	if (id & CLEAR_PSEUDONYM) {
    123 		os_free(data->pseudonym);
    124 		data->pseudonym = NULL;
    125 		data->pseudonym_len = 0;
    126 	}
    127 	if (id & CLEAR_REAUTH_ID) {
    128 		os_free(data->reauth_id);
    129 		data->reauth_id = NULL;
    130 		data->reauth_id_len = 0;
    131 	}
    132 	if (id & CLEAR_EAP_ID) {
    133 		os_free(data->last_eap_identity);
    134 		data->last_eap_identity = NULL;
    135 		data->last_eap_identity_len = 0;
    136 	}
    137 }
    138 
    139 
    140 static int eap_aka_learn_ids(struct eap_aka_data *data,
    141 			     struct eap_sim_attrs *attr)
    142 {
    143 	if (attr->next_pseudonym) {
    144 		os_free(data->pseudonym);
    145 		data->pseudonym = os_malloc(attr->next_pseudonym_len);
    146 		if (data->pseudonym == NULL) {
    147 			wpa_printf(MSG_INFO, "EAP-AKA: (encr) No memory for "
    148 				   "next pseudonym");
    149 			return -1;
    150 		}
    151 		os_memcpy(data->pseudonym, attr->next_pseudonym,
    152 			  attr->next_pseudonym_len);
    153 		data->pseudonym_len = attr->next_pseudonym_len;
    154 		wpa_hexdump_ascii(MSG_DEBUG,
    155 				  "EAP-AKA: (encr) AT_NEXT_PSEUDONYM",
    156 				  data->pseudonym,
    157 				  data->pseudonym_len);
    158 	}
    159 
    160 	if (attr->next_reauth_id) {
    161 		os_free(data->reauth_id);
    162 		data->reauth_id = os_malloc(attr->next_reauth_id_len);
    163 		if (data->reauth_id == NULL) {
    164 			wpa_printf(MSG_INFO, "EAP-AKA: (encr) No memory for "
    165 				   "next reauth_id");
    166 			return -1;
    167 		}
    168 		os_memcpy(data->reauth_id, attr->next_reauth_id,
    169 			  attr->next_reauth_id_len);
    170 		data->reauth_id_len = attr->next_reauth_id_len;
    171 		wpa_hexdump_ascii(MSG_DEBUG,
    172 				  "EAP-AKA: (encr) AT_NEXT_REAUTH_ID",
    173 				  data->reauth_id,
    174 				  data->reauth_id_len);
    175 	}
    176 
    177 	return 0;
    178 }
    179 
    180 
    181 static u8 * eap_aka_client_error(struct eap_aka_data *data,
    182 				 const struct eap_hdr *req,
    183 				 size_t *respDataLen, int err)
    184 {
    185 	struct eap_sim_msg *msg;
    186 
    187 	data->state = FAILURE;
    188 	data->num_id_req = 0;
    189 	data->num_notification = 0;
    190 
    191 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
    192 			       EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CLIENT_ERROR);
    193 	eap_sim_msg_add(msg, EAP_SIM_AT_CLIENT_ERROR_CODE, err, NULL, 0);
    194 	return eap_sim_msg_finish(msg, respDataLen, NULL, NULL, 0);
    195 }
    196 
    197 
    198 static u8 * eap_aka_authentication_reject(struct eap_aka_data *data,
    199 					  const struct eap_hdr *req,
    200 					  size_t *respDataLen)
    201 {
    202 	struct eap_sim_msg *msg;
    203 
    204 	data->state = FAILURE;
    205 	data->num_id_req = 0;
    206 	data->num_notification = 0;
    207 
    208 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Authentication-Reject "
    209 		   "(id=%d)", req->identifier);
    210 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
    211 			       EAP_TYPE_AKA,
    212 			       EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT);
    213 	return eap_sim_msg_finish(msg, respDataLen, NULL, NULL, 0);
    214 }
    215 
    216 
    217 static u8 * eap_aka_synchronization_failure(struct eap_aka_data *data,
    218 					    const struct eap_hdr *req,
    219 					    size_t *respDataLen)
    220 {
    221 	struct eap_sim_msg *msg;
    222 
    223 	data->num_id_req = 0;
    224 	data->num_notification = 0;
    225 
    226 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Synchronization-Failure "
    227 		   "(id=%d)", req->identifier);
    228 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
    229 			       EAP_TYPE_AKA,
    230 			       EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE);
    231 	wpa_printf(MSG_DEBUG, "   AT_AUTS");
    232 	eap_sim_msg_add_full(msg, EAP_SIM_AT_AUTS, data->auts,
    233 			     EAP_AKA_AUTS_LEN);
    234 	return eap_sim_msg_finish(msg, respDataLen, NULL, NULL, 0);
    235 }
    236 
    237 
    238 static u8 * eap_aka_response_identity(struct eap_sm *sm,
    239 				      struct eap_aka_data *data,
    240 				      const struct eap_hdr *req,
    241 				      size_t *respDataLen,
    242 				      enum eap_sim_id_req id_req)
    243 {
    244 	const u8 *identity = NULL;
    245 	size_t identity_len = 0;
    246 	struct eap_sim_msg *msg;
    247 
    248 	data->reauth = 0;
    249 	if (id_req == ANY_ID && data->reauth_id) {
    250 		identity = data->reauth_id;
    251 		identity_len = data->reauth_id_len;
    252 		data->reauth = 1;
    253 	} else if ((id_req == ANY_ID || id_req == FULLAUTH_ID) &&
    254 		   data->pseudonym) {
    255 		identity = data->pseudonym;
    256 		identity_len = data->pseudonym_len;
    257 		eap_aka_clear_identities(data, CLEAR_REAUTH_ID);
    258 	} else if (id_req != NO_ID_REQ) {
    259 		identity = eap_get_config_identity(sm, &identity_len);
    260 		if (identity) {
    261 			eap_aka_clear_identities(data, CLEAR_PSEUDONYM |
    262 						 CLEAR_REAUTH_ID);
    263 		}
    264 	}
    265 	if (id_req != NO_ID_REQ)
    266 		eap_aka_clear_identities(data, CLEAR_EAP_ID);
    267 
    268 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Identity (id=%d)",
    269 		   req->identifier);
    270 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
    271 			       EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY);
    272 
    273 	if (identity) {
    274 		wpa_hexdump_ascii(MSG_DEBUG, "   AT_IDENTITY",
    275 				  identity, identity_len);
    276 		eap_sim_msg_add(msg, EAP_SIM_AT_IDENTITY, identity_len,
    277 				identity, identity_len);
    278 	}
    279 
    280 	return eap_sim_msg_finish(msg, respDataLen, NULL, NULL, 0);
    281 }
    282 
    283 
    284 static u8 * eap_aka_response_challenge(struct eap_aka_data *data,
    285 				       const struct eap_hdr *req,
    286 				       size_t *respDataLen)
    287 {
    288 	struct eap_sim_msg *msg;
    289 
    290 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Challenge (id=%d)",
    291 		   req->identifier);
    292 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
    293 			       EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE);
    294 	wpa_printf(MSG_DEBUG, "   AT_RES");
    295 	eap_sim_msg_add(msg, EAP_SIM_AT_RES, data->res_len * 8,
    296 			data->res, data->res_len);
    297 	wpa_printf(MSG_DEBUG, "   AT_MAC");
    298 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
    299 	return eap_sim_msg_finish(msg, respDataLen, data->k_aut, (u8 *) "", 0);
    300 }
    301 
    302 
    303 static u8 * eap_aka_response_reauth(struct eap_aka_data *data,
    304 				    const struct eap_hdr *req,
    305 				    size_t *respDataLen, int counter_too_small,
    306 				    const u8 *nonce_s)
    307 {
    308 	struct eap_sim_msg *msg;
    309 	unsigned int counter;
    310 
    311 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Reauthentication (id=%d)",
    312 		   req->identifier);
    313 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
    314 			       EAP_TYPE_AKA,
    315 			       EAP_AKA_SUBTYPE_REAUTHENTICATION);
    316 	wpa_printf(MSG_DEBUG, "   AT_IV");
    317 	wpa_printf(MSG_DEBUG, "   AT_ENCR_DATA");
    318 	eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, EAP_SIM_AT_ENCR_DATA);
    319 
    320 	if (counter_too_small) {
    321 		wpa_printf(MSG_DEBUG, "   *AT_COUNTER_TOO_SMALL");
    322 		eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER_TOO_SMALL, 0, NULL, 0);
    323 		counter = data->counter_too_small;
    324 	} else
    325 		counter = data->counter;
    326 
    327 	wpa_printf(MSG_DEBUG, "   *AT_COUNTER %d", counter);
    328 	eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, counter, NULL, 0);
    329 
    330 	if (eap_sim_msg_add_encr_end(msg, data->k_encr, EAP_SIM_AT_PADDING)) {
    331 		wpa_printf(MSG_WARNING, "EAP-AKA: Failed to encrypt "
    332 			   "AT_ENCR_DATA");
    333 		eap_sim_msg_free(msg);
    334 		return NULL;
    335 	}
    336 	wpa_printf(MSG_DEBUG, "   AT_MAC");
    337 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
    338 	return eap_sim_msg_finish(msg, respDataLen, data->k_aut, nonce_s,
    339 				  EAP_SIM_NONCE_S_LEN);
    340 }
    341 
    342 
    343 static u8 * eap_aka_response_notification(struct eap_aka_data *data,
    344 					  const struct eap_hdr *req,
    345 					  size_t *respDataLen,
    346 					  u16 notification)
    347 {
    348 	struct eap_sim_msg *msg;
    349 	u8 *k_aut = (notification & 0x4000) == 0 ? data->k_aut : NULL;
    350 
    351 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Notification (id=%d)",
    352 		   req->identifier);
    353 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
    354 			       EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION);
    355 	if (k_aut && data->reauth) {
    356 		wpa_printf(MSG_DEBUG, "   AT_IV");
    357 		wpa_printf(MSG_DEBUG, "   AT_ENCR_DATA");
    358 		eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV,
    359 					   EAP_SIM_AT_ENCR_DATA);
    360 		wpa_printf(MSG_DEBUG, "   *AT_COUNTER %d", data->counter);
    361 		eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, data->counter,
    362 				NULL, 0);
    363 		if (eap_sim_msg_add_encr_end(msg, data->k_encr,
    364 					     EAP_SIM_AT_PADDING)) {
    365 			wpa_printf(MSG_WARNING, "EAP-AKA: Failed to encrypt "
    366 				   "AT_ENCR_DATA");
    367 			eap_sim_msg_free(msg);
    368 			return NULL;
    369 		}
    370 	}
    371 	if (k_aut) {
    372 		wpa_printf(MSG_DEBUG, "   AT_MAC");
    373 		eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
    374 	}
    375 	return eap_sim_msg_finish(msg, respDataLen, k_aut, (u8 *) "", 0);
    376 }
    377 
    378 
    379 static u8 * eap_aka_process_identity(struct eap_sm *sm,
    380 				     struct eap_aka_data *data,
    381 				     const struct eap_hdr *req,
    382 				     size_t *respDataLen,
    383 				     struct eap_sim_attrs *attr)
    384 {
    385 	int id_error;
    386 
    387 	wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Identity");
    388 
    389 	id_error = 0;
    390 	switch (attr->id_req) {
    391 	case NO_ID_REQ:
    392 		break;
    393 	case ANY_ID:
    394 		if (data->num_id_req > 0)
    395 			id_error++;
    396 		data->num_id_req++;
    397 		break;
    398 	case FULLAUTH_ID:
    399 		if (data->num_id_req > 1)
    400 			id_error++;
    401 		data->num_id_req++;
    402 		break;
    403 	case PERMANENT_ID:
    404 		if (data->num_id_req > 2)
    405 			id_error++;
    406 		data->num_id_req++;
    407 		break;
    408 	}
    409 	if (id_error) {
    410 		wpa_printf(MSG_INFO, "EAP-AKA: Too many ID requests "
    411 			   "used within one authentication");
    412 		return eap_aka_client_error(data, req, respDataLen,
    413 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
    414 	}
    415 
    416 	return eap_aka_response_identity(sm, data, req, respDataLen,
    417 					 attr->id_req);
    418 }
    419 
    420 
    421 static u8 * eap_aka_process_challenge(struct eap_sm *sm,
    422 				      struct eap_aka_data *data,
    423 				      const struct eap_hdr *req,
    424 				      size_t reqDataLen,
    425 				      size_t *respDataLen,
    426 				      struct eap_sim_attrs *attr)
    427 {
    428 	const u8 *identity;
    429 	size_t identity_len;
    430 	int res;
    431 	struct eap_sim_attrs eattr;
    432 
    433 	wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Challenge");
    434 	data->reauth = 0;
    435 	if (!attr->mac || !attr->rand || !attr->autn) {
    436 		wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
    437 			   "did not include%s%s%s",
    438 			   !attr->mac ? " AT_MAC" : "",
    439 			   !attr->rand ? " AT_RAND" : "",
    440 			   !attr->autn ? " AT_AUTN" : "");
    441 		return eap_aka_client_error(data, req, respDataLen,
    442 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
    443 	}
    444 	os_memcpy(data->rand, attr->rand, EAP_AKA_RAND_LEN);
    445 	os_memcpy(data->autn, attr->autn, EAP_AKA_AUTN_LEN);
    446 
    447 	res = eap_aka_umts_auth(sm, data);
    448 	if (res == -1) {
    449 		wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication "
    450 			   "failed (AUTN)");
    451 		return eap_aka_authentication_reject(data, req, respDataLen);
    452 	} else if (res == -2) {
    453 		wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication "
    454 			   "failed (AUTN seq# -> AUTS)");
    455 		return eap_aka_synchronization_failure(data, req, respDataLen);
    456 	} else if (res) {
    457 		wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication failed");
    458 		return eap_aka_client_error(data, req, respDataLen,
    459 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
    460 	}
    461 	if (data->last_eap_identity) {
    462 		identity = data->last_eap_identity;
    463 		identity_len = data->last_eap_identity_len;
    464 	} else if (data->pseudonym) {
    465 		identity = data->pseudonym;
    466 		identity_len = data->pseudonym_len;
    467 	} else
    468 		identity = eap_get_config_identity(sm, &identity_len);
    469 	wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Selected identity for MK "
    470 			  "derivation", identity, identity_len);
    471 	eap_aka_derive_mk(identity, identity_len, data->ik, data->ck,
    472 			  data->mk);
    473 	eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,
    474 			    data->emsk);
    475 	if (eap_sim_verify_mac(data->k_aut, (const u8 *) req, reqDataLen,
    476 			       attr->mac, (u8 *) "", 0)) {
    477 		wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
    478 			   "used invalid AT_MAC");
    479 		return eap_aka_client_error(data, req, respDataLen,
    480 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
    481 	}
    482 
    483 	/* Old reauthentication and pseudonym identities must not be used
    484 	 * anymore. In other words, if no new identities are received, full
    485 	 * authentication will be used on next reauthentication. */
    486 	eap_aka_clear_identities(data, CLEAR_PSEUDONYM | CLEAR_REAUTH_ID |
    487 				 CLEAR_EAP_ID);
    488 
    489 	if (attr->encr_data) {
    490 		u8 *decrypted;
    491 		decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
    492 					       attr->encr_data_len, attr->iv,
    493 					       &eattr, 0);
    494 		if (decrypted == NULL) {
    495 			return eap_aka_client_error(
    496 				data, req, respDataLen,
    497 				EAP_AKA_UNABLE_TO_PROCESS_PACKET);
    498 		}
    499 		eap_aka_learn_ids(data, &eattr);
    500 		os_free(decrypted);
    501 	}
    502 
    503 	if (data->state != FAILURE)
    504 		data->state = SUCCESS;
    505 
    506 	data->num_id_req = 0;
    507 	data->num_notification = 0;
    508 	/* RFC 4187 specifies that counter is initialized to one after
    509 	 * fullauth, but initializing it to zero makes it easier to implement
    510 	 * reauth verification. */
    511 	data->counter = 0;
    512 	return eap_aka_response_challenge(data, req, respDataLen);
    513 }
    514 
    515 
    516 static int eap_aka_process_notification_reauth(struct eap_aka_data *data,
    517 					       struct eap_sim_attrs *attr)
    518 {
    519 	struct eap_sim_attrs eattr;
    520 	u8 *decrypted;
    521 
    522 	if (attr->encr_data == NULL || attr->iv == NULL) {
    523 		wpa_printf(MSG_WARNING, "EAP-AKA: Notification message after "
    524 			   "reauth did not include encrypted data");
    525 		return -1;
    526 	}
    527 
    528 	decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
    529 				       attr->encr_data_len, attr->iv, &eattr,
    530 				       0);
    531 	if (decrypted == NULL) {
    532 		wpa_printf(MSG_WARNING, "EAP-AKA: Failed to parse encrypted "
    533 			   "data from notification message");
    534 		return -1;
    535 	}
    536 
    537 	if (eattr.counter < 0 || (size_t) eattr.counter != data->counter) {
    538 		wpa_printf(MSG_WARNING, "EAP-AKA: Counter in notification "
    539 			   "message does not match with counter in reauth "
    540 			   "message");
    541 		os_free(decrypted);
    542 		return -1;
    543 	}
    544 
    545 	os_free(decrypted);
    546 	return 0;
    547 }
    548 
    549 
    550 static int eap_aka_process_notification_auth(struct eap_aka_data *data,
    551 					     const struct eap_hdr *req,
    552 					     size_t reqDataLen,
    553 					     struct eap_sim_attrs *attr)
    554 {
    555 	if (attr->mac == NULL) {
    556 		wpa_printf(MSG_INFO, "EAP-AKA: no AT_MAC in after_auth "
    557 			   "Notification message");
    558 		return -1;
    559 	}
    560 
    561 	if (eap_sim_verify_mac(data->k_aut, (const u8 *) req, reqDataLen,
    562 			       attr->mac, (u8 *) "", 0)) {
    563 		wpa_printf(MSG_WARNING, "EAP-AKA: Notification message "
    564 			   "used invalid AT_MAC");
    565 		return -1;
    566 	}
    567 
    568 	if (data->reauth &&
    569 	    eap_aka_process_notification_reauth(data, attr)) {
    570 		wpa_printf(MSG_WARNING, "EAP-AKA: Invalid notification "
    571 			   "message after reauth");
    572 		return -1;
    573 	}
    574 
    575 	return 0;
    576 }
    577 
    578 
    579 static u8 * eap_aka_process_notification(struct eap_sm *sm,
    580 					 struct eap_aka_data *data,
    581 					 const struct eap_hdr *req,
    582 					 size_t reqDataLen,
    583 					 size_t *respDataLen,
    584 					 struct eap_sim_attrs *attr)
    585 {
    586 	wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Notification");
    587 	if (data->num_notification > 0) {
    588 		wpa_printf(MSG_INFO, "EAP-AKA: too many notification "
    589 			   "rounds (only one allowed)");
    590 		return eap_aka_client_error(data, req, respDataLen,
    591 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
    592 	}
    593 	data->num_notification++;
    594 	if (attr->notification == -1) {
    595 		wpa_printf(MSG_INFO, "EAP-AKA: no AT_NOTIFICATION in "
    596 			   "Notification message");
    597 		return eap_aka_client_error(data, req, respDataLen,
    598 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
    599 	}
    600 
    601 	if ((attr->notification & 0x4000) == 0 &&
    602 	    eap_aka_process_notification_auth(data, req, reqDataLen, attr)) {
    603 		return eap_aka_client_error(data, req, respDataLen,
    604 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
    605 	}
    606 
    607 	eap_sim_report_notification(sm->msg_ctx, attr->notification, 1);
    608 	if (attr->notification >= 0 && attr->notification < 32768) {
    609 		data->state = FAILURE;
    610 	}
    611 	return eap_aka_response_notification(data, req, respDataLen,
    612 					     attr->notification);
    613 }
    614 
    615 
    616 static u8 * eap_aka_process_reauthentication(struct eap_sm *sm,
    617 					     struct eap_aka_data *data,
    618 					     const struct eap_hdr *req,
    619 					     size_t reqDataLen,
    620 					     size_t *respDataLen,
    621 					     struct eap_sim_attrs *attr)
    622 {
    623 	struct eap_sim_attrs eattr;
    624 	u8 *decrypted;
    625 
    626 	wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Reauthentication");
    627 
    628 	if (data->reauth_id == NULL) {
    629 		wpa_printf(MSG_WARNING, "EAP-AKA: Server is trying "
    630 			   "reauthentication, but no reauth_id available");
    631 		return eap_aka_client_error(data, req, respDataLen,
    632 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
    633 	}
    634 
    635 	data->reauth = 1;
    636 	if (eap_sim_verify_mac(data->k_aut, (const u8 *) req, reqDataLen,
    637 			       attr->mac, (u8 *) "", 0)) {
    638 		wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication "
    639 			   "did not have valid AT_MAC");
    640 		return eap_aka_client_error(data, req, respDataLen,
    641 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
    642 	}
    643 
    644 	if (attr->encr_data == NULL || attr->iv == NULL) {
    645 		wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication "
    646 			   "message did not include encrypted data");
    647 		return eap_aka_client_error(data, req, respDataLen,
    648 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
    649 	}
    650 
    651 	decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
    652 				       attr->encr_data_len, attr->iv, &eattr,
    653 				       0);
    654 	if (decrypted == NULL) {
    655 		wpa_printf(MSG_WARNING, "EAP-AKA: Failed to parse encrypted "
    656 			   "data from reauthentication message");
    657 		return eap_aka_client_error(data, req, respDataLen,
    658 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
    659 	}
    660 
    661 	if (eattr.nonce_s == NULL || eattr.counter < 0) {
    662 		wpa_printf(MSG_INFO, "EAP-AKA: (encr) No%s%s in reauth packet",
    663 			   !eattr.nonce_s ? " AT_NONCE_S" : "",
    664 			   eattr.counter < 0 ? " AT_COUNTER" : "");
    665 		os_free(decrypted);
    666 		return eap_aka_client_error(data, req, respDataLen,
    667 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
    668 	}
    669 
    670 	if (eattr.counter < 0 || (size_t) eattr.counter <= data->counter) {
    671 		u8 *res;
    672 		wpa_printf(MSG_INFO, "EAP-AKA: (encr) Invalid counter "
    673 			   "(%d <= %d)", eattr.counter, data->counter);
    674 		data->counter_too_small = eattr.counter;
    675 
    676 		eap_sim_derive_keys_reauth(eattr.counter, data->reauth_id,
    677 					   data->reauth_id_len, eattr.nonce_s,
    678 					   data->mk, NULL, NULL);
    679 
    680 		/* Reply using Re-auth w/ AT_COUNTER_TOO_SMALL. The current
    681 		 * reauth_id must not be used to start a new reauthentication.
    682 		 * However, since it was used in the last EAP-Response-Identity
    683 		 * packet, it has to saved for the following fullauth to be
    684 		 * used in MK derivation. */
    685 		os_free(data->last_eap_identity);
    686 		data->last_eap_identity = data->reauth_id;
    687 		data->last_eap_identity_len = data->reauth_id_len;
    688 		data->reauth_id = NULL;
    689 		data->reauth_id_len = 0;
    690 
    691 		res = eap_aka_response_reauth(data, req, respDataLen, 1,
    692 					      eattr.nonce_s);
    693 		os_free(decrypted);
    694 
    695 		return res;
    696 	}
    697 	data->counter = eattr.counter;
    698 
    699 	os_memcpy(data->nonce_s, eattr.nonce_s, EAP_SIM_NONCE_S_LEN);
    700 	wpa_hexdump(MSG_DEBUG, "EAP-AKA: (encr) AT_NONCE_S",
    701 		    data->nonce_s, EAP_SIM_NONCE_S_LEN);
    702 
    703 	eap_sim_derive_keys_reauth(data->counter,
    704 				   data->reauth_id, data->reauth_id_len,
    705 				   data->nonce_s, data->mk, data->msk,
    706 				   data->emsk);
    707 	eap_aka_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
    708 	eap_aka_learn_ids(data, &eattr);
    709 
    710 	if (data->state != FAILURE)
    711 		data->state = SUCCESS;
    712 
    713 	data->num_id_req = 0;
    714 	data->num_notification = 0;
    715 	if (data->counter > EAP_AKA_MAX_FAST_REAUTHS) {
    716 		wpa_printf(MSG_DEBUG, "EAP-AKA: Maximum number of "
    717 			   "fast reauths performed - force fullauth");
    718 		eap_aka_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
    719 	}
    720 	os_free(decrypted);
    721 	return eap_aka_response_reauth(data, req, respDataLen, 0,
    722 				       data->nonce_s);
    723 }
    724 
    725 
    726 static u8 * eap_aka_process(struct eap_sm *sm, void *priv,
    727 			    struct eap_method_ret *ret,
    728 			    const u8 *reqData, size_t reqDataLen,
    729 			    size_t *respDataLen)
    730 {
    731 	struct eap_aka_data *data = priv;
    732 	const struct eap_hdr *req;
    733 	u8 subtype, *res;
    734 	const u8 *pos;
    735 	struct eap_sim_attrs attr;
    736 	size_t len;
    737 
    738 	wpa_hexdump(MSG_DEBUG, "EAP-AKA: EAP data", reqData, reqDataLen);
    739 	if (eap_get_config_identity(sm, &len) == NULL) {
    740 		wpa_printf(MSG_INFO, "EAP-AKA: Identity not configured");
    741 		eap_sm_request_identity(sm);
    742 		ret->ignore = TRUE;
    743 		return NULL;
    744 	}
    745 
    746 	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_AKA,
    747 			       reqData, reqDataLen, &len);
    748 	if (pos == NULL || len < 1) {
    749 		ret->ignore = TRUE;
    750 		return NULL;
    751 	}
    752 	req = (const struct eap_hdr *) reqData;
    753 	len = be_to_host16(req->length);
    754 
    755 	ret->ignore = FALSE;
    756 	ret->methodState = METHOD_MAY_CONT;
    757 	ret->decision = DECISION_FAIL;
    758 	ret->allowNotifications = TRUE;
    759 
    760 	subtype = *pos++;
    761 	wpa_printf(MSG_DEBUG, "EAP-AKA: Subtype=%d", subtype);
    762 	pos += 2; /* Reserved */
    763 
    764 	if (eap_sim_parse_attr(pos, reqData + len, &attr, 1, 0)) {
    765 		res = eap_aka_client_error(data, req, respDataLen,
    766 					   EAP_AKA_UNABLE_TO_PROCESS_PACKET);
    767 		goto done;
    768 	}
    769 
    770 	switch (subtype) {
    771 	case EAP_AKA_SUBTYPE_IDENTITY:
    772 		res = eap_aka_process_identity(sm, data, req,
    773 					       respDataLen, &attr);
    774 		break;
    775 	case EAP_AKA_SUBTYPE_CHALLENGE:
    776 		res = eap_aka_process_challenge(sm, data, req, len,
    777 						respDataLen, &attr);
    778 		break;
    779 	case EAP_AKA_SUBTYPE_NOTIFICATION:
    780 		res = eap_aka_process_notification(sm, data, req, len,
    781 						   respDataLen, &attr);
    782 		break;
    783 	case EAP_AKA_SUBTYPE_REAUTHENTICATION:
    784 		res = eap_aka_process_reauthentication(sm, data, req, len,
    785 						       respDataLen, &attr);
    786 		break;
    787 	case EAP_AKA_SUBTYPE_CLIENT_ERROR:
    788 		wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Client-Error");
    789 		res = eap_aka_client_error(data, req, respDataLen,
    790 					   EAP_AKA_UNABLE_TO_PROCESS_PACKET);
    791 		break;
    792 	default:
    793 		wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown subtype=%d", subtype);
    794 		res = eap_aka_client_error(data, req, respDataLen,
    795 					   EAP_AKA_UNABLE_TO_PROCESS_PACKET);
    796 		break;
    797 	}
    798 
    799 done:
    800 	if (data->state == FAILURE) {
    801 		ret->decision = DECISION_FAIL;
    802 		ret->methodState = METHOD_DONE;
    803 	} else if (data->state == SUCCESS) {
    804 		ret->decision = DECISION_COND_SUCC;
    805 		/*
    806 		 * It is possible for the server to reply with AKA
    807 		 * Notification, so we must allow the method to continue and
    808 		 * not only accept EAP-Success at this point.
    809 		 */
    810 		ret->methodState = METHOD_MAY_CONT;
    811 	}
    812 
    813 	if (ret->methodState == METHOD_DONE) {
    814 		ret->allowNotifications = FALSE;
    815 	}
    816 
    817 	return res;
    818 }
    819 
    820 
    821 static Boolean eap_aka_has_reauth_data(struct eap_sm *sm, void *priv)
    822 {
    823 	struct eap_aka_data *data = priv;
    824 	return data->pseudonym || data->reauth_id;
    825 }
    826 
    827 
    828 static void eap_aka_deinit_for_reauth(struct eap_sm *sm, void *priv)
    829 {
    830 	struct eap_aka_data *data = priv;
    831 	eap_aka_clear_identities(data, CLEAR_EAP_ID);
    832 }
    833 
    834 
    835 static void * eap_aka_init_for_reauth(struct eap_sm *sm, void *priv)
    836 {
    837 	struct eap_aka_data *data = priv;
    838 	data->num_id_req = 0;
    839 	data->num_notification = 0;
    840 	data->state = CONTINUE;
    841 	return priv;
    842 }
    843 
    844 
    845 static const u8 * eap_aka_get_identity(struct eap_sm *sm, void *priv,
    846 				       size_t *len)
    847 {
    848 	struct eap_aka_data *data = priv;
    849 
    850 	if (data->reauth_id) {
    851 		*len = data->reauth_id_len;
    852 		return data->reauth_id;
    853 	}
    854 
    855 	if (data->pseudonym) {
    856 		*len = data->pseudonym_len;
    857 		return data->pseudonym;
    858 	}
    859 
    860 	return NULL;
    861 }
    862 
    863 
    864 static Boolean eap_aka_isKeyAvailable(struct eap_sm *sm, void *priv)
    865 {
    866 	struct eap_aka_data *data = priv;
    867 	return data->state == SUCCESS;
    868 }
    869 
    870 
    871 static u8 * eap_aka_getKey(struct eap_sm *sm, void *priv, size_t *len)
    872 {
    873 	struct eap_aka_data *data = priv;
    874 	u8 *key;
    875 
    876 	if (data->state != SUCCESS)
    877 		return NULL;
    878 
    879 	key = os_malloc(EAP_SIM_KEYING_DATA_LEN);
    880 	if (key == NULL)
    881 		return NULL;
    882 
    883 	*len = EAP_SIM_KEYING_DATA_LEN;
    884 	os_memcpy(key, data->msk, EAP_SIM_KEYING_DATA_LEN);
    885 
    886 	return key;
    887 }
    888 
    889 
    890 static u8 * eap_aka_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
    891 {
    892 	struct eap_aka_data *data = priv;
    893 	u8 *key;
    894 
    895 	if (data->state != SUCCESS)
    896 		return NULL;
    897 
    898 	key = os_malloc(EAP_EMSK_LEN);
    899 	if (key == NULL)
    900 		return NULL;
    901 
    902 	*len = EAP_EMSK_LEN;
    903 	os_memcpy(key, data->emsk, EAP_EMSK_LEN);
    904 
    905 	return key;
    906 }
    907 
    908 
    909 int eap_peer_aka_register(void)
    910 {
    911 	struct eap_method *eap;
    912 	int ret;
    913 
    914 	eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
    915 				    EAP_VENDOR_IETF, EAP_TYPE_AKA, "AKA");
    916 	if (eap == NULL)
    917 		return -1;
    918 
    919 	eap->init = eap_aka_init;
    920 	eap->deinit = eap_aka_deinit;
    921 	eap->process = eap_aka_process;
    922 	eap->isKeyAvailable = eap_aka_isKeyAvailable;
    923 	eap->getKey = eap_aka_getKey;
    924 	eap->has_reauth_data = eap_aka_has_reauth_data;
    925 	eap->deinit_for_reauth = eap_aka_deinit_for_reauth;
    926 	eap->init_for_reauth = eap_aka_init_for_reauth;
    927 	eap->get_identity = eap_aka_get_identity;
    928 	eap->get_emsk = eap_aka_get_emsk;
    929 
    930 	ret = eap_peer_method_register(eap);
    931 	if (ret)
    932 		eap_peer_method_free(eap);
    933 	return ret;
    934 }
    935