1 /* 2 * EAP peer method: EAP-AKA (RFC 4187) 3 * Copyright (c) 2004-2006, Jouni Malinen <j (at) 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 "eap_i.h" 19 #include "crypto.h" 20 #include "pcsc_funcs.h" 21 #include "eap_sim_common.h" 22 23 24 struct eap_aka_data { 25 u8 ik[EAP_AKA_IK_LEN], ck[EAP_AKA_CK_LEN], res[EAP_AKA_RES_MAX_LEN]; 26 size_t res_len; 27 u8 nonce_s[EAP_SIM_NONCE_S_LEN]; 28 u8 mk[EAP_SIM_MK_LEN]; 29 u8 k_aut[EAP_SIM_K_AUT_LEN]; 30 u8 k_encr[EAP_SIM_K_ENCR_LEN]; 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 36 int num_id_req, num_notification; 37 u8 *pseudonym; 38 size_t pseudonym_len; 39 u8 *reauth_id; 40 size_t reauth_id_len; 41 int reauth; 42 unsigned int counter, counter_too_small; 43 u8 *last_eap_identity; 44 size_t last_eap_identity_len; 45 enum { CONTINUE, SUCCESS, FAILURE } state; 46 }; 47 48 49 static void * eap_aka_init(struct eap_sm *sm) 50 { 51 struct eap_aka_data *data; 52 data = os_zalloc(sizeof(*data)); 53 if (data == NULL) 54 return NULL; 55 56 data->state = CONTINUE; 57 58 return data; 59 } 60 61 62 static void eap_aka_deinit(struct eap_sm *sm, void *priv) 63 { 64 struct eap_aka_data *data = priv; 65 if (data) { 66 os_free(data->pseudonym); 67 os_free(data->reauth_id); 68 os_free(data->last_eap_identity); 69 os_free(data); 70 } 71 } 72 73 74 static int eap_aka_umts_auth(struct eap_sm *sm, struct eap_aka_data *data) 75 { 76 wpa_printf(MSG_DEBUG, "EAP-AKA: UMTS authentication algorithm"); 77 #ifdef PCSC_FUNCS 78 return scard_umts_auth(sm->scard_ctx, data->rand, 79 data->autn, data->res, &data->res_len, 80 data->ik, data->ck, data->auts); 81 #else /* PCSC_FUNCS */ 82 /* These hardcoded Kc and SRES values are used for testing. 83 * Could consider making them configurable. */ 84 os_memset(data->res, '2', EAP_AKA_RES_MAX_LEN); 85 data->res_len = EAP_AKA_RES_MAX_LEN; 86 os_memset(data->ik, '3', EAP_AKA_IK_LEN); 87 os_memset(data->ck, '4', EAP_AKA_CK_LEN); 88 { 89 u8 autn[EAP_AKA_AUTN_LEN]; 90 os_memset(autn, '1', EAP_AKA_AUTN_LEN); 91 if (os_memcmp(autn, data->autn, EAP_AKA_AUTN_LEN) != 0) { 92 wpa_printf(MSG_WARNING, "EAP-AKA: AUTN did not match " 93 "with expected value"); 94 return -1; 95 } 96 } 97 #if 0 98 { 99 static int test_resync = 1; 100 if (test_resync) { 101 /* Test Resynchronization */ 102 test_resync = 0; 103 return -2; 104 } 105 } 106 #endif 107 return 0; 108 #endif /* PCSC_FUNCS */ 109 } 110 111 112 #define CLEAR_PSEUDONYM 0x01 113 #define CLEAR_REAUTH_ID 0x02 114 #define CLEAR_EAP_ID 0x04 115 116 static void eap_aka_clear_identities(struct eap_aka_data *data, int id) 117 { 118 wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old%s%s%s", 119 id & CLEAR_PSEUDONYM ? " pseudonym" : "", 120 id & CLEAR_REAUTH_ID ? " reauth_id" : "", 121 id & CLEAR_EAP_ID ? " eap_id" : ""); 122 if (id & CLEAR_PSEUDONYM) { 123 os_free(data->pseudonym); 124 data->pseudonym = NULL; 125 data->pseudonym_len = 0; 126 } 127 if (id & CLEAR_REAUTH_ID) { 128 os_free(data->reauth_id); 129 data->reauth_id = NULL; 130 data->reauth_id_len = 0; 131 } 132 if (id & CLEAR_EAP_ID) { 133 os_free(data->last_eap_identity); 134 data->last_eap_identity = NULL; 135 data->last_eap_identity_len = 0; 136 } 137 } 138 139 140 static int eap_aka_learn_ids(struct eap_aka_data *data, 141 struct eap_sim_attrs *attr) 142 { 143 if (attr->next_pseudonym) { 144 os_free(data->pseudonym); 145 data->pseudonym = os_malloc(attr->next_pseudonym_len); 146 if (data->pseudonym == NULL) { 147 wpa_printf(MSG_INFO, "EAP-AKA: (encr) No memory for " 148 "next pseudonym"); 149 return -1; 150 } 151 os_memcpy(data->pseudonym, attr->next_pseudonym, 152 attr->next_pseudonym_len); 153 data->pseudonym_len = attr->next_pseudonym_len; 154 wpa_hexdump_ascii(MSG_DEBUG, 155 "EAP-AKA: (encr) AT_NEXT_PSEUDONYM", 156 data->pseudonym, 157 data->pseudonym_len); 158 } 159 160 if (attr->next_reauth_id) { 161 os_free(data->reauth_id); 162 data->reauth_id = os_malloc(attr->next_reauth_id_len); 163 if (data->reauth_id == NULL) { 164 wpa_printf(MSG_INFO, "EAP-AKA: (encr) No memory for " 165 "next reauth_id"); 166 return -1; 167 } 168 os_memcpy(data->reauth_id, attr->next_reauth_id, 169 attr->next_reauth_id_len); 170 data->reauth_id_len = attr->next_reauth_id_len; 171 wpa_hexdump_ascii(MSG_DEBUG, 172 "EAP-AKA: (encr) AT_NEXT_REAUTH_ID", 173 data->reauth_id, 174 data->reauth_id_len); 175 } 176 177 return 0; 178 } 179 180 181 static u8 * eap_aka_client_error(struct eap_aka_data *data, 182 const struct eap_hdr *req, 183 size_t *respDataLen, int err) 184 { 185 struct eap_sim_msg *msg; 186 187 data->state = FAILURE; 188 data->num_id_req = 0; 189 data->num_notification = 0; 190 191 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier, 192 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CLIENT_ERROR); 193 eap_sim_msg_add(msg, EAP_SIM_AT_CLIENT_ERROR_CODE, err, NULL, 0); 194 return eap_sim_msg_finish(msg, respDataLen, NULL, NULL, 0); 195 } 196 197 198 static u8 * eap_aka_authentication_reject(struct eap_aka_data *data, 199 const struct eap_hdr *req, 200 size_t *respDataLen) 201 { 202 struct eap_sim_msg *msg; 203 204 data->state = FAILURE; 205 data->num_id_req = 0; 206 data->num_notification = 0; 207 208 wpa_printf(MSG_DEBUG, "Generating EAP-AKA Authentication-Reject " 209 "(id=%d)", req->identifier); 210 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier, 211 EAP_TYPE_AKA, 212 EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT); 213 return eap_sim_msg_finish(msg, respDataLen, NULL, NULL, 0); 214 } 215 216 217 static u8 * eap_aka_synchronization_failure(struct eap_aka_data *data, 218 const struct eap_hdr *req, 219 size_t *respDataLen) 220 { 221 struct eap_sim_msg *msg; 222 223 data->num_id_req = 0; 224 data->num_notification = 0; 225 226 wpa_printf(MSG_DEBUG, "Generating EAP-AKA Synchronization-Failure " 227 "(id=%d)", req->identifier); 228 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier, 229 EAP_TYPE_AKA, 230 EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE); 231 wpa_printf(MSG_DEBUG, " AT_AUTS"); 232 eap_sim_msg_add_full(msg, EAP_SIM_AT_AUTS, data->auts, 233 EAP_AKA_AUTS_LEN); 234 return eap_sim_msg_finish(msg, respDataLen, NULL, NULL, 0); 235 } 236 237 238 static u8 * eap_aka_response_identity(struct eap_sm *sm, 239 struct eap_aka_data *data, 240 const struct eap_hdr *req, 241 size_t *respDataLen, 242 enum eap_sim_id_req id_req) 243 { 244 const u8 *identity = NULL; 245 size_t identity_len = 0; 246 struct eap_sim_msg *msg; 247 248 data->reauth = 0; 249 if (id_req == ANY_ID && data->reauth_id) { 250 identity = data->reauth_id; 251 identity_len = data->reauth_id_len; 252 data->reauth = 1; 253 } else if ((id_req == ANY_ID || id_req == FULLAUTH_ID) && 254 data->pseudonym) { 255 identity = data->pseudonym; 256 identity_len = data->pseudonym_len; 257 eap_aka_clear_identities(data, CLEAR_REAUTH_ID); 258 } else if (id_req != NO_ID_REQ) { 259 identity = eap_get_config_identity(sm, &identity_len); 260 if (identity) { 261 eap_aka_clear_identities(data, CLEAR_PSEUDONYM | 262 CLEAR_REAUTH_ID); 263 } 264 } 265 if (id_req != NO_ID_REQ) 266 eap_aka_clear_identities(data, CLEAR_EAP_ID); 267 268 wpa_printf(MSG_DEBUG, "Generating EAP-AKA Identity (id=%d)", 269 req->identifier); 270 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier, 271 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY); 272 273 if (identity) { 274 wpa_hexdump_ascii(MSG_DEBUG, " AT_IDENTITY", 275 identity, identity_len); 276 eap_sim_msg_add(msg, EAP_SIM_AT_IDENTITY, identity_len, 277 identity, identity_len); 278 } 279 280 return eap_sim_msg_finish(msg, respDataLen, NULL, NULL, 0); 281 } 282 283 284 static u8 * eap_aka_response_challenge(struct eap_aka_data *data, 285 const struct eap_hdr *req, 286 size_t *respDataLen) 287 { 288 struct eap_sim_msg *msg; 289 290 wpa_printf(MSG_DEBUG, "Generating EAP-AKA Challenge (id=%d)", 291 req->identifier); 292 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier, 293 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE); 294 wpa_printf(MSG_DEBUG, " AT_RES"); 295 eap_sim_msg_add(msg, EAP_SIM_AT_RES, data->res_len * 8, 296 data->res, data->res_len); 297 wpa_printf(MSG_DEBUG, " AT_MAC"); 298 eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); 299 return eap_sim_msg_finish(msg, respDataLen, data->k_aut, (u8 *) "", 0); 300 } 301 302 303 static u8 * eap_aka_response_reauth(struct eap_aka_data *data, 304 const struct eap_hdr *req, 305 size_t *respDataLen, int counter_too_small, 306 const u8 *nonce_s) 307 { 308 struct eap_sim_msg *msg; 309 unsigned int counter; 310 311 wpa_printf(MSG_DEBUG, "Generating EAP-AKA Reauthentication (id=%d)", 312 req->identifier); 313 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier, 314 EAP_TYPE_AKA, 315 EAP_AKA_SUBTYPE_REAUTHENTICATION); 316 wpa_printf(MSG_DEBUG, " AT_IV"); 317 wpa_printf(MSG_DEBUG, " AT_ENCR_DATA"); 318 eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, EAP_SIM_AT_ENCR_DATA); 319 320 if (counter_too_small) { 321 wpa_printf(MSG_DEBUG, " *AT_COUNTER_TOO_SMALL"); 322 eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER_TOO_SMALL, 0, NULL, 0); 323 counter = data->counter_too_small; 324 } else 325 counter = data->counter; 326 327 wpa_printf(MSG_DEBUG, " *AT_COUNTER %d", counter); 328 eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, counter, NULL, 0); 329 330 if (eap_sim_msg_add_encr_end(msg, data->k_encr, EAP_SIM_AT_PADDING)) { 331 wpa_printf(MSG_WARNING, "EAP-AKA: Failed to encrypt " 332 "AT_ENCR_DATA"); 333 eap_sim_msg_free(msg); 334 return NULL; 335 } 336 wpa_printf(MSG_DEBUG, " AT_MAC"); 337 eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); 338 return eap_sim_msg_finish(msg, respDataLen, data->k_aut, nonce_s, 339 EAP_SIM_NONCE_S_LEN); 340 } 341 342 343 static u8 * eap_aka_response_notification(struct eap_aka_data *data, 344 const struct eap_hdr *req, 345 size_t *respDataLen, 346 u16 notification) 347 { 348 struct eap_sim_msg *msg; 349 u8 *k_aut = (notification & 0x4000) == 0 ? data->k_aut : NULL; 350 351 wpa_printf(MSG_DEBUG, "Generating EAP-AKA Notification (id=%d)", 352 req->identifier); 353 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier, 354 EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION); 355 if (k_aut && data->reauth) { 356 wpa_printf(MSG_DEBUG, " AT_IV"); 357 wpa_printf(MSG_DEBUG, " AT_ENCR_DATA"); 358 eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, 359 EAP_SIM_AT_ENCR_DATA); 360 wpa_printf(MSG_DEBUG, " *AT_COUNTER %d", data->counter); 361 eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, data->counter, 362 NULL, 0); 363 if (eap_sim_msg_add_encr_end(msg, data->k_encr, 364 EAP_SIM_AT_PADDING)) { 365 wpa_printf(MSG_WARNING, "EAP-AKA: Failed to encrypt " 366 "AT_ENCR_DATA"); 367 eap_sim_msg_free(msg); 368 return NULL; 369 } 370 } 371 if (k_aut) { 372 wpa_printf(MSG_DEBUG, " AT_MAC"); 373 eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); 374 } 375 return eap_sim_msg_finish(msg, respDataLen, k_aut, (u8 *) "", 0); 376 } 377 378 379 static u8 * eap_aka_process_identity(struct eap_sm *sm, 380 struct eap_aka_data *data, 381 const struct eap_hdr *req, 382 size_t *respDataLen, 383 struct eap_sim_attrs *attr) 384 { 385 int id_error; 386 387 wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Identity"); 388 389 id_error = 0; 390 switch (attr->id_req) { 391 case NO_ID_REQ: 392 break; 393 case ANY_ID: 394 if (data->num_id_req > 0) 395 id_error++; 396 data->num_id_req++; 397 break; 398 case FULLAUTH_ID: 399 if (data->num_id_req > 1) 400 id_error++; 401 data->num_id_req++; 402 break; 403 case PERMANENT_ID: 404 if (data->num_id_req > 2) 405 id_error++; 406 data->num_id_req++; 407 break; 408 } 409 if (id_error) { 410 wpa_printf(MSG_INFO, "EAP-AKA: Too many ID requests " 411 "used within one authentication"); 412 return eap_aka_client_error(data, req, respDataLen, 413 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 414 } 415 416 return eap_aka_response_identity(sm, data, req, respDataLen, 417 attr->id_req); 418 } 419 420 421 static u8 * eap_aka_process_challenge(struct eap_sm *sm, 422 struct eap_aka_data *data, 423 const struct eap_hdr *req, 424 size_t reqDataLen, 425 size_t *respDataLen, 426 struct eap_sim_attrs *attr) 427 { 428 const u8 *identity; 429 size_t identity_len; 430 int res; 431 struct eap_sim_attrs eattr; 432 433 wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Challenge"); 434 data->reauth = 0; 435 if (!attr->mac || !attr->rand || !attr->autn) { 436 wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message " 437 "did not include%s%s%s", 438 !attr->mac ? " AT_MAC" : "", 439 !attr->rand ? " AT_RAND" : "", 440 !attr->autn ? " AT_AUTN" : ""); 441 return eap_aka_client_error(data, req, respDataLen, 442 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 443 } 444 os_memcpy(data->rand, attr->rand, EAP_AKA_RAND_LEN); 445 os_memcpy(data->autn, attr->autn, EAP_AKA_AUTN_LEN); 446 447 res = eap_aka_umts_auth(sm, data); 448 if (res == -1) { 449 wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication " 450 "failed (AUTN)"); 451 return eap_aka_authentication_reject(data, req, respDataLen); 452 } else if (res == -2) { 453 wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication " 454 "failed (AUTN seq# -> AUTS)"); 455 return eap_aka_synchronization_failure(data, req, respDataLen); 456 } else if (res) { 457 wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication failed"); 458 return eap_aka_client_error(data, req, respDataLen, 459 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 460 } 461 if (data->last_eap_identity) { 462 identity = data->last_eap_identity; 463 identity_len = data->last_eap_identity_len; 464 } else if (data->pseudonym) { 465 identity = data->pseudonym; 466 identity_len = data->pseudonym_len; 467 } else 468 identity = eap_get_config_identity(sm, &identity_len); 469 wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Selected identity for MK " 470 "derivation", identity, identity_len); 471 eap_aka_derive_mk(identity, identity_len, data->ik, data->ck, 472 data->mk); 473 eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk, 474 data->emsk); 475 if (eap_sim_verify_mac(data->k_aut, (const u8 *) req, reqDataLen, 476 attr->mac, (u8 *) "", 0)) { 477 wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message " 478 "used invalid AT_MAC"); 479 return eap_aka_client_error(data, req, respDataLen, 480 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 481 } 482 483 /* Old reauthentication and pseudonym identities must not be used 484 * anymore. In other words, if no new identities are received, full 485 * authentication will be used on next reauthentication. */ 486 eap_aka_clear_identities(data, CLEAR_PSEUDONYM | CLEAR_REAUTH_ID | 487 CLEAR_EAP_ID); 488 489 if (attr->encr_data) { 490 u8 *decrypted; 491 decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, 492 attr->encr_data_len, attr->iv, 493 &eattr, 0); 494 if (decrypted == NULL) { 495 return eap_aka_client_error( 496 data, req, respDataLen, 497 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 498 } 499 eap_aka_learn_ids(data, &eattr); 500 os_free(decrypted); 501 } 502 503 if (data->state != FAILURE) 504 data->state = SUCCESS; 505 506 data->num_id_req = 0; 507 data->num_notification = 0; 508 /* RFC 4187 specifies that counter is initialized to one after 509 * fullauth, but initializing it to zero makes it easier to implement 510 * reauth verification. */ 511 data->counter = 0; 512 return eap_aka_response_challenge(data, req, respDataLen); 513 } 514 515 516 static int eap_aka_process_notification_reauth(struct eap_aka_data *data, 517 struct eap_sim_attrs *attr) 518 { 519 struct eap_sim_attrs eattr; 520 u8 *decrypted; 521 522 if (attr->encr_data == NULL || attr->iv == NULL) { 523 wpa_printf(MSG_WARNING, "EAP-AKA: Notification message after " 524 "reauth did not include encrypted data"); 525 return -1; 526 } 527 528 decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, 529 attr->encr_data_len, attr->iv, &eattr, 530 0); 531 if (decrypted == NULL) { 532 wpa_printf(MSG_WARNING, "EAP-AKA: Failed to parse encrypted " 533 "data from notification message"); 534 return -1; 535 } 536 537 if (eattr.counter < 0 || (size_t) eattr.counter != data->counter) { 538 wpa_printf(MSG_WARNING, "EAP-AKA: Counter in notification " 539 "message does not match with counter in reauth " 540 "message"); 541 os_free(decrypted); 542 return -1; 543 } 544 545 os_free(decrypted); 546 return 0; 547 } 548 549 550 static int eap_aka_process_notification_auth(struct eap_aka_data *data, 551 const struct eap_hdr *req, 552 size_t reqDataLen, 553 struct eap_sim_attrs *attr) 554 { 555 if (attr->mac == NULL) { 556 wpa_printf(MSG_INFO, "EAP-AKA: no AT_MAC in after_auth " 557 "Notification message"); 558 return -1; 559 } 560 561 if (eap_sim_verify_mac(data->k_aut, (const u8 *) req, reqDataLen, 562 attr->mac, (u8 *) "", 0)) { 563 wpa_printf(MSG_WARNING, "EAP-AKA: Notification message " 564 "used invalid AT_MAC"); 565 return -1; 566 } 567 568 if (data->reauth && 569 eap_aka_process_notification_reauth(data, attr)) { 570 wpa_printf(MSG_WARNING, "EAP-AKA: Invalid notification " 571 "message after reauth"); 572 return -1; 573 } 574 575 return 0; 576 } 577 578 579 static u8 * eap_aka_process_notification(struct eap_sm *sm, 580 struct eap_aka_data *data, 581 const struct eap_hdr *req, 582 size_t reqDataLen, 583 size_t *respDataLen, 584 struct eap_sim_attrs *attr) 585 { 586 wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Notification"); 587 if (data->num_notification > 0) { 588 wpa_printf(MSG_INFO, "EAP-AKA: too many notification " 589 "rounds (only one allowed)"); 590 return eap_aka_client_error(data, req, respDataLen, 591 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 592 } 593 data->num_notification++; 594 if (attr->notification == -1) { 595 wpa_printf(MSG_INFO, "EAP-AKA: no AT_NOTIFICATION in " 596 "Notification message"); 597 return eap_aka_client_error(data, req, respDataLen, 598 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 599 } 600 601 if ((attr->notification & 0x4000) == 0 && 602 eap_aka_process_notification_auth(data, req, reqDataLen, attr)) { 603 return eap_aka_client_error(data, req, respDataLen, 604 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 605 } 606 607 eap_sim_report_notification(sm->msg_ctx, attr->notification, 1); 608 if (attr->notification >= 0 && attr->notification < 32768) { 609 data->state = FAILURE; 610 } 611 return eap_aka_response_notification(data, req, respDataLen, 612 attr->notification); 613 } 614 615 616 static u8 * eap_aka_process_reauthentication(struct eap_sm *sm, 617 struct eap_aka_data *data, 618 const struct eap_hdr *req, 619 size_t reqDataLen, 620 size_t *respDataLen, 621 struct eap_sim_attrs *attr) 622 { 623 struct eap_sim_attrs eattr; 624 u8 *decrypted; 625 626 wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Reauthentication"); 627 628 if (data->reauth_id == NULL) { 629 wpa_printf(MSG_WARNING, "EAP-AKA: Server is trying " 630 "reauthentication, but no reauth_id available"); 631 return eap_aka_client_error(data, req, respDataLen, 632 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 633 } 634 635 data->reauth = 1; 636 if (eap_sim_verify_mac(data->k_aut, (const u8 *) req, reqDataLen, 637 attr->mac, (u8 *) "", 0)) { 638 wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication " 639 "did not have valid AT_MAC"); 640 return eap_aka_client_error(data, req, respDataLen, 641 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 642 } 643 644 if (attr->encr_data == NULL || attr->iv == NULL) { 645 wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication " 646 "message did not include encrypted data"); 647 return eap_aka_client_error(data, req, respDataLen, 648 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 649 } 650 651 decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, 652 attr->encr_data_len, attr->iv, &eattr, 653 0); 654 if (decrypted == NULL) { 655 wpa_printf(MSG_WARNING, "EAP-AKA: Failed to parse encrypted " 656 "data from reauthentication message"); 657 return eap_aka_client_error(data, req, respDataLen, 658 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 659 } 660 661 if (eattr.nonce_s == NULL || eattr.counter < 0) { 662 wpa_printf(MSG_INFO, "EAP-AKA: (encr) No%s%s in reauth packet", 663 !eattr.nonce_s ? " AT_NONCE_S" : "", 664 eattr.counter < 0 ? " AT_COUNTER" : ""); 665 os_free(decrypted); 666 return eap_aka_client_error(data, req, respDataLen, 667 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 668 } 669 670 if (eattr.counter < 0 || (size_t) eattr.counter <= data->counter) { 671 u8 *res; 672 wpa_printf(MSG_INFO, "EAP-AKA: (encr) Invalid counter " 673 "(%d <= %d)", eattr.counter, data->counter); 674 data->counter_too_small = eattr.counter; 675 676 eap_sim_derive_keys_reauth(eattr.counter, data->reauth_id, 677 data->reauth_id_len, eattr.nonce_s, 678 data->mk, NULL, NULL); 679 680 /* Reply using Re-auth w/ AT_COUNTER_TOO_SMALL. The current 681 * reauth_id must not be used to start a new reauthentication. 682 * However, since it was used in the last EAP-Response-Identity 683 * packet, it has to saved for the following fullauth to be 684 * used in MK derivation. */ 685 os_free(data->last_eap_identity); 686 data->last_eap_identity = data->reauth_id; 687 data->last_eap_identity_len = data->reauth_id_len; 688 data->reauth_id = NULL; 689 data->reauth_id_len = 0; 690 691 res = eap_aka_response_reauth(data, req, respDataLen, 1, 692 eattr.nonce_s); 693 os_free(decrypted); 694 695 return res; 696 } 697 data->counter = eattr.counter; 698 699 os_memcpy(data->nonce_s, eattr.nonce_s, EAP_SIM_NONCE_S_LEN); 700 wpa_hexdump(MSG_DEBUG, "EAP-AKA: (encr) AT_NONCE_S", 701 data->nonce_s, EAP_SIM_NONCE_S_LEN); 702 703 eap_sim_derive_keys_reauth(data->counter, 704 data->reauth_id, data->reauth_id_len, 705 data->nonce_s, data->mk, data->msk, 706 data->emsk); 707 eap_aka_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID); 708 eap_aka_learn_ids(data, &eattr); 709 710 if (data->state != FAILURE) 711 data->state = SUCCESS; 712 713 data->num_id_req = 0; 714 data->num_notification = 0; 715 if (data->counter > EAP_AKA_MAX_FAST_REAUTHS) { 716 wpa_printf(MSG_DEBUG, "EAP-AKA: Maximum number of " 717 "fast reauths performed - force fullauth"); 718 eap_aka_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID); 719 } 720 os_free(decrypted); 721 return eap_aka_response_reauth(data, req, respDataLen, 0, 722 data->nonce_s); 723 } 724 725 726 static u8 * eap_aka_process(struct eap_sm *sm, void *priv, 727 struct eap_method_ret *ret, 728 const u8 *reqData, size_t reqDataLen, 729 size_t *respDataLen) 730 { 731 struct eap_aka_data *data = priv; 732 const struct eap_hdr *req; 733 u8 subtype, *res; 734 const u8 *pos; 735 struct eap_sim_attrs attr; 736 size_t len; 737 738 wpa_hexdump(MSG_DEBUG, "EAP-AKA: EAP data", reqData, reqDataLen); 739 if (eap_get_config_identity(sm, &len) == NULL) { 740 wpa_printf(MSG_INFO, "EAP-AKA: Identity not configured"); 741 eap_sm_request_identity(sm); 742 ret->ignore = TRUE; 743 return NULL; 744 } 745 746 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_AKA, 747 reqData, reqDataLen, &len); 748 if (pos == NULL || len < 1) { 749 ret->ignore = TRUE; 750 return NULL; 751 } 752 req = (const struct eap_hdr *) reqData; 753 len = be_to_host16(req->length); 754 755 ret->ignore = FALSE; 756 ret->methodState = METHOD_MAY_CONT; 757 ret->decision = DECISION_FAIL; 758 ret->allowNotifications = TRUE; 759 760 subtype = *pos++; 761 wpa_printf(MSG_DEBUG, "EAP-AKA: Subtype=%d", subtype); 762 pos += 2; /* Reserved */ 763 764 if (eap_sim_parse_attr(pos, reqData + len, &attr, 1, 0)) { 765 res = eap_aka_client_error(data, req, respDataLen, 766 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 767 goto done; 768 } 769 770 switch (subtype) { 771 case EAP_AKA_SUBTYPE_IDENTITY: 772 res = eap_aka_process_identity(sm, data, req, 773 respDataLen, &attr); 774 break; 775 case EAP_AKA_SUBTYPE_CHALLENGE: 776 res = eap_aka_process_challenge(sm, data, req, len, 777 respDataLen, &attr); 778 break; 779 case EAP_AKA_SUBTYPE_NOTIFICATION: 780 res = eap_aka_process_notification(sm, data, req, len, 781 respDataLen, &attr); 782 break; 783 case EAP_AKA_SUBTYPE_REAUTHENTICATION: 784 res = eap_aka_process_reauthentication(sm, data, req, len, 785 respDataLen, &attr); 786 break; 787 case EAP_AKA_SUBTYPE_CLIENT_ERROR: 788 wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Client-Error"); 789 res = eap_aka_client_error(data, req, respDataLen, 790 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 791 break; 792 default: 793 wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown subtype=%d", subtype); 794 res = eap_aka_client_error(data, req, respDataLen, 795 EAP_AKA_UNABLE_TO_PROCESS_PACKET); 796 break; 797 } 798 799 done: 800 if (data->state == FAILURE) { 801 ret->decision = DECISION_FAIL; 802 ret->methodState = METHOD_DONE; 803 } else if (data->state == SUCCESS) { 804 ret->decision = DECISION_COND_SUCC; 805 /* 806 * It is possible for the server to reply with AKA 807 * Notification, so we must allow the method to continue and 808 * not only accept EAP-Success at this point. 809 */ 810 ret->methodState = METHOD_MAY_CONT; 811 } 812 813 if (ret->methodState == METHOD_DONE) { 814 ret->allowNotifications = FALSE; 815 } 816 817 return res; 818 } 819 820 821 static Boolean eap_aka_has_reauth_data(struct eap_sm *sm, void *priv) 822 { 823 struct eap_aka_data *data = priv; 824 return data->pseudonym || data->reauth_id; 825 } 826 827 828 static void eap_aka_deinit_for_reauth(struct eap_sm *sm, void *priv) 829 { 830 struct eap_aka_data *data = priv; 831 eap_aka_clear_identities(data, CLEAR_EAP_ID); 832 } 833 834 835 static void * eap_aka_init_for_reauth(struct eap_sm *sm, void *priv) 836 { 837 struct eap_aka_data *data = priv; 838 data->num_id_req = 0; 839 data->num_notification = 0; 840 data->state = CONTINUE; 841 return priv; 842 } 843 844 845 static const u8 * eap_aka_get_identity(struct eap_sm *sm, void *priv, 846 size_t *len) 847 { 848 struct eap_aka_data *data = priv; 849 850 if (data->reauth_id) { 851 *len = data->reauth_id_len; 852 return data->reauth_id; 853 } 854 855 if (data->pseudonym) { 856 *len = data->pseudonym_len; 857 return data->pseudonym; 858 } 859 860 return NULL; 861 } 862 863 864 static Boolean eap_aka_isKeyAvailable(struct eap_sm *sm, void *priv) 865 { 866 struct eap_aka_data *data = priv; 867 return data->state == SUCCESS; 868 } 869 870 871 static u8 * eap_aka_getKey(struct eap_sm *sm, void *priv, size_t *len) 872 { 873 struct eap_aka_data *data = priv; 874 u8 *key; 875 876 if (data->state != SUCCESS) 877 return NULL; 878 879 key = os_malloc(EAP_SIM_KEYING_DATA_LEN); 880 if (key == NULL) 881 return NULL; 882 883 *len = EAP_SIM_KEYING_DATA_LEN; 884 os_memcpy(key, data->msk, EAP_SIM_KEYING_DATA_LEN); 885 886 return key; 887 } 888 889 890 static u8 * eap_aka_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 891 { 892 struct eap_aka_data *data = priv; 893 u8 *key; 894 895 if (data->state != SUCCESS) 896 return NULL; 897 898 key = os_malloc(EAP_EMSK_LEN); 899 if (key == NULL) 900 return NULL; 901 902 *len = EAP_EMSK_LEN; 903 os_memcpy(key, data->emsk, EAP_EMSK_LEN); 904 905 return key; 906 } 907 908 909 int eap_peer_aka_register(void) 910 { 911 struct eap_method *eap; 912 int ret; 913 914 eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 915 EAP_VENDOR_IETF, EAP_TYPE_AKA, "AKA"); 916 if (eap == NULL) 917 return -1; 918 919 eap->init = eap_aka_init; 920 eap->deinit = eap_aka_deinit; 921 eap->process = eap_aka_process; 922 eap->isKeyAvailable = eap_aka_isKeyAvailable; 923 eap->getKey = eap_aka_getKey; 924 eap->has_reauth_data = eap_aka_has_reauth_data; 925 eap->deinit_for_reauth = eap_aka_deinit_for_reauth; 926 eap->init_for_reauth = eap_aka_init_for_reauth; 927 eap->get_identity = eap_aka_get_identity; 928 eap->get_emsk = eap_aka_get_emsk; 929 930 ret = eap_peer_method_register(eap); 931 if (ret) 932 eap_peer_method_free(eap); 933 return ret; 934 } 935