static int scard_test(void) { struct scard_data *scard; size_t len; char imsi[20]; unsigned char rand[16]; unsigned char sres[4]; unsigned char kc[8]; const int num_triplets = 5; unsigned char rand_[num_triplets][16]; unsigned char sres_[num_triplets][4]; unsigned char kc_[num_triplets][8]; int i, j; scard = scard_init(SCARD_TRY_BOTH, "1234"); if (scard == NULL) return -1; len = sizeof(imsi); if (scard_get_imsi(scard, imsi, &len)) goto failed; wpa_hexdump_ascii(MSG_DEBUG, "SCARD: IMSI", imsi, len); /* NOTE: Permanent Username: 1 | IMSI */ memset(rand, 0, sizeof(rand)); if (scard_gsm_auth(scard, rand, sres, kc)) goto failed; memset(rand, 0xff, sizeof(rand)); if (scard_gsm_auth(scard, rand, sres, kc)) goto failed; for (i = 0; i < num_triplets; i++) { memset(rand_[i], i, sizeof(rand_[i])); if (scard_gsm_auth(scard, rand_[i], sres_[i], kc_[i])) goto failed; } for (i = 0; i < num_triplets; i++) { printf("1"); for (j = 0; j < len; j++) printf("%c", imsi[j]); printf(","); for (j = 0; j < 16; j++) printf("%02X", rand_[i][j]); printf(","); for (j = 0; j < 4; j++) printf("%02X", sres_[i][j]); printf(","); for (j = 0; j < 8; j++) printf("%02X", kc_[i][j]); printf("\n"); } failed: scard_deinit(scard); return 0; }
static int scard_get_triplets(int argc, char *argv[]) { struct scard_data *scard; size_t len; char imsi[20]; unsigned char rand[16]; unsigned char sres[4]; unsigned char kc[8]; int num_triplets; int i, j; if (argc < 2 || ((num_triplets = atoi(argv[1])) <= 0)) { printf("invalid parameters for sim command\n"); return -1; } if (argc <= 2 || strcmp(argv[2], "debug") != 0) { /* disable debug output */ wpa_debug_level = 99; } scard = scard_init(SCARD_GSM_SIM_ONLY, argv[0]); if (scard == NULL) { printf("Failed to open smartcard connection\n"); return -1; } len = sizeof(imsi); if (scard_get_imsi(scard, imsi, &len)) { scard_deinit(scard); return -1; } for (i = 0; i < num_triplets; i++) { memset(rand, i, sizeof(rand)); if (scard_gsm_auth(scard, rand, sres, kc)) break; /* IMSI:Kc:SRES:RAND */ for (j = 0; j < len; j++) printf("%c", imsi[j]); printf(":"); for (j = 0; j < 8; j++) printf("%02X", kc[j]); printf(":"); for (j = 0; j < 4; j++) printf("%02X", sres[j]); printf(":"); for (j = 0; j < 16; j++) printf("%02X", rand[j]); printf("\n"); } scard_deinit(scard); return 0; }
static void wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { char buf[100]; size_t len; if (ssid->pcsc == NULL) return; if (wpa_s->scard != NULL) { wpa_supplicant_imsi_identity(wpa_s, ssid); return; } wpa_printf(MSG_DEBUG, "Selected network is configured to use SIM - " "initialize PCSC"); wpa_s->scard = scard_init(SCARD_TRY_BOTH, ssid->pin); if (wpa_s->scard == NULL) { wpa_printf(MSG_WARNING, "Failed to initialize SIM " "(pcsc-lite)"); /* TODO: what to do here? */ return; } eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard); len = sizeof(buf); if (scard_get_imsi(wpa_s->scard, buf, &len)) { wpa_printf(MSG_WARNING, "Failed to get IMSI from SIM"); /* TODO: what to do here? */ return; } wpa_hexdump(MSG_DEBUG, "IMSI", buf, len); free(wpa_s->imsi); wpa_s->imsi = malloc(len); if (wpa_s->imsi) { wpa_s->imsi = buf; wpa_s->imsi_len = len; wpa_supplicant_imsi_identity(wpa_s, ssid); } }
static int eap_sm_imsi_identity(struct eap_sm *sm, struct wpa_ssid *ssid) { int aka = 0; char imsi[100]; size_t imsi_len; u8 *pos = ssid->eap_methods; imsi_len = sizeof(imsi); if (scard_get_imsi(sm->scard_ctx, imsi, &imsi_len)) { wpa_printf(MSG_WARNING, "Failed to get IMSI from SIM"); return -1; } wpa_hexdump_ascii(MSG_DEBUG, "IMSI", (u8 *) imsi, imsi_len); while (pos && *pos != EAP_TYPE_NONE) { if (*pos == EAP_TYPE_AKA) { aka = 1; break; } pos++; } free(ssid->identity); ssid->identity = malloc(1 + imsi_len); if (ssid->identity == NULL) { wpa_printf(MSG_WARNING, "Failed to allocate buffer for " "IMSI-based identity"); return -1; } ssid->identity[0] = aka ? '0' : '1'; memcpy(ssid->identity + 1, imsi, imsi_len); ssid->identity_len = 1 + imsi_len; return 0; }
static int scard_test(void) { struct scard_data *scard; size_t len; char imsi[20]; unsigned char _rand[16]; #ifdef PCSC_FUNCS unsigned char sres[4]; unsigned char kc[8]; #endif /* PCSC_FUNCS */ #define num_triplets 5 unsigned char rand_[num_triplets][16]; unsigned char sres_[num_triplets][4]; unsigned char kc_[num_triplets][8]; int i, res; size_t j; #define AKA_RAND_LEN 16 #define AKA_AUTN_LEN 16 #define AKA_AUTS_LEN 14 #define RES_MAX_LEN 16 #define IK_LEN 16 #define CK_LEN 16 unsigned char aka_rand[AKA_RAND_LEN]; unsigned char aka_autn[AKA_AUTN_LEN]; unsigned char aka_auts[AKA_AUTS_LEN]; unsigned char aka_res[RES_MAX_LEN]; size_t aka_res_len; unsigned char aka_ik[IK_LEN]; unsigned char aka_ck[CK_LEN]; scard = scard_init(SCARD_TRY_BOTH); if (scard == NULL) return -1; if (scard_set_pin(scard, "1234")) { wpa_printf(MSG_WARNING, "PIN validation failed"); scard_deinit(scard); return -1; } len = sizeof(imsi); if (scard_get_imsi(scard, imsi, &len)) goto failed; wpa_hexdump_ascii(MSG_DEBUG, "SCARD: IMSI", (u8 *) imsi, len); /* NOTE: Permanent Username: 1 | IMSI */ os_memset(_rand, 0, sizeof(_rand)); if (scard_gsm_auth(scard, _rand, sres, kc)) goto failed; os_memset(_rand, 0xff, sizeof(_rand)); if (scard_gsm_auth(scard, _rand, sres, kc)) goto failed; for (i = 0; i < num_triplets; i++) { os_memset(rand_[i], i, sizeof(rand_[i])); if (scard_gsm_auth(scard, rand_[i], sres_[i], kc_[i])) goto failed; } for (i = 0; i < num_triplets; i++) { printf("1"); for (j = 0; j < len; j++) printf("%c", imsi[j]); printf(","); for (j = 0; j < 16; j++) printf("%02X", rand_[i][j]); printf(","); for (j = 0; j < 4; j++) printf("%02X", sres_[i][j]); printf(","); for (j = 0; j < 8; j++) printf("%02X", kc_[i][j]); printf("\n"); } wpa_printf(MSG_DEBUG, "Trying to use UMTS authentication"); /* seq 39 (0x28) */ os_memset(aka_rand, 0xaa, 16); os_memcpy(aka_autn, "\x86\x71\x31\xcb\xa2\xfc\x61\xdf" "\xa3\xb3\x97\x9d\x07\x32\xa2\x12", 16); res = scard_umts_auth(scard, aka_rand, aka_autn, aka_res, &aka_res_len, aka_ik, aka_ck, aka_auts); if (res == 0) { wpa_printf(MSG_DEBUG, "UMTS auth completed successfully"); wpa_hexdump(MSG_DEBUG, "RES", aka_res, aka_res_len); wpa_hexdump(MSG_DEBUG, "IK", aka_ik, IK_LEN); wpa_hexdump(MSG_DEBUG, "CK", aka_ck, CK_LEN); } else if (res == -2) { wpa_printf(MSG_DEBUG, "UMTS auth resulted in synchronization " "failure"); wpa_hexdump(MSG_DEBUG, "AUTS", aka_auts, AKA_AUTS_LEN); } else { wpa_printf(MSG_DEBUG, "UMTS auth failed"); } failed: scard_deinit(scard); return 0; #undef num_triplets }
static int scard_get_triplets(struct eapol_test_data *e, int argc, char *argv[]) { struct scard_data *scard; size_t len; char imsi[20]; unsigned char _rand[16]; unsigned char sres[4]; unsigned char kc[8]; int num_triplets; int i; size_t j; if (argc < 2 || ((num_triplets = atoi(argv[1])) <= 0)) { printf("invalid parameters for sim command\n"); return -1; } if (argc <= 2 || os_strcmp(argv[2], "debug") != 0) { /* disable debug output */ wpa_debug_level = 99; } scard = scard_init(e->pcsc_reader); if (scard == NULL) { printf("Failed to open smartcard connection\n"); return -1; } if (scard_set_pin(scard, argv[0])) { wpa_printf(MSG_WARNING, "PIN validation failed"); scard_deinit(scard); return -1; } len = sizeof(imsi); if (scard_get_imsi(scard, imsi, &len)) { scard_deinit(scard); return -1; } for (i = 0; i < num_triplets; i++) { os_memset(_rand, i, sizeof(_rand)); if (scard_gsm_auth(scard, _rand, sres, kc)) break; /* IMSI:Kc:SRES:RAND */ for (j = 0; j < len; j++) printf("%c", imsi[j]); printf(":"); for (j = 0; j < 8; j++) printf("%02X", kc[j]); printf(":"); for (j = 0; j < 4; j++) printf("%02X", sres[j]); printf(":"); for (j = 0; j < 16; j++) printf("%02X", _rand[j]); printf("\n"); } scard_deinit(scard); return 0; }