/* * fakesim.c - part of Fake SIM application * * Copyright (C) 2003 BLADOX, s.r.o. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. */ #include <config.h> #include <turbo/turbo.h> #include <stdlib.h> #include <string.h> /* TODO do not reactivate active */ /* *INDENT-OFF* */ lc_char PROGMEM lc_Fake_sim[]={ LC_EN("Fake SIM") LC_END }; lc_char PROGMEM lc_Default[]={ LC_EN("Default") LC_END }; lc_char PROGMEM lc_Activate[]={ LC_EN("Activate") LC_END }; lc_char PROGMEM lc_Name[]={ LC_EN("Name:") LC_END }; lc_char PROGMEM lc_Ki[]={ LC_UN("Ki:") LC_END }; lc_char PROGMEM lc_IMSI[]={ LC_UN("IMSI:") LC_END }; /* *INDENT-ON* */ void A3A8 (u8 key[16], u8 rand[16], u8 simoutput[12]); u8 PROGMEM ef_imsi_path[] = { 0x3F, 0x00, 0x7F, 0x20, 0x6F, 0x07 }; typedef struct _Fake_sim { u8 imsi[9]; u8 ki[16]; } Fake_sim; typedef struct _sims_mem { SEdge *sims; Fake_sim *cur_sim; } sims_mem; SEdge *sims; Fake_sim *cur_sim; u8 *get_resp_gsm; u8 PROGMEM _ef_imsi[] = { 0x00, 0x00, 0x00, 0x09, 0x6F, 0x07, 0x04, 0x00, 0x14, 0x00, 0x14, 0x01, 0x01, 0x00, 0x00 }; void fake_sim_file (File_apdu_data * fa) { u8 i; dbsp ("FAKE_SIM_FILE\n"); dbsp ("EF "); dbih (fa->ef); dbc ('\n'); if (fa->ins == ME_CMD_SELECT) { u16 ef = (fa->data[0] << 8) | fa->data[1]; if (ef == 0x6F07) { dbsp ("FAKE_IMSI_SELECT\n"); fa->data[0] = 0x9F; fa->data[1] = 0x0F; } return; } if (fa->prev_ins == ME_CMD_SELECT && fa->ef == 0x6F07) { dbsp ("FAKE_IMSI\n"); if (fa->ins == ME_CMD_GET_RESPONSE) { memcpy (fa->data, _ef_imsi, sizeof (_ef_imsi)); fa->data[fa->p3] = 0x90; fa->data[fa->p3 + 1] = 0x00; } if (fa->ins == ME_CMD_READ_BINARY) { memcpy (fa->data, &cur_sim->imsi, 9); fa->data[fa->p3] = 0x90; fa->data[fa->p3 + 1] = 0x00; } } if (fa->prev_ins == ME_CMD_RUN_GSM_ALGORITHM && fa->ins == ME_CMD_GET_RESPONSE) { dbsp ("FAKE_GSM_GET_RESP\n"); memcpy (fa->data, get_resp_gsm, 0x0c); fa->data[0x0c] = 0x90; fa->data[0x0d] = 0x00; free (get_resp_gsm); get_resp_gsm = NULL; } } void run_gsm (File_apdu_data * fa) { u8 key[16]; u8 i; u8 s[16]; dbsp (">fake_sim_run_gsm\n"); memcpy (s, fa->data, 16); get_resp_gsm = malloc (12); for (i = 0; i < 16; i++) key[i] = rb (&cur_sim->ki[i]); #ifdef DEBUG dbsp ("KEY :"); for (i = 0; i < 16; i++) { dbch (key[i]); dbc (' '); } dbc ('\n'); #endif A3A8 (key, s, get_resp_gsm); #ifdef DEBUG dbsp ("RES :"); for (i = 0; i < 16; i++) { dbch (get_resp_gsm[i]); dbc (' '); } dbc ('\n'); #endif //buf for get_resp fa->data[0] = 0x9f; fa->data[1] = 0x0c; dbsp ("<fake_sim_run_gsm\n"); } b16 hextoint (char x) { if (x >= 'a' && x <= 'f') return x - 'a' + 10; else if (x >= 'A' && x <= 'F') return x - 'A' + 10; else if (x >= '0' && x <= '9') return x - '0'; return -1; } SNodeP fake_sim_n; SNodeP fake_sim_n_3; SNodeP fake_sim_n_4; SNodeP fake_sim_n_5; SNodeP fake_sim_n_6; u8 fake_sim_ctx (SCtx * ctx, u8 action) { if (action == APP_ENTER) { dbsp (">fake_sim_ctx\n"); spider_append_r (ctx, &fake_sim_n_5); spider_append_r (ctx, &fake_sim_n_3); dbsp ("<fake_sim_ctx\n"); } else if (action == APP_LEAVE) { spider_clear_r (ctx); } } u8 *insert_sim (u8 * name, u8 imsi[9], u8 ki[16]) { Fake_sim *s; SNode *n; SEdge *e; u8 *t; u8 l = strlen (name) + 1; sims_mem *p; dbsp (">insert_sim\n"); s = emalloc (sizeof (Fake_sim)); if (s == NULL) return NULL; n = emalloc (sizeof (SNode)); if (n == NULL) goto X1; e = emalloc (sizeof (SEdge)); if (e == NULL) goto X2; t = emalloc (l); if (t == NULL) goto X3; memcpy (&s->imsi, imsi, 9); memcpy (&s->ki, ki, 16); memcpy (t, name, l); ww (&n->text, t); ww (&n->cb, fake_sim_ctx); ww (&n->p, s); ww (&e->f, &fake_sim_n); ww (&e->t, n); wb (&e->source, MEM_F_P | MEM_T_E); ww (&e->next, sims); sims = e; p = app_data (); ww (&p->sims, sims); dbsp ("<insert_sim\n"); return s; X3: dbsp ("<insert_sim_3\n"); efree (e); X2: dbsp ("<insert_sim_2\n"); efree (n); X1: dbsp ("<insert_sim_1\n"); efree (s); return NULL; } u8 fake_sim_new (SCtx * ctx, u8 action) { if (action == APP_ENTER) { u8 i, j, k; u8 name[16]; u8 imsi[9]; u8 ki[16]; u8 *res; b16 x; // name res = get_input (locale (lc_Name), 1, 15, NULL, Q_GET_INPUT_ALPHABET); if (res == ENULL) return APP_END; if (res == NULL) return APP_BACK; j = res[0] - 1; res++; //len res++; //dcs memcpy (name, res, j); name[j] = '\0'; // IMSI X3: res = get_input (locale (lc_IMSI), 18, 18, NULL, Q_GET_INPUT_ALPHABET); if (res == ENULL) return APP_END; if (res == NULL) return APP_BACK; j = res[0] - 1; res++; //len res++; //dcs for (i = 0; i < 9; i++) { x = hextoint (res[2 * i]); if (x == -1) { perror (ERR_BAD_INPUT); goto X3; } j = x << 4; x = hextoint (res[2 * i + 1]); if (x == -1) { perror (ERR_BAD_INPUT); goto X3; } k = x; imsi[i] = j | k; } // Ki X4: res = get_input (locale (lc_Ki), 32, 32, NULL, Q_GET_INPUT_ALPHABET); if (res == ENULL) return APP_END; if (res == NULL) return APP_BACK; j = res[0] - 1; res++; //len res++; //dcs for (i = 0; i < 16; i++) { x = hextoint (res[2 * i]); if (x == -1) { perror (ERR_BAD_INPUT); goto X3; } j = x << 4; x = hextoint (res[2 * i + 1]); if (x == -1) { perror (ERR_BAD_INPUT); goto X3; } k = x; ki[i] = j | k; } // SMSC... res = insert_sim (name, imsi, ki); if (res == NULL) perror (ERR_NO_EEPROM); else ctx->eE = sims; return APP_BACK; } } u8 fake_sim_activate_default (SCtx * ctx, u8 action) { if (action == APP_ENTER) { unreg_file (ef_imsi_path, 3); unreg_action (ACTION_RUN_GSM_ALGORITHM); cur_sim = 0; ww (&((sims_mem *) app_data ())->cur_sim, cur_sim); change_imsi (); return APP_BACK; } } u8 fake_sim_delete (SCtx * ctx, u8 action) { } u8 fake_sim_activate (SCtx * ctx, u8 action) { if (action == APP_ENTER) { if (cur_sim == 0) { reg_file (ef_imsi_path, 3); reg_action (ACTION_RUN_GSM_ALGORITHM); } cur_sim = rw (&ctx->parent->f->p); ww (&((sims_mem *) app_data ())->cur_sim, cur_sim); change_imsi (); return APP_BACK; } } u8 fake_sim_view (SCtx * ctx, u8 action) { if (action == APP_ENTER) { u8 *s = buf_B (); u8 *r = s; u8 i; u8 l; Fake_sim *sim; sim = rw (&ctx->parent->f->p); r = sprints (r, locale (lc_IMSI)); r = sprintc (r, '\n'); for (i = 0; i < 9; i++) { r = sprintch (r, rb (&sim->imsi[i])); } r = sprintc (r, '\n'); r = sprints (r, locale (lc_Ki)); r = sprintc (r, '\n'); for (i = 0; i < 16; i++) { r = sprintch (r, rb (&sim->ki[i])); } r = sprintc (r, '\0'); if (display_text (s, NULL) == APP_END) return APP_END; return APP_BACK; } } u8 fake_sim_edit (SCtx * ctx, u8 action) { } SNodeP fake_sim_n = { lc_Fake_sim, NULL }; SNodeP fake_sim_n_1 = { LC_NEW, fake_sim_new }; SNodeP fake_sim_n_2 = { lc_Default, NULL }; SNodeP fake_sim_n_3 = { lc_Activate, fake_sim_activate }; SNodeP fake_sim_n_4 = { LC_DELETE, not_implemented /*fake_sim_delete */ }; SNodeP fake_sim_n_5 = { LC_VIEW, fake_sim_view }; SNodeP fake_sim_n_6 = { LC_EDIT, not_implemented /*fake_sim_edit */ }; SNodeP fake_sim_n_7 = { lc_Activate, fake_sim_activate_default }; SEdgeP fake_sim_edges_p[]={ {&fake_sim_n,&fake_sim_n_1}, // Fake_sim->New {&fake_sim_n,&fake_sim_n_2}, // Fake_sim->Default {&fake_sim_n_2,&fake_sim_n_7}, // Default->Activate NULL }; void fake_sim (void *x) { SCtx *c = spider_init (); if (c == NULL) return; c->n = &fake_sim_n; c->eP = &fake_sim_edges_p; c->eE = sims; spider (c); } void turbo_handler (u8 action, void *data) { switch (action) { case ACTION_APP_REGISTER: { sims_mem *p = emalloc (sizeof (sims_mem)); sims = 0; ww (&p->sims, 0); ww (&p->cur_sim, 0); reg_app_data (p); } break; case ACTION_APP_UNREGISTER: { SEdge *e = sims; SNode *n; while (e != NULL) { n = rw (&e->t); efree (rw (&n->p)); efree (rw (&n->text)); efree (n); sims = e; e = rw (&sims->next); efree (sims); } } break; case ACTION_APP_INIT: { sims_mem *p = app_data (); sims = rw (&p->sims); cur_sim = rw (&p->cur_sim); if (cur_sim) { reg_file (ef_imsi_path, 3); reg_action (ACTION_RUN_GSM_ALGORITHM); } } break; case ACTION_INSERT_MENU: insert_menu (locale (lc_Fake_sim)); break; case ACTION_MENU_SELECTION: stk_thread (fake_sim, NULL); break; case ACTION_RUN_GSM_ALGORITHM: run_gsm (data); break; case ACTION_FILE_APDU: fake_sim_file (data); break; default: break; } }
Copyright © 2004-2006 BLADOX | Turbo version 1.2
|