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