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 *msg1, 446 const struct wpabuf *msg2) 447 { 448 size_t len; 449 450 if (!msg1) 451 return -1; 452 len = wpabuf_len(msg1); 453 if (msg2) 454 len += wpabuf_len(msg2); 455 456 if (!data->id_msgs) { 457 data->id_msgs = wpabuf_alloc(len); 458 if (!data->id_msgs) 459 return -1; 460 } else if (wpabuf_resize(&data->id_msgs, len) < 0) { 461 return -1; 462 } 463 464 wpabuf_put_buf(data->id_msgs, msg1); 465 if (msg2) 466 wpabuf_put_buf(data->id_msgs, msg2); 467 468 return 0; 469 } 470 471 472 static void eap_aka_add_checkcode(struct eap_aka_data *data, 473 struct eap_sim_msg *msg) 474 { 475 const u8 *addr; 476 size_t len; 477 u8 hash[SHA256_MAC_LEN]; 478 479 wpa_printf(MSG_DEBUG, " AT_CHECKCODE"); 480 481 if (data->id_msgs == NULL) { 482 /* 483 * No EAP-AKA/Identity packets were exchanged - send empty 484 * checkcode. 485 */ 486 eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, NULL, 0); 487 return; 488 } 489 490 /* Checkcode is SHA1/SHA256 hash over all EAP-AKA/Identity packets. */ 491 addr = wpabuf_head(data->id_msgs); 492 len = wpabuf_len(data->id_msgs); 493 wpa_hexdump(MSG_MSGDUMP, "EAP-AKA: AT_CHECKCODE data", addr, len); 494 #ifdef EAP_AKA_PRIME 495 if (data->eap_method == EAP_TYPE_AKA_PRIME) 496 sha256_vector(1, &addr, &len, hash); 497 else 498 #endif /* EAP_AKA_PRIME */ 499 sha1_vector(1, &addr, &len, hash); 500 501 eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, hash, 502 data->eap_method == EAP_TYPE_AKA_PRIME ? 503 EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN); 504 } 505 506 507 static int eap_aka_verify_checkcode(struct eap_aka_data *data, 508 const u8 *checkcode, size_t checkcode_len) 509 { 510 const u8 *addr; 511 size_t len; 512 u8 hash[SHA256_MAC_LEN]; 513 size_t hash_len; 514 515 if (checkcode == NULL) 516 return -1; 517 518 if (data->id_msgs == NULL) { 519 if (checkcode_len != 0) { 520 wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from server " 521 "indicates that AKA/Identity messages were " 522 "used, but they were not"); 523 return -1; 524 } 525 return 0; 526 } 527 528 hash_len = data->eap_method == EAP_TYPE_AKA_PRIME ? 529 EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN; 530 531 if (checkcode_len != hash_len) { 532 wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from server " 533 "indicates that AKA/Identity message were not " 534 "used, but they were"); 535 return -1; 536 } 537 538 /* Checkcode is SHA1/SHA256 hash over all EAP-AKA/Identity packets. */ 539 addr = wpabuf_head(data->id_msgs); 540 len = wpabuf_len(data->id_msgs); 541 #ifdef EAP_AKA_PRIME 542 if (data->eap_method == EAP_TYPE_AKA_PRIME) 543 sha256_vector(1, &addr, &len, hash); 544 else 545 #endif /* EAP_AKA_PRIME */ 546 sha1_vector(1, &addr, &len, hash); 547 548 if (os_memcmp_const(hash, checkcode, hash_len) != 0) { 549 wpa_printf(MSG_DEBUG, "EAP-AKA: Mismatch in AT_CHECKCODE"); 550 return -1; 551 } 552 553 return 0; 554 } 555 556 557 static struct wpabuf * eap_aka_client_error(struct eap_aka_data *data, u8 id, 558 int err) 559 { 560 struct eap_sim_msg *msg; 561 562 eap_aka_state(data, FAILURE); 563 data->num_id_req = 0; 564 data->num_notification = 0; 565 566 wpa_printf(MSG_DEBUG, "EAP-AKA: Send Client-Error (error code %d)", 567 err); 568 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method, 569 EAP_AKA_SUBTYPE_CLIENT_ERROR); 570 eap_sim_msg_add(msg, EAP_SIM_AT_CLIENT_ERROR_CODE, err, NULL, 0); 571 return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0); 572 } 573 574 575 static struct wpabuf * eap_aka_authentication_reject(struct eap_aka_data *data, 576 u8 id) 577 { 578 struct eap_sim_msg *msg; 579 580 eap_aka_state(data, FAILURE); 581 data->num_id_req = 0; 582 data->num_notification = 0; 583 584 wpa_printf(MSG_DEBUG, "Generating EAP-AKA Authentication-Reject " 585 "(id=%d)", id); 586 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method, 587 EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT); 588 return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0); 589 } 590 591 592 static struct wpabuf * eap_aka_synchronization_failure( 593 struct eap_aka_data *data, u8 id, struct eap_sim_attrs *attr) 594 { 595 struct eap_sim_msg *msg; 596 597 data->num_id_req = 0; 598 data->num_notification = 0; 599 600 wpa_printf(MSG_DEBUG, "Generating EAP-AKA Synchronization-Failure " 601 "(id=%d)", id); 602 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method, 603 EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE); 604 wpa_printf(MSG_DEBUG, " AT_AUTS"); 605 eap_sim_msg_add_full(msg, EAP_SIM_AT_AUTS, data->auts, 606 EAP_AKA_AUTS_LEN); 607 if (data->eap_method == EAP_TYPE_AKA_PRIME) { 608 size_t i; 609 610 for (i = 0; i < attr->kdf_count; i++) { 611 wpa_printf(MSG_DEBUG, " AT_KDF"); 612 eap_sim_msg_add(msg, EAP_SIM_AT_KDF, attr->kdf[i], 613 NULL, 0); 614 } 615 } 616 return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0); 617 } 618 619 620 static struct wpabuf * eap_aka_response_identity(struct eap_sm *sm, 621 struct eap_aka_data *data, 622 u8 id, 623 enum eap_sim_id_req id_req) 624 { 625 const u8 *identity = NULL; 626 size_t identity_len = 0; 627 struct eap_sim_msg *msg; 628 629 data->reauth = 0; 630 if (id_req == ANY_ID && data->reauth_id) { 631 identity = data->reauth_id; 632 identity_len = data->reauth_id_len; 633 data->reauth = 1; 634 } else if ((id_req == ANY_ID || id_req == FULLAUTH_ID) && 635 data->pseudonym && 636 !eap_sim_anonymous_username(data->pseudonym, 637 data->pseudonym_len)) { 638 identity = data->pseudonym; 639 identity_len = data->pseudonym_len; 640 eap_aka_clear_identities(sm, data, CLEAR_REAUTH_ID); 641 } else if (id_req != NO_ID_REQ) { 642 identity = eap_get_config_identity(sm, &identity_len); 643 if (identity) { 644 int ids = CLEAR_PSEUDONYM | CLEAR_REAUTH_ID; 645 646 if (data->pseudonym && 647 eap_sim_anonymous_username(data->pseudonym, 648 data->pseudonym_len)) 649 ids &= ~CLEAR_PSEUDONYM; 650 eap_aka_clear_identities(sm, data, ids); 651 } 652 } 653 if (id_req != NO_ID_REQ) 654 eap_aka_clear_identities(sm, data, CLEAR_EAP_ID); 655 656 wpa_printf(MSG_DEBUG, "Generating EAP-AKA Identity (id=%d)", id); 657 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method, 658 EAP_AKA_SUBTYPE_IDENTITY); 659 660 if (identity) { 661 wpa_hexdump_ascii(MSG_DEBUG, " AT_IDENTITY", 662 identity, identity_len); 663 eap_sim_msg_add(msg, EAP_SIM_AT_IDENTITY, identity_len, 664 identity, identity_len); 665 } 666 667 return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0); 668 } 669 670 671 static struct wpabuf * eap_aka_response_challenge(struct eap_aka_data *data, 672 u8 id) 673 { 674 struct eap_sim_msg *msg; 675 676 wpa_printf(MSG_DEBUG, "Generating EAP-AKA Challenge (id=%d)", id); 677 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method, 678 EAP_AKA_SUBTYPE_CHALLENGE); 679 wpa_printf(MSG_DEBUG, " AT_RES"); 680 eap_sim_msg_add(msg, EAP_SIM_AT_RES, data->res_len * 8, 681 data->res, data->res_len); 682 eap_aka_add_checkcode(data, msg); 683 if (data->use_result_ind) { 684 wpa_printf(MSG_DEBUG, " AT_RESULT_IND"); 685 eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0); 686 } 687 wpa_printf(MSG_DEBUG, " AT_MAC"); 688 eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); 689 return eap_sim_msg_finish(msg, data->eap_method, data->k_aut, (u8 *) "", 690 0); 691 } 692 693 694 static struct wpabuf * eap_aka_response_reauth(struct eap_aka_data *data, 695 u8 id, int counter_too_small, 696 const u8 *nonce_s) 697 { 698 struct eap_sim_msg *msg; 699 unsigned int counter; 700 701 wpa_printf(MSG_DEBUG, "Generating EAP-AKA Reauthentication (id=%d)", 702 id); 703 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method, 704 EAP_AKA_SUBTYPE_REAUTHENTICATION); 705 wpa_printf(MSG_DEBUG, " AT_IV"); 706 wpa_printf(MSG_DEBUG, " AT_ENCR_DATA"); 707 eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, EAP_SIM_AT_ENCR_DATA); 708 709 if (counter_too_small) { 710 wpa_printf(MSG_DEBUG, " *AT_COUNTER_TOO_SMALL"); 711 eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER_TOO_SMALL, 0, NULL, 0); 712 counter = data->counter_too_small; 713 } else 714 counter = data->counter; 715 716 wpa_printf(MSG_DEBUG, " *AT_COUNTER %d", counter); 717 eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, counter, NULL, 0); 718 719 if (eap_sim_msg_add_encr_end(msg, data->k_encr, EAP_SIM_AT_PADDING)) { 720 wpa_printf(MSG_WARNING, "EAP-AKA: Failed to encrypt " 721 "AT_ENCR_DATA"); 722 eap_sim_msg_free(msg); 723 return NULL; 724 } 725 eap_aka_add_checkcode(data, msg); 726 if (data->use_result_ind) { 727 wpa_printf(MSG_DEBUG, " AT_RESULT_IND"); 728 eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0); 729 } 730 wpa_printf(MSG_DEBUG, " AT_MAC"); 731 eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); 732 return eap_sim_msg_finish(msg, data->eap_method, data->k_aut, nonce_s, 733 EAP_SIM_NONCE_S_LEN); 734 } 735 736 737 static struct wpabuf * eap_aka_response_notification(struct eap_aka_data *data, 738 u8 id, u16 notification) 739 { 740 struct eap_sim_msg *msg; 741 u8 *k_aut = (notification & 0x4000) == 0 ? data->k_aut : NULL; 742 743 wpa_printf(MSG_DEBUG, "Generating EAP-AKA Notification (id=%d)", id); 744 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method, 745 EAP_AKA_SUBTYPE_NOTIFICATION); 746 if (k_aut && data->reauth) { 747 wpa_printf(MSG_DEBUG, " AT_IV"); 748 wpa_printf(MSG_DEBUG, " AT_ENCR_DATA"); 749 eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, 750 EAP_SIM_AT_ENCR_DATA); 751 wpa_printf(MSG_DEBUG, " *AT_COUNTER %d", data->counter); 752 eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, data->counter, 753 NULL, 0); 754 if (eap_sim_msg_add_encr_end(msg, data->k_encr, 755 EAP_SIM_AT_PADDING)) { 756 wpa_printf(MSG_WARNING, "EAP-AKA: Failed to encrypt " 757 "AT_ENCR_DATA"); 758 eap_sim_msg_free(msg); 759 return NULL; 760 } 761 } 762 if (k_aut) { 763 wpa_printf(MSG_DEBUG, " AT_MAC"); 764 eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); 765 } 766 return eap_sim_msg_finish(msg, data->eap_method, k_aut, (u8 *) "", 0); 767 } 768 769 770 static struct wpabuf * eap_aka_process_identity(struct eap_sm *sm, 771 struct eap_aka_data *data, 772 u8 id, 773 const struct wpabuf *reqData, 774 struct eap_sim_attrs *attr) 775 { 776 int id_error; 777 struct wpabuf *buf; 778 779 wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Identity"); 780 781 id_error = 0; 782 switch (attr->id_req) { 783 case NO_ID_REQ: 784 break; 785 case ANY_ID: 786 if (data->num_id_req > 0) 787 id_error++; 788 data->num_id_req++; 789 break; 790 case FULLAUTH_ID: 791 if (data->num_id_req > 1) 792 id_error++; 793 data->num_id_req++; 794 break; 795 case PERMANENT_ID: 796 if (data->num_id_req > 2) 797 id_error++; 798 data->num_id_req++; 799 break; 800 } 801 if (id_error) { 802 wpa_printf(MSG_INFO, "EAP-AKA: Too many ID requests " 803 "used within one authentication"); 804 return eap_aka_client_error(data, id, 805 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 806 } 807 808 buf = eap_aka_response_identity(sm, data, id, attr->id_req); 809 810 if (data->prev_id != id) { 811 if (eap_aka_add_id_msg(data, reqData, buf) < 0) { 812 wpa_printf(MSG_INFO, 813 "EAP-AKA: Failed to store ID messages"); 814 wpabuf_free(buf); 815 return eap_aka_client_error( 816 data, id, EAP_AKA_UNABLE_TO_PROCESS_PACKET); 817 } 818 data->prev_id = id; 819 } 820 821 return buf; 822 } 823 824 825 static int eap_aka_verify_mac(struct eap_aka_data *data, 826 const struct wpabuf *req, 827 const u8 *mac, const u8 *extra, 828 size_t extra_len) 829 { 830 if (data->eap_method == EAP_TYPE_AKA_PRIME) 831 return eap_sim_verify_mac_sha256(data->k_aut, req, mac, extra, 832 extra_len); 833 return eap_sim_verify_mac(data->k_aut, req, mac, extra, extra_len); 834 } 835 836 837 #ifdef EAP_AKA_PRIME 838 static struct wpabuf * eap_aka_prime_kdf_select(struct eap_aka_data *data, 839 u8 id, u16 kdf) 840 { 841 struct eap_sim_msg *msg; 842 843 data->kdf_negotiation = 1; 844 data->kdf = kdf; 845 wpa_printf(MSG_DEBUG, "Generating EAP-AKA Challenge (id=%d) (KDF " 846 "select)", id); 847 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method, 848 EAP_AKA_SUBTYPE_CHALLENGE); 849 wpa_printf(MSG_DEBUG, " AT_KDF"); 850 eap_sim_msg_add(msg, EAP_SIM_AT_KDF, kdf, NULL, 0); 851 return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0); 852 } 853 854 855 static struct wpabuf * eap_aka_prime_kdf_neg(struct eap_aka_data *data, 856 u8 id, struct eap_sim_attrs *attr) 857 { 858 size_t i; 859 860 for (i = 0; i < attr->kdf_count; i++) { 861 if (attr->kdf[i] == EAP_AKA_PRIME_KDF) { 862 os_memcpy(data->last_kdf_attrs, attr->kdf, 863 sizeof(u16) * attr->kdf_count); 864 data->last_kdf_count = attr->kdf_count; 865 return eap_aka_prime_kdf_select(data, id, 866 EAP_AKA_PRIME_KDF); 867 } 868 } 869 870 /* No matching KDF found - fail authentication as if AUTN had been 871 * incorrect */ 872 return eap_aka_authentication_reject(data, id); 873 } 874 875 876 static int eap_aka_prime_kdf_valid(struct eap_aka_data *data, 877 struct eap_sim_attrs *attr) 878 { 879 size_t i, j; 880 881 if (attr->kdf_count == 0) 882 return 0; 883 884 /* The only allowed (and required) duplication of a KDF is the addition 885 * of the selected KDF into the beginning of the list. */ 886 887 if (data->kdf_negotiation) { 888 /* When the peer receives the new EAP-Request/AKA'-Challenge 889 * message, must check only requested change occurred in the 890 * list of AT_KDF attributes. If there are any other changes, 891 * the peer must behave like the case that AT_MAC had been 892 * incorrect and authentication is failed. These are defined in 893 * EAP-AKA' specification RFC 5448, Section 3.2. */ 894 if (attr->kdf[0] != data->kdf) { 895 wpa_printf(MSG_WARNING, "EAP-AKA': The server did not " 896 "accept the selected KDF"); 897 return -1; 898 } 899 900 if (attr->kdf_count > EAP_AKA_PRIME_KDF_MAX || 901 attr->kdf_count != data->last_kdf_count + 1) { 902 wpa_printf(MSG_WARNING, 903 "EAP-AKA': The length of KDF attributes is wrong"); 904 return -1; 905 } 906 907 for (i = 1; i < attr->kdf_count; i++) { 908 if (attr->kdf[i] != data->last_kdf_attrs[i - 1]) { 909 wpa_printf(MSG_WARNING, 910 "EAP-AKA': The KDF attributes except selected KDF are not same as original one"); 911 return -1; 912 } 913 } 914 } 915 916 for (i = data->kdf ? 1 : 0; i < attr->kdf_count; i++) { 917 for (j = i + 1; j < attr->kdf_count; j++) { 918 if (attr->kdf[i] == attr->kdf[j]) { 919 wpa_printf(MSG_WARNING, "EAP-AKA': The server " 920 "included a duplicated KDF"); 921 return 0; 922 } 923 } 924 } 925 926 return 1; 927 } 928 #endif /* EAP_AKA_PRIME */ 929 930 931 static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm, 932 struct eap_aka_data *data, 933 u8 id, 934 const struct wpabuf *reqData, 935 struct eap_sim_attrs *attr) 936 { 937 const u8 *identity; 938 size_t identity_len; 939 int res; 940 struct eap_sim_attrs eattr; 941 942 wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Challenge"); 943 944 if (attr->checkcode && 945 eap_aka_verify_checkcode(data, attr->checkcode, 946 attr->checkcode_len)) { 947 wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the " 948 "message"); 949 #ifdef TEST_FUZZ 950 wpa_printf(MSG_INFO, 951 "TEST: Ignore AT_CHECKCODE mismatch for fuzz testing"); 952 #else /* TEST_FUZZ */ 953 return eap_aka_client_error(data, id, 954 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 955 #endif /* TEST_FUZZ */ 956 } 957 958 #ifdef EAP_AKA_PRIME 959 if (data->eap_method == EAP_TYPE_AKA_PRIME) { 960 if (!attr->kdf_input || attr->kdf_input_len == 0) { 961 wpa_printf(MSG_WARNING, "EAP-AKA': Challenge message " 962 "did not include non-empty AT_KDF_INPUT"); 963 /* Fail authentication as if AUTN had been incorrect */ 964 return eap_aka_authentication_reject(data, id); 965 } 966 os_free(data->network_name); 967 data->network_name = os_memdup(attr->kdf_input, 968 attr->kdf_input_len); 969 if (data->network_name == NULL) { 970 wpa_printf(MSG_WARNING, "EAP-AKA': No memory for " 971 "storing Network Name"); 972 return eap_aka_authentication_reject(data, id); 973 } 974 data->network_name_len = attr->kdf_input_len; 975 wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA': Network Name " 976 "(AT_KDF_INPUT)", 977 data->network_name, data->network_name_len); 978 /* TODO: check Network Name per 3GPP.33.402 */ 979 980 res = eap_aka_prime_kdf_valid(data, attr); 981 if (res == 0) 982 return eap_aka_authentication_reject(data, id); 983 else if (res == -1) 984 return eap_aka_client_error( 985 data, id, EAP_AKA_UNABLE_TO_PROCESS_PACKET); 986 987 if (attr->kdf[0] != EAP_AKA_PRIME_KDF) 988 return eap_aka_prime_kdf_neg(data, id, attr); 989 990 data->kdf = EAP_AKA_PRIME_KDF; 991 wpa_printf(MSG_DEBUG, "EAP-AKA': KDF %d selected", data->kdf); 992 } 993 994 if (data->eap_method == EAP_TYPE_AKA && attr->bidding) { 995 u16 flags = WPA_GET_BE16(attr->bidding); 996 if ((flags & EAP_AKA_BIDDING_FLAG_D) && 997 eap_allowed_method(sm, EAP_VENDOR_IETF, 998 EAP_TYPE_AKA_PRIME)) { 999 wpa_printf(MSG_WARNING, "EAP-AKA: Bidding down from " 1000 "AKA' to AKA detected"); 1001 /* Fail authentication as if AUTN had been incorrect */ 1002 return eap_aka_authentication_reject(data, id); 1003 } 1004 } 1005 #endif /* EAP_AKA_PRIME */ 1006 1007 data->reauth = 0; 1008 if (!attr->mac || !attr->rand || !attr->autn) { 1009 wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message " 1010 "did not include%s%s%s", 1011 !attr->mac ? " AT_MAC" : "", 1012 !attr->rand ? " AT_RAND" : "", 1013 !attr->autn ? " AT_AUTN" : ""); 1014 return eap_aka_client_error(data, id, 1015 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1016 } 1017 os_memcpy(data->rand, attr->rand, EAP_AKA_RAND_LEN); 1018 os_memcpy(data->autn, attr->autn, EAP_AKA_AUTN_LEN); 1019 1020 res = eap_aka_umts_auth(sm, data); 1021 if (res == -1) { 1022 wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication " 1023 "failed (AUTN)"); 1024 return eap_aka_authentication_reject(data, id); 1025 } else if (res == -2) { 1026 wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication " 1027 "failed (AUTN seq# -> AUTS)"); 1028 return eap_aka_synchronization_failure(data, id, attr); 1029 } else if (res > 0) { 1030 wpa_printf(MSG_DEBUG, "EAP-AKA: Wait for external USIM processing"); 1031 return NULL; 1032 } else if (res) { 1033 wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication failed"); 1034 return eap_aka_client_error(data, id, 1035 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1036 } 1037 #ifdef EAP_AKA_PRIME 1038 if (data->eap_method == EAP_TYPE_AKA_PRIME) { 1039 /* Note: AUTN = (SQN ^ AK) || AMF || MAC which gives us the 1040 * needed 6-octet SQN ^ AK for CK',IK' derivation */ 1041 u16 amf = WPA_GET_BE16(data->autn + 6); 1042 if (!(amf & 0x8000)) { 1043 wpa_printf(MSG_WARNING, "EAP-AKA': AMF separation bit " 1044 "not set (AMF=0x%4x)", amf); 1045 return eap_aka_authentication_reject(data, id); 1046 } 1047 eap_aka_prime_derive_ck_ik_prime(data->ck, data->ik, 1048 data->autn, 1049 data->network_name, 1050 data->network_name_len); 1051 } 1052 #endif /* EAP_AKA_PRIME */ 1053 if (data->last_eap_identity) { 1054 identity = data->last_eap_identity; 1055 identity_len = data->last_eap_identity_len; 1056 } else if (data->pseudonym && 1057 !eap_sim_anonymous_username(data->pseudonym, 1058 data->pseudonym_len)) { 1059 identity = data->pseudonym; 1060 identity_len = data->pseudonym_len; 1061 } else { 1062 struct eap_peer_config *config; 1063 1064 config = eap_get_config(sm); 1065 if (config && config->imsi_identity) { 1066 identity = config->imsi_identity; 1067 identity_len = config->imsi_identity_len; 1068 } else { 1069 identity = eap_get_config_identity(sm, &identity_len); 1070 } 1071 } 1072 wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Selected identity for MK " 1073 "derivation", identity, identity_len); 1074 if (data->eap_method == EAP_TYPE_AKA_PRIME) { 1075 eap_aka_prime_derive_keys(identity, identity_len, data->ik, 1076 data->ck, data->k_encr, data->k_aut, 1077 data->k_re, data->msk, data->emsk); 1078 } else { 1079 eap_aka_derive_mk(identity, identity_len, data->ik, data->ck, 1080 data->mk); 1081 eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, 1082 data->msk, data->emsk); 1083 } 1084 if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) { 1085 wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message " 1086 "used invalid AT_MAC"); 1087 #ifdef TEST_FUZZ 1088 wpa_printf(MSG_INFO, 1089 "TEST: Ignore AT_MAC mismatch for fuzz testing"); 1090 #else /* TEST_FUZZ */ 1091 return eap_aka_client_error(data, id, 1092 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1093 #endif /* TEST_FUZZ */ 1094 } 1095 1096 /* Old reauthentication identity must not be used anymore. In 1097 * other words, if no new identities are received, full 1098 * authentication will be used on next reauthentication (using 1099 * pseudonym identity or permanent identity). */ 1100 eap_aka_clear_identities(sm, data, CLEAR_REAUTH_ID | CLEAR_EAP_ID); 1101 1102 if (attr->encr_data) { 1103 u8 *decrypted; 1104 decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, 1105 attr->encr_data_len, attr->iv, 1106 &eattr, 0); 1107 if (decrypted == NULL) { 1108 return eap_aka_client_error( 1109 data, id, EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1110 } 1111 eap_aka_learn_ids(sm, data, &eattr); 1112 os_free(decrypted); 1113 } 1114 1115 if (data->result_ind && attr->result_ind) 1116 data->use_result_ind = 1; 1117 1118 if (data->state != FAILURE) { 1119 eap_aka_state(data, data->use_result_ind ? 1120 RESULT_SUCCESS : SUCCESS); 1121 } 1122 1123 data->num_id_req = 0; 1124 data->num_notification = 0; 1125 /* RFC 4187 specifies that counter is initialized to one after 1126 * fullauth, but initializing it to zero makes it easier to implement 1127 * reauth verification. */ 1128 data->counter = 0; 1129 return eap_aka_response_challenge(data, id); 1130 } 1131 1132 1133 static int eap_aka_process_notification_reauth(struct eap_aka_data *data, 1134 struct eap_sim_attrs *attr) 1135 { 1136 struct eap_sim_attrs eattr; 1137 u8 *decrypted; 1138 1139 if (attr->encr_data == NULL || attr->iv == NULL) { 1140 wpa_printf(MSG_WARNING, "EAP-AKA: Notification message after " 1141 "reauth did not include encrypted data"); 1142 return -1; 1143 } 1144 1145 decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, 1146 attr->encr_data_len, attr->iv, &eattr, 1147 0); 1148 if (decrypted == NULL) { 1149 wpa_printf(MSG_WARNING, "EAP-AKA: Failed to parse encrypted " 1150 "data from notification message"); 1151 return -1; 1152 } 1153 1154 if (eattr.counter < 0 || (size_t) eattr.counter != data->counter) { 1155 wpa_printf(MSG_WARNING, "EAP-AKA: Counter in notification " 1156 "message does not match with counter in reauth " 1157 "message"); 1158 os_free(decrypted); 1159 return -1; 1160 } 1161 1162 os_free(decrypted); 1163 return 0; 1164 } 1165 1166 1167 static int eap_aka_process_notification_auth(struct eap_aka_data *data, 1168 const struct wpabuf *reqData, 1169 struct eap_sim_attrs *attr) 1170 { 1171 if (attr->mac == NULL) { 1172 wpa_printf(MSG_INFO, "EAP-AKA: no AT_MAC in after_auth " 1173 "Notification message"); 1174 return -1; 1175 } 1176 1177 if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) { 1178 wpa_printf(MSG_WARNING, "EAP-AKA: Notification message " 1179 "used invalid AT_MAC"); 1180 return -1; 1181 } 1182 1183 if (data->reauth && 1184 eap_aka_process_notification_reauth(data, attr)) { 1185 wpa_printf(MSG_WARNING, "EAP-AKA: Invalid notification " 1186 "message after reauth"); 1187 return -1; 1188 } 1189 1190 return 0; 1191 } 1192 1193 1194 static struct wpabuf * eap_aka_process_notification( 1195 struct eap_sm *sm, struct eap_aka_data *data, u8 id, 1196 const struct wpabuf *reqData, struct eap_sim_attrs *attr) 1197 { 1198 wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Notification"); 1199 if (data->num_notification > 0) { 1200 wpa_printf(MSG_INFO, "EAP-AKA: too many notification " 1201 "rounds (only one allowed)"); 1202 return eap_aka_client_error(data, id, 1203 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1204 } 1205 data->num_notification++; 1206 if (attr->notification == -1) { 1207 wpa_printf(MSG_INFO, "EAP-AKA: no AT_NOTIFICATION in " 1208 "Notification message"); 1209 return eap_aka_client_error(data, id, 1210 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1211 } 1212 1213 if ((attr->notification & 0x4000) == 0 && 1214 eap_aka_process_notification_auth(data, reqData, attr)) { 1215 return eap_aka_client_error(data, id, 1216 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1217 } 1218 1219 eap_sim_report_notification(sm->msg_ctx, attr->notification, 1); 1220 if (attr->notification >= 0 && attr->notification < 32768) { 1221 data->error_code = attr->notification; 1222 eap_aka_state(data, FAILURE); 1223 } else if (attr->notification == EAP_SIM_SUCCESS && 1224 data->state == RESULT_SUCCESS) 1225 eap_aka_state(data, SUCCESS); 1226 return eap_aka_response_notification(data, id, attr->notification); 1227 } 1228 1229 1230 static struct wpabuf * eap_aka_process_reauthentication( 1231 struct eap_sm *sm, struct eap_aka_data *data, u8 id, 1232 const struct wpabuf *reqData, struct eap_sim_attrs *attr) 1233 { 1234 struct eap_sim_attrs eattr; 1235 u8 *decrypted; 1236 1237 wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Reauthentication"); 1238 1239 if (attr->checkcode && 1240 eap_aka_verify_checkcode(data, attr->checkcode, 1241 attr->checkcode_len)) { 1242 #ifdef TEST_FUZZ 1243 wpa_printf(MSG_INFO, 1244 "TEST: Ignore AT_CHECKCODE mismatch for fuzz testing"); 1245 #else /* TEST_FUZZ */ 1246 wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the " 1247 "message"); 1248 #endif /* TEST_FUZZ */ 1249 return eap_aka_client_error(data, id, 1250 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1251 } 1252 1253 if (data->reauth_id == NULL) { 1254 wpa_printf(MSG_WARNING, "EAP-AKA: Server is trying " 1255 "reauthentication, but no reauth_id available"); 1256 return eap_aka_client_error(data, id, 1257 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1258 } 1259 1260 data->reauth = 1; 1261 if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) { 1262 wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication " 1263 "did not have valid AT_MAC"); 1264 return eap_aka_client_error(data, id, 1265 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1266 } 1267 1268 /* At this stage the received MAC has been verified. Use this MAC for 1269 * reauth Session-Id calculation if all other checks pass. 1270 * The peer does not use the local MAC but the received MAC in deriving 1271 * Session-Id. */ 1272 os_memcpy(data->reauth_mac, attr->mac, EAP_SIM_MAC_LEN); 1273 wpa_hexdump(MSG_DEBUG, "EAP-AKA: Server MAC", 1274 data->reauth_mac, EAP_SIM_MAC_LEN); 1275 1276 if (attr->encr_data == NULL || attr->iv == NULL) { 1277 wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication " 1278 "message did not include encrypted data"); 1279 return eap_aka_client_error(data, id, 1280 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1281 } 1282 1283 decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, 1284 attr->encr_data_len, attr->iv, &eattr, 1285 0); 1286 if (decrypted == NULL) { 1287 wpa_printf(MSG_WARNING, "EAP-AKA: Failed to parse encrypted " 1288 "data from reauthentication message"); 1289 return eap_aka_client_error(data, id, 1290 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1291 } 1292 1293 if (eattr.nonce_s == NULL || eattr.counter < 0) { 1294 wpa_printf(MSG_INFO, "EAP-AKA: (encr) No%s%s in reauth packet", 1295 !eattr.nonce_s ? " AT_NONCE_S" : "", 1296 eattr.counter < 0 ? " AT_COUNTER" : ""); 1297 os_free(decrypted); 1298 return eap_aka_client_error(data, id, 1299 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1300 } 1301 1302 if (eattr.counter < 0 || (size_t) eattr.counter <= data->counter) { 1303 struct wpabuf *res; 1304 wpa_printf(MSG_INFO, "EAP-AKA: (encr) Invalid counter " 1305 "(%d <= %d)", eattr.counter, data->counter); 1306 data->counter_too_small = eattr.counter; 1307 1308 /* Reply using Re-auth w/ AT_COUNTER_TOO_SMALL. The current 1309 * reauth_id must not be used to start a new reauthentication. 1310 * However, since it was used in the last EAP-Response-Identity 1311 * packet, it has to saved for the following fullauth to be 1312 * used in MK derivation. */ 1313 os_free(data->last_eap_identity); 1314 data->last_eap_identity = data->reauth_id; 1315 data->last_eap_identity_len = data->reauth_id_len; 1316 data->reauth_id = NULL; 1317 data->reauth_id_len = 0; 1318 1319 res = eap_aka_response_reauth(data, id, 1, eattr.nonce_s); 1320 os_free(decrypted); 1321 1322 return res; 1323 } 1324 data->counter = eattr.counter; 1325 1326 os_memcpy(data->nonce_s, eattr.nonce_s, EAP_SIM_NONCE_S_LEN); 1327 wpa_hexdump(MSG_DEBUG, "EAP-AKA: (encr) AT_NONCE_S", 1328 data->nonce_s, EAP_SIM_NONCE_S_LEN); 1329 1330 if (data->eap_method == EAP_TYPE_AKA_PRIME) { 1331 eap_aka_prime_derive_keys_reauth(data->k_re, data->counter, 1332 data->reauth_id, 1333 data->reauth_id_len, 1334 data->nonce_s, 1335 data->msk, data->emsk); 1336 } else { 1337 eap_sim_derive_keys_reauth(data->counter, data->reauth_id, 1338 data->reauth_id_len, 1339 data->nonce_s, data->mk, 1340 data->msk, data->emsk); 1341 } 1342 eap_aka_clear_identities(sm, data, CLEAR_REAUTH_ID | CLEAR_EAP_ID); 1343 eap_aka_learn_ids(sm, data, &eattr); 1344 1345 if (data->result_ind && attr->result_ind) 1346 data->use_result_ind = 1; 1347 1348 if (data->state != FAILURE) { 1349 eap_aka_state(data, data->use_result_ind ? 1350 RESULT_SUCCESS : SUCCESS); 1351 } 1352 1353 data->num_id_req = 0; 1354 data->num_notification = 0; 1355 if (data->counter > EAP_AKA_MAX_FAST_REAUTHS) { 1356 wpa_printf(MSG_DEBUG, "EAP-AKA: Maximum number of " 1357 "fast reauths performed - force fullauth"); 1358 eap_aka_clear_identities(sm, data, 1359 CLEAR_REAUTH_ID | CLEAR_EAP_ID); 1360 } 1361 os_free(decrypted); 1362 return eap_aka_response_reauth(data, id, 0, data->nonce_s); 1363 } 1364 1365 1366 static struct wpabuf * eap_aka_process(struct eap_sm *sm, void *priv, 1367 struct eap_method_ret *ret, 1368 const struct wpabuf *reqData) 1369 { 1370 struct eap_aka_data *data = priv; 1371 const struct eap_hdr *req; 1372 u8 subtype, id; 1373 struct wpabuf *res; 1374 const u8 *pos; 1375 struct eap_sim_attrs attr; 1376 size_t len; 1377 1378 wpa_hexdump_buf(MSG_DEBUG, "EAP-AKA: EAP data", reqData); 1379 if (eap_get_config_identity(sm, &len) == NULL) { 1380 wpa_printf(MSG_INFO, "EAP-AKA: Identity not configured"); 1381 eap_sm_request_identity(sm); 1382 ret->ignore = true; 1383 return NULL; 1384 } 1385 1386 pos = eap_hdr_validate(EAP_VENDOR_IETF, data->eap_method, reqData, 1387 &len); 1388 if (pos == NULL || len < 3) { 1389 ret->ignore = true; 1390 return NULL; 1391 } 1392 req = wpabuf_head(reqData); 1393 id = req->identifier; 1394 len = be_to_host16(req->length); 1395 1396 ret->ignore = false; 1397 ret->methodState = METHOD_MAY_CONT; 1398 ret->decision = DECISION_FAIL; 1399 ret->allowNotifications = true; 1400 1401 subtype = *pos++; 1402 wpa_printf(MSG_DEBUG, "EAP-AKA: Subtype=%d", subtype); 1403 pos += 2; /* Reserved */ 1404 1405 if (eap_sim_parse_attr(pos, wpabuf_head_u8(reqData) + len, &attr, 1406 data->eap_method == EAP_TYPE_AKA_PRIME ? 2 : 1, 1407 0)) { 1408 res = eap_aka_client_error(data, id, 1409 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1410 goto done; 1411 } 1412 1413 switch (subtype) { 1414 case EAP_AKA_SUBTYPE_IDENTITY: 1415 res = eap_aka_process_identity(sm, data, id, reqData, &attr); 1416 break; 1417 case EAP_AKA_SUBTYPE_CHALLENGE: 1418 res = eap_aka_process_challenge(sm, data, id, reqData, &attr); 1419 break; 1420 case EAP_AKA_SUBTYPE_NOTIFICATION: 1421 res = eap_aka_process_notification(sm, data, id, reqData, 1422 &attr); 1423 break; 1424 case EAP_AKA_SUBTYPE_REAUTHENTICATION: 1425 res = eap_aka_process_reauthentication(sm, data, id, reqData, 1426 &attr); 1427 break; 1428 case EAP_AKA_SUBTYPE_CLIENT_ERROR: 1429 wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Client-Error"); 1430 res = eap_aka_client_error(data, id, 1431 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1432 break; 1433 default: 1434 wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown subtype=%d", subtype); 1435 res = eap_aka_client_error(data, id, 1436 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 1437 break; 1438 } 1439 1440 done: 1441 if (data->state == FAILURE) { 1442 ret->decision = DECISION_FAIL; 1443 ret->methodState = METHOD_DONE; 1444 } else if (data->state == SUCCESS) { 1445 ret->decision = data->use_result_ind ? 1446 DECISION_UNCOND_SUCC : DECISION_COND_SUCC; 1447 /* 1448 * It is possible for the server to reply with AKA 1449 * Notification, so we must allow the method to continue and 1450 * not only accept EAP-Success at this point. 1451 */ 1452 ret->methodState = data->use_result_ind ? 1453 METHOD_DONE : METHOD_MAY_CONT; 1454 } else if (data->state == RESULT_SUCCESS) 1455 ret->methodState = METHOD_CONT; 1456 1457 if (ret->methodState == METHOD_DONE) { 1458 ret->allowNotifications = false; 1459 } 1460 1461 return res; 1462 } 1463 1464 1465 static bool eap_aka_has_reauth_data(struct eap_sm *sm, void *priv) 1466 { 1467 struct eap_aka_data *data = priv; 1468 return data->pseudonym || data->reauth_id; 1469 } 1470 1471 1472 static void eap_aka_deinit_for_reauth(struct eap_sm *sm, void *priv) 1473 { 1474 struct eap_aka_data *data = priv; 1475 eap_aka_clear_identities(sm, data, CLEAR_EAP_ID); 1476 data->prev_id = -1; 1477 wpabuf_free(data->id_msgs); 1478 data->id_msgs = NULL; 1479 data->use_result_ind = 0; 1480 data->kdf_negotiation = 0; 1481 eap_aka_clear_keys(data, 1); 1482 } 1483 1484 1485 static void * eap_aka_init_for_reauth(struct eap_sm *sm, void *priv) 1486 { 1487 struct eap_aka_data *data = priv; 1488 data->num_id_req = 0; 1489 data->num_notification = 0; 1490 eap_aka_state(data, CONTINUE); 1491 return priv; 1492 } 1493 1494 1495 static const u8 * eap_aka_get_identity(struct eap_sm *sm, void *priv, 1496 size_t *len) 1497 { 1498 struct eap_aka_data *data = priv; 1499 1500 if (data->reauth_id) { 1501 *len = data->reauth_id_len; 1502 return data->reauth_id; 1503 } 1504 1505 if (data->pseudonym) { 1506 *len = data->pseudonym_len; 1507 return data->pseudonym; 1508 } 1509 1510 return NULL; 1511 } 1512 1513 1514 static bool eap_aka_isKeyAvailable(struct eap_sm *sm, void *priv) 1515 { 1516 struct eap_aka_data *data = priv; 1517 return data->state == SUCCESS; 1518 } 1519 1520 1521 static u8 * eap_aka_getKey(struct eap_sm *sm, void *priv, size_t *len) 1522 { 1523 struct eap_aka_data *data = priv; 1524 u8 *key; 1525 1526 if (data->state != SUCCESS) 1527 return NULL; 1528 1529 key = os_memdup(data->msk, EAP_SIM_KEYING_DATA_LEN); 1530 if (key == NULL) 1531 return NULL; 1532 1533 *len = EAP_SIM_KEYING_DATA_LEN; 1534 1535 return key; 1536 } 1537 1538 1539 static u8 * eap_aka_get_session_id(struct eap_sm *sm, void *priv, size_t *len) 1540 { 1541 struct eap_aka_data *data = priv; 1542 u8 *id; 1543 1544 if (data->state != SUCCESS) 1545 return NULL; 1546 1547 if (!data->reauth) 1548 *len = 1 + EAP_AKA_RAND_LEN + EAP_AKA_AUTN_LEN; 1549 else 1550 *len = 1 + EAP_SIM_NONCE_S_LEN + EAP_SIM_MAC_LEN; 1551 id = os_malloc(*len); 1552 if (id == NULL) 1553 return NULL; 1554 1555 id[0] = data->eap_method; 1556 if (!data->reauth) { 1557 os_memcpy(id + 1, data->rand, EAP_AKA_RAND_LEN); 1558 os_memcpy(id + 1 + EAP_AKA_RAND_LEN, data->autn, 1559 EAP_AKA_AUTN_LEN); 1560 } else { 1561 os_memcpy(id + 1, data->nonce_s, EAP_SIM_NONCE_S_LEN); 1562 os_memcpy(id + 1 + EAP_SIM_NONCE_S_LEN, data->reauth_mac, 1563 EAP_SIM_MAC_LEN); 1564 } 1565 wpa_hexdump(MSG_DEBUG, "EAP-AKA: Derived Session-Id", id, *len); 1566 1567 return id; 1568 } 1569 1570 1571 static u8 * eap_aka_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 1572 { 1573 struct eap_aka_data *data = priv; 1574 u8 *key; 1575 1576 if (data->state != SUCCESS) 1577 return NULL; 1578 1579 key = os_memdup(data->emsk, EAP_EMSK_LEN); 1580 if (key == NULL) 1581 return NULL; 1582 1583 *len = EAP_EMSK_LEN; 1584 1585 return key; 1586 } 1587 1588 1589 static int eap_aka_get_error_code(void *priv) 1590 { 1591 struct eap_aka_data *data = priv; 1592 int current_data_error; 1593 1594 if (!data) 1595 return NO_EAP_METHOD_ERROR; 1596 1597 current_data_error = data->error_code; 1598 1599 /* Now reset for next transaction */ 1600 data->error_code = NO_EAP_METHOD_ERROR; 1601 1602 return current_data_error; 1603 } 1604 1605 1606 int eap_peer_aka_register(void) 1607 { 1608 struct eap_method *eap; 1609 1610 eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 1611 EAP_VENDOR_IETF, EAP_TYPE_AKA, "AKA"); 1612 if (eap == NULL) 1613 return -1; 1614 1615 eap->init = eap_aka_init; 1616 eap->deinit = eap_aka_deinit; 1617 eap->process = eap_aka_process; 1618 eap->isKeyAvailable = eap_aka_isKeyAvailable; 1619 eap->getKey = eap_aka_getKey; 1620 eap->getSessionId = eap_aka_get_session_id; 1621 eap->has_reauth_data = eap_aka_has_reauth_data; 1622 eap->deinit_for_reauth = eap_aka_deinit_for_reauth; 1623 eap->init_for_reauth = eap_aka_init_for_reauth; 1624 eap->get_identity = eap_aka_get_identity; 1625 eap->get_emsk = eap_aka_get_emsk; 1626 eap->get_error_code = eap_aka_get_error_code; 1627 1628 return eap_peer_method_register(eap); 1629 } 1630 1631 1632 #ifdef EAP_AKA_PRIME 1633 int eap_peer_aka_prime_register(void) 1634 { 1635 struct eap_method *eap; 1636 1637 eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 1638 EAP_VENDOR_IETF, EAP_TYPE_AKA_PRIME, 1639 "AKA'"); 1640 if (eap == NULL) 1641 return -1; 1642 1643 eap->init = eap_aka_prime_init; 1644 eap->deinit = eap_aka_deinit; 1645 eap->process = eap_aka_process; 1646 eap->isKeyAvailable = eap_aka_isKeyAvailable; 1647 eap->getKey = eap_aka_getKey; 1648 eap->getSessionId = eap_aka_get_session_id; 1649 eap->has_reauth_data = eap_aka_has_reauth_data; 1650 eap->deinit_for_reauth = eap_aka_deinit_for_reauth; 1651 eap->init_for_reauth = eap_aka_init_for_reauth; 1652 eap->get_identity = eap_aka_get_identity; 1653 eap->get_emsk = eap_aka_get_emsk; 1654 eap->get_error_code = eap_aka_get_error_code; 1655 1656 return eap_peer_method_register(eap); 1657 } 1658 #endif /* EAP_AKA_PRIME */ 1659