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