// Stop when button is pressed
// Or return TRUE when command is captured
//-----------------------------------------------------------------------------
-static int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len) {
+int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len) {
// Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen
// only, since we are receiving, not transmitting).
// Signal field is off with the appropriate LED
uint8_t emdata[MAX_MIFARE_FRAME_SIZE];
emlGetMemBt( emdata, start, 16);
AppendCrc14443a(emdata, 16);
- EmSendCmdEx(emdata, sizeof(emdata), false);
+ EmSendCmdEx(emdata, sizeof(emdata));
// We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below
p_response = NULL;
} else { // all other tags (16 byte block tags)
uint8_t emdata[MAX_MIFARE_FRAME_SIZE];
emlGetMemBt( emdata, block, 16);
AppendCrc14443a(emdata, 16);
- EmSendCmdEx(emdata, sizeof(emdata), false);
- // EmSendCmdEx(data+(4*receivedCmd[1]),16,false);
+ EmSendCmdEx(emdata, sizeof(emdata));
+ // EmSendCmdEx(data+(4*receivedCmd[1]),16);
// Dbprintf("Read request from reader: %x %x",receivedCmd[0],receivedCmd[1]);
// We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below
p_response = NULL;
int len = (receivedCmd[2] - receivedCmd[1] + 1) * 4;
emlGetMemBt( emdata, start, len);
AppendCrc14443a(emdata, len);
- EmSendCmdEx(emdata, len+2, false);
+ EmSendCmdEx(emdata, len+2);
p_response = NULL;
} else if(receivedCmd[0] == MIFARE_ULEV1_READSIG && tagType == 7) { // Received a READ SIGNATURE --
// first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature]
uint8_t emdata[34];
emlGetMemBt( emdata, start, 32);
AppendCrc14443a(emdata, 32);
- EmSendCmdEx(emdata, sizeof(emdata), false);
+ EmSendCmdEx(emdata, sizeof(emdata));
p_response = NULL;
} else if (receivedCmd[0] == MIFARE_ULEV1_READ_CNT && tagType == 7) { // Received a READ COUNTER --
uint8_t index = receivedCmd[1];
num_to_bytes(counters[index], 3, cmd);
AppendCrc14443a(cmd, sizeof(cmd)-2);
}
- EmSendCmdEx(cmd,sizeof(cmd),false);
+ EmSendCmdEx(cmd,sizeof(cmd));
p_response = NULL;
} else if (receivedCmd[0] == MIFARE_ULEV1_INCR_CNT && tagType == 7) { // Received a INC COUNTER --
// number of counter
// send ACK
uint8_t ack[] = {0x0a};
- EmSendCmdEx(ack,sizeof(ack),false);
+ EmSendCmdEx(ack,sizeof(ack));
p_response = NULL;
} else if(receivedCmd[0] == MIFARE_ULEV1_CHECKTEAR && tagType == 7) { // Received a CHECK_TEARING_EVENT --
// first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature]
if (receivedCmd[1]<3) counter = receivedCmd[1];
emlGetMemBt( emdata, 10+counter, 1);
AppendCrc14443a(emdata, sizeof(emdata)-2);
- EmSendCmdEx(emdata, sizeof(emdata), false);
+ EmSendCmdEx(emdata, sizeof(emdata));
p_response = NULL;
} else if(receivedCmd[0] == ISO14443A_CMD_HALT) { // Received a HALT
LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
uint8_t emdata[10];
emlGetMemBt( emdata, 0, 8 );
AppendCrc14443a(emdata, sizeof(emdata)-2);
- EmSendCmdEx(emdata, sizeof(emdata), false);
+ EmSendCmdEx(emdata, sizeof(emdata));
p_response = NULL;
} else {
uint8_t emdata[4];
emlGetMemBt( emdata, start, 2);
AppendCrc14443a(emdata, 2);
- EmSendCmdEx(emdata, sizeof(emdata), false);
+ EmSendCmdEx(emdata, sizeof(emdata));
p_response = NULL;
uint32_t pwd = bytes_to_num(receivedCmd+1,4);
cmdsRecvd++;
if (p_response != NULL) {
- EmSendCmd14443aRaw(p_response->modulation, p_response->modulation_n, receivedCmd[0] == 0x52);
+ EmSendCmd14443aRaw(p_response->modulation, p_response->modulation_n);
// do the tracing for the previous reader request and this tag answer:
uint8_t par[MAX_PARITY_SIZE] = {0x00};
GetParity(p_response->response, p_response->response_n, par);
BigBuf_free_keep_EM();
LED_A_OFF();
- /*
- if(flags & FLAG_NR_AR_ATTACK && MF_DBGLEVEL >= 1) {
-
- for ( uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) {
- if (ar_nr_collected[i] == 2) {
- Dbprintf("Collected two pairs of AR/NR which can be used to extract %s from reader for sector %d:", (i<ATTACK_KEY_COUNT/2) ? "keyA" : "keyB", ar_nr_resp[i].sector);
- Dbprintf("../tools/mfkey/mfkey32 %08x %08x %08x %08x %08x %08x",
- ar_nr_resp[i].cuid, //UID
- ar_nr_resp[i].nonce, //NT
- ar_nr_resp[i].nr, //NR1
- ar_nr_resp[i].ar, //AR1
- ar_nr_resp[i].nr2, //NR2
- ar_nr_resp[i].ar2 //AR2
- );
- }
- }
-
- for ( uint8_t i = ATTACK_KEY_COUNT; i < ATTACK_KEY_COUNT*2; i++) {
- if (ar_nr_collected[i] == 2) {
- Dbprintf("Collected two pairs of AR/NR which can be used to extract %s from reader for sector %d:", (i<ATTACK_KEY_COUNT/2) ? "keyA" : "keyB", ar_nr_resp[i].sector);
- Dbprintf("../tools/mfkey/mfkey32v2 %08x %08x %08x %08x %08x %08x %08x",
- ar_nr_resp[i].cuid, //UID
- ar_nr_resp[i].nonce, //NT
- ar_nr_resp[i].nr, //NR1
- ar_nr_resp[i].ar, //AR1
- ar_nr_resp[i].nonce2,//NT2
- ar_nr_resp[i].nr2, //NR2
- ar_nr_resp[i].ar2 //AR2
- );
- }
- }
- }
- */
-
if (MF_DBGLEVEL >= 4){
Dbprintf("-[ Wake ups after halt [%d]", happened);
Dbprintf("-[ Messages after halt [%d]", happened2);
// Stop when button is pressed (return 1) or field was gone (return 2)
// Or return 0 when command is captured
//-----------------------------------------------------------------------------
-static int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) {
+int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) {
*len = 0;
uint32_t timer = 0, vtime = 0;
}
}
-int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen, bool correctionNeeded) {
+int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) {
uint8_t b;
uint16_t i = 0;
uint32_t ThisTransferTime;
+ bool correctionNeeded;
// Modulate Manchester
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD);
- // include correction bit if necessary
- if (Uart.parityBits & 0x01) {
- correctionNeeded = TRUE;
+ // Include correction bit if necessary
+ if (Uart.bitCount == 7)
+ {
+ // Short tags (7 bits) don't have parity, determine the correct value from MSB
+ correctionNeeded = Uart.output[0] & 0x40;
+ }
+ else
+ {
+ // The parity bits are left-aligned
+ correctionNeeded = Uart.parity[(Uart.len-1)/8] & (0x80 >> ((Uart.len-1) & 7));
}
// 1236, so correction bit needed
i = (correctionNeeded) ? 0 : 1;
i++;
}
}
- LastTimeProxToAirStart = ThisTransferTime + (correctionNeeded?8:0);
+ LastTimeProxToAirStart = ThisTransferTime + (correctionNeeded ? 8 : 0);
return 0;
}
-int EmSend4bitEx(uint8_t resp, bool correctionNeeded){
+int EmSend4bit(uint8_t resp){
Code4bitAnswerAsTag(resp);
- int res = EmSendCmd14443aRaw(ToSend, ToSendMax, correctionNeeded);
+ int res = EmSendCmd14443aRaw(ToSend, ToSendMax);
// do the tracing for the previous reader request and this tag answer:
uint8_t par[1] = {0x00};
GetParity(&resp, 1, par);
return res;
}
-int EmSend4bit(uint8_t resp){
- return EmSend4bitEx(resp, false);
-}
-
-int EmSendCmdExPar(uint8_t *resp, uint16_t respLen, bool correctionNeeded, uint8_t *par){
+int EmSendCmdExPar(uint8_t *resp, uint16_t respLen, uint8_t *par){
CodeIso14443aAsTagPar(resp, respLen, par);
- int res = EmSendCmd14443aRaw(ToSend, ToSendMax, correctionNeeded);
+ int res = EmSendCmd14443aRaw(ToSend, ToSendMax);
// do the tracing for the previous reader request and this tag answer:
EmLogTrace(Uart.output,
Uart.len,
return res;
}
-int EmSendCmdEx(uint8_t *resp, uint16_t respLen, bool correctionNeeded){
+int EmSendCmdEx(uint8_t *resp, uint16_t respLen){
uint8_t par[MAX_PARITY_SIZE] = {0x00};
GetParity(resp, respLen, par);
- return EmSendCmdExPar(resp, respLen, correctionNeeded, par);
+ return EmSendCmdExPar(resp, respLen, par);
}
int EmSendCmd(uint8_t *resp, uint16_t respLen){
uint8_t par[MAX_PARITY_SIZE] = {0x00};
GetParity(resp, respLen, par);
- return EmSendCmdExPar(resp, respLen, false, par);
+ return EmSendCmdExPar(resp, respLen, par);
}
int EmSendCmdPar(uint8_t *resp, uint16_t respLen, uint8_t *par){
- return EmSendCmdExPar(resp, respLen, false, par);
+ return EmSendCmdExPar(resp, respLen, par);
}
bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint8_t *reader_Parity,
// this if-statement doesn't match the specification above. (iceman)
if (len == 1 && ((receivedCmd[0] == ISO14443A_CMD_REQA && cardSTATE != MFEMUL_HALTED) || receivedCmd[0] == ISO14443A_CMD_WUPA)) {
selTimer = GetTickCount();
- EmSendCmdEx(atqa, sizeof(atqa), (receivedCmd[0] == ISO14443A_CMD_WUPA));
+ EmSendCmdEx(atqa, sizeof(atqa));
cardSTATE = MFEMUL_SELECT1;
crypto1_destroy(pcs);
cardAUTHKEY = 0xff;
//test if auth OK
if (cardRr != prng_successor(nonce, 64)){
- if (MF_DBGLEVEL >= 3)
+ if (MF_DBGLEVEL >= 3) {
Dbprintf("AUTH FAILED for sector %d with key %c. [nr=%08x cardRr=%08x] [nt=%08x succ=%08x]"
, cardAUTHSC
, (cardAUTHKEY == 0) ? 'A' : 'B'
, cardRr
, nonce // nt
, prng_successor(nonce, 64)
-
);
+ }
// Shouldn't we respond anything here?
// Right now, we don't nack or anything, which causes the
// reader to do a WUPA after a while. /Martin
// load key into crypto
crypto1_create(pcs, emlGetKey(cardAUTHSC, cardAUTHKEY));
- if (!encrypted_data) {
+ if (!encrypted_data) {
// first authentication
// Update crypto state init (UID ^ NONCE)
crypto1_word(pcs, cuid ^ nonce, 0);
num_to_bytes(nonce, 4, rAUTH_AT);
- }
-
} else {
// nested authentication
ans = nonce ^ crypto1_word(pcs, cuid ^ nonce, 0);