C-Netz SIM: Improve and use PIN input to program card

Imrovements are less memeory usage.

Card data can be programmed by using PIN input.
This commit is contained in:
Andreas Eversberg
2024-08-15 21:56:49 +02:00
parent c67dcc8170
commit 9d8c9d8986
5 changed files with 178 additions and 89 deletions

View File

@@ -391,7 +391,7 @@ This way it is possible to even emulate service cards ("Wartungskarten"), to put
<p> <p>
If the PIN is disabled (default), the first card with first subscriber data is emulates. If the PIN is disabled (default), the first card with first subscriber data is emulates.
To select different card with dfferent subscriber data, change the PIN to 0001 .. 0008. To select different card with dfferent subscriber data, change the PIN to 0001 .. 0008.
Refer to the phone's manual on how to change the PIN. Refer to the phone's manual on how to enable, disable or change the PIN.
E.g. if you store the PIN 0000 or 0001, the first card with the first subscriber data is emulated. E.g. if you store the PIN 0000 or 0001, the first card with the first subscriber data is emulated.
E.g. if you store the PIN 0005, the fifth card with the fifth subscriber data is emulated. E.g. if you store the PIN 0005, the fifth card with the fifth subscriber data is emulated.
In all cases, there is no PIN required when you turn on the phone. In all cases, there is no PIN required when you turn on the phone.
@@ -413,7 +413,7 @@ In all cases, there is no PIN required when you turn on the phone.
<p> <p>
You may want to use a PIN to select the card whenever you turn on the phone. You may want to use a PIN to select the card whenever you turn on the phone.
Use the phone to enable a PIN that does not start with "000". Use the phone to enable a PIN that does not start with "000", "888", "999".
When you restart your phone, you may enter that PIN, to select the first card. When you restart your phone, you may enter that PIN, to select the first card.
Alternatively you may enter the PIN 0000 or 0001, to select the first card, no matter what the PIN was. Alternatively you may enter the PIN 0000 or 0001, to select the first card, no matter what the PIN was.
Or you may enter the PIN 0002 .. 0008, to select second to eighth card. Or you may enter the PIN 0002 .. 0008, to select second to eighth card.
@@ -422,13 +422,31 @@ Or you may enter the PIN 0002 .. 0008, to select second to eighth card.
<p> <p>
You may also alter each of the 8 different subscriber data store on the SIM. You may also alter each of the 8 different subscriber data store on the SIM.
In order to do that, you need to set a PIN, so the phone will ask for a PIN whenever it is turned on. In order to do that, you need to set a PIN, so the phone will ask for a PIN whenever it is turned on.
Choose any PIN you like, but not a PIN stat starts with 000. Choose any PIN you like, but not a PIN that startw with "000", "888", "999".
Turn on the phone and you will be asked for a PIN. Reset the phone and you will be asked for a PIN.
<br><br>
Altering subscriber data via phonebook funcion:<br>
Enter the PIN 9991 to alter the first subscriber data. Enter the PIN 9991 to alter the first subscriber data.
Enter the PIN 9992 .. 9998 to alter second to eighth subscriber data. Enter the PIN 9992 .. 9998 to alter second to eighth subscriber data.
The subscriber data is shown in the telephone directory and can be altered by changing the numbers in that directory. The subscriber data is shown in the telephone directory and can be altered by changing the numbers in that directory.
Also the SIM software version is shown on entry 06 of the telephone directory, but it cannot be changed. Also the SIM software version is shown on entry 06 of the telephone directory, but it cannot be changed.
The Bosch OF 7 does not like to store numbers less than 3 digits. Put zeroes in front, if you want to store a value less than 1000. The Bosch OF 7 does not like to store numbers less than 3 digits. Put zeroes in front, if you want to store a value less than 1000.
<br><br>
Altering subscriber data via PIN input:<br>
Enter the PIN 8881 to alter the first subscriber data.
Enter the PIN 8882 .. 8888 to alter second to eighth subscriber data.
After that the phone displays that the PIN was wrong and prompts for another PIN.
With this trick the PIN prompt is used to input the subscriber data.
Now enter all 5 values of subscriber data, value by value.
Whenever you entered one value, the phone display that the PIN was wrong and prompts for the next value.
If the value is less than 4 digits, add zeros in front of it to make it at least 4 digits long.
After all 5 values have been entered, the SIM starts emulating that subscriber data.
If one of the input values is out of range, the SIM card will emulate a fictitious number "3333333".
This is displayed on the phone. This means that the input was wrong. Check the values and start over again.
<br><br>
Example for PIN input:<br>
Miniporty monitor mode: 8881, 2222002, 0001, 0001, 0900, 1728
</p> </p>
<p> <p>

View File

@@ -49,10 +49,10 @@ static int baudrate = 9600;
static const char *eeprom_name = NULL; static const char *eeprom_name = NULL;
static const char *futln = NULL; static const char *futln = NULL;
static const char *sicherung = NULL; static int sicherung = -1;
static const char *karten = NULL; static int karten = -1;
static const char *sonder = NULL; static int sonder = -1;
static const char *wartung = NULL; static int wartung = -1;
static const char *pin = NULL; static const char *pin = NULL;
#define MAX_DIR_COUNT 64 #define MAX_DIR_COUNT 64
static int dir_count = 0; static int dir_count = 0;
@@ -89,13 +89,13 @@ static void print_help(const char *arg0)
printf(" -F --futln <phone number>\n"); printf(" -F --futln <phone number>\n");
printf(" Give 7 digits subscriber ID (default = '%s')\n", FUTLN_DEFAULT); printf(" Give 7 digits subscriber ID (default = '%s')\n", FUTLN_DEFAULT);
printf(" --sicherung <security code>\n"); printf(" --sicherung <security code>\n");
printf(" Card's security code for simple authentication (default = '%s')\n", SICHERUNG_DEFAULT); printf(" Card's security code for simple authentication (default = '%d')\n", SICHERUNG_DEFAULT);
printf(" --kartenkennung <card ID>\n"); printf(" --kartenkennung <card ID>\n");
printf(" Card's ID. Not relevant! (default = '%s')\n", KARTEN_DEFAULT); printf(" Card's ID. Not relevant! (default = '%d')\n", KARTEN_DEFAULT);
printf(" --sonder <special code>\n"); printf(" --sonder <special code>\n");
printf(" Special codes are used for service cards (default = '%s')\n", SONDER_DEFAULT); printf(" Special codes are used for service cards (default = '%d')\n", SONDER_DEFAULT);
printf(" --wartung <maitenance code>\n"); printf(" --wartung <maitenance code>\n");
printf(" May define features of service cards (default = '%s')\n", WARTUNG_DEFAULT); printf(" May define features of service cards (default = '%d')\n", WARTUNG_DEFAULT);
printf(" -P --pin <pin> | 0000\n"); printf(" -P --pin <pin> | 0000\n");
printf(" Give 4 .. 8 digits of pin. Use '0000' to disable. (default = '%s')\n", PIN_DEFAULT); printf(" Give 4 .. 8 digits of pin. Use '0000' to disable. (default = '%s')\n", PIN_DEFAULT);
printf(" This will also reset the PIN error counter and unlocks the card.\n"); printf(" This will also reset the PIN error counter and unlocks the card.\n");
@@ -165,16 +165,16 @@ static int handle_options(int short_option, int argi, char **argv)
futln = options_strdup(argv[argi]); futln = options_strdup(argv[argi]);
break; break;
case OPT_SICHERUNG: case OPT_SICHERUNG:
sicherung = options_strdup(argv[argi]); sicherung = atoi(argv[argi]);
break; break;
case OPT_KARTEN: case OPT_KARTEN:
karten = options_strdup(argv[argi]); karten = atoi(argv[argi]);
break; break;
case OPT_SONDER: case OPT_SONDER:
sonder = options_strdup(argv[argi]); sonder = atoi(argv[argi]);
break; break;
case OPT_WARTUNG: case OPT_WARTUNG:
wartung = options_strdup(argv[argi]); wartung = atoi(argv[argi]);
break; break;
case 'P': case 'P':
pin = options_strdup(argv[argi]); pin = options_strdup(argv[argi]);

View File

@@ -103,7 +103,7 @@ static void write_flags(sim_sim_t *sim)
} }
/* encode EBDT from strings */ /* encode EBDT from strings */
int encode_ebdt(uint8_t *data, const char *futln, const char *sicherung, const char *karten, const char *sonder, const char *wartung) int encode_ebdt(uint8_t *data, const char *futln, int32_t sicherung, int32_t karten, int32_t sonder, int32_t wartung)
{ {
uint32_t temp; uint32_t temp;
int i; int i;
@@ -144,46 +144,46 @@ int encode_ebdt(uint8_t *data, const char *futln, const char *sicherung, const c
} }
temp = my_strtoul(futln, NULL, 10); temp = my_strtoul(futln, NULL, 10);
if (i < 5 || temp > 65535) { if (i < 5 || temp > 65535) {
LOGP(DSIM7, LOGL_NOTICE, "Given FUTLN '%s' has invalid last digits. (Must be '00000' .. '65535')\n", futln); LOGP(DSIM7, LOGL_NOTICE, "Given FUTLN '%d' has invalid last digits. (Must be '00000' .. '65535')\n", temp);
return -EINVAL; return -EINVAL;
} }
data[1] = temp >> 8; data[1] = temp >> 8;
data[2] = temp; data[2] = temp;
} }
if (sicherung) { if (sicherung >= 0) {
temp = my_strtoul(sicherung, NULL, 10); temp = sicherung;
if (temp > 65535) { if (temp > 65535) {
LOGP(DSIM7, LOGL_NOTICE, "Given security code '%s' has invalid digits. (Must be '0' .. '65535')\n", sicherung); LOGP(DSIM7, LOGL_NOTICE, "Given security code '%d' has invalid digits. (Must be '0' .. '65535')\n", temp);
return -EINVAL; return -EINVAL;
} }
data[3] = temp >> 8; data[3] = temp >> 8;
data[4] = temp; data[4] = temp;
} }
if (karten) { if (karten >= 0) {
temp = my_strtoul(karten, NULL, 10); temp = karten;
if (temp > 7) { if (temp > 7) {
LOGP(DSIM7, LOGL_NOTICE, "Given card number '%s' has invalid digit. (Must be '0' .. '7')\n", karten); LOGP(DSIM7, LOGL_NOTICE, "Given card number '%d' has invalid digit. (Must be '0' .. '7')\n", temp);
return -EINVAL; return -EINVAL;
} }
data[5] = (data[5] & 0x1f) | ((karten[0] - '0') << 5); data[5] = (data[5] & 0x1f) | (temp << 5);
} }
if (sonder) { if (sonder >= 0) {
temp = my_strtoul(sonder, NULL, 10); temp = sonder;
if (temp > 8191) { if (temp > 8191) {
LOGP(DSIM7, LOGL_NOTICE, "Given spacial code '%s' has invalid digits. (Must be '0' .. '8191')\n", sonder); LOGP(DSIM7, LOGL_NOTICE, "Given spacial code '%d' has invalid digits. (Must be '0' .. '8191')\n", temp);
return -EINVAL; return -EINVAL;
} }
data[5] = (data[5] & 0xe0) | (temp >> 8); data[5] = (data[5] & 0xe0) | (temp >> 8);
data[6] = temp; data[6] = temp;
} }
if (wartung) { if (wartung >= 0) {
temp = my_strtoul(wartung, NULL, 10); temp = wartung;
if (temp > 65535) { if (temp > 65535) {
LOGP(DSIM7, LOGL_NOTICE, "Given maintenance code '%s' has invalid digits. (Must be '0' .. '65535')\n", wartung); LOGP(DSIM7, LOGL_NOTICE, "Given maintenance code '%d' has invalid digits. (Must be '0' .. '65535')\n", temp);
return -EINVAL; return -EINVAL;
} }
data[7] = temp >> 8; data[7] = temp >> 8;
@@ -358,27 +358,76 @@ static uint8_t get_aprc(sim_sim_t *sim)
/* validate PIN and change states */ /* validate PIN and change states */
static int validate_pin(sim_sim_t *sim, uint8_t *data, int length) static int validate_pin(sim_sim_t *sim, uint8_t *data, int length)
{ {
uint8_t valid = 0, program_mode = 0; uint8_t valid = 0;
int i; int i, rc;
if (!sim->pin_required) if (!sim->pin_required)
return 0; return 0;
/* in PIN programming mode retrieve data from pin input */
if (sim->sim_mode == SIM_MODE_PIN) {
if (sim->pin_program_index == 0) {
memcpy(sim->pin_program_futln, data, length);
sim->pin_program_futln[length] = '\0';
} else {
uint8_t value_str[9];
memcpy(value_str, data, length);
value_str[length] = '\0';
sim->pin_program_values[sim->pin_program_index - 1] = my_strtoul((char *)value_str, NULL, 10);
}
sim->pin_program_index++;
valid = 1;
uint8_t ebdt_data[9];
rc = encode_ebdt(ebdt_data,
sim->pin_program_futln,
(sim->pin_program_index > 1) ? sim->pin_program_values[0] : -1,
(sim->pin_program_index > 2) ? sim->pin_program_values[1] : -1,
(sim->pin_program_index > 3) ? sim->pin_program_values[2] : -1,
(sim->pin_program_index > 4) ? sim->pin_program_values[3] : -1);
if (rc < 0) {
LOGP(DSIM1, LOGL_INFO, "Invalid data has been entered, using special FUTLN to indicate error.\n");
sim->sim_mode = SIM_MODE_ERROR;
} else if (sim->pin_program_index == 5) {
LOGP(DSIM1, LOGL_INFO, "Entering card #%d via PIN input is complete valid.\n", sim->card + 1);
sim->sim_mode = SIM_MODE_NONE;
eeprom_write(EEPROM_FUTLN_H + sim->card, ebdt_data[0]);
eeprom_write(EEPROM_FUTLN_M + sim->card, ebdt_data[1]);
eeprom_write(EEPROM_FUTLN_L + sim->card, ebdt_data[2]);
eeprom_write(EEPROM_SICH_H + sim->card, ebdt_data[3]);
eeprom_write(EEPROM_SICH_L + sim->card, ebdt_data[4]);
eeprom_write(EEPROM_SONDER_H + sim->card, ebdt_data[5]);
eeprom_write(EEPROM_SONDER_L + sim->card, ebdt_data[6]);
eeprom_write(EEPROM_WARTUNG_H + sim->card, ebdt_data[7]);
eeprom_write(EEPROM_WARTUNG_L + sim->card, ebdt_data[8]);
}
}
/* no PIN mode */ /* no PIN mode */
if (length == 4 && data[0] == '0' && data[1] == '0' && data[2] == '0' && data[3] >= '0' && data[3] <= '0' + MAX_CARDS) { if (!valid && length == 4 && data[0] == '0' && data[1] == '0' && data[2] == '0' && data[3] >= '0' && data[3] <= '0' + MAX_CARDS) {
sim->sim_mode = SIM_MODE_NONE;
valid = 1; valid = 1;
if (data[3] > '0') if (data[3] > '0')
sim->card = data[3] - '1'; sim->card = data[3] - '1';
LOGP(DSIM1, LOGL_INFO, "System PIN '000%c' entered. Selecting card #%d.\n", data[3], sim->card + 1); LOGP(DSIM1, LOGL_INFO, "System PIN '000%c' entered. Selecting card #%d.\n", data[3], sim->card + 1);
} }
/* programming mode */ /* phonebook programming mode (use phonebook to program card) */
if (length == 4 && data[0] == '9' && data[1] == '9' && data[2] == '9' && data[3] >= '0' && data[3] <= '0' + MAX_CARDS) { if (!valid && length == 4 && data[0] == '9' && data[1] == '9' && data[2] == '9' && data[3] >= '0' && data[3] <= '0' + MAX_CARDS) {
program_mode = 1; sim->sim_mode = SIM_MODE_PHONEBOOK;
valid = 1; valid = 1;
if (data[3] > '0') if (data[3] > '0')
sim->card = data[3] - '1'; sim->card = data[3] - '1';
LOGP(DSIM1, LOGL_INFO, "Configuration PIN '999%c' entered. Selecting card #%d in configuration mode.\n", data[3], sim->card + 1); LOGP(DSIM1, LOGL_INFO, "Configuration PIN '999%c' entered. Selecting card #%d in phonebook programming mode.\n", data[3], sim->card + 1);
}
/* PIN programming mode (use pin entering to program card) */
if (!valid && length == 4 && data[0] == '8' && data[1] == '8' && data[2] == '8' && data[3] >= '0' && data[3] <= '0' + MAX_CARDS) {
sim->sim_mode = SIM_MODE_PIN;
sim->pin_program_index = 0;
valid = 1;
if (data[3] > '0')
sim->card = data[3] - '1';
LOGP(DSIM1, LOGL_INFO, "Configuration PIN '888%c' entered. Selecting card #%d in PIN programming mode.\n", data[3], sim->card + 1);
} }
/* if not 'program mode' and PIN matches EEPROM */ /* if not 'program mode' and PIN matches EEPROM */
@@ -399,10 +448,10 @@ static int validate_pin(sim_sim_t *sim, uint8_t *data, int length)
sim->pin_try = MAX_PIN_TRY; sim->pin_try = MAX_PIN_TRY;
write_flags(sim); write_flags(sim);
} }
sim->pin_required = 0; /* PIN is required in PIN programming mode */
if (program_mode) sim->pin_required = (sim->sim_mode == SIM_MODE_PIN) ? 1 : 0;
sim->program_mode = 1; /* Indicate 'invalid PIN' in PIN programming mode, so phone can provide next PIN */
return 0; return (sim->sim_mode == SIM_MODE_PIN) ? -EINVAL : 0;
} else { } else {
LOGP(DSIM1, LOGL_INFO, "Wrong PIN was entered.\n"); LOGP(DSIM1, LOGL_INFO, "Wrong PIN was entered.\n");
#ifndef ARDUINO #ifndef ARDUINO
@@ -561,8 +610,9 @@ static void rd_ebdt(sim_sim_t *sim)
/* respond */ /* respond */
data = alloc_msg(sim, 9); data = alloc_msg(sim, 9);
if (sim->program_mode) { switch (sim->sim_mode) {
/* SERVICE MODE */ case SIM_MODE_PHONEBOOK:
/* phonebook programming mode */
data[0] = 0; data[0] = 0;
data[1] = 0; data[1] = 0;
data[2] = sim->card + 1; data[2] = sim->card + 1;
@@ -572,7 +622,13 @@ static void rd_ebdt(sim_sim_t *sim)
data[6] = 0; data[6] = 0;
data[7] = 0x0ff; data[7] = 0x0ff;
data[8] = 0x0ff; data[8] = 0x0ff;
} else { break;
case SIM_MODE_ERROR:
/* display error mode */
encode_ebdt(data, "3333333", SICHERUNG_DEFAULT, KARTEN_DEFAULT, SONDER_DEFAULT, WARTUNG_DEFAULT);
break;
default:
/* emulation mode */
data[0] = eeprom_read(EEPROM_FUTLN_H + sim->card); data[0] = eeprom_read(EEPROM_FUTLN_H + sim->card);
data[1] = eeprom_read(EEPROM_FUTLN_M + sim->card); data[1] = eeprom_read(EEPROM_FUTLN_M + sim->card);
data[2] = eeprom_read(EEPROM_FUTLN_L + sim->card); data[2] = eeprom_read(EEPROM_FUTLN_L + sim->card);
@@ -600,14 +656,14 @@ static void rd_rufn(sim_sim_t *sim, uint8_t *data, int length)
LOGP(DSIM7, LOGL_INFO, " RD-RUFN (loc=%d)\n", rufn); LOGP(DSIM7, LOGL_INFO, " RD-RUFN (loc=%d)\n", rufn);
/* SERVICE MODE */ /* PROGRAMMING MODE */
if (sim->program_mode) { if (sim->sim_mode == SIM_MODE_PHONEBOOK) {
char number[16]; char number[16];
/* respond */ /* respond */
data = alloc_msg(sim, 24); data = alloc_msg(sim, 24);
switch (rufn) { switch (rufn) {
case 0: /* send bitmap for service mode */ case 0: /* send bitmap for programming mode */
memset(data, 0xff, 24); memset(data, 0xff, 24);
data[0] = 6; /* 6 entries */ data[0] = 6; /* 6 entries */
data[1] = 0x03; /* upper 6 bits = 0 */ data[1] = 0x03; /* upper 6 bits = 0 */
@@ -618,38 +674,38 @@ static void rd_rufn(sim_sim_t *sim, uint8_t *data, int length)
data[2] = eeprom_read(EEPROM_FUTLN_L + sim->card); data[2] = eeprom_read(EEPROM_FUTLN_L + sim->card);
decode_ebdt(data, number, NULL, NULL, NULL, NULL); decode_ebdt(data, number, NULL, NULL, NULL, NULL);
encode_directory(data, number, "FUTLN"); encode_directory(data, number, "FUTLN");
LOGP(DSIM7, LOGL_INFO, "service mode: FUTLN = %s\n", number); LOGP(DSIM7, LOGL_INFO, "programming mode: FUTLN = %s\n", number);
break; break;
case 2: /* security code */ case 2: /* security code */
data[3] = eeprom_read(EEPROM_SICH_H + sim->card); data[3] = eeprom_read(EEPROM_SICH_H + sim->card);
data[4] = eeprom_read(EEPROM_SICH_L + sim->card); data[4] = eeprom_read(EEPROM_SICH_L + sim->card);
decode_ebdt(data, NULL, number, NULL, NULL, NULL); decode_ebdt(data, NULL, number, NULL, NULL, NULL);
encode_directory(data, number, "Sicherungscode"); encode_directory(data, number, "Sicherungscode");
LOGP(DSIM7, LOGL_INFO, "service mode: security = %s\n", number); LOGP(DSIM7, LOGL_INFO, "programming mode: security = %s\n", number);
break; break;
case 3: /* card ID */ case 3: /* card ID */
data[5] = eeprom_read(EEPROM_SONDER_H + sim->card); data[5] = eeprom_read(EEPROM_SONDER_H + sim->card);
decode_ebdt(data, NULL, NULL, number, NULL, NULL); decode_ebdt(data, NULL, NULL, number, NULL, NULL);
encode_directory(data, number, "Kartenkennung"); encode_directory(data, number, "Kartenkennung");
LOGP(DSIM7, LOGL_INFO, "service mode: card = %s\n", number); LOGP(DSIM7, LOGL_INFO, "programming mode: card = %s\n", number);
break; break;
case 4: /* special key */ case 4: /* special key */
data[5] = eeprom_read(EEPROM_SONDER_H + sim->card); data[5] = eeprom_read(EEPROM_SONDER_H + sim->card);
data[6] = eeprom_read(EEPROM_SONDER_L + sim->card); data[6] = eeprom_read(EEPROM_SONDER_L + sim->card);
decode_ebdt(data, NULL, NULL, NULL, number, NULL); decode_ebdt(data, NULL, NULL, NULL, number, NULL);
encode_directory(data, number, "Sonderheitsschl."); encode_directory(data, number, "Sonderheitsschl.");
LOGP(DSIM7, LOGL_INFO, "service mode: special = %s\n", number); LOGP(DSIM7, LOGL_INFO, "programming mode: special = %s\n", number);
break; break;
case 5: /* maintenance key */ case 5: /* maintenance key */
data[7] = eeprom_read(EEPROM_WARTUNG_H + sim->card); data[7] = eeprom_read(EEPROM_WARTUNG_H + sim->card);
data[8] = eeprom_read(EEPROM_WARTUNG_L + sim->card); data[8] = eeprom_read(EEPROM_WARTUNG_L + sim->card);
decode_ebdt(data, NULL, NULL, NULL, NULL, number); decode_ebdt(data, NULL, NULL, NULL, NULL, number);
encode_directory(data, number, "Wartungsschl."); encode_directory(data, number, "Wartungsschl.");
LOGP(DSIM7, LOGL_INFO, "service mode: maintenance = %s\n", number); LOGP(DSIM7, LOGL_INFO, "programming mode: maintenance = %s\n", number);
break; break;
case 6: /* sim version */ case 6: /* sim version */
encode_directory(data, SIM_VERSION, SIM_VERSION_NAME); encode_directory(data, SIM_VERSION, SIM_VERSION_NAME);
LOGP(DSIM7, LOGL_INFO, "service mode: display SIM version = %s\n", SIM_VERSION); LOGP(DSIM7, LOGL_INFO, "programming mode: display SIM version = %s\n", SIM_VERSION);
break; break;
} }
tx_sdu(sim, 0, data, 24); tx_sdu(sim, 0, data, 24);
@@ -684,10 +740,11 @@ static void wt_rufn(sim_sim_t *sim, uint8_t *data, int length)
LOGP(DSIM7, LOGL_INFO, " WT-RUFN (loc=%d)\n", rufn); LOGP(DSIM7, LOGL_INFO, " WT-RUFN (loc=%d)\n", rufn);
/* SERVICE MODE */ /* PROGRAMMING MODE */
if (sim->program_mode) { if (sim->sim_mode == SIM_MODE_PHONEBOOK) {
int rc; int rc;
char number[17]; char number[17];
int value;
decode_directory(data + 1, number, NULL); decode_directory(data + 1, number, NULL);
/* if number is cleared (no digits), we ignore that */ /* if number is cleared (no digits), we ignore that */
@@ -695,8 +752,8 @@ static void wt_rufn(sim_sim_t *sim, uint8_t *data, int length)
goto respond; goto respond;
switch (rufn) { switch (rufn) {
case 1: /* FUTLN */ case 1: /* FUTLN */
LOGP(DSIM7, LOGL_INFO, "service mode: FUTLN = %s\n", number); LOGP(DSIM7, LOGL_INFO, "programming mode: FUTLN = %s\n", number);
rc = encode_ebdt(data, number, NULL, NULL, NULL, NULL); rc = encode_ebdt(data, number, -1, -1, -1, -1);
if (rc < 0) if (rc < 0)
break; break;
eeprom_write(EEPROM_FUTLN_H + sim->card, data[0]); eeprom_write(EEPROM_FUTLN_H + sim->card, data[0]);
@@ -704,33 +761,37 @@ static void wt_rufn(sim_sim_t *sim, uint8_t *data, int length)
eeprom_write(EEPROM_FUTLN_L + sim->card, data[2]); eeprom_write(EEPROM_FUTLN_L + sim->card, data[2]);
break; break;
case 2: /* security code */ case 2: /* security code */
LOGP(DSIM7, LOGL_INFO, "service mode: security = %s\n", number); LOGP(DSIM7, LOGL_INFO, "programming mode: security = %s\n", number);
rc = encode_ebdt(data, NULL, number, NULL, NULL, NULL); value = my_strtoul(number, NULL, 10);
rc = encode_ebdt(data, NULL, value, -1, -1, -1);
if (rc < 0) if (rc < 0)
break; break;
eeprom_write(EEPROM_SICH_H + sim->card, data[3]); eeprom_write(EEPROM_SICH_H + sim->card, data[3]);
eeprom_write(EEPROM_SICH_L + sim->card, data[4]); eeprom_write(EEPROM_SICH_L + sim->card, data[4]);
break; break;
case 3: /* card ID */ case 3: /* card ID */
LOGP(DSIM7, LOGL_INFO, "service mode: card = %s\n", number); LOGP(DSIM7, LOGL_INFO, "programming mode: card = %s\n", number);
data[5] = eeprom_read(EEPROM_SONDER_H + sim->card); data[5] = eeprom_read(EEPROM_SONDER_H + sim->card);
rc = encode_ebdt(data, NULL, NULL, number, NULL, NULL); value = my_strtoul(number, NULL, 10);
rc = encode_ebdt(data, NULL, -1, value, -1, -1);
if (rc < 0) if (rc < 0)
break; break;
eeprom_write(EEPROM_SONDER_H + sim->card, data[5]); eeprom_write(EEPROM_SONDER_H + sim->card, data[5]);
break; break;
case 4: /* special key */ case 4: /* special key */
LOGP(DSIM7, LOGL_INFO, "service mode: special = %s\n", number); LOGP(DSIM7, LOGL_INFO, "programming mode: special = %s\n", number);
data[5] = eeprom_read(EEPROM_SONDER_H + sim->card); data[5] = eeprom_read(EEPROM_SONDER_H + sim->card);
rc = encode_ebdt(data, NULL, NULL, NULL, number, NULL); value = my_strtoul(number, NULL, 10);
rc = encode_ebdt(data, NULL, -1, -1, value, -1);
if (rc < 0) if (rc < 0)
break; break;
eeprom_write(EEPROM_SONDER_H + sim->card, data[5]); eeprom_write(EEPROM_SONDER_H + sim->card, data[5]);
eeprom_write(EEPROM_SONDER_L + sim->card, data[6]); eeprom_write(EEPROM_SONDER_L + sim->card, data[6]);
break; break;
case 5: /* maintenance key */ case 5: /* maintenance key */
LOGP(DSIM7, LOGL_INFO, "service mode: maintenance = %s\n", number); LOGP(DSIM7, LOGL_INFO, "programming mode: maintenance = %s\n", number);
rc = encode_ebdt(data, NULL, NULL, NULL, NULL, number); value = my_strtoul(number, NULL, 10);
rc = encode_ebdt(data, NULL, -1, -1, -1, value);
if (rc < 0) if (rc < 0)
break; break;
eeprom_write(EEPROM_WARTUNG_H + sim->card, data[7]); eeprom_write(EEPROM_WARTUNG_H + sim->card, data[7]);

View File

@@ -1,13 +1,13 @@
#define SIM_VERSION_NAME "TelecardVersion" #define SIM_VERSION_NAME "TelecardVersion"
#define SIM_VERSION "3" #define SIM_VERSION "4"
#define JOLLY_NAME "Jolly" #define JOLLY_NAME "Jolly Zuhause"
#define JOLLY_PHONE "04644973171" #define JOLLY_PHONE "04644973171"
#define FUTLN_DEFAULT "2222001" #define FUTLN_DEFAULT "2222001"
#define SICHERUNG_DEFAULT "3103" #define SICHERUNG_DEFAULT 3103
#define KARTEN_DEFAULT "3" #define KARTEN_DEFAULT 3
#define SONDER_DEFAULT "0" #define SONDER_DEFAULT 0
#define WARTUNG_DEFAULT "65535" #define WARTUNG_DEFAULT 65535
#define PIN_DEFAULT "0000" #define PIN_DEFAULT "0000"
#define AUTH_DEFAULT ((uint64_t)0x000000000badefee) #define AUTH_DEFAULT ((uint64_t)0x000000000badefee)
@@ -28,6 +28,13 @@ enum block_state {
BLOCK_STATE_DATA, BLOCK_STATE_DATA,
}; };
enum sim_mode {
SIM_MODE_NONE = 0, /* SIM from EEPROM */
SIM_MODE_PHONEBOOK, /* SIM that contains the phonebook */
SIM_MODE_PIN, /* entering SIM via PIN */
SIM_MODE_ERROR, /* SIM via PIN failed */
};
#define MAX_PIN_TRY 3 #define MAX_PIN_TRY 3
#define MAX_CARDS 8 /* must also be defined at eeprom.h */ #define MAX_CARDS 8 /* must also be defined at eeprom.h */
@@ -53,25 +60,28 @@ typedef struct sim_sim {
int resync_sent; int resync_sent;
/* ICL layer states */ /* ICL layer states */
int icl_online; uint8_t icl_online;
int icl_master; uint8_t icl_master;
int icl_chaining; uint8_t icl_chaining;
int icl_error; uint8_t icl_error;
/* layer 7 states */ /* layer 7 states */
int addr_src; uint8_t addr_src;
int addr_dst; uint8_t addr_dst;
int sh_appl_count; /* counts applications for SH_APPL */ uint8_t sh_appl_count; /* counts applications for SH_APPL */
/* CNETZ states */ /* CNETZ states */
int pin_required; /* pin required an not yet validated */ uint8_t pin_required; /* pin required an not yet validated */
int program_mode; /* program mode active (special PIN entered) */ enum sim_mode sim_mode; /* sim mode active (programming mode) */
int pin_len; /* length of pin (4 .. 8) */ char pin_program_futln[9]; /* PIN program mode: FUTLN string with maximum of 8 characters */
int pin_try; /* number of tries left (0 == card locked) */ int32_t pin_program_values[4]; /* PIN program mode: other 4 values */
int app; /* currently selected APP number */ uint8_t pin_program_index; /* PIN program mode: strin to be entered */
int app_locked; /* application locked */ uint8_t pin_len; /* length of pin (4 .. 8) */
int gebz_locked; /* metering counter and phonebook locked */ uint8_t pin_try; /* number of tries left (0 == card locked) */
int gebz_full; /* metering counter full (does this really happen?) */ uint8_t app; /* currently selected APP number */
uint8_t app_locked; /* application locked */
uint8_t gebz_locked; /* metering counter and phonebook locked */
uint8_t gebz_full; /* metering counter full (does this really happen?) */
} sim_sim_t; } sim_sim_t;
/* layer 2 */ /* layer 2 */
@@ -142,7 +152,7 @@ enum l2_cmd {
/* defined for main.c */ /* defined for main.c */
size_t eeprom_length(void); size_t eeprom_length(void);
int encode_ebdt(uint8_t *data, const char *futln, const char *sicherung, const char *karten, const char *sonder, const char *wartung); int encode_ebdt(uint8_t *data, const char *futln, int32_t sicherung, int32_t karten, int32_t sonder, int32_t wartung);
void decode_ebdt(uint8_t *data, char *futln, char *sicherung, char *karten, char *sonder, char *wartung); void decode_ebdt(uint8_t *data, char *futln, char *sicherung, char *karten, char *sonder, char *wartung);
int directory_size(void); int directory_size(void);
int save_directory(int location, uint8_t *data); int save_directory(int location, uint8_t *data);

View File

@@ -1,4 +1,4 @@
/* SIM card for ATMEL /* C-Netz SIM card emulator for ATMEL
* *
* (C) 2020 by Andreas Eversberg <jolly@eversberg.eu> * (C) 2020 by Andreas Eversberg <jolly@eversberg.eu>
* All Rights Reserved * All Rights Reserved