// Needed for CRC in emulation mode;
// same construction as in ISO 14443;
// different initial value (CRC_ICLASS)
-#include "iso14443crc.h"
-#include "iso15693tools.h"
+#include "../common/iso14443crc.h"
+#include "../common/iso15693tools.h"
+//#include "iso15693tools.h"
-
+ #include "cipher.h"
+ #include "protocols.h"
+
static int timeout = 4096;
LED_C_ON();
// Okay, look at the command now.
- if(receivedCmd[0] == 0x0a ) {
+ if(receivedCmd[0] == ICLASS_CMD_ACTALL ) {
// Reader in anticollission phase
- modulated_response = resp1; modulated_response_size = resp1Len; //order = 1;
- trace_data = response1;
- trace_data_size = sizeof(response1);
- } else if(receivedCmd[0] == 0x0c) {
+ modulated_response = resp_sof; modulated_response_size = resp_sof_Len; //order = 1;
+ trace_data = sof_data;
+ trace_data_size = sizeof(sof_data);
+ } else if(receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY && len == 1) {
// Reader asks for anticollission CSN
- modulated_response = resp2; modulated_response_size = resp2Len; //order = 2;
- trace_data = response2;
- trace_data_size = sizeof(response2);
+ modulated_response = resp_anticoll; modulated_response_size = resp_anticoll_len; //order = 2;
+ trace_data = anticoll_data;
+ trace_data_size = sizeof(anticoll_data);
//DbpString("Reader requests anticollission CSN:");
- } else if(receivedCmd[0] == 0x81) {
+ } else if(receivedCmd[0] == ICLASS_CMD_SELECT) {
// Reader selects anticollission CSN.
// Tag sends the corresponding real CSN
- modulated_response = resp3; modulated_response_size = resp3Len; //order = 3;
- trace_data = response3;
- trace_data_size = sizeof(response3);
+ modulated_response = resp_csn; modulated_response_size = resp_csn_len; //order = 3;
+ trace_data = csn_data;
+ trace_data_size = sizeof(csn_data);
//DbpString("Reader selects anticollission CSN:");
- } else if(receivedCmd[0] == 0x88) {
+ } else if(receivedCmd[0] == ICLASS_CMD_READCHECK_KD) {
// Read e-purse (88 02)
- modulated_response = resp4; modulated_response_size = resp4Len; //order = 4;
- trace_data = response4;
- trace_data_size = sizeof(response4);
+ modulated_response = resp_cc; modulated_response_size = resp_cc_len; //order = 4;
+ trace_data = card_challenge_data;
+ trace_data_size = sizeof(card_challenge_data);
LED_B_ON();
- } else if(receivedCmd[0] == 0x05) {
+ } else if(receivedCmd[0] == ICLASS_CMD_CHECK) {
// Reader random and reader MAC!!!
- // Do not respond
+ if(simulationMode == MODE_FULLSIM)
+ { //This is what we must do..
+ //Reader just sent us NR and MAC(k,cc * nr)
+ //The diversified key should be stored on block 3
+ //However, from a typical dump, the key will not be there
+ uint8_t *diversified_key = { 0 };
+ //Get the diversified key from emulator memory
+ memcpy(diversified_key, emulator+(8*3),8);
+ uint8_t ccnr[12] = { 0 };
+ //Put our cc there (block 2)
+ memcpy(ccnr, emulator + (8 * 2), 8);
+ //Put nr there
+ memcpy(ccnr+8, receivedCmd+1,4);
+ //Now, calc MAC
+ doMAC(ccnr,diversified_key, trace_data);
+ trace_data_size = 4;
+ CodeIClassTagAnswer(trace_data , trace_data_size);
+ memcpy(data_response, ToSend, ToSendMax);
+ modulated_response = data_response;
+ modulated_response_size = ToSendMax;
+ }else
+ { //Not fullsim, we don't respond
- // We do not know what to answer, so lets keep quiet
+ // We do not know what to answer, so lets keep quiet
- modulated_response = resp1; modulated_response_size = 0; //order = 5;
+ modulated_response = resp_sof; modulated_response_size = 0;
- trace_data = NULL;
- trace_data_size = 0;
+ trace_data = NULL;
+ trace_data_size = 0;
- if (breakAfterMacReceived){
+ if (simulationMode == MODE_EXIT_AFTER_MAC){
- // dbprintf:ing ...
- Dbprintf("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("RDR: (len=%02d): %02x %02x %02x %02x %02x %02x %02x %02x %02x",len,
- receivedCmd[0], receivedCmd[1], receivedCmd[2],
- receivedCmd[3], receivedCmd[4], receivedCmd[5],
- receivedCmd[6], receivedCmd[7], receivedCmd[8]);
- if (reader_mac_buf != NULL)
- {
- memcpy(reader_mac_buf,receivedCmd+1,8);
- }
- exitLoop = true;
+ // dbprintf:ing ...
+ Dbprintf("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("RDR: (len=%02d): %02x %02x %02x %02x %02x %02x %02x %02x %02x",len,
+ receivedCmd[0], receivedCmd[1], receivedCmd[2],
+ receivedCmd[3], receivedCmd[4], receivedCmd[5],
+ receivedCmd[6], receivedCmd[7], receivedCmd[8]);
+ if (reader_mac_buf != NULL)
+ {
+ memcpy(reader_mac_buf,receivedCmd+1,8);
}
- } else if(receivedCmd[0] == 0x00 && len == 1) {
+ exitLoop = true;
+ }
+ }
+
+ } else if(receivedCmd[0] == ICLASS_CMD_HALT && len == 1) {
// Reader ends the session
- modulated_response = resp1; modulated_response_size = 0; //order = 0;
+ modulated_response = resp_sof; modulated_response_size = 0; //order = 0;
trace_data = NULL;
trace_data_size = 0;
- } else {
+ } else if(simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY && len == 4){
+ //Read block
+ uint16_t blk = receivedCmd[1];
+ trace_data = emulator+(blk << 3);
+ trace_data_size = 8;
+ CodeIClassTagAnswer(trace_data , trace_data_size);
+ memcpy(data_response, ToSend, ToSendMax);
+ modulated_response = data_response;
+ modulated_response_size = ToSendMax;
+ }
+ else {
//#db# Unknown command received from reader (len=5): 26 1 0 f6 a 44 44 44 44
// Never seen this command before
Dbprintf("Unknown command received from reader (len=%d): %x %x %x %x %x %x %x %x %x",
if(read_status == 1) datasize = 8;
if(read_status == 2) datasize = 16;
- LED_B_ON();
- //Send back to client, but don't bother if we already sent this
- if(memcmp(last_csn, card_data, 8) != 0)
+ //Todo, read the public blocks 1,5 aswell:
+ //
+ // 0 : CSN (we already have)
+ // 1 : Configuration
+ // 2 : e-purse (we already have)
+ // (3,4 write-only)
+ // 5 Application issuer area
+ //
+ //Then we can 'ship' back the 8 * 5 bytes of data,
+ // with 0xFF:s in block 3 and 4.
+
+ LED_B_ON();
+ //Send back to client, but don't bother if we already sent this
+ if(memcmp(last_csn, card_data, 8) != 0)
{
if(!get_cc || (get_cc && read_status == 2))
BitstreamIn input_32_zeroes = {zeroes_32,sizeof(zeroes_32)*8,0};
State initState = suc(k,init(k),&input);
output(k,initState,&input_32_zeroes,&out);
-}
+}
- void doMAC(uint8_t *cc_nr_p, int length, uint8_t *div_key_p, uint8_t mac[4])
+ void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4])
{
- uint8_t *cc_nr;
+ uint8_t cc_nr[13] = { 0 };
uint8_t div_key[8];
- cc_nr=(uint8_t*)malloc(length+1);
- memcpy(cc_nr,cc_nr_p,length);
+ //cc_nr=(uint8_t*)malloc(length+1);
+
+ memcpy(cc_nr,cc_nr_p,12);
memcpy(div_key,div_key_p,8);
-
+
- reverse_arraybytes(cc_nr,length);
- BitstreamIn bitstream = {cc_nr,length * 8,0};
+ reverse_arraybytes(cc_nr,12);
+ BitstreamIn bitstream = {cc_nr,12 * 8,0};
- uint8_t dest []= {0,0,0,0,0,0,0,0};
- BitstreamOut out = { dest, sizeof(dest)*8, 0 };
- MAC(div_key,bitstream, out);
- //The output MAC must also be reversed
- reverse_arraybytes(dest, sizeof(dest));
- memcpy(mac, dest, 4);
+ uint8_t dest []= {0,0,0,0,0,0,0,0};
+ BitstreamOut out = { dest, sizeof(dest)*8, 0 };
+ MAC(div_key,bitstream, out);
+ //The output MAC must also be reversed
+ reverse_arraybytes(dest, sizeof(dest));
+ memcpy(mac,dest,4);
- //printf("Calculated_MAC\t%02x%02x%02x%02x\n", dest[0],dest[1],dest[2],dest[3]);
- free(cc_nr);
+ //free(cc_nr);
return;
}
-
+ #ifndef ON_DEVICE
int testMAC()
{
prnlog("[+] Testing MAC calculation...");