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