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