1 /* 2 * EAP peer method: EAP-SIM (RFC 4186) 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/milenage.h" 20 #include "eap_peer/eap_i.h" 21 #include "eap_config.h" 22 #include "eap_common/eap_sim_common.h" 23 24 25 struct eap_sim_data { 26 u8 *ver_list; 27 size_t ver_list_len; 28 int selected_version; 29 size_t min_num_chal, num_chal; 30 31 u8 kc[3][EAP_SIM_KC_LEN]; 32 u8 sres[3][EAP_SIM_SRES_LEN]; 33 u8 nonce_mt[EAP_SIM_NONCE_MT_LEN], nonce_s[EAP_SIM_NONCE_S_LEN]; 34 u8 mk[EAP_SIM_MK_LEN]; 35 u8 k_aut[EAP_SIM_K_AUT_LEN]; 36 u8 k_encr[EAP_SIM_K_ENCR_LEN]; 37 u8 msk[EAP_SIM_KEYING_DATA_LEN]; 38 u8 emsk[EAP_EMSK_LEN]; 39 u8 rand[3][GSM_RAND_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 int result_ind, use_result_ind; 54 }; 55 56 57 #ifndef CONFIG_NO_STDOUT_DEBUG 58 static const char * eap_sim_state_txt(int state) 59 { 60 switch (state) { 61 case CONTINUE: 62 return "CONTINUE"; 63 case RESULT_SUCCESS: 64 return "RESULT_SUCCESS"; 65 case RESULT_FAILURE: 66 return "RESULT_FAILURE"; 67 case SUCCESS: 68 return "SUCCESS"; 69 case FAILURE: 70 return "FAILURE"; 71 default: 72 return "?"; 73 } 74 } 75 #endif /* CONFIG_NO_STDOUT_DEBUG */ 76 77 78 static void eap_sim_state(struct eap_sim_data *data, int state) 79 { 80 wpa_printf(MSG_DEBUG, "EAP-SIM: %s -> %s", 81 eap_sim_state_txt(data->state), 82 eap_sim_state_txt(state)); 83 data->state = state; 84 } 85 86 87 static void * eap_sim_init(struct eap_sm *sm) 88 { 89 struct eap_sim_data *data; 90 struct eap_peer_config *config = eap_get_config(sm); 91 92 data = os_zalloc(sizeof(*data)); 93 if (data == NULL) 94 return NULL; 95 96 if (os_get_random(data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) { 97 wpa_printf(MSG_WARNING, "EAP-SIM: Failed to get random data " 98 "for NONCE_MT"); 99 os_free(data); 100 return NULL; 101 } 102 103 data->min_num_chal = 2; 104 if (config && config->phase1) { 105 char *pos = os_strstr(config->phase1, "sim_min_num_chal="); 106 if (pos) { 107 data->min_num_chal = atoi(pos + 17); 108 if (data->min_num_chal < 2 || data->min_num_chal > 3) { 109 wpa_printf(MSG_WARNING, "EAP-SIM: Invalid " 110 "sim_min_num_chal configuration " 111 "(%lu, expected 2 or 3)", 112 (unsigned long) data->min_num_chal); 113 os_free(data); 114 return NULL; 115 } 116 wpa_printf(MSG_DEBUG, "EAP-SIM: Set minimum number of " 117 "challenges to %lu", 118 (unsigned long) data->min_num_chal); 119 } 120 121 data->result_ind = os_strstr(config->phase1, "result_ind=1") != 122 NULL; 123 } 124 125 eap_sim_state(data, CONTINUE); 126 127 return data; 128 } 129 130 131 static void eap_sim_deinit(struct eap_sm *sm, void *priv) 132 { 133 struct eap_sim_data *data = priv; 134 if (data) { 135 os_free(data->ver_list); 136 os_free(data->pseudonym); 137 os_free(data->reauth_id); 138 os_free(data->last_eap_identity); 139 os_free(data); 140 } 141 } 142 143 144 static int eap_sim_gsm_auth(struct eap_sm *sm, struct eap_sim_data *data) 145 { 146 struct eap_peer_config *conf; 147 148 wpa_printf(MSG_DEBUG, "EAP-SIM: GSM authentication algorithm"); 149 150 conf = eap_get_config(sm); 151 if (conf == NULL) 152 return -1; 153 if (conf->pcsc) { 154 if (scard_gsm_auth(sm->scard_ctx, data->rand[0], 155 data->sres[0], data->kc[0]) || 156 scard_gsm_auth(sm->scard_ctx, data->rand[1], 157 data->sres[1], data->kc[1]) || 158 (data->num_chal > 2 && 159 scard_gsm_auth(sm->scard_ctx, data->rand[2], 160 data->sres[2], data->kc[2]))) { 161 wpa_printf(MSG_DEBUG, "EAP-SIM: GSM SIM " 162 "authentication could not be completed"); 163 return -1; 164 } 165 return 0; 166 } 167 168 #ifdef CONFIG_SIM_SIMULATOR 169 if (conf->password) { 170 u8 opc[16], k[16]; 171 const char *pos; 172 size_t i; 173 wpa_printf(MSG_DEBUG, "EAP-SIM: Use internal GSM-Milenage " 174 "implementation for authentication"); 175 if (conf->password_len < 65) { 176 wpa_printf(MSG_DEBUG, "EAP-SIM: invalid GSM-Milenage " 177 "password"); 178 return -1; 179 } 180 pos = (const char *) conf->password; 181 if (hexstr2bin(pos, k, 16)) 182 return -1; 183 pos += 32; 184 if (*pos != ':') 185 return -1; 186 pos++; 187 188 if (hexstr2bin(pos, opc, 16)) 189 return -1; 190 191 for (i = 0; i < data->num_chal; i++) { 192 if (gsm_milenage(opc, k, data->rand[i], 193 data->sres[i], data->kc[i])) { 194 wpa_printf(MSG_DEBUG, "EAP-SIM: " 195 "GSM-Milenage authentication " 196 "could not be completed"); 197 return -1; 198 } 199 wpa_hexdump(MSG_DEBUG, "EAP-SIM: RAND", 200 data->rand[i], GSM_RAND_LEN); 201 wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: SRES", 202 data->sres[i], EAP_SIM_SRES_LEN); 203 wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: Kc", 204 data->kc[i], EAP_SIM_KC_LEN); 205 } 206 return 0; 207 } 208 #endif /* CONFIG_SIM_SIMULATOR */ 209 210 #ifdef CONFIG_SIM_HARDCODED 211 /* These hardcoded Kc and SRES values are used for testing. RAND to 212 * KC/SREC mapping is very bogus as far as real authentication is 213 * concerned, but it is quite useful for cases where the AS is rotating 214 * the order of pre-configured values. */ 215 { 216 size_t i; 217 218 wpa_printf(MSG_DEBUG, "EAP-SIM: Use hardcoded Kc and SRES " 219 "values for testing"); 220 221 for (i = 0; i < data->num_chal; i++) { 222 if (data->rand[i][0] == 0xaa) { 223 os_memcpy(data->kc[i], 224 "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7", 225 EAP_SIM_KC_LEN); 226 os_memcpy(data->sres[i], "\xd1\xd2\xd3\xd4", 227 EAP_SIM_SRES_LEN); 228 } else if (data->rand[i][0] == 0xbb) { 229 os_memcpy(data->kc[i], 230 "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7", 231 EAP_SIM_KC_LEN); 232 os_memcpy(data->sres[i], "\xe1\xe2\xe3\xe4", 233 EAP_SIM_SRES_LEN); 234 } else { 235 os_memcpy(data->kc[i], 236 "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7", 237 EAP_SIM_KC_LEN); 238 os_memcpy(data->sres[i], "\xf1\xf2\xf3\xf4", 239 EAP_SIM_SRES_LEN); 240 } 241 } 242 } 243 244 return 0; 245 246 #else /* CONFIG_SIM_HARDCODED */ 247 248 wpa_printf(MSG_DEBUG, "EAP-SIM: No GSM authentication algorithm " 249 "enabled"); 250 return -1; 251 252 #endif /* CONFIG_SIM_HARDCODED */ 253 } 254 255 256 static int eap_sim_supported_ver(int version) 257 { 258 return version == EAP_SIM_VERSION; 259 } 260 261 262 #define CLEAR_PSEUDONYM 0x01 263 #define CLEAR_REAUTH_ID 0x02 264 #define CLEAR_EAP_ID 0x04 265 266 static void eap_sim_clear_identities(struct eap_sim_data *data, int id) 267 { 268 wpa_printf(MSG_DEBUG, "EAP-SIM: forgetting old%s%s%s", 269 id & CLEAR_PSEUDONYM ? " pseudonym" : "", 270 id & CLEAR_REAUTH_ID ? " reauth_id" : "", 271 id & CLEAR_EAP_ID ? " eap_id" : ""); 272 if (id & CLEAR_PSEUDONYM) { 273 os_free(data->pseudonym); 274 data->pseudonym = NULL; 275 data->pseudonym_len = 0; 276 } 277 if (id & CLEAR_REAUTH_ID) { 278 os_free(data->reauth_id); 279 data->reauth_id = NULL; 280 data->reauth_id_len = 0; 281 } 282 if (id & CLEAR_EAP_ID) { 283 os_free(data->last_eap_identity); 284 data->last_eap_identity = NULL; 285 data->last_eap_identity_len = 0; 286 } 287 } 288 289 290 static int eap_sim_learn_ids(struct eap_sim_data *data, 291 struct eap_sim_attrs *attr) 292 { 293 if (attr->next_pseudonym) { 294 os_free(data->pseudonym); 295 data->pseudonym = os_malloc(attr->next_pseudonym_len); 296 if (data->pseudonym == NULL) { 297 wpa_printf(MSG_INFO, "EAP-SIM: (encr) No memory for " 298 "next pseudonym"); 299 return -1; 300 } 301 os_memcpy(data->pseudonym, attr->next_pseudonym, 302 attr->next_pseudonym_len); 303 data->pseudonym_len = attr->next_pseudonym_len; 304 wpa_hexdump_ascii(MSG_DEBUG, 305 "EAP-SIM: (encr) AT_NEXT_PSEUDONYM", 306 data->pseudonym, 307 data->pseudonym_len); 308 } 309 310 if (attr->next_reauth_id) { 311 os_free(data->reauth_id); 312 data->reauth_id = os_malloc(attr->next_reauth_id_len); 313 if (data->reauth_id == NULL) { 314 wpa_printf(MSG_INFO, "EAP-SIM: (encr) No memory for " 315 "next reauth_id"); 316 return -1; 317 } 318 os_memcpy(data->reauth_id, attr->next_reauth_id, 319 attr->next_reauth_id_len); 320 data->reauth_id_len = attr->next_reauth_id_len; 321 wpa_hexdump_ascii(MSG_DEBUG, 322 "EAP-SIM: (encr) AT_NEXT_REAUTH_ID", 323 data->reauth_id, 324 data->reauth_id_len); 325 } 326 327 return 0; 328 } 329 330 331 static struct wpabuf * eap_sim_client_error(struct eap_sim_data *data, u8 id, 332 int err) 333 { 334 struct eap_sim_msg *msg; 335 336 eap_sim_state(data, FAILURE); 337 data->num_id_req = 0; 338 data->num_notification = 0; 339 340 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_SIM, 341 EAP_SIM_SUBTYPE_CLIENT_ERROR); 342 eap_sim_msg_add(msg, EAP_SIM_AT_CLIENT_ERROR_CODE, err, NULL, 0); 343 return eap_sim_msg_finish(msg, NULL, NULL, 0); 344 } 345 346 347 static struct wpabuf * eap_sim_response_start(struct eap_sm *sm, 348 struct eap_sim_data *data, u8 id, 349 enum eap_sim_id_req id_req) 350 { 351 const u8 *identity = NULL; 352 size_t identity_len = 0; 353 struct eap_sim_msg *msg; 354 355 data->reauth = 0; 356 if (id_req == ANY_ID && data->reauth_id) { 357 identity = data->reauth_id; 358 identity_len = data->reauth_id_len; 359 data->reauth = 1; 360 } else if ((id_req == ANY_ID || id_req == FULLAUTH_ID) && 361 data->pseudonym) { 362 identity = data->pseudonym; 363 identity_len = data->pseudonym_len; 364 eap_sim_clear_identities(data, CLEAR_REAUTH_ID); 365 } else if (id_req != NO_ID_REQ) { 366 identity = eap_get_config_identity(sm, &identity_len); 367 if (identity) { 368 eap_sim_clear_identities(data, CLEAR_PSEUDONYM | 369 CLEAR_REAUTH_ID); 370 } 371 } 372 if (id_req != NO_ID_REQ) 373 eap_sim_clear_identities(data, CLEAR_EAP_ID); 374 375 wpa_printf(MSG_DEBUG, "Generating EAP-SIM Start (id=%d)", id); 376 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, 377 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START); 378 if (!data->reauth) { 379 wpa_hexdump(MSG_DEBUG, " AT_NONCE_MT", 380 data->nonce_mt, EAP_SIM_NONCE_MT_LEN); 381 eap_sim_msg_add(msg, EAP_SIM_AT_NONCE_MT, 0, 382 data->nonce_mt, EAP_SIM_NONCE_MT_LEN); 383 wpa_printf(MSG_DEBUG, " AT_SELECTED_VERSION %d", 384 data->selected_version); 385 eap_sim_msg_add(msg, EAP_SIM_AT_SELECTED_VERSION, 386 data->selected_version, NULL, 0); 387 } 388 389 if (identity) { 390 wpa_hexdump_ascii(MSG_DEBUG, " AT_IDENTITY", 391 identity, identity_len); 392 eap_sim_msg_add(msg, EAP_SIM_AT_IDENTITY, identity_len, 393 identity, identity_len); 394 } 395 396 return eap_sim_msg_finish(msg, NULL, NULL, 0); 397 } 398 399 400 static struct wpabuf * eap_sim_response_challenge(struct eap_sim_data *data, 401 u8 id) 402 { 403 struct eap_sim_msg *msg; 404 405 wpa_printf(MSG_DEBUG, "Generating EAP-SIM Challenge (id=%d)", id); 406 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_SIM, 407 EAP_SIM_SUBTYPE_CHALLENGE); 408 if (data->use_result_ind) { 409 wpa_printf(MSG_DEBUG, " AT_RESULT_IND"); 410 eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0); 411 } 412 wpa_printf(MSG_DEBUG, " AT_MAC"); 413 eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); 414 return eap_sim_msg_finish(msg, data->k_aut, (u8 *) data->sres, 415 data->num_chal * EAP_SIM_SRES_LEN); 416 } 417 418 419 static struct wpabuf * eap_sim_response_reauth(struct eap_sim_data *data, 420 u8 id, int counter_too_small) 421 { 422 struct eap_sim_msg *msg; 423 unsigned int counter; 424 425 wpa_printf(MSG_DEBUG, "Generating EAP-SIM Reauthentication (id=%d)", 426 id); 427 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_SIM, 428 EAP_SIM_SUBTYPE_REAUTHENTICATION); 429 wpa_printf(MSG_DEBUG, " AT_IV"); 430 wpa_printf(MSG_DEBUG, " AT_ENCR_DATA"); 431 eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, EAP_SIM_AT_ENCR_DATA); 432 433 if (counter_too_small) { 434 wpa_printf(MSG_DEBUG, " *AT_COUNTER_TOO_SMALL"); 435 eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER_TOO_SMALL, 0, NULL, 0); 436 counter = data->counter_too_small; 437 } else 438 counter = data->counter; 439 440 wpa_printf(MSG_DEBUG, " *AT_COUNTER %d", counter); 441 eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, counter, NULL, 0); 442 443 if (eap_sim_msg_add_encr_end(msg, data->k_encr, EAP_SIM_AT_PADDING)) { 444 wpa_printf(MSG_WARNING, "EAP-SIM: Failed to encrypt " 445 "AT_ENCR_DATA"); 446 eap_sim_msg_free(msg); 447 return NULL; 448 } 449 if (data->use_result_ind) { 450 wpa_printf(MSG_DEBUG, " AT_RESULT_IND"); 451 eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0); 452 } 453 wpa_printf(MSG_DEBUG, " AT_MAC"); 454 eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); 455 return eap_sim_msg_finish(msg, data->k_aut, data->nonce_s, 456 EAP_SIM_NONCE_S_LEN); 457 } 458 459 460 static struct wpabuf * eap_sim_response_notification(struct eap_sim_data *data, 461 u8 id, u16 notification) 462 { 463 struct eap_sim_msg *msg; 464 u8 *k_aut = (notification & 0x4000) == 0 ? data->k_aut : NULL; 465 466 wpa_printf(MSG_DEBUG, "Generating EAP-SIM Notification (id=%d)", id); 467 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, 468 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION); 469 if (k_aut && data->reauth) { 470 wpa_printf(MSG_DEBUG, " AT_IV"); 471 wpa_printf(MSG_DEBUG, " AT_ENCR_DATA"); 472 eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, 473 EAP_SIM_AT_ENCR_DATA); 474 wpa_printf(MSG_DEBUG, " *AT_COUNTER %d", data->counter); 475 eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, data->counter, 476 NULL, 0); 477 if (eap_sim_msg_add_encr_end(msg, data->k_encr, 478 EAP_SIM_AT_PADDING)) { 479 wpa_printf(MSG_WARNING, "EAP-SIM: Failed to encrypt " 480 "AT_ENCR_DATA"); 481 eap_sim_msg_free(msg); 482 return NULL; 483 } 484 } 485 if (k_aut) { 486 wpa_printf(MSG_DEBUG, " AT_MAC"); 487 eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); 488 } 489 return eap_sim_msg_finish(msg, k_aut, (u8 *) "", 0); 490 } 491 492 493 static struct wpabuf * eap_sim_process_start(struct eap_sm *sm, 494 struct eap_sim_data *data, u8 id, 495 struct eap_sim_attrs *attr) 496 { 497 int selected_version = -1, id_error; 498 size_t i; 499 u8 *pos; 500 501 wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Start"); 502 if (attr->version_list == NULL) { 503 wpa_printf(MSG_INFO, "EAP-SIM: No AT_VERSION_LIST in " 504 "SIM/Start"); 505 return eap_sim_client_error(data, id, 506 EAP_SIM_UNSUPPORTED_VERSION); 507 } 508 509 os_free(data->ver_list); 510 data->ver_list = os_malloc(attr->version_list_len); 511 if (data->ver_list == NULL) { 512 wpa_printf(MSG_DEBUG, "EAP-SIM: Failed to allocate " 513 "memory for version list"); 514 return eap_sim_client_error(data, id, 515 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 516 } 517 os_memcpy(data->ver_list, attr->version_list, attr->version_list_len); 518 data->ver_list_len = attr->version_list_len; 519 pos = data->ver_list; 520 for (i = 0; i < data->ver_list_len / 2; i++) { 521 int ver = pos[0] * 256 + pos[1]; 522 pos += 2; 523 if (eap_sim_supported_ver(ver)) { 524 selected_version = ver; 525 break; 526 } 527 } 528 if (selected_version < 0) { 529 wpa_printf(MSG_INFO, "EAP-SIM: Could not find a supported " 530 "version"); 531 return eap_sim_client_error(data, id, 532 EAP_SIM_UNSUPPORTED_VERSION); 533 } 534 wpa_printf(MSG_DEBUG, "EAP-SIM: Selected Version %d", 535 selected_version); 536 data->selected_version = selected_version; 537 538 id_error = 0; 539 switch (attr->id_req) { 540 case NO_ID_REQ: 541 break; 542 case ANY_ID: 543 if (data->num_id_req > 0) 544 id_error++; 545 data->num_id_req++; 546 break; 547 case FULLAUTH_ID: 548 if (data->num_id_req > 1) 549 id_error++; 550 data->num_id_req++; 551 break; 552 case PERMANENT_ID: 553 if (data->num_id_req > 2) 554 id_error++; 555 data->num_id_req++; 556 break; 557 } 558 if (id_error) { 559 wpa_printf(MSG_INFO, "EAP-SIM: Too many ID requests " 560 "used within one authentication"); 561 return eap_sim_client_error(data, id, 562 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 563 } 564 565 return eap_sim_response_start(sm, data, id, attr->id_req); 566 } 567 568 569 static struct wpabuf * eap_sim_process_challenge(struct eap_sm *sm, 570 struct eap_sim_data *data, 571 u8 id, 572 const struct wpabuf *reqData, 573 struct eap_sim_attrs *attr) 574 { 575 const u8 *identity; 576 size_t identity_len; 577 struct eap_sim_attrs eattr; 578 579 wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Challenge"); 580 data->reauth = 0; 581 if (!attr->mac || !attr->rand) { 582 wpa_printf(MSG_WARNING, "EAP-SIM: Challenge message " 583 "did not include%s%s", 584 !attr->mac ? " AT_MAC" : "", 585 !attr->rand ? " AT_RAND" : ""); 586 return eap_sim_client_error(data, id, 587 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 588 } 589 590 wpa_printf(MSG_DEBUG, "EAP-SIM: %lu challenges", 591 (unsigned long) attr->num_chal); 592 if (attr->num_chal < data->min_num_chal) { 593 wpa_printf(MSG_INFO, "EAP-SIM: Insufficient number of " 594 "challenges (%lu)", (unsigned long) attr->num_chal); 595 return eap_sim_client_error(data, id, 596 EAP_SIM_INSUFFICIENT_NUM_OF_CHAL); 597 } 598 if (attr->num_chal > 3) { 599 wpa_printf(MSG_INFO, "EAP-SIM: Too many challenges " 600 "(%lu)", (unsigned long) attr->num_chal); 601 return eap_sim_client_error(data, id, 602 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 603 } 604 605 /* Verify that RANDs are different */ 606 if (os_memcmp(attr->rand, attr->rand + GSM_RAND_LEN, 607 GSM_RAND_LEN) == 0 || 608 (attr->num_chal > 2 && 609 (os_memcmp(attr->rand, attr->rand + 2 * GSM_RAND_LEN, 610 GSM_RAND_LEN) == 0 || 611 os_memcmp(attr->rand + GSM_RAND_LEN, 612 attr->rand + 2 * GSM_RAND_LEN, 613 GSM_RAND_LEN) == 0))) { 614 wpa_printf(MSG_INFO, "EAP-SIM: Same RAND used multiple times"); 615 return eap_sim_client_error(data, id, 616 EAP_SIM_RAND_NOT_FRESH); 617 } 618 619 os_memcpy(data->rand, attr->rand, attr->num_chal * GSM_RAND_LEN); 620 data->num_chal = attr->num_chal; 621 622 if (eap_sim_gsm_auth(sm, data)) { 623 wpa_printf(MSG_WARNING, "EAP-SIM: GSM authentication failed"); 624 return eap_sim_client_error(data, id, 625 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 626 } 627 if (data->last_eap_identity) { 628 identity = data->last_eap_identity; 629 identity_len = data->last_eap_identity_len; 630 } else if (data->pseudonym) { 631 identity = data->pseudonym; 632 identity_len = data->pseudonym_len; 633 } else 634 identity = eap_get_config_identity(sm, &identity_len); 635 wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Selected identity for MK " 636 "derivation", identity, identity_len); 637 eap_sim_derive_mk(identity, identity_len, data->nonce_mt, 638 data->selected_version, data->ver_list, 639 data->ver_list_len, data->num_chal, 640 (const u8 *) data->kc, data->mk); 641 eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk, 642 data->emsk); 643 if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, data->nonce_mt, 644 EAP_SIM_NONCE_MT_LEN)) { 645 wpa_printf(MSG_WARNING, "EAP-SIM: Challenge message " 646 "used invalid AT_MAC"); 647 return eap_sim_client_error(data, id, 648 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 649 } 650 651 /* Old reauthentication and pseudonym identities must not be used 652 * anymore. In other words, if no new identities are received, full 653 * authentication will be used on next reauthentication. */ 654 eap_sim_clear_identities(data, CLEAR_PSEUDONYM | CLEAR_REAUTH_ID | 655 CLEAR_EAP_ID); 656 657 if (attr->encr_data) { 658 u8 *decrypted; 659 decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, 660 attr->encr_data_len, attr->iv, 661 &eattr, 0); 662 if (decrypted == NULL) { 663 return eap_sim_client_error( 664 data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET); 665 } 666 eap_sim_learn_ids(data, &eattr); 667 os_free(decrypted); 668 } 669 670 if (data->result_ind && attr->result_ind) 671 data->use_result_ind = 1; 672 673 if (data->state != FAILURE && data->state != RESULT_FAILURE) { 674 eap_sim_state(data, data->use_result_ind ? 675 RESULT_SUCCESS : SUCCESS); 676 } 677 678 data->num_id_req = 0; 679 data->num_notification = 0; 680 /* RFC 4186 specifies that counter is initialized to one after 681 * fullauth, but initializing it to zero makes it easier to implement 682 * reauth verification. */ 683 data->counter = 0; 684 return eap_sim_response_challenge(data, id); 685 } 686 687 688 static int eap_sim_process_notification_reauth(struct eap_sim_data *data, 689 struct eap_sim_attrs *attr) 690 { 691 struct eap_sim_attrs eattr; 692 u8 *decrypted; 693 694 if (attr->encr_data == NULL || attr->iv == NULL) { 695 wpa_printf(MSG_WARNING, "EAP-SIM: Notification message after " 696 "reauth did not include encrypted data"); 697 return -1; 698 } 699 700 decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, 701 attr->encr_data_len, attr->iv, &eattr, 702 0); 703 if (decrypted == NULL) { 704 wpa_printf(MSG_WARNING, "EAP-SIM: Failed to parse encrypted " 705 "data from notification message"); 706 return -1; 707 } 708 709 if (eattr.counter < 0 || (size_t) eattr.counter != data->counter) { 710 wpa_printf(MSG_WARNING, "EAP-SIM: Counter in notification " 711 "message does not match with counter in reauth " 712 "message"); 713 os_free(decrypted); 714 return -1; 715 } 716 717 os_free(decrypted); 718 return 0; 719 } 720 721 722 static int eap_sim_process_notification_auth(struct eap_sim_data *data, 723 const struct wpabuf *reqData, 724 struct eap_sim_attrs *attr) 725 { 726 if (attr->mac == NULL) { 727 wpa_printf(MSG_INFO, "EAP-SIM: no AT_MAC in after_auth " 728 "Notification message"); 729 return -1; 730 } 731 732 if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0)) 733 { 734 wpa_printf(MSG_WARNING, "EAP-SIM: Notification message " 735 "used invalid AT_MAC"); 736 return -1; 737 } 738 739 if (data->reauth && 740 eap_sim_process_notification_reauth(data, attr)) { 741 wpa_printf(MSG_WARNING, "EAP-SIM: Invalid notification " 742 "message after reauth"); 743 return -1; 744 } 745 746 return 0; 747 } 748 749 750 static struct wpabuf * eap_sim_process_notification( 751 struct eap_sm *sm, struct eap_sim_data *data, u8 id, 752 const struct wpabuf *reqData, struct eap_sim_attrs *attr) 753 { 754 wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Notification"); 755 if (data->num_notification > 0) { 756 wpa_printf(MSG_INFO, "EAP-SIM: too many notification " 757 "rounds (only one allowed)"); 758 return eap_sim_client_error(data, id, 759 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 760 } 761 data->num_notification++; 762 if (attr->notification == -1) { 763 wpa_printf(MSG_INFO, "EAP-SIM: no AT_NOTIFICATION in " 764 "Notification message"); 765 return eap_sim_client_error(data, id, 766 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 767 } 768 769 if ((attr->notification & 0x4000) == 0 && 770 eap_sim_process_notification_auth(data, reqData, attr)) { 771 return eap_sim_client_error(data, id, 772 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 773 } 774 775 eap_sim_report_notification(sm->msg_ctx, attr->notification, 0); 776 if (attr->notification >= 0 && attr->notification < 32768) { 777 eap_sim_state(data, FAILURE); 778 } else if (attr->notification == EAP_SIM_SUCCESS && 779 data->state == RESULT_SUCCESS) 780 eap_sim_state(data, SUCCESS); 781 return eap_sim_response_notification(data, id, attr->notification); 782 } 783 784 785 static struct wpabuf * eap_sim_process_reauthentication( 786 struct eap_sm *sm, struct eap_sim_data *data, u8 id, 787 const struct wpabuf *reqData, struct eap_sim_attrs *attr) 788 { 789 struct eap_sim_attrs eattr; 790 u8 *decrypted; 791 792 wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Reauthentication"); 793 794 if (data->reauth_id == NULL) { 795 wpa_printf(MSG_WARNING, "EAP-SIM: Server is trying " 796 "reauthentication, but no reauth_id available"); 797 return eap_sim_client_error(data, id, 798 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 799 } 800 801 data->reauth = 1; 802 if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0)) 803 { 804 wpa_printf(MSG_WARNING, "EAP-SIM: Reauthentication " 805 "did not have valid AT_MAC"); 806 return eap_sim_client_error(data, id, 807 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 808 } 809 810 if (attr->encr_data == NULL || attr->iv == NULL) { 811 wpa_printf(MSG_WARNING, "EAP-SIM: Reauthentication " 812 "message did not include encrypted data"); 813 return eap_sim_client_error(data, id, 814 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 815 } 816 817 decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, 818 attr->encr_data_len, attr->iv, &eattr, 819 0); 820 if (decrypted == NULL) { 821 wpa_printf(MSG_WARNING, "EAP-SIM: Failed to parse encrypted " 822 "data from reauthentication message"); 823 return eap_sim_client_error(data, id, 824 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 825 } 826 827 if (eattr.nonce_s == NULL || eattr.counter < 0) { 828 wpa_printf(MSG_INFO, "EAP-SIM: (encr) No%s%s in reauth packet", 829 !eattr.nonce_s ? " AT_NONCE_S" : "", 830 eattr.counter < 0 ? " AT_COUNTER" : ""); 831 os_free(decrypted); 832 return eap_sim_client_error(data, id, 833 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 834 } 835 836 if (eattr.counter < 0 || (size_t) eattr.counter <= data->counter) { 837 wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid counter " 838 "(%d <= %d)", eattr.counter, data->counter); 839 data->counter_too_small = eattr.counter; 840 /* Reply using Re-auth w/ AT_COUNTER_TOO_SMALL. The current 841 * reauth_id must not be used to start a new reauthentication. 842 * However, since it was used in the last EAP-Response-Identity 843 * packet, it has to saved for the following fullauth to be 844 * used in MK derivation. */ 845 os_free(data->last_eap_identity); 846 data->last_eap_identity = data->reauth_id; 847 data->last_eap_identity_len = data->reauth_id_len; 848 data->reauth_id = NULL; 849 data->reauth_id_len = 0; 850 os_free(decrypted); 851 return eap_sim_response_reauth(data, id, 1); 852 } 853 data->counter = eattr.counter; 854 855 os_memcpy(data->nonce_s, eattr.nonce_s, EAP_SIM_NONCE_S_LEN); 856 wpa_hexdump(MSG_DEBUG, "EAP-SIM: (encr) AT_NONCE_S", 857 data->nonce_s, EAP_SIM_NONCE_S_LEN); 858 859 eap_sim_derive_keys_reauth(data->counter, 860 data->reauth_id, data->reauth_id_len, 861 data->nonce_s, data->mk, data->msk, 862 data->emsk); 863 eap_sim_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID); 864 eap_sim_learn_ids(data, &eattr); 865 866 if (data->result_ind && attr->result_ind) 867 data->use_result_ind = 1; 868 869 if (data->state != FAILURE && data->state != RESULT_FAILURE) { 870 eap_sim_state(data, data->use_result_ind ? 871 RESULT_SUCCESS : SUCCESS); 872 } 873 874 data->num_id_req = 0; 875 data->num_notification = 0; 876 if (data->counter > EAP_SIM_MAX_FAST_REAUTHS) { 877 wpa_printf(MSG_DEBUG, "EAP-SIM: Maximum number of " 878 "fast reauths performed - force fullauth"); 879 eap_sim_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID); 880 } 881 os_free(decrypted); 882 return eap_sim_response_reauth(data, id, 0); 883 } 884 885 886 static struct wpabuf * eap_sim_process(struct eap_sm *sm, void *priv, 887 struct eap_method_ret *ret, 888 const struct wpabuf *reqData) 889 { 890 struct eap_sim_data *data = priv; 891 const struct eap_hdr *req; 892 u8 subtype, id; 893 struct wpabuf *res; 894 const u8 *pos; 895 struct eap_sim_attrs attr; 896 size_t len; 897 898 wpa_hexdump_buf(MSG_DEBUG, "EAP-SIM: EAP data", reqData); 899 if (eap_get_config_identity(sm, &len) == NULL) { 900 wpa_printf(MSG_INFO, "EAP-SIM: Identity not configured"); 901 eap_sm_request_identity(sm); 902 ret->ignore = TRUE; 903 return NULL; 904 } 905 906 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SIM, reqData, &len); 907 if (pos == NULL || len < 1) { 908 ret->ignore = TRUE; 909 return NULL; 910 } 911 req = wpabuf_head(reqData); 912 id = req->identifier; 913 len = be_to_host16(req->length); 914 915 ret->ignore = FALSE; 916 ret->methodState = METHOD_MAY_CONT; 917 ret->decision = DECISION_FAIL; 918 ret->allowNotifications = TRUE; 919 920 subtype = *pos++; 921 wpa_printf(MSG_DEBUG, "EAP-SIM: Subtype=%d", subtype); 922 pos += 2; /* Reserved */ 923 924 if (eap_sim_parse_attr(pos, wpabuf_head_u8(reqData) + len, &attr, 0, 925 0)) { 926 res = eap_sim_client_error(data, id, 927 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 928 goto done; 929 } 930 931 switch (subtype) { 932 case EAP_SIM_SUBTYPE_START: 933 res = eap_sim_process_start(sm, data, id, &attr); 934 break; 935 case EAP_SIM_SUBTYPE_CHALLENGE: 936 res = eap_sim_process_challenge(sm, data, id, reqData, &attr); 937 break; 938 case EAP_SIM_SUBTYPE_NOTIFICATION: 939 res = eap_sim_process_notification(sm, data, id, reqData, 940 &attr); 941 break; 942 case EAP_SIM_SUBTYPE_REAUTHENTICATION: 943 res = eap_sim_process_reauthentication(sm, data, id, reqData, 944 &attr); 945 break; 946 case EAP_SIM_SUBTYPE_CLIENT_ERROR: 947 wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Client-Error"); 948 res = eap_sim_client_error(data, id, 949 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 950 break; 951 default: 952 wpa_printf(MSG_DEBUG, "EAP-SIM: Unknown subtype=%d", subtype); 953 res = eap_sim_client_error(data, id, 954 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 955 break; 956 } 957 958 done: 959 if (data->state == FAILURE) { 960 ret->decision = DECISION_FAIL; 961 ret->methodState = METHOD_DONE; 962 } else if (data->state == SUCCESS) { 963 ret->decision = data->use_result_ind ? 964 DECISION_UNCOND_SUCC : DECISION_COND_SUCC; 965 ret->methodState = data->use_result_ind ? 966 METHOD_DONE : METHOD_MAY_CONT; 967 } else if (data->state == RESULT_FAILURE) 968 ret->methodState = METHOD_CONT; 969 else if (data->state == RESULT_SUCCESS) 970 ret->methodState = METHOD_CONT; 971 972 if (ret->methodState == METHOD_DONE) { 973 ret->allowNotifications = FALSE; 974 } 975 976 return res; 977 } 978 979 980 static Boolean eap_sim_has_reauth_data(struct eap_sm *sm, void *priv) 981 { 982 struct eap_sim_data *data = priv; 983 return data->pseudonym || data->reauth_id; 984 } 985 986 987 static void eap_sim_deinit_for_reauth(struct eap_sm *sm, void *priv) 988 { 989 struct eap_sim_data *data = priv; 990 eap_sim_clear_identities(data, CLEAR_EAP_ID); 991 data->use_result_ind = 0; 992 } 993 994 995 static void * eap_sim_init_for_reauth(struct eap_sm *sm, void *priv) 996 { 997 struct eap_sim_data *data = priv; 998 if (os_get_random(data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) { 999 wpa_printf(MSG_WARNING, "EAP-SIM: Failed to get random data " 1000 "for NONCE_MT"); 1001 os_free(data); 1002 return NULL; 1003 } 1004 data->num_id_req = 0; 1005 data->num_notification = 0; 1006 eap_sim_state(data, CONTINUE); 1007 return priv; 1008 } 1009 1010 1011 static const u8 * eap_sim_get_identity(struct eap_sm *sm, void *priv, 1012 size_t *len) 1013 { 1014 struct eap_sim_data *data = priv; 1015 1016 if (data->reauth_id) { 1017 *len = data->reauth_id_len; 1018 return data->reauth_id; 1019 } 1020 1021 if (data->pseudonym) { 1022 *len = data->pseudonym_len; 1023 return data->pseudonym; 1024 } 1025 1026 return NULL; 1027 } 1028 1029 1030 static Boolean eap_sim_isKeyAvailable(struct eap_sm *sm, void *priv) 1031 { 1032 struct eap_sim_data *data = priv; 1033 return data->state == SUCCESS; 1034 } 1035 1036 1037 static u8 * eap_sim_getKey(struct eap_sm *sm, void *priv, size_t *len) 1038 { 1039 struct eap_sim_data *data = priv; 1040 u8 *key; 1041 1042 if (data->state != SUCCESS) 1043 return NULL; 1044 1045 key = os_malloc(EAP_SIM_KEYING_DATA_LEN); 1046 if (key == NULL) 1047 return NULL; 1048 1049 *len = EAP_SIM_KEYING_DATA_LEN; 1050 os_memcpy(key, data->msk, EAP_SIM_KEYING_DATA_LEN); 1051 1052 return key; 1053 } 1054 1055 1056 static u8 * eap_sim_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 1057 { 1058 struct eap_sim_data *data = priv; 1059 u8 *key; 1060 1061 if (data->state != SUCCESS) 1062 return NULL; 1063 1064 key = os_malloc(EAP_EMSK_LEN); 1065 if (key == NULL) 1066 return NULL; 1067 1068 *len = EAP_EMSK_LEN; 1069 os_memcpy(key, data->emsk, EAP_EMSK_LEN); 1070 1071 return key; 1072 } 1073 1074 1075 int eap_peer_sim_register(void) 1076 { 1077 struct eap_method *eap; 1078 int ret; 1079 1080 eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 1081 EAP_VENDOR_IETF, EAP_TYPE_SIM, "SIM"); 1082 if (eap == NULL) 1083 return -1; 1084 1085 eap->init = eap_sim_init; 1086 eap->deinit = eap_sim_deinit; 1087 eap->process = eap_sim_process; 1088 eap->isKeyAvailable = eap_sim_isKeyAvailable; 1089 eap->getKey = eap_sim_getKey; 1090 eap->has_reauth_data = eap_sim_has_reauth_data; 1091 eap->deinit_for_reauth = eap_sim_deinit_for_reauth; 1092 eap->init_for_reauth = eap_sim_init_for_reauth; 1093 eap->get_identity = eap_sim_get_identity; 1094 eap->get_emsk = eap_sim_get_emsk; 1095 1096 ret = eap_peer_method_register(eap); 1097 if (ret) 1098 eap_peer_method_free(eap); 1099 return ret; 1100 } 1101