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