1 /* 2 * EAP peer method: EAP-SIM (RFC 4186) 3 * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "includes.h" 10 11 #include "common.h" 12 #include "utils/base64.h" 13 #include "pcsc_funcs.h" 14 #include "crypto/crypto.h" 15 #include "crypto/milenage.h" 16 #include "crypto/random.h" 17 #include "eap_peer/eap_i.h" 18 #include "eap_config.h" 19 #include "eap_common/eap_sim_common.h" 20 21 22 struct eap_sim_data { 23 u8 *ver_list; 24 size_t ver_list_len; 25 int selected_version; 26 size_t min_num_chal, num_chal; 27 28 u8 kc[3][EAP_SIM_KC_LEN]; 29 u8 sres[3][EAP_SIM_SRES_LEN]; 30 u8 nonce_mt[EAP_SIM_NONCE_MT_LEN], nonce_s[EAP_SIM_NONCE_S_LEN]; 31 u8 mk[EAP_SIM_MK_LEN]; 32 u8 k_aut[EAP_SIM_K_AUT_LEN]; 33 u8 k_encr[EAP_SIM_K_ENCR_LEN]; 34 u8 msk[EAP_SIM_KEYING_DATA_LEN]; 35 u8 emsk[EAP_EMSK_LEN]; 36 u8 rand[3][GSM_RAND_LEN]; 37 u8 reauth_mac[EAP_SIM_MAC_LEN]; 38 39 int num_id_req, num_notification; 40 u8 *pseudonym; 41 size_t pseudonym_len; 42 u8 *reauth_id; 43 size_t reauth_id_len; 44 int reauth; 45 unsigned int counter, counter_too_small; 46 u8 *mk_identity; 47 size_t mk_identity_len; 48 enum { 49 CONTINUE, START_DONE, RESULT_SUCCESS, SUCCESS, FAILURE 50 } state; 51 int result_ind, use_result_ind; 52 int use_pseudonym; 53 int error_code; 54 struct crypto_rsa_key *imsi_privacy_key; 55 }; 56 57 58 #ifndef CONFIG_NO_STDOUT_DEBUG 59 static const char * eap_sim_state_txt(int state) 60 { 61 switch (state) { 62 case CONTINUE: 63 return "CONTINUE"; 64 case START_DONE: 65 return "START_DONE"; 66 case RESULT_SUCCESS: 67 return "RESULT_SUCCESS"; 68 case SUCCESS: 69 return "SUCCESS"; 70 case FAILURE: 71 return "FAILURE"; 72 default: 73 return "?"; 74 } 75 } 76 #endif /* CONFIG_NO_STDOUT_DEBUG */ 77 78 79 static void eap_sim_state(struct eap_sim_data *data, int state) 80 { 81 wpa_printf(MSG_DEBUG, "EAP-SIM: %s -> %s", 82 eap_sim_state_txt(data->state), 83 eap_sim_state_txt(state)); 84 data->state = state; 85 } 86 87 88 static void * eap_sim_init(struct eap_sm *sm) 89 { 90 struct eap_sim_data *data; 91 struct eap_peer_config *config = eap_get_config(sm); 92 93 data = os_zalloc(sizeof(*data)); 94 if (data == NULL) 95 return NULL; 96 97 if (random_get_bytes(data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) { 98 wpa_printf(MSG_WARNING, "EAP-SIM: Failed to get random data " 99 "for NONCE_MT"); 100 os_free(data); 101 return NULL; 102 } 103 104 if (config && config->imsi_privacy_cert) { 105 #ifdef CRYPTO_RSA_OAEP_SHA256 106 data->imsi_privacy_key = crypto_rsa_key_read( 107 config->imsi_privacy_cert, false); 108 if (!data->imsi_privacy_key) { 109 wpa_printf(MSG_ERROR, 110 "EAP-SIM: Failed to read/parse IMSI privacy certificate %s", 111 config->imsi_privacy_cert); 112 os_free(data); 113 return NULL; 114 } 115 #else /* CRYPTO_RSA_OAEP_SHA256 */ 116 wpa_printf(MSG_ERROR, 117 "EAP-SIM: No support for imsi_privacy_cert in the build"); 118 os_free(data); 119 return NULL; 120 #endif /* CRYPTO_RSA_OAEP_SHA256 */ 121 } 122 123 /* Zero is a valid error code, so we need to initialize */ 124 data->error_code = NO_EAP_METHOD_ERROR; 125 126 data->min_num_chal = 2; 127 if (config && config->phase1) { 128 char *pos = os_strstr(config->phase1, "sim_min_num_chal="); 129 if (pos) { 130 data->min_num_chal = atoi(pos + 17); 131 if (data->min_num_chal < 2 || data->min_num_chal > 3) { 132 wpa_printf(MSG_WARNING, "EAP-SIM: Invalid " 133 "sim_min_num_chal configuration " 134 "(%lu, expected 2 or 3)", 135 (unsigned long) data->min_num_chal); 136 #ifdef CRYPTO_RSA_OAEP_SHA256 137 crypto_rsa_key_free(data->imsi_privacy_key); 138 #endif /* CRYPTO_RSA_OAEP_SHA256 */ 139 os_free(data); 140 return NULL; 141 } 142 wpa_printf(MSG_DEBUG, "EAP-SIM: Set minimum number of " 143 "challenges to %lu", 144 (unsigned long) data->min_num_chal); 145 } 146 147 data->result_ind = os_strstr(config->phase1, "result_ind=1") != 148 NULL; 149 } 150 151 data->use_pseudonym = !sm->init_phase2; 152 if (config && config->anonymous_identity && data->use_pseudonym) { 153 data->pseudonym = os_malloc(config->anonymous_identity_len); 154 if (data->pseudonym) { 155 os_memcpy(data->pseudonym, config->anonymous_identity, 156 config->anonymous_identity_len); 157 data->pseudonym_len = config->anonymous_identity_len; 158 } 159 } 160 161 if (sm->identity) { 162 /* Use the EAP-Response/Identity in MK derivation if AT_IDENTITY 163 * is not used. */ 164 data->mk_identity = os_memdup(sm->identity, sm->identity_len); 165 data->mk_identity_len = sm->identity_len; 166 } 167 168 eap_sim_state(data, CONTINUE); 169 170 return data; 171 } 172 173 174 static void eap_sim_clear_keys(struct eap_sim_data *data, int reauth) 175 { 176 if (!reauth) { 177 os_memset(data->mk, 0, EAP_SIM_MK_LEN); 178 os_memset(data->k_aut, 0, EAP_SIM_K_AUT_LEN); 179 os_memset(data->k_encr, 0, EAP_SIM_K_ENCR_LEN); 180 } 181 os_memset(data->kc, 0, 3 * EAP_SIM_KC_LEN); 182 os_memset(data->sres, 0, 3 * EAP_SIM_SRES_LEN); 183 os_memset(data->msk, 0, EAP_SIM_KEYING_DATA_LEN); 184 os_memset(data->emsk, 0, EAP_EMSK_LEN); 185 } 186 187 188 static void eap_sim_deinit(struct eap_sm *sm, void *priv) 189 { 190 struct eap_sim_data *data = priv; 191 if (data) { 192 os_free(data->ver_list); 193 os_free(data->pseudonym); 194 os_free(data->reauth_id); 195 os_free(data->mk_identity); 196 eap_sim_clear_keys(data, 0); 197 #ifdef CRYPTO_RSA_OAEP_SHA256 198 crypto_rsa_key_free(data->imsi_privacy_key); 199 #endif /* CRYPTO_RSA_OAEP_SHA256 */ 200 os_free(data); 201 } 202 } 203 204 205 static int eap_sim_ext_sim_req(struct eap_sm *sm, struct eap_sim_data *data) 206 { 207 char req[200], *pos, *end; 208 size_t i; 209 210 wpa_printf(MSG_DEBUG, "EAP-SIM: Use external SIM processing"); 211 pos = req; 212 end = pos + sizeof(req); 213 pos += os_snprintf(pos, end - pos, "GSM-AUTH"); 214 for (i = 0; i < data->num_chal; i++) { 215 pos += os_snprintf(pos, end - pos, ":"); 216 pos += wpa_snprintf_hex(pos, end - pos, data->rand[i], 217 GSM_RAND_LEN); 218 } 219 220 eap_sm_request_sim(sm, req); 221 return 1; 222 } 223 224 225 static int eap_sim_ext_sim_result(struct eap_sm *sm, struct eap_sim_data *data, 226 struct eap_peer_config *conf) 227 { 228 char *resp, *pos; 229 size_t i; 230 231 wpa_printf(MSG_DEBUG, 232 "EAP-SIM: Use result from external SIM processing"); 233 234 resp = conf->external_sim_resp; 235 conf->external_sim_resp = NULL; 236 237 if (os_strncmp(resp, "GSM-AUTH:", 9) != 0) { 238 wpa_printf(MSG_DEBUG, "EAP-SIM: Unrecognized external SIM processing response"); 239 os_free(resp); 240 return -1; 241 } 242 243 pos = resp + 9; 244 for (i = 0; i < data->num_chal; i++) { 245 wpa_hexdump(MSG_DEBUG, "EAP-SIM: RAND", 246 data->rand[i], GSM_RAND_LEN); 247 248 if (hexstr2bin(pos, data->kc[i], EAP_SIM_KC_LEN) < 0) 249 goto invalid; 250 wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: Kc", 251 data->kc[i], EAP_SIM_KC_LEN); 252 pos += EAP_SIM_KC_LEN * 2; 253 if (*pos != ':') 254 goto invalid; 255 pos++; 256 257 if (hexstr2bin(pos, data->sres[i], EAP_SIM_SRES_LEN) < 0) 258 goto invalid; 259 wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: SRES", 260 data->sres[i], EAP_SIM_SRES_LEN); 261 pos += EAP_SIM_SRES_LEN * 2; 262 if (i + 1 < data->num_chal) { 263 if (*pos != ':') 264 goto invalid; 265 pos++; 266 } 267 } 268 269 os_free(resp); 270 return 0; 271 272 invalid: 273 wpa_printf(MSG_DEBUG, "EAP-SIM: Invalid external SIM processing GSM-AUTH response"); 274 os_free(resp); 275 return -1; 276 } 277 278 279 static int eap_sim_gsm_auth(struct eap_sm *sm, struct eap_sim_data *data) 280 { 281 struct eap_peer_config *conf; 282 283 wpa_printf(MSG_DEBUG, "EAP-SIM: GSM authentication algorithm"); 284 285 conf = eap_get_config(sm); 286 if (conf == NULL) 287 return -1; 288 289 if (sm->external_sim) { 290 if (conf->external_sim_resp) 291 return eap_sim_ext_sim_result(sm, data, conf); 292 else 293 return eap_sim_ext_sim_req(sm, data); 294 } 295 296 #ifdef PCSC_FUNCS 297 if (conf->pcsc) { 298 if (scard_gsm_auth(sm->scard_ctx, data->rand[0], 299 data->sres[0], data->kc[0]) || 300 scard_gsm_auth(sm->scard_ctx, data->rand[1], 301 data->sres[1], data->kc[1]) || 302 (data->num_chal > 2 && 303 scard_gsm_auth(sm->scard_ctx, data->rand[2], 304 data->sres[2], data->kc[2]))) { 305 wpa_printf(MSG_DEBUG, "EAP-SIM: GSM SIM " 306 "authentication could not be completed"); 307 return -1; 308 } 309 return 0; 310 } 311 #endif /* PCSC_FUNCS */ 312 313 #ifdef CONFIG_SIM_SIMULATOR 314 if (conf->password) { 315 u8 opc[16], k[16]; 316 const char *pos; 317 size_t i; 318 wpa_printf(MSG_DEBUG, "EAP-SIM: Use internal GSM-Milenage " 319 "implementation for authentication"); 320 if (conf->password_len < 65) { 321 wpa_printf(MSG_DEBUG, "EAP-SIM: invalid GSM-Milenage " 322 "password"); 323 return -1; 324 } 325 pos = (const char *) conf->password; 326 if (hexstr2bin(pos, k, 16)) 327 return -1; 328 pos += 32; 329 if (*pos != ':') 330 return -1; 331 pos++; 332 333 if (hexstr2bin(pos, opc, 16)) 334 return -1; 335 336 for (i = 0; i < data->num_chal; i++) { 337 if (gsm_milenage(opc, k, data->rand[i], 338 data->sres[i], data->kc[i])) { 339 wpa_printf(MSG_DEBUG, "EAP-SIM: " 340 "GSM-Milenage authentication " 341 "could not be completed"); 342 return -1; 343 } 344 wpa_hexdump(MSG_DEBUG, "EAP-SIM: RAND", 345 data->rand[i], GSM_RAND_LEN); 346 wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: SRES", 347 data->sres[i], EAP_SIM_SRES_LEN); 348 wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: Kc", 349 data->kc[i], EAP_SIM_KC_LEN); 350 } 351 return 0; 352 } 353 #endif /* CONFIG_SIM_SIMULATOR */ 354 355 #ifdef CONFIG_SIM_HARDCODED 356 /* These hardcoded Kc and SRES values are used for testing. RAND to 357 * KC/SREC mapping is very bogus as far as real authentication is 358 * concerned, but it is quite useful for cases where the AS is rotating 359 * the order of pre-configured values. */ 360 { 361 size_t i; 362 363 wpa_printf(MSG_DEBUG, "EAP-SIM: Use hardcoded Kc and SRES " 364 "values for testing"); 365 366 for (i = 0; i < data->num_chal; i++) { 367 if (data->rand[i][0] == 0xaa) { 368 os_memcpy(data->kc[i], 369 "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7", 370 EAP_SIM_KC_LEN); 371 os_memcpy(data->sres[i], "\xd1\xd2\xd3\xd4", 372 EAP_SIM_SRES_LEN); 373 } else if (data->rand[i][0] == 0xbb) { 374 os_memcpy(data->kc[i], 375 "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7", 376 EAP_SIM_KC_LEN); 377 os_memcpy(data->sres[i], "\xe1\xe2\xe3\xe4", 378 EAP_SIM_SRES_LEN); 379 } else { 380 os_memcpy(data->kc[i], 381 "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7", 382 EAP_SIM_KC_LEN); 383 os_memcpy(data->sres[i], "\xf1\xf2\xf3\xf4", 384 EAP_SIM_SRES_LEN); 385 } 386 } 387 } 388 389 return 0; 390 391 #else /* CONFIG_SIM_HARDCODED */ 392 393 wpa_printf(MSG_DEBUG, "EAP-SIM: No GSM authentication algorithm " 394 "enabled"); 395 return -1; 396 397 #endif /* CONFIG_SIM_HARDCODED */ 398 } 399 400 401 static int eap_sim_supported_ver(int version) 402 { 403 return version == EAP_SIM_VERSION; 404 } 405 406 407 #define CLEAR_PSEUDONYM 0x01 408 #define CLEAR_REAUTH_ID 0x02 409 410 static void eap_sim_clear_identities(struct eap_sm *sm, 411 struct eap_sim_data *data, int id) 412 { 413 if ((id & CLEAR_PSEUDONYM) && data->pseudonym) { 414 wpa_printf(MSG_DEBUG, "EAP-SIM: forgetting old pseudonym"); 415 os_free(data->pseudonym); 416 data->pseudonym = NULL; 417 data->pseudonym_len = 0; 418 if (data->use_pseudonym) 419 eap_set_anon_id(sm, NULL, 0); 420 } 421 if ((id & CLEAR_REAUTH_ID) && data->reauth_id) { 422 wpa_printf(MSG_DEBUG, "EAP-SIM: forgetting old reauth_id"); 423 os_free(data->reauth_id); 424 data->reauth_id = NULL; 425 data->reauth_id_len = 0; 426 } 427 } 428 429 430 static int eap_sim_learn_ids(struct eap_sm *sm, struct eap_sim_data *data, 431 struct eap_sim_attrs *attr) 432 { 433 if (attr->next_pseudonym) { 434 const u8 *identity = NULL; 435 size_t identity_len = 0; 436 const u8 *realm = NULL; 437 size_t realm_len = 0; 438 439 wpa_hexdump_ascii(MSG_DEBUG, 440 "EAP-SIM: (encr) AT_NEXT_PSEUDONYM", 441 attr->next_pseudonym, 442 attr->next_pseudonym_len); 443 os_free(data->pseudonym); 444 /* Look for the realm of the permanent identity */ 445 identity = eap_get_config_identity(sm, &identity_len); 446 if (identity) { 447 for (realm = identity, realm_len = identity_len; 448 realm_len > 0; realm_len--, realm++) { 449 if (*realm == '@') 450 break; 451 } 452 } 453 data->pseudonym = os_malloc(attr->next_pseudonym_len + 454 realm_len); 455 if (data->pseudonym == NULL) { 456 wpa_printf(MSG_INFO, "EAP-SIM: (encr) No memory for " 457 "next pseudonym"); 458 data->pseudonym_len = 0; 459 return -1; 460 } 461 os_memcpy(data->pseudonym, attr->next_pseudonym, 462 attr->next_pseudonym_len); 463 if (realm_len) { 464 os_memcpy(data->pseudonym + attr->next_pseudonym_len, 465 realm, realm_len); 466 } 467 data->pseudonym_len = attr->next_pseudonym_len + realm_len; 468 if (data->use_pseudonym) 469 eap_set_anon_id(sm, data->pseudonym, 470 data->pseudonym_len); 471 } 472 473 if (attr->next_reauth_id) { 474 os_free(data->reauth_id); 475 data->reauth_id = os_memdup(attr->next_reauth_id, 476 attr->next_reauth_id_len); 477 if (data->reauth_id == NULL) { 478 wpa_printf(MSG_INFO, "EAP-SIM: (encr) No memory for " 479 "next reauth_id"); 480 data->reauth_id_len = 0; 481 return -1; 482 } 483 data->reauth_id_len = attr->next_reauth_id_len; 484 wpa_hexdump_ascii(MSG_DEBUG, 485 "EAP-SIM: (encr) AT_NEXT_REAUTH_ID", 486 data->reauth_id, 487 data->reauth_id_len); 488 } 489 490 return 0; 491 } 492 493 494 static struct wpabuf * eap_sim_client_error(struct eap_sim_data *data, u8 id, 495 int err) 496 { 497 struct eap_sim_msg *msg; 498 499 eap_sim_state(data, FAILURE); 500 data->num_id_req = 0; 501 data->num_notification = 0; 502 503 wpa_printf(MSG_DEBUG, "EAP-SIM: Send Client-Error (error code %d)", 504 err); 505 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_SIM, 506 EAP_SIM_SUBTYPE_CLIENT_ERROR); 507 eap_sim_msg_add(msg, EAP_SIM_AT_CLIENT_ERROR_CODE, err, NULL, 0); 508 return eap_sim_msg_finish(msg, EAP_TYPE_SIM, NULL, NULL, 0); 509 } 510 511 512 #ifdef CRYPTO_RSA_OAEP_SHA256 513 static struct wpabuf * 514 eap_sim_encrypt_identity(struct crypto_rsa_key *imsi_privacy_key, 515 const u8 *identity, size_t identity_len, 516 const char *attr) 517 { 518 struct wpabuf *imsi_buf, *enc; 519 char *b64; 520 size_t b64_len, len; 521 522 wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Encrypt permanent identity", 523 identity, identity_len); 524 525 imsi_buf = wpabuf_alloc_copy(identity, identity_len); 526 if (!imsi_buf) 527 return NULL; 528 enc = crypto_rsa_oaep_sha256_encrypt(imsi_privacy_key, imsi_buf); 529 wpabuf_free(imsi_buf); 530 if (!enc) 531 return NULL; 532 533 b64 = base64_encode_no_lf(wpabuf_head(enc), wpabuf_len(enc), &b64_len); 534 wpabuf_free(enc); 535 if (!b64) 536 return NULL; 537 538 len = 1 + b64_len; 539 if (attr) 540 len += 1 + os_strlen(attr); 541 enc = wpabuf_alloc(len); 542 if (!enc) { 543 os_free(b64); 544 return NULL; 545 } 546 wpabuf_put_u8(enc, '\0'); 547 wpabuf_put_data(enc, b64, b64_len); 548 os_free(b64); 549 if (attr) { 550 wpabuf_put_u8(enc, ','); 551 wpabuf_put_str(enc, attr); 552 } 553 wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Encrypted permanent identity", 554 wpabuf_head(enc), wpabuf_len(enc)); 555 556 return enc; 557 } 558 #endif /* CRYPTO_RSA_OAEP_SHA256 */ 559 560 561 static struct wpabuf * eap_sim_response_start(struct eap_sm *sm, 562 struct eap_sim_data *data, u8 id, 563 enum eap_sim_id_req id_req) 564 { 565 const u8 *identity = NULL; 566 size_t identity_len = 0; 567 struct eap_sim_msg *msg; 568 struct wpabuf *resp; 569 struct wpabuf *enc_identity = NULL; 570 struct eap_peer_config *config = NULL; 571 bool use_imsi_identity = false; 572 573 data->reauth = 0; 574 if (id_req == ANY_ID && data->reauth_id) { 575 identity = data->reauth_id; 576 identity_len = data->reauth_id_len; 577 data->reauth = 1; 578 } else if ((id_req == ANY_ID || id_req == FULLAUTH_ID) && 579 data->pseudonym && 580 !eap_sim_anonymous_username(data->pseudonym, 581 data->pseudonym_len)) { 582 identity = data->pseudonym; 583 identity_len = data->pseudonym_len; 584 eap_sim_clear_identities(sm, data, CLEAR_REAUTH_ID); 585 } else if (id_req != NO_ID_REQ) { 586 identity = eap_get_config_identity(sm, &identity_len); 587 if (identity) { 588 int ids = CLEAR_PSEUDONYM | CLEAR_REAUTH_ID; 589 590 if (data->pseudonym && 591 eap_sim_anonymous_username(data->pseudonym, 592 data->pseudonym_len)) 593 ids &= ~CLEAR_PSEUDONYM; 594 eap_sim_clear_identities(sm, data, ids); 595 596 config = eap_get_config(sm); 597 if (config && config->imsi_identity) 598 use_imsi_identity = true; 599 } 600 #ifdef CRYPTO_RSA_OAEP_SHA256 601 if (identity && data->imsi_privacy_key) { 602 const char *attr = NULL; 603 604 config = eap_get_config(sm); 605 if (config) 606 attr = config->imsi_privacy_attr; 607 enc_identity = eap_sim_encrypt_identity( 608 data->imsi_privacy_key, 609 identity, identity_len, attr); 610 if (!enc_identity) { 611 wpa_printf(MSG_INFO, 612 "EAP-SIM: Failed to encrypt permanent identity"); 613 return eap_sim_client_error( 614 data, id, 615 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 616 } 617 /* Use the real identity, not the encrypted one, in MK 618 * derivation. */ 619 os_free(data->mk_identity); 620 data->mk_identity = os_memdup(identity, identity_len); 621 data->mk_identity_len = identity_len; 622 identity = wpabuf_head(enc_identity); 623 identity_len = wpabuf_len(enc_identity); 624 } 625 #endif /* CRYPTO_RSA_OAEP_SHA256 */ 626 } 627 628 wpa_printf(MSG_DEBUG, "Generating EAP-SIM Start (id=%d)", id); 629 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, 630 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START); 631 if (identity) { 632 wpa_hexdump_ascii(MSG_DEBUG, " AT_IDENTITY", 633 identity, identity_len); 634 eap_sim_msg_add(msg, EAP_SIM_AT_IDENTITY, identity_len, 635 identity, identity_len); 636 if (use_imsi_identity && config && config->imsi_identity) { 637 /* Use the IMSI identity override, i.e., the not 638 * encrypted one, in MK derivation, when using 639 * externally encrypted identity in configuration. */ 640 os_free(data->mk_identity); 641 data->mk_identity = os_memdup( 642 config->imsi_identity, 643 config->imsi_identity_len); 644 data->mk_identity_len = config->imsi_identity_len; 645 } else if (!enc_identity) { 646 /* Use the last AT_IDENTITY value as the identity in 647 * MK derivation. */ 648 os_free(data->mk_identity); 649 data->mk_identity = os_memdup(identity, identity_len); 650 data->mk_identity_len = identity_len; 651 } 652 } 653 wpabuf_free(enc_identity); 654 if (!data->reauth) { 655 wpa_hexdump(MSG_DEBUG, " AT_NONCE_MT", 656 data->nonce_mt, EAP_SIM_NONCE_MT_LEN); 657 eap_sim_msg_add(msg, EAP_SIM_AT_NONCE_MT, 0, 658 data->nonce_mt, EAP_SIM_NONCE_MT_LEN); 659 wpa_printf(MSG_DEBUG, " AT_SELECTED_VERSION %d", 660 data->selected_version); 661 eap_sim_msg_add(msg, EAP_SIM_AT_SELECTED_VERSION, 662 data->selected_version, NULL, 0); 663 } 664 665 resp = eap_sim_msg_finish(msg, EAP_TYPE_SIM, NULL, NULL, 0); 666 if (resp) 667 eap_sim_state(data, START_DONE); 668 return resp; 669 } 670 671 672 static struct wpabuf * eap_sim_response_challenge(struct eap_sim_data *data, 673 u8 id) 674 { 675 struct eap_sim_msg *msg; 676 677 wpa_printf(MSG_DEBUG, "Generating EAP-SIM Challenge (id=%d)", id); 678 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_SIM, 679 EAP_SIM_SUBTYPE_CHALLENGE); 680 if (data->use_result_ind) { 681 wpa_printf(MSG_DEBUG, " AT_RESULT_IND"); 682 eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0); 683 } 684 wpa_printf(MSG_DEBUG, " AT_MAC"); 685 eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); 686 return eap_sim_msg_finish(msg, EAP_TYPE_SIM, data->k_aut, 687 (u8 *) data->sres, 688 data->num_chal * EAP_SIM_SRES_LEN); 689 } 690 691 692 static struct wpabuf * eap_sim_response_reauth(struct eap_sim_data *data, 693 u8 id, int counter_too_small, 694 const u8 *nonce_s) 695 { 696 struct eap_sim_msg *msg; 697 unsigned int counter; 698 699 wpa_printf(MSG_DEBUG, "Generating EAP-SIM Reauthentication (id=%d)", 700 id); 701 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_SIM, 702 EAP_SIM_SUBTYPE_REAUTHENTICATION); 703 wpa_printf(MSG_DEBUG, " AT_IV"); 704 wpa_printf(MSG_DEBUG, " AT_ENCR_DATA"); 705 eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, EAP_SIM_AT_ENCR_DATA); 706 707 if (counter_too_small) { 708 wpa_printf(MSG_DEBUG, " *AT_COUNTER_TOO_SMALL"); 709 eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER_TOO_SMALL, 0, NULL, 0); 710 counter = data->counter_too_small; 711 } else 712 counter = data->counter; 713 714 wpa_printf(MSG_DEBUG, " *AT_COUNTER %d", counter); 715 eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, counter, NULL, 0); 716 717 if (eap_sim_msg_add_encr_end(msg, data->k_encr, EAP_SIM_AT_PADDING)) { 718 wpa_printf(MSG_WARNING, "EAP-SIM: Failed to encrypt " 719 "AT_ENCR_DATA"); 720 eap_sim_msg_free(msg); 721 return NULL; 722 } 723 if (data->use_result_ind) { 724 wpa_printf(MSG_DEBUG, " AT_RESULT_IND"); 725 eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0); 726 } 727 wpa_printf(MSG_DEBUG, " AT_MAC"); 728 eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); 729 return eap_sim_msg_finish(msg, EAP_TYPE_SIM, data->k_aut, nonce_s, 730 EAP_SIM_NONCE_S_LEN); 731 } 732 733 734 static struct wpabuf * eap_sim_response_notification(struct eap_sim_data *data, 735 u8 id, u16 notification) 736 { 737 struct eap_sim_msg *msg; 738 u8 *k_aut = (notification & 0x4000) == 0 ? data->k_aut : NULL; 739 740 wpa_printf(MSG_DEBUG, "Generating EAP-SIM Notification (id=%d)", id); 741 msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, 742 EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION); 743 if (k_aut && data->reauth) { 744 wpa_printf(MSG_DEBUG, " AT_IV"); 745 wpa_printf(MSG_DEBUG, " AT_ENCR_DATA"); 746 eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, 747 EAP_SIM_AT_ENCR_DATA); 748 wpa_printf(MSG_DEBUG, " *AT_COUNTER %d", data->counter); 749 eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, data->counter, 750 NULL, 0); 751 if (eap_sim_msg_add_encr_end(msg, data->k_encr, 752 EAP_SIM_AT_PADDING)) { 753 wpa_printf(MSG_WARNING, "EAP-SIM: Failed to encrypt " 754 "AT_ENCR_DATA"); 755 eap_sim_msg_free(msg); 756 return NULL; 757 } 758 } 759 if (k_aut) { 760 wpa_printf(MSG_DEBUG, " AT_MAC"); 761 eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC); 762 } 763 return eap_sim_msg_finish(msg, EAP_TYPE_SIM, k_aut, (u8 *) "", 0); 764 } 765 766 767 static struct wpabuf * eap_sim_process_start(struct eap_sm *sm, 768 struct eap_sim_data *data, u8 id, 769 struct eap_sim_attrs *attr) 770 { 771 int selected_version = -1, id_error; 772 size_t i; 773 u8 *pos; 774 775 wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Start"); 776 if (attr->version_list == NULL) { 777 wpa_printf(MSG_INFO, "EAP-SIM: No AT_VERSION_LIST in " 778 "SIM/Start"); 779 return eap_sim_client_error(data, id, 780 EAP_SIM_UNSUPPORTED_VERSION); 781 } 782 783 os_free(data->ver_list); 784 data->ver_list = os_memdup(attr->version_list, attr->version_list_len); 785 if (data->ver_list == NULL) { 786 wpa_printf(MSG_DEBUG, "EAP-SIM: Failed to allocate " 787 "memory for version list"); 788 return eap_sim_client_error(data, id, 789 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 790 } 791 data->ver_list_len = attr->version_list_len; 792 pos = data->ver_list; 793 for (i = 0; i < data->ver_list_len / 2; i++) { 794 int ver = pos[0] * 256 + pos[1]; 795 pos += 2; 796 if (eap_sim_supported_ver(ver)) { 797 selected_version = ver; 798 break; 799 } 800 } 801 if (selected_version < 0) { 802 wpa_printf(MSG_INFO, "EAP-SIM: Could not find a supported " 803 "version"); 804 return eap_sim_client_error(data, id, 805 EAP_SIM_UNSUPPORTED_VERSION); 806 } 807 wpa_printf(MSG_DEBUG, "EAP-SIM: Selected Version %d", 808 selected_version); 809 data->selected_version = selected_version; 810 811 id_error = 0; 812 switch (attr->id_req) { 813 case NO_ID_REQ: 814 break; 815 case ANY_ID: 816 if (data->num_id_req > 0) 817 id_error++; 818 data->num_id_req++; 819 break; 820 case FULLAUTH_ID: 821 if (data->num_id_req > 1) 822 id_error++; 823 data->num_id_req++; 824 break; 825 case PERMANENT_ID: 826 if (data->num_id_req > 2) 827 id_error++; 828 data->num_id_req++; 829 break; 830 } 831 if (id_error) { 832 wpa_printf(MSG_INFO, "EAP-SIM: Too many ID requests " 833 "used within one authentication"); 834 return eap_sim_client_error(data, id, 835 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 836 } 837 838 return eap_sim_response_start(sm, data, id, attr->id_req); 839 } 840 841 842 static struct wpabuf * eap_sim_process_challenge(struct eap_sm *sm, 843 struct eap_sim_data *data, 844 u8 id, 845 const struct wpabuf *reqData, 846 struct eap_sim_attrs *attr) 847 { 848 const u8 *identity; 849 size_t identity_len; 850 struct eap_sim_attrs eattr; 851 int res; 852 853 wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Challenge"); 854 if (data->state != START_DONE) { 855 wpa_printf(MSG_DEBUG, 856 "EAP-SIM: Unexpected Challenge in state %s", 857 eap_sim_state_txt(data->state)); 858 return eap_sim_client_error(data, id, 859 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 860 } 861 data->reauth = 0; 862 if (!attr->mac || !attr->rand) { 863 wpa_printf(MSG_WARNING, "EAP-SIM: Challenge message " 864 "did not include%s%s", 865 !attr->mac ? " AT_MAC" : "", 866 !attr->rand ? " AT_RAND" : ""); 867 return eap_sim_client_error(data, id, 868 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 869 } 870 871 wpa_printf(MSG_DEBUG, "EAP-SIM: %lu challenges", 872 (unsigned long) attr->num_chal); 873 if (attr->num_chal < data->min_num_chal) { 874 wpa_printf(MSG_INFO, "EAP-SIM: Insufficient number of " 875 "challenges (%lu)", (unsigned long) attr->num_chal); 876 return eap_sim_client_error(data, id, 877 EAP_SIM_INSUFFICIENT_NUM_OF_CHAL); 878 } 879 if (attr->num_chal > 3) { 880 wpa_printf(MSG_INFO, "EAP-SIM: Too many challenges " 881 "(%lu)", (unsigned long) attr->num_chal); 882 return eap_sim_client_error(data, id, 883 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 884 } 885 886 /* Verify that RANDs are different */ 887 if (os_memcmp(attr->rand, attr->rand + GSM_RAND_LEN, 888 GSM_RAND_LEN) == 0 || 889 (attr->num_chal > 2 && 890 (os_memcmp(attr->rand, attr->rand + 2 * GSM_RAND_LEN, 891 GSM_RAND_LEN) == 0 || 892 os_memcmp(attr->rand + GSM_RAND_LEN, 893 attr->rand + 2 * GSM_RAND_LEN, 894 GSM_RAND_LEN) == 0))) { 895 wpa_printf(MSG_INFO, "EAP-SIM: Same RAND used multiple times"); 896 return eap_sim_client_error(data, id, 897 EAP_SIM_RAND_NOT_FRESH); 898 } 899 900 os_memcpy(data->rand, attr->rand, attr->num_chal * GSM_RAND_LEN); 901 data->num_chal = attr->num_chal; 902 903 res = eap_sim_gsm_auth(sm, data); 904 if (res > 0) { 905 wpa_printf(MSG_DEBUG, "EAP-SIM: Wait for external SIM processing"); 906 return NULL; 907 } 908 if (res) { 909 wpa_printf(MSG_WARNING, "EAP-SIM: GSM authentication failed"); 910 return eap_sim_client_error(data, id, 911 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 912 } 913 914 identity = data->mk_identity; 915 identity_len = data->mk_identity_len; 916 wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Selected identity for MK " 917 "derivation", identity, identity_len); 918 eap_sim_derive_mk(identity, identity_len, data->nonce_mt, 919 data->selected_version, data->ver_list, 920 data->ver_list_len, data->num_chal, 921 (const u8 *) data->kc, data->mk); 922 eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk, 923 data->emsk); 924 if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, data->nonce_mt, 925 EAP_SIM_NONCE_MT_LEN)) { 926 wpa_printf(MSG_WARNING, "EAP-SIM: Challenge message " 927 "used invalid AT_MAC"); 928 #ifdef TEST_FUZZ 929 wpa_printf(MSG_INFO, 930 "TEST: Ignore AT_MAC mismatch for fuzz testing"); 931 #else /* TEST_FUZZ */ 932 return eap_sim_client_error(data, id, 933 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 934 #endif /* TEST_FUZZ */ 935 } 936 937 /* Old reauthentication identity must not be used anymore. In 938 * other words, if no new reauth identity is received, full 939 * authentication will be used on next reauthentication (using 940 * pseudonym identity or permanent identity). */ 941 eap_sim_clear_identities(sm, data, CLEAR_REAUTH_ID); 942 943 if (attr->encr_data) { 944 u8 *decrypted; 945 decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, 946 attr->encr_data_len, attr->iv, 947 &eattr, 0); 948 if (decrypted == NULL) { 949 return eap_sim_client_error( 950 data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET); 951 } 952 eap_sim_learn_ids(sm, data, &eattr); 953 os_free(decrypted); 954 } 955 956 if (data->result_ind && attr->result_ind) 957 data->use_result_ind = 1; 958 959 if (data->state != FAILURE) { 960 eap_sim_state(data, data->use_result_ind ? 961 RESULT_SUCCESS : SUCCESS); 962 } 963 964 data->num_id_req = 0; 965 data->num_notification = 0; 966 /* RFC 4186 specifies that counter is initialized to one after 967 * fullauth, but initializing it to zero makes it easier to implement 968 * reauth verification. */ 969 data->counter = 0; 970 return eap_sim_response_challenge(data, id); 971 } 972 973 974 static int eap_sim_process_notification_reauth(struct eap_sim_data *data, 975 struct eap_sim_attrs *attr) 976 { 977 struct eap_sim_attrs eattr; 978 u8 *decrypted; 979 980 if (attr->encr_data == NULL || attr->iv == NULL) { 981 wpa_printf(MSG_WARNING, "EAP-SIM: Notification message after " 982 "reauth did not include encrypted data"); 983 return -1; 984 } 985 986 decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, 987 attr->encr_data_len, attr->iv, &eattr, 988 0); 989 if (decrypted == NULL) { 990 wpa_printf(MSG_WARNING, "EAP-SIM: Failed to parse encrypted " 991 "data from notification message"); 992 return -1; 993 } 994 995 if (eattr.counter < 0 || (size_t) eattr.counter != data->counter) { 996 wpa_printf(MSG_WARNING, "EAP-SIM: Counter in notification " 997 "message does not match with counter in reauth " 998 "message"); 999 os_free(decrypted); 1000 return -1; 1001 } 1002 1003 os_free(decrypted); 1004 return 0; 1005 } 1006 1007 1008 static int eap_sim_process_notification_auth(struct eap_sim_data *data, 1009 const struct wpabuf *reqData, 1010 struct eap_sim_attrs *attr) 1011 { 1012 if (attr->mac == NULL) { 1013 wpa_printf(MSG_INFO, "EAP-SIM: no AT_MAC in after_auth " 1014 "Notification message"); 1015 return -1; 1016 } 1017 1018 if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0)) 1019 { 1020 wpa_printf(MSG_WARNING, "EAP-SIM: Notification message " 1021 "used invalid AT_MAC"); 1022 return -1; 1023 } 1024 1025 if (data->reauth && 1026 eap_sim_process_notification_reauth(data, attr)) { 1027 wpa_printf(MSG_WARNING, "EAP-SIM: Invalid notification " 1028 "message after reauth"); 1029 return -1; 1030 } 1031 1032 return 0; 1033 } 1034 1035 1036 static struct wpabuf * eap_sim_process_notification( 1037 struct eap_sm *sm, struct eap_sim_data *data, u8 id, 1038 const struct wpabuf *reqData, struct eap_sim_attrs *attr) 1039 { 1040 wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Notification"); 1041 if (data->num_notification > 0) { 1042 wpa_printf(MSG_INFO, "EAP-SIM: too many notification " 1043 "rounds (only one allowed)"); 1044 return eap_sim_client_error(data, id, 1045 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 1046 } 1047 data->num_notification++; 1048 if (attr->notification == -1) { 1049 wpa_printf(MSG_INFO, "EAP-SIM: no AT_NOTIFICATION in " 1050 "Notification message"); 1051 return eap_sim_client_error(data, id, 1052 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 1053 } 1054 1055 if ((attr->notification & 0x4000) == 0 && 1056 eap_sim_process_notification_auth(data, reqData, attr)) { 1057 return eap_sim_client_error(data, id, 1058 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 1059 } 1060 1061 eap_sim_report_notification(sm->msg_ctx, attr->notification, 0); 1062 if (attr->notification >= 0 && attr->notification < 32768) { 1063 data->error_code = attr->notification; 1064 eap_sim_state(data, FAILURE); 1065 } else if (attr->notification == EAP_SIM_SUCCESS && 1066 data->state == RESULT_SUCCESS) 1067 eap_sim_state(data, SUCCESS); 1068 return eap_sim_response_notification(data, id, attr->notification); 1069 } 1070 1071 1072 static struct wpabuf * eap_sim_process_reauthentication( 1073 struct eap_sm *sm, struct eap_sim_data *data, u8 id, 1074 const struct wpabuf *reqData, struct eap_sim_attrs *attr) 1075 { 1076 struct eap_sim_attrs eattr; 1077 u8 *decrypted; 1078 1079 wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Reauthentication"); 1080 1081 if (data->reauth_id == NULL) { 1082 wpa_printf(MSG_WARNING, "EAP-SIM: Server is trying " 1083 "reauthentication, but no reauth_id available"); 1084 return eap_sim_client_error(data, id, 1085 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 1086 } 1087 1088 data->reauth = 1; 1089 if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0)) 1090 { 1091 wpa_printf(MSG_WARNING, "EAP-SIM: Reauthentication " 1092 "did not have valid AT_MAC"); 1093 #ifdef TEST_FUZZ 1094 wpa_printf(MSG_INFO, 1095 "TEST: Ignore AT_MAC mismatch for fuzz testing"); 1096 #else /* TEST_FUZZ */ 1097 return eap_sim_client_error(data, id, 1098 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 1099 #endif /* TEST_FUZZ */ 1100 } 1101 1102 /* At this stage the received MAC has been verified. Use this MAC for 1103 * reauth Session-Id calculation if all other checks pass. 1104 * The peer does not use the local MAC but the received MAC in deriving 1105 * Session-Id. */ 1106 #ifdef TEST_FUZZ 1107 if (attr->mac) 1108 os_memcpy(data->reauth_mac, attr->mac, EAP_SIM_MAC_LEN); 1109 else 1110 os_memset(data->reauth_mac, 0x12, EAP_SIM_MAC_LEN); 1111 #else /* TEST_FUZZ */ 1112 os_memcpy(data->reauth_mac, attr->mac, EAP_SIM_MAC_LEN); 1113 #endif /* TEST_FUZZ */ 1114 wpa_hexdump(MSG_DEBUG, "EAP-SIM: Server MAC", 1115 data->reauth_mac, EAP_SIM_MAC_LEN); 1116 1117 if (attr->encr_data == NULL || attr->iv == NULL) { 1118 wpa_printf(MSG_WARNING, "EAP-SIM: Reauthentication " 1119 "message did not include encrypted data"); 1120 return eap_sim_client_error(data, id, 1121 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 1122 } 1123 1124 decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, 1125 attr->encr_data_len, attr->iv, &eattr, 1126 0); 1127 if (decrypted == NULL) { 1128 wpa_printf(MSG_WARNING, "EAP-SIM: Failed to parse encrypted " 1129 "data from reauthentication message"); 1130 return eap_sim_client_error(data, id, 1131 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 1132 } 1133 1134 if (eattr.nonce_s == NULL || eattr.counter < 0) { 1135 wpa_printf(MSG_INFO, "EAP-SIM: (encr) No%s%s in reauth packet", 1136 !eattr.nonce_s ? " AT_NONCE_S" : "", 1137 eattr.counter < 0 ? " AT_COUNTER" : ""); 1138 os_free(decrypted); 1139 return eap_sim_client_error(data, id, 1140 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 1141 } 1142 1143 if (eattr.counter < 0 || (size_t) eattr.counter <= data->counter) { 1144 struct wpabuf *res; 1145 wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid counter " 1146 "(%d <= %d)", eattr.counter, data->counter); 1147 data->counter_too_small = eattr.counter; 1148 1149 /* Reply using Re-auth w/ AT_COUNTER_TOO_SMALL. The current 1150 * reauth_id must not be used to start a new reauthentication. 1151 */ 1152 eap_sim_clear_identities(sm, data, CLEAR_REAUTH_ID); 1153 1154 res = eap_sim_response_reauth(data, id, 1, eattr.nonce_s); 1155 os_free(decrypted); 1156 1157 return res; 1158 } 1159 data->counter = eattr.counter; 1160 1161 os_memcpy(data->nonce_s, eattr.nonce_s, EAP_SIM_NONCE_S_LEN); 1162 wpa_hexdump(MSG_DEBUG, "EAP-SIM: (encr) AT_NONCE_S", 1163 data->nonce_s, EAP_SIM_NONCE_S_LEN); 1164 1165 eap_sim_derive_keys_reauth(data->counter, 1166 data->reauth_id, data->reauth_id_len, 1167 data->nonce_s, data->mk, data->msk, 1168 data->emsk); 1169 eap_sim_clear_identities(sm, data, CLEAR_REAUTH_ID); 1170 eap_sim_learn_ids(sm, data, &eattr); 1171 1172 if (data->result_ind && attr->result_ind) 1173 data->use_result_ind = 1; 1174 1175 if (data->state != FAILURE) { 1176 eap_sim_state(data, data->use_result_ind ? 1177 RESULT_SUCCESS : SUCCESS); 1178 } 1179 1180 data->num_id_req = 0; 1181 data->num_notification = 0; 1182 if (data->counter > EAP_SIM_MAX_FAST_REAUTHS) { 1183 wpa_printf(MSG_DEBUG, "EAP-SIM: Maximum number of " 1184 "fast reauths performed - force fullauth"); 1185 eap_sim_clear_identities(sm, data, CLEAR_REAUTH_ID); 1186 } 1187 os_free(decrypted); 1188 return eap_sim_response_reauth(data, id, 0, data->nonce_s); 1189 } 1190 1191 1192 static struct wpabuf * eap_sim_process(struct eap_sm *sm, void *priv, 1193 struct eap_method_ret *ret, 1194 const struct wpabuf *reqData) 1195 { 1196 struct eap_sim_data *data = priv; 1197 const struct eap_hdr *req; 1198 u8 subtype, id; 1199 struct wpabuf *res; 1200 const u8 *pos; 1201 struct eap_sim_attrs attr; 1202 size_t len; 1203 1204 wpa_hexdump_buf(MSG_DEBUG, "EAP-SIM: EAP data", reqData); 1205 if (eap_get_config_identity(sm, &len) == NULL) { 1206 wpa_printf(MSG_INFO, "EAP-SIM: Identity not configured"); 1207 eap_sm_request_identity(sm); 1208 ret->ignore = true; 1209 return NULL; 1210 } 1211 1212 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SIM, reqData, &len); 1213 if (pos == NULL || len < 3) { 1214 ret->ignore = true; 1215 return NULL; 1216 } 1217 req = wpabuf_head(reqData); 1218 id = req->identifier; 1219 len = be_to_host16(req->length); 1220 1221 ret->ignore = false; 1222 ret->methodState = METHOD_MAY_CONT; 1223 ret->decision = DECISION_FAIL; 1224 ret->allowNotifications = true; 1225 1226 subtype = *pos++; 1227 wpa_printf(MSG_DEBUG, "EAP-SIM: Subtype=%d", subtype); 1228 pos += 2; /* Reserved */ 1229 1230 if (eap_sim_parse_attr(pos, wpabuf_head_u8(reqData) + len, &attr, 0, 1231 0)) { 1232 res = eap_sim_client_error(data, id, 1233 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 1234 goto done; 1235 } 1236 1237 switch (subtype) { 1238 case EAP_SIM_SUBTYPE_START: 1239 res = eap_sim_process_start(sm, data, id, &attr); 1240 break; 1241 case EAP_SIM_SUBTYPE_CHALLENGE: 1242 res = eap_sim_process_challenge(sm, data, id, reqData, &attr); 1243 break; 1244 case EAP_SIM_SUBTYPE_NOTIFICATION: 1245 res = eap_sim_process_notification(sm, data, id, reqData, 1246 &attr); 1247 break; 1248 case EAP_SIM_SUBTYPE_REAUTHENTICATION: 1249 res = eap_sim_process_reauthentication(sm, data, id, reqData, 1250 &attr); 1251 break; 1252 case EAP_SIM_SUBTYPE_CLIENT_ERROR: 1253 wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Client-Error"); 1254 res = eap_sim_client_error(data, id, 1255 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 1256 break; 1257 default: 1258 wpa_printf(MSG_DEBUG, "EAP-SIM: Unknown subtype=%d", subtype); 1259 res = eap_sim_client_error(data, id, 1260 EAP_SIM_UNABLE_TO_PROCESS_PACKET); 1261 break; 1262 } 1263 1264 done: 1265 if (data->state == FAILURE) { 1266 ret->decision = DECISION_FAIL; 1267 ret->methodState = METHOD_DONE; 1268 } else if (data->state == SUCCESS) { 1269 ret->decision = data->use_result_ind ? 1270 DECISION_UNCOND_SUCC : DECISION_COND_SUCC; 1271 ret->methodState = data->use_result_ind ? 1272 METHOD_DONE : METHOD_MAY_CONT; 1273 } else if (data->state == RESULT_SUCCESS) 1274 ret->methodState = METHOD_CONT; 1275 1276 if (ret->methodState == METHOD_DONE) { 1277 ret->allowNotifications = false; 1278 } 1279 1280 return res; 1281 } 1282 1283 1284 static bool eap_sim_has_reauth_data(struct eap_sm *sm, void *priv) 1285 { 1286 struct eap_sim_data *data = priv; 1287 return data->pseudonym || data->reauth_id; 1288 } 1289 1290 1291 static void eap_sim_deinit_for_reauth(struct eap_sm *sm, void *priv) 1292 { 1293 struct eap_sim_data *data = priv; 1294 1295 os_free(data->mk_identity); 1296 data->mk_identity = NULL; 1297 data->mk_identity_len = 0; 1298 data->use_result_ind = 0; 1299 eap_sim_clear_keys(data, 1); 1300 } 1301 1302 1303 static void * eap_sim_init_for_reauth(struct eap_sm *sm, void *priv) 1304 { 1305 struct eap_sim_data *data = priv; 1306 if (random_get_bytes(data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) { 1307 wpa_printf(MSG_WARNING, "EAP-SIM: Failed to get random data " 1308 "for NONCE_MT"); 1309 eap_sim_deinit(sm, data); 1310 return NULL; 1311 } 1312 1313 if (sm->identity) { 1314 /* Use the EAP-Response/Identity in MK derivation if AT_IDENTITY 1315 * is not used. */ 1316 os_free(data->mk_identity); 1317 data->mk_identity = os_memdup(sm->identity, sm->identity_len); 1318 data->mk_identity_len = sm->identity_len; 1319 } 1320 1321 data->num_id_req = 0; 1322 data->num_notification = 0; 1323 eap_sim_state(data, CONTINUE); 1324 return priv; 1325 } 1326 1327 1328 static const u8 * eap_sim_get_identity(struct eap_sm *sm, void *priv, 1329 size_t *len) 1330 { 1331 struct eap_sim_data *data = priv; 1332 1333 if (data->reauth_id) { 1334 *len = data->reauth_id_len; 1335 return data->reauth_id; 1336 } 1337 1338 if (data->pseudonym) { 1339 *len = data->pseudonym_len; 1340 return data->pseudonym; 1341 } 1342 1343 return NULL; 1344 } 1345 1346 1347 static bool eap_sim_isKeyAvailable(struct eap_sm *sm, void *priv) 1348 { 1349 struct eap_sim_data *data = priv; 1350 return data->state == SUCCESS; 1351 } 1352 1353 1354 static u8 * eap_sim_getKey(struct eap_sm *sm, void *priv, size_t *len) 1355 { 1356 struct eap_sim_data *data = priv; 1357 u8 *key; 1358 1359 if (data->state != SUCCESS) 1360 return NULL; 1361 1362 key = os_memdup(data->msk, EAP_SIM_KEYING_DATA_LEN); 1363 if (key == NULL) 1364 return NULL; 1365 1366 *len = EAP_SIM_KEYING_DATA_LEN; 1367 1368 return key; 1369 } 1370 1371 1372 static u8 * eap_sim_get_session_id(struct eap_sm *sm, void *priv, size_t *len) 1373 { 1374 struct eap_sim_data *data = priv; 1375 u8 *id; 1376 1377 if (data->state != SUCCESS) 1378 return NULL; 1379 1380 if (!data->reauth) 1381 *len = 1 + data->num_chal * GSM_RAND_LEN + EAP_SIM_NONCE_MT_LEN; 1382 else 1383 *len = 1 + EAP_SIM_NONCE_S_LEN + EAP_SIM_MAC_LEN; 1384 id = os_malloc(*len); 1385 if (id == NULL) 1386 return NULL; 1387 1388 id[0] = EAP_TYPE_SIM; 1389 if (!data->reauth) { 1390 os_memcpy(id + 1, data->rand, data->num_chal * GSM_RAND_LEN); 1391 os_memcpy(id + 1 + data->num_chal * GSM_RAND_LEN, 1392 data->nonce_mt, EAP_SIM_NONCE_MT_LEN); 1393 } else { 1394 os_memcpy(id + 1, data->nonce_s, EAP_SIM_NONCE_S_LEN); 1395 os_memcpy(id + 1 + EAP_SIM_NONCE_S_LEN, data->reauth_mac, 1396 EAP_SIM_MAC_LEN); 1397 } 1398 wpa_hexdump(MSG_DEBUG, "EAP-SIM: Derived Session-Id", id, *len); 1399 1400 return id; 1401 } 1402 1403 1404 static u8 * eap_sim_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 1405 { 1406 struct eap_sim_data *data = priv; 1407 u8 *key; 1408 1409 if (data->state != SUCCESS) 1410 return NULL; 1411 1412 key = os_memdup(data->emsk, EAP_EMSK_LEN); 1413 if (key == NULL) 1414 return NULL; 1415 1416 *len = EAP_EMSK_LEN; 1417 1418 return key; 1419 } 1420 1421 1422 static int eap_sim_get_error_code(void *priv) 1423 { 1424 struct eap_sim_data *data = priv; 1425 int current_data_error; 1426 1427 if (!data) 1428 return NO_EAP_METHOD_ERROR; 1429 1430 current_data_error = data->error_code; 1431 1432 /* Now reset for next transaction */ 1433 data->error_code = NO_EAP_METHOD_ERROR; 1434 1435 return current_data_error; 1436 } 1437 1438 1439 int eap_peer_sim_register(void) 1440 { 1441 struct eap_method *eap; 1442 1443 eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 1444 EAP_VENDOR_IETF, EAP_TYPE_SIM, "SIM"); 1445 if (eap == NULL) 1446 return -1; 1447 1448 eap->init = eap_sim_init; 1449 eap->deinit = eap_sim_deinit; 1450 eap->process = eap_sim_process; 1451 eap->isKeyAvailable = eap_sim_isKeyAvailable; 1452 eap->getKey = eap_sim_getKey; 1453 eap->getSessionId = eap_sim_get_session_id; 1454 eap->has_reauth_data = eap_sim_has_reauth_data; 1455 eap->deinit_for_reauth = eap_sim_deinit_for_reauth; 1456 eap->init_for_reauth = eap_sim_init_for_reauth; 1457 eap->get_identity = eap_sim_get_identity; 1458 eap->get_emsk = eap_sim_get_emsk; 1459 eap->get_error_code = eap_sim_get_error_code; 1460 1461 return eap_peer_method_register(eap); 1462 } 1463