mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-07-08 14:10:54 -07:00
fix 'hf iclass sim'
* add simulation of multiple pages (PAGESEL by @sherhannn9) * maintain cipher states per page * update cipher state after UPDATE commands (@sherhannn9) * add simulation of personalization mode * respond with SOF on HALT * display "<SOF>" instead of "0f" in 'hf list iclass' * standard LED handling
This commit is contained in:
parent
8ddb81a217
commit
ae60ceca92
2 changed files with 132 additions and 85 deletions
178
armsrc/iclass.c
178
armsrc/iclass.c
|
@ -758,15 +758,8 @@ void rotateCSN(uint8_t* originalCSN, uint8_t* rotatedCSN) {
|
||||||
|
|
||||||
// Encode SOF only
|
// Encode SOF only
|
||||||
static void CodeIClassTagSOF() {
|
static void CodeIClassTagSOF() {
|
||||||
//So far a dummy implementation, not used
|
|
||||||
//int lastProxToAirDuration =0;
|
|
||||||
|
|
||||||
ToSendReset();
|
ToSendReset();
|
||||||
// Send SOF
|
|
||||||
ToSend[++ToSendMax] = 0x1D;
|
ToSend[++ToSendMax] = 0x1D;
|
||||||
// lastProxToAirDuration = 8*ToSendMax - 3*8;//Not counting zeroes in the beginning
|
|
||||||
|
|
||||||
// Convert from last byte pos to length
|
|
||||||
ToSendMax++;
|
ToSendMax++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -783,16 +776,20 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
// free eventually allocated BigBuf memory
|
// free eventually allocated BigBuf memory
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
|
|
||||||
State cipher_state_KC;
|
uint16_t page_size = 32 * 8;
|
||||||
State cipher_state_KD;
|
uint8_t current_page = 0;
|
||||||
|
|
||||||
|
// maintain cipher states for both credit and debit key for each page
|
||||||
|
State cipher_state_KC[8];
|
||||||
|
State cipher_state_KD[8];
|
||||||
|
State *cipher_state = &cipher_state_KD[0];
|
||||||
|
|
||||||
uint8_t *emulator = BigBuf_get_EM_addr();
|
uint8_t *emulator = BigBuf_get_EM_addr();
|
||||||
uint8_t *csn = emulator;
|
uint8_t *csn = emulator;
|
||||||
uint8_t sof_data[] = { 0x0F } ;
|
|
||||||
|
|
||||||
// CSN followed by two CRC bytes
|
// CSN followed by two CRC bytes
|
||||||
uint8_t anticoll_data[10] = { 0 };
|
uint8_t anticoll_data[10];
|
||||||
uint8_t csn_data[10] = { 0 };
|
uint8_t csn_data[10];
|
||||||
memcpy(csn_data, csn, sizeof(csn_data));
|
memcpy(csn_data, csn, sizeof(csn_data));
|
||||||
Dbprintf("Simulating CSN %02x%02x%02x%02x%02x%02x%02x%02x", csn[0], csn[1], csn[2], csn[3], csn[4], csn[5], csn[6], csn[7]);
|
Dbprintf("Simulating CSN %02x%02x%02x%02x%02x%02x%02x%02x", csn[0], csn[1], csn[2], csn[3], csn[4], csn[5], csn[6], csn[7]);
|
||||||
|
|
||||||
|
@ -803,26 +800,56 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
AppendCrc(anticoll_data, 8);
|
AppendCrc(anticoll_data, 8);
|
||||||
AppendCrc(csn_data, 8);
|
AppendCrc(csn_data, 8);
|
||||||
|
|
||||||
uint8_t diversified_key_d[8] = { 0 };
|
uint8_t diversified_key_d[8];
|
||||||
uint8_t diversified_key_c[8] = { 0 };
|
uint8_t diversified_key_c[8];
|
||||||
|
uint8_t *diversified_key = diversified_key_d;
|
||||||
|
|
||||||
|
// configuration block
|
||||||
|
uint8_t conf_block[10] = {0x12, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0xFF, 0x3C, 0x00, 0x00};
|
||||||
|
AppendCrc(conf_block, 8);
|
||||||
|
|
||||||
// e-Purse
|
// e-Purse
|
||||||
uint8_t card_challenge_data[8] = { 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
uint8_t card_challenge_data[8] = { 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||||
//uint8_t card_challenge_data[8] = { 0 };
|
|
||||||
if (simulationMode == ICLASS_SIM_MODE_FULL) {
|
if (simulationMode == ICLASS_SIM_MODE_FULL) {
|
||||||
// Get the diversified keys from emulator memory
|
// initialize from page 0
|
||||||
memcpy(diversified_key_d, emulator + (8 * 3), 8);
|
memcpy(conf_block, emulator + 8 * 1, 8);
|
||||||
memcpy(diversified_key_c, emulator + (8 * 4), 8);
|
memcpy(card_challenge_data, emulator + 8 * 2, 8); // e-purse
|
||||||
// Card challenge, a.k.a e-purse is on block 2
|
memcpy(diversified_key_d, emulator + 8 * 3, 8); // Kd
|
||||||
memcpy(card_challenge_data, emulator + (8 * 2), 8);
|
memcpy(diversified_key_c, emulator + 8 * 4, 8); // Kc
|
||||||
// Precalculate the cipher states, feeding it the CC
|
|
||||||
cipher_state_KD = opt_doTagMAC_1(card_challenge_data, diversified_key_d);
|
|
||||||
cipher_state_KC = opt_doTagMAC_1(card_challenge_data, diversified_key_c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// save card challenge for sim2,4 attack
|
// save card challenge for sim2,4 attack
|
||||||
if (reader_mac_buf != NULL) {
|
if (reader_mac_buf != NULL) {
|
||||||
memcpy(reader_mac_buf, card_challenge_data, 8);
|
memcpy(reader_mac_buf, card_challenge_data, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (conf_block[5] & 0x80) {
|
||||||
|
page_size = 256 * 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// From PicoPass DS:
|
||||||
|
// When the page is in personalization mode this bit is equal to 1.
|
||||||
|
// Once the application issuer has personalized and coded its dedicated areas, this bit must be set to 0:
|
||||||
|
// the page is then "in application mode".
|
||||||
|
bool personalization_mode = conf_block[7] & 0x80;
|
||||||
|
|
||||||
|
// chip memory may be divided in 8 pages
|
||||||
|
uint8_t max_page = conf_block[4] & 0x10 ? 0 : 7;
|
||||||
|
|
||||||
|
// Precalculate the cipher states, feeding it the CC
|
||||||
|
cipher_state_KD[0] = opt_doTagMAC_1(card_challenge_data, diversified_key_d);
|
||||||
|
cipher_state_KC[0] = opt_doTagMAC_1(card_challenge_data, diversified_key_c);
|
||||||
|
if (simulationMode == ICLASS_SIM_MODE_FULL) {
|
||||||
|
for (int i = 1; i < max_page; i++) {
|
||||||
|
uint8_t *epurse = emulator + i*page_size + 8*2;
|
||||||
|
uint8_t *Kd = emulator + i*page_size + 8*3;
|
||||||
|
uint8_t *Kc = emulator + i*page_size + 8*4;
|
||||||
|
cipher_state_KD[i] = opt_doTagMAC_1(epurse, Kd);
|
||||||
|
cipher_state_KC[i] = opt_doTagMAC_1(epurse, Kc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int exitLoop = 0;
|
int exitLoop = 0;
|
||||||
// Reader 0a
|
// Reader 0a
|
||||||
// Tag 0f
|
// Tag 0f
|
||||||
|
@ -837,7 +864,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
int trace_data_size = 0;
|
int trace_data_size = 0;
|
||||||
|
|
||||||
// Respond SOF -- takes 1 bytes
|
// Respond SOF -- takes 1 bytes
|
||||||
uint8_t *resp_sof = BigBuf_malloc(2);
|
uint8_t *resp_sof = BigBuf_malloc(1);
|
||||||
int resp_sof_Len;
|
int resp_sof_Len;
|
||||||
|
|
||||||
// Anticollision CSN (rotated CSN)
|
// Anticollision CSN (rotated CSN)
|
||||||
|
@ -853,8 +880,6 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
// configuration (block 1) picopass 2ks
|
// configuration (block 1) picopass 2ks
|
||||||
uint8_t *resp_conf = BigBuf_malloc(22);
|
uint8_t *resp_conf = BigBuf_malloc(22);
|
||||||
int resp_conf_len;
|
int resp_conf_len;
|
||||||
uint8_t conf_data[10] = {0x12, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0xFF, 0x3C, 0x00, 0x00};
|
|
||||||
AppendCrc(conf_data, 8);
|
|
||||||
|
|
||||||
// e-Purse (block 2)
|
// e-Purse (block 2)
|
||||||
// 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/bit)
|
// 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/bit)
|
||||||
|
@ -877,7 +902,6 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
// Prepare card messages
|
// Prepare card messages
|
||||||
ToSendMax = 0;
|
|
||||||
|
|
||||||
// First card answer: SOF only
|
// First card answer: SOF only
|
||||||
CodeIClassTagSOF();
|
CodeIClassTagSOF();
|
||||||
|
@ -895,7 +919,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
resp_csn_len = ToSendMax;
|
resp_csn_len = ToSendMax;
|
||||||
|
|
||||||
// Configuration (block 1)
|
// Configuration (block 1)
|
||||||
CodeIso15693AsTag(conf_data, sizeof(conf_data));
|
CodeIso15693AsTag(conf_block, sizeof(conf_block));
|
||||||
memcpy(resp_conf, ToSend, ToSendMax);
|
memcpy(resp_conf, ToSend, ToSendMax);
|
||||||
resp_conf_len = ToSendMax;
|
resp_conf_len = ToSendMax;
|
||||||
|
|
||||||
|
@ -918,16 +942,11 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
uint8_t *data_generic_trace = BigBuf_malloc(32 + 2); // 32 bytes data + 2byte CRC is max tag answer
|
uint8_t *data_generic_trace = BigBuf_malloc(32 + 2); // 32 bytes data + 2byte CRC is max tag answer
|
||||||
uint8_t *data_response = BigBuf_malloc( (32 + 2) * 2 + 2);
|
uint8_t *data_response = BigBuf_malloc( (32 + 2) * 2 + 2);
|
||||||
|
|
||||||
LED_A_ON();
|
|
||||||
bool buttonPressed = false;
|
bool buttonPressed = false;
|
||||||
enum { IDLE, ACTIVATED, SELECTED, HALTED } chip_state = IDLE;
|
enum { IDLE, ACTIVATED, SELECTED, HALTED } chip_state = IDLE;
|
||||||
|
|
||||||
while (!exitLoop) {
|
while (!exitLoop) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
LED_B_OFF();
|
|
||||||
//Signal tracer
|
|
||||||
// Can be used to get a trigger for an oscilloscope..
|
|
||||||
LED_C_OFF();
|
|
||||||
|
|
||||||
uint32_t reader_eof_time = 0;
|
uint32_t reader_eof_time = 0;
|
||||||
len = GetIso15693CommandFromReader(receivedCmd, MAX_FRAME_SIZE, &reader_eof_time);
|
len = GetIso15693CommandFromReader(receivedCmd, MAX_FRAME_SIZE, &reader_eof_time);
|
||||||
|
@ -936,9 +955,6 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Signal tracer
|
|
||||||
LED_C_ON();
|
|
||||||
|
|
||||||
// Now look at the reader command and provide appropriate responses
|
// Now look at the reader command and provide appropriate responses
|
||||||
// default is no response:
|
// default is no response:
|
||||||
modulated_response = NULL;
|
modulated_response = NULL;
|
||||||
|
@ -951,8 +967,6 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
if (chip_state != HALTED) {
|
if (chip_state != HALTED) {
|
||||||
modulated_response = resp_sof;
|
modulated_response = resp_sof;
|
||||||
modulated_response_size = resp_sof_Len;
|
modulated_response_size = resp_sof_Len;
|
||||||
trace_data = sof_data;
|
|
||||||
trace_data_size = sizeof(sof_data);
|
|
||||||
chip_state = ACTIVATED;
|
chip_state = ACTIVATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1004,8 +1018,8 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
case 1: // configuration (block 01)
|
case 1: // configuration (block 01)
|
||||||
modulated_response = resp_conf;
|
modulated_response = resp_conf;
|
||||||
modulated_response_size = resp_conf_len;
|
modulated_response_size = resp_conf_len;
|
||||||
trace_data = conf_data;
|
trace_data = conf_block;
|
||||||
trace_data_size = sizeof(conf_data);
|
trace_data_size = sizeof(conf_block);
|
||||||
break;
|
break;
|
||||||
case 2: // e-purse (block 02)
|
case 2: // e-purse (block 02)
|
||||||
modulated_response = resp_cc;
|
modulated_response = resp_cc;
|
||||||
|
@ -1039,7 +1053,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
trace_data = ff_data;
|
trace_data = ff_data;
|
||||||
trace_data_size = sizeof(ff_data);
|
trace_data_size = sizeof(ff_data);
|
||||||
} else { // use data from emulator memory
|
} else { // use data from emulator memory
|
||||||
memcpy(data_generic_trace, emulator + 8*blockNo, 8);
|
memcpy(data_generic_trace, emulator + current_page*page_size + 8*blockNo, 8);
|
||||||
AppendCrc(data_generic_trace, 8);
|
AppendCrc(data_generic_trace, 8);
|
||||||
trace_data = data_generic_trace;
|
trace_data = data_generic_trace;
|
||||||
trace_data_size = 10;
|
trace_data_size = 10;
|
||||||
|
@ -1055,11 +1069,17 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
|| receivedCmd[0] == ICLASS_CMD_READCHECK_KC) && receivedCmd[1] == 0x02 && len == 2) {
|
|| receivedCmd[0] == ICLASS_CMD_READCHECK_KC) && receivedCmd[1] == 0x02 && len == 2) {
|
||||||
// Read e-purse (88 02 || 18 02)
|
// Read e-purse (88 02 || 18 02)
|
||||||
if (chip_state == SELECTED) {
|
if (chip_state == SELECTED) {
|
||||||
|
if(receivedCmd[0] == ICLASS_CMD_READCHECK_KD){
|
||||||
|
cipher_state = &cipher_state_KD[current_page];
|
||||||
|
diversified_key = diversified_key_d;
|
||||||
|
} else {
|
||||||
|
cipher_state = &cipher_state_KC[current_page];
|
||||||
|
diversified_key = diversified_key_c;
|
||||||
|
}
|
||||||
modulated_response = resp_cc;
|
modulated_response = resp_cc;
|
||||||
modulated_response_size = resp_cc_len;
|
modulated_response_size = resp_cc_len;
|
||||||
trace_data = card_challenge_data;
|
trace_data = card_challenge_data;
|
||||||
trace_data_size = sizeof(card_challenge_data);
|
trace_data_size = sizeof(card_challenge_data);
|
||||||
LED_B_ON();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ((receivedCmd[0] == ICLASS_CMD_CHECK_KC
|
} else if ((receivedCmd[0] == ICLASS_CMD_CHECK_KC
|
||||||
|
@ -1068,11 +1088,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
if (chip_state == SELECTED) {
|
if (chip_state == SELECTED) {
|
||||||
if (simulationMode == ICLASS_SIM_MODE_FULL) {
|
if (simulationMode == ICLASS_SIM_MODE_FULL) {
|
||||||
//NR, from reader, is in receivedCmd+1
|
//NR, from reader, is in receivedCmd+1
|
||||||
if (receivedCmd[0] == ICLASS_CMD_CHECK_KC) {
|
opt_doTagMAC_2(*cipher_state, receivedCmd+1, data_generic_trace, diversified_key);
|
||||||
opt_doTagMAC_2(cipher_state_KC, receivedCmd+1, data_generic_trace, diversified_key_c);
|
|
||||||
} else {
|
|
||||||
opt_doTagMAC_2(cipher_state_KD, receivedCmd+1, data_generic_trace, diversified_key_d);
|
|
||||||
}
|
|
||||||
trace_data = data_generic_trace;
|
trace_data = data_generic_trace;
|
||||||
trace_data_size = 4;
|
trace_data_size = 4;
|
||||||
CodeIso15693AsTag(trace_data, trace_data_size);
|
CodeIso15693AsTag(trace_data, trace_data_size);
|
||||||
|
@ -1095,13 +1111,16 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
} else if (receivedCmd[0] == ICLASS_CMD_HALT && len == 1) {
|
} else if (receivedCmd[0] == ICLASS_CMD_HALT && len == 1) {
|
||||||
if (chip_state == SELECTED) {
|
if (chip_state == SELECTED) {
|
||||||
// Reader ends the session
|
// Reader ends the session
|
||||||
|
modulated_response = resp_sof;
|
||||||
|
modulated_response_size = resp_sof_Len;
|
||||||
chip_state = HALTED;
|
chip_state = HALTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (simulationMode == ICLASS_SIM_MODE_FULL && receivedCmd[0] == ICLASS_CMD_READ4 && len == 4) { // 0x06
|
} else if (simulationMode == ICLASS_SIM_MODE_FULL && receivedCmd[0] == ICLASS_CMD_READ4 && len == 4) { // 0x06
|
||||||
//Read 4 blocks
|
//Read 4 blocks
|
||||||
if (chip_state == SELECTED) {
|
if (chip_state == SELECTED) {
|
||||||
memcpy(data_generic_trace, emulator + receivedCmd[1]*8, 8 * 4);
|
uint8_t blockNo = receivedCmd[1];
|
||||||
|
memcpy(data_generic_trace, emulator + current_page*page_size + blockNo*8, 8 * 4);
|
||||||
AppendCrc(data_generic_trace, 8 * 4);
|
AppendCrc(data_generic_trace, 8 * 4);
|
||||||
trace_data = data_generic_trace;
|
trace_data = data_generic_trace;
|
||||||
trace_data_size = 8 * 4 + 2;
|
trace_data_size = 8 * 4 + 2;
|
||||||
|
@ -1121,29 +1140,37 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
CodeIso15693AsTag(card_challenge_data, sizeof(card_challenge_data));
|
CodeIso15693AsTag(card_challenge_data, sizeof(card_challenge_data));
|
||||||
memcpy(resp_cc, ToSend, ToSendMax);
|
memcpy(resp_cc, ToSend, ToSendMax);
|
||||||
resp_cc_len = ToSendMax;
|
resp_cc_len = ToSendMax;
|
||||||
cipher_state_KD = opt_doTagMAC_1(card_challenge_data, diversified_key_d);
|
cipher_state_KD[current_page] = opt_doTagMAC_1(card_challenge_data, diversified_key_d);
|
||||||
cipher_state_KC = opt_doTagMAC_1(card_challenge_data, diversified_key_c);
|
cipher_state_KC[current_page] = opt_doTagMAC_1(card_challenge_data, diversified_key_c);
|
||||||
if (simulationMode == ICLASS_SIM_MODE_FULL) {
|
if (simulationMode == ICLASS_SIM_MODE_FULL) {
|
||||||
memcpy(emulator + 8*2, card_challenge_data, 8);
|
memcpy(emulator + current_page*page_size + 8*2, card_challenge_data, 8);
|
||||||
}
|
}
|
||||||
} else if (blockNo == 3) { // update Kd
|
} else if (blockNo == 3) { // update Kd
|
||||||
for (int i = 0; i < 8; i++){
|
for (int i = 0; i < 8; i++) {
|
||||||
diversified_key_d[i] = diversified_key_d[i] ^ receivedCmd[2 + i];
|
if (personalization_mode) {
|
||||||
|
diversified_key_d[i] = receivedCmd[2 + i];
|
||||||
|
} else {
|
||||||
|
diversified_key_d[i] ^= receivedCmd[2 + i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cipher_state_KD = opt_doTagMAC_1(card_challenge_data, diversified_key_d);
|
cipher_state_KD[current_page] = opt_doTagMAC_1(card_challenge_data, diversified_key_d);
|
||||||
if (simulationMode == ICLASS_SIM_MODE_FULL) {
|
if (simulationMode == ICLASS_SIM_MODE_FULL) {
|
||||||
memcpy(emulator + 8*3, diversified_key_d, 8);
|
memcpy(emulator + current_page*page_size + 8*3, diversified_key_d, 8);
|
||||||
}
|
}
|
||||||
} else if (blockNo == 4) { // update Kc
|
} else if (blockNo == 4) { // update Kc
|
||||||
for(int i = 0; i < 8; i++){
|
for (int i = 0; i < 8; i++) {
|
||||||
diversified_key_c[i] = diversified_key_c[i] ^ receivedCmd[2 + i];
|
if (personalization_mode) {
|
||||||
|
diversified_key_c[i] = receivedCmd[2 + i];
|
||||||
|
} else {
|
||||||
|
diversified_key_c[i] ^= receivedCmd[2 + i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cipher_state_KC = opt_doTagMAC_1(card_challenge_data, diversified_key_c);
|
cipher_state_KC[current_page] = opt_doTagMAC_1(card_challenge_data, diversified_key_c);
|
||||||
if (simulationMode == ICLASS_SIM_MODE_FULL) {
|
if (simulationMode == ICLASS_SIM_MODE_FULL) {
|
||||||
memcpy(emulator + 8*4, diversified_key_c, 8);
|
memcpy(emulator + current_page*page_size + 8*4, diversified_key_c, 8);
|
||||||
}
|
}
|
||||||
} else if (simulationMode == ICLASS_SIM_MODE_FULL) { // update any other data block
|
} else if (simulationMode == ICLASS_SIM_MODE_FULL) { // update any other data block
|
||||||
memcpy(emulator + 8*blockNo, receivedCmd+2, 8);
|
memcpy(emulator + current_page*page_size + 8*blockNo, receivedCmd+2, 8);
|
||||||
}
|
}
|
||||||
memcpy(data_generic_trace, receivedCmd + 2, 8);
|
memcpy(data_generic_trace, receivedCmd + 2, 8);
|
||||||
AppendCrc(data_generic_trace, 8);
|
AppendCrc(data_generic_trace, 8);
|
||||||
|
@ -1157,11 +1184,24 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
|
|
||||||
} else if (receivedCmd[0] == ICLASS_CMD_PAGESEL && len == 4) {
|
} else if (receivedCmd[0] == ICLASS_CMD_PAGESEL && len == 4) {
|
||||||
// Pagesel
|
// Pagesel
|
||||||
|
// Chips with a single page will not answer to this command
|
||||||
|
// Otherwise, we should answer 8bytes (block) + 2bytes CRC
|
||||||
if (chip_state == SELECTED) {
|
if (chip_state == SELECTED) {
|
||||||
// Pagesel enables to select a page in the selected chip memory and return its configuration block
|
if (simulationMode == ICLASS_SIM_MODE_FULL && max_page > 0) {
|
||||||
// Chips with a single page will not answer to this command
|
current_page = receivedCmd[1];
|
||||||
// It appears we're fine ignoring this.
|
memcpy(data_generic_trace, emulator + current_page*page_size + 8*1, 8);
|
||||||
// Otherwise, we should answer 8bytes (block) + 2bytes CRC
|
memcpy(diversified_key_d, emulator + current_page*page_size + 8*3, 8);
|
||||||
|
memcpy(diversified_key_c, emulator + current_page*page_size + 8*4, 8);
|
||||||
|
cipher_state = &cipher_state_KD[current_page];
|
||||||
|
personalization_mode = data_generic_trace[7] & 0x80;
|
||||||
|
AppendCrc(data_generic_trace, 8);
|
||||||
|
trace_data = data_generic_trace;
|
||||||
|
trace_data_size = 10;
|
||||||
|
CodeIso15693AsTag(trace_data, trace_data_size);
|
||||||
|
memcpy(data_response, ToSend, ToSendMax);
|
||||||
|
modulated_response = data_response;
|
||||||
|
modulated_response_size = ToSendMax;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (receivedCmd[0] == 0x26 && len == 5) {
|
} else if (receivedCmd[0] == 0x26 && len == 5) {
|
||||||
|
@ -1189,10 +1229,6 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LED_A_OFF();
|
|
||||||
LED_B_OFF();
|
|
||||||
LED_C_OFF();
|
|
||||||
|
|
||||||
if (buttonPressed)
|
if (buttonPressed)
|
||||||
{
|
{
|
||||||
DbpString("Button pressed");
|
DbpString("Button pressed");
|
||||||
|
@ -1213,6 +1249,9 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||||
* @param datain
|
* @param datain
|
||||||
*/
|
*/
|
||||||
void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) {
|
void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) {
|
||||||
|
|
||||||
|
LED_A_ON();
|
||||||
|
|
||||||
uint32_t simType = arg0;
|
uint32_t simType = arg0;
|
||||||
uint32_t numberOfCSNS = arg1;
|
uint32_t numberOfCSNS = arg1;
|
||||||
|
|
||||||
|
@ -1220,6 +1259,7 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
|
||||||
|
LED_D_OFF();
|
||||||
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
|
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
|
||||||
StartCountSspClk();
|
StartCountSspClk();
|
||||||
|
|
||||||
|
@ -1270,8 +1310,10 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
|
||||||
// That will speed things up a little, but not required just yet.
|
// That will speed things up a little, but not required just yet.
|
||||||
Dbprintf("The mode is not implemented, reserved for future use");
|
Dbprintf("The mode is not implemented, reserved for future use");
|
||||||
}
|
}
|
||||||
|
|
||||||
Dbprintf("Done...");
|
Dbprintf("Done...");
|
||||||
|
|
||||||
|
LED_A_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -225,17 +225,18 @@ void annotateIclass(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ICLASS_CMD_SELECT: snprintf(exp,size, "SELECT"); break;
|
case ICLASS_CMD_SELECT: snprintf(exp,size, "SELECT"); break;
|
||||||
case ICLASS_CMD_PAGESEL: snprintf(exp,size, "PAGESEL(%d)", cmd[1]); break;
|
case ICLASS_CMD_PAGESEL: snprintf(exp,size, "PAGESEL(%d)", cmd[1]); break;
|
||||||
case ICLASS_CMD_READCHECK_KC:snprintf(exp,size, "READCHECK[Kc](%d)", cmd[1]); break;
|
case ICLASS_CMD_READCHECK_KC: snprintf(exp,size, "READCHECK[Kc](%d)", cmd[1]); break;
|
||||||
case ICLASS_CMD_READCHECK_KD:snprintf(exp,size, "READCHECK[Kd](%d)", cmd[1]); break;
|
case ICLASS_CMD_READCHECK_KD: snprintf(exp,size, "READCHECK[Kd](%d)", cmd[1]); break;
|
||||||
case ICLASS_CMD_CHECK: snprintf(exp,size, "CHECK"); break;
|
case ICLASS_CMD_CHECK_KC:
|
||||||
case ICLASS_CMD_DETECT: snprintf(exp,size, "DETECT"); break;
|
case ICLASS_CMD_CHECK_KD: snprintf(exp,size, "CHECK"); break;
|
||||||
case ICLASS_CMD_HALT: snprintf(exp,size, "HALT"); break;
|
case ICLASS_CMD_DETECT: snprintf(exp,size, "DETECT"); break;
|
||||||
case ICLASS_CMD_UPDATE: snprintf(exp,size, "UPDATE(%d)",cmd[1]); break;
|
case ICLASS_CMD_HALT: snprintf(exp,size, "HALT"); break;
|
||||||
case ICLASS_CMD_ACT: snprintf(exp,size, "ACT"); break;
|
case ICLASS_CMD_UPDATE: snprintf(exp,size, "UPDATE(%d)",cmd[1]); break;
|
||||||
case ICLASS_CMD_READ4: snprintf(exp,size, "READ4(%d)",cmd[1]); break;
|
case ICLASS_CMD_ACT: snprintf(exp,size, "ACT"); break;
|
||||||
default: snprintf(exp,size, "?"); break;
|
case ICLASS_CMD_READ4: snprintf(exp,size, "READ4(%d)",cmd[1]); break;
|
||||||
|
default: snprintf(exp,size, "?"); break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -973,7 +974,11 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data_len == 0) {
|
if (data_len == 0) {
|
||||||
sprintf(line[0]," <empty trace - possible error>");
|
if (protocol == ICLASS && duration == 2048) {
|
||||||
|
sprintf(line[0], " <SOF>");
|
||||||
|
} else {
|
||||||
|
sprintf(line[0], " <empty trace - possible error>");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--- Draw the CRC column
|
//--- Draw the CRC column
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue