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