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