// Routines to support ISO 14443 type A.
//-----------------------------------------------------------------------------
-#include "proxmark3.h"
+#include "../include/proxmark3.h"
#include "apps.h"
#include "util.h"
#include "string.h"
-#include "cmd.h"
-
-#include "iso14443crc.h"
+#include "../common/cmd.h"
+#include "../common/iso14443crc.h"
#include "iso14443a.h"
#include "crapto1.h"
#include "mifareutil.h"
//
// Total delays including SSC-Transfers between ARM and FPGA. These are in carrier clock cycles (1/13,56MHz)
//
-// When the PM acts as reader and is receiving, it takes
-// 3 ticks for the A/D conversion
-// 10 ticks ( 16 on average) delay in the modulation detector.
-// 6 ticks until the SSC samples the first data
-// 7*16 ticks to complete the transfer from FPGA to ARM
-// 8 ticks to the next ssp_clk rising edge
+// When the PM acts as reader and is receiving tag data, it takes
+// 3 ticks delay in the AD converter
+// 16 ticks until the modulation detector completes and sets curbit
+// 8 ticks until bit_to_arm is assigned from curbit
+// 8*16 ticks for the transfer from FPGA to ARM
// 4*16 ticks until we measure the time
// - 8*16 ticks because we measure the time of the previous transfer
-#define DELAY_AIR2ARM_AS_READER (3 + 10 + 6 + 7*16 + 8 + 4*16 - 8*16)
+#define DELAY_AIR2ARM_AS_READER (3 + 16 + 8 + 8*16 + 4*16 - 8*16)
// When the PM acts as a reader and is sending, it takes
// 4*16 ticks until we can write data to the sending hold register
#define DELAY_ARM2AIR_AS_READER (4*16 + 8*16 + 8 + 8 + 1)
// When the PM acts as tag and is receiving it takes
-// 12 ticks delay in the RF part,
+// 2 ticks delay in the RF part (for the first falling edge),
// 3 ticks for the A/D conversion,
// 8 ticks on average until the start of the SSC transfer,
// 8 ticks until the SSC samples the first data
// 7*16 ticks to complete the transfer from FPGA to ARM
// 8 ticks until the next ssp_clk rising edge
-// 3*16 ticks until we measure the time
+// 4*16 ticks until we measure the time
// - 8*16 ticks because we measure the time of the previous transfer
-#define DELAY_AIR2ARM_AS_TAG (12 + 3 + 8 + 8 + 7*16 + 8 + 3*16 - 8*16)
+#define DELAY_AIR2ARM_AS_TAG (2 + 3 + 8 + 8 + 7*16 + 8 + 4*16 - 8*16)
// The FPGA will report its internal sending delay in
uint16_t FpgaSendQueueDelay;
#define DELAY_FPGA_QUEUE (FpgaSendQueueDelay<<1)
// When the PM acts as tag and is sending, it takes
-// 5*16 ticks until we can write data to the sending hold register
+// 4*16 ticks until we can write data to the sending hold register
// 8*16 ticks until the SHR is transferred to the Sending Shift Register
// 8 ticks until the first transfer starts
// 8 ticks later the FPGA samples the data
// + a varying number of ticks in the FPGA Delay Queue (mod_sig_buf)
// + 1 tick to assign mod_sig_coil
-#define DELAY_ARM2AIR_AS_TAG (5*16 + 8*16 + 8 + 8 + DELAY_FPGA_QUEUE + 1)
+#define DELAY_ARM2AIR_AS_TAG (4*16 + 8*16 + 8 + 8 + DELAY_FPGA_QUEUE + 1)
// When the PM acts as sniffer and is receiving tag data, it takes
// 3 ticks A/D conversion
-// 16 ticks delay in the modulation detector (on average).
-// + 16 ticks until it's result is sampled.
+// 14 ticks to complete the modulation detection
+// 8 ticks (on average) until the result is stored in to_arm
// + the delays in transferring data - which is the same for
// sniffing reader and tag data and therefore not relevant
-#define DELAY_TAG_AIR2ARM_AS_SNIFFER (3 + 16 + 16)
+#define DELAY_TAG_AIR2ARM_AS_SNIFFER (3 + 14 + 8)
-// When the PM acts as sniffer and is receiving tag data, it takes
-// 12 ticks delay in analogue RF receiver
+// When the PM acts as sniffer and is receiving reader data, it takes
+// 2 ticks delay in analogue RF receiver (for the falling edge of the
+// start bit, which marks the start of the communication)
// 3 ticks A/D conversion
-// 8 ticks on average until we sample the data.
+// 8 ticks on average until the data is stored in to_arm.
// + the delays in transferring data - which is the same for
// sniffing reader and tag data and therefore not relevant
-#define DELAY_READER_AIR2ARM_AS_SNIFFER (12 + 3 + 8)
+#define DELAY_READER_AIR2ARM_AS_SNIFFER (2 + 3 + 8)
//variables used for timing purposes:
//these are in ssp_clk cycles:
}
// The function LogTrace() is also used by the iClass implementation in iClass.c
-bool RAMFUNC LogTrace(const uint8_t * btBytes, uint8_t iLen, uint32_t timestamp, uint32_t dwParity, bool bReader)
+bool RAMFUNC LogTrace(const uint8_t * btBytes, uint8_t iLen, uint32_t timestamp, uint32_t dwParity, bool readerToTag)
{
+ if (!tracing) return FALSE;
// Return when trace is full
if (traceLen + sizeof(timestamp) + sizeof(dwParity) + iLen >= TRACE_SIZE) {
tracing = FALSE; // don't trace any more
trace[traceLen++] = ((timestamp >> 8) & 0xff);
trace[traceLen++] = ((timestamp >> 16) & 0xff);
trace[traceLen++] = ((timestamp >> 24) & 0xff);
- if (!bReader) {
+
+ if (!readerToTag) {
trace[traceLen - 1] |= 0x80;
}
trace[traceLen++] = ((dwParity >> 0) & 0xff);
//-----------------------------------------------------------------------------
static tUart Uart;
+// Lookup-Table to decide if 4 raw bits are a modulation.
+// We accept two or three consecutive "0" in any position with the rest "1"
+const bool Mod_Miller_LUT[] = {
+ TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE,
+ TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE
+};
+#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x00F0) >> 4])
+#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x000F)])
+
void UartReset()
{
Uart.state = STATE_UNSYNCD;
Uart.endTime = 0;
}
-inline RAMFUNC Modulation_t MillerModulation(uint8_t b)
-{
- // switch (b & 0x88) {
- // case 0x00: return MILLER_MOD_BOTH_HALVES;
- // case 0x08: return MILLER_MOD_FIRST_HALF;
- // case 0x80: return MILLER_MOD_SECOND_HALF;
- // case 0x88: return MILLER_MOD_NOMOD;
- // }
- // test the second cycle for a pause. For whatever reason the startbit tends to appear earlier than the rest.
- switch (b & 0x44) {
- case 0x00: return MOD_BOTH_HALVES;
- case 0x04: return MOD_FIRST_HALF;
- case 0x40: return MOD_SECOND_HALF;
- default: return MOD_NOMOD;
- }
-}
// use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time
static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
if (Uart.syncBit != 0xFFFF) {
Uart.startTime = non_real_time?non_real_time:(GetCountSspClk() & 0xfffffff8);
Uart.startTime -= Uart.syncBit;
+ Uart.endTime = Uart.startTime;
Uart.state = STATE_START_OF_COMMUNICATION;
}
}
} else {
- switch (MillerModulation(Uart.twoBits >> Uart.syncBit)) {
- case MOD_FIRST_HALF: // Sequence Z = 0
+ if (IsMillerModulationNibble1(Uart.twoBits >> Uart.syncBit)) {
+ if (IsMillerModulationNibble2(Uart.twoBits >> Uart.syncBit)) { // Modulation in both halves - error
+ UartReset();
+ Uart.highCnt = 6;
+ } else { // Modulation in first half = Sequence Z = logic "0"
if (Uart.state == STATE_MILLER_X) { // error - must not follow after X
UartReset();
Uart.highCnt = 6;
Uart.shiftReg = 0;
}
}
- break;
- case MOD_SECOND_HALF: // Sequence X = 1
+ }
+ } else {
+ if (IsMillerModulationNibble2(Uart.twoBits >> Uart.syncBit)) { // Modulation second half = Sequence X = logic "1"
Uart.bitCount++;
Uart.shiftReg = (Uart.shiftReg >> 1) | 0x100; // add a 1 to the shiftreg
Uart.state = STATE_MILLER_X;
Uart.bitCount = 0;
Uart.shiftReg = 0;
}
- break;
- case MOD_NOMOD: // no modulation in both halves - Sequence Y
+ } else { // no modulation in both halves - Sequence Y
if (Uart.state == STATE_MILLER_Z || Uart.state == STATE_MILLER_Y) { // Y after logic "0" - End of Communication
Uart.state = STATE_UNSYNCD;
if(Uart.len == 0 && Uart.bitCount > 0) { // if we decoded some bits
Uart.shiftReg >>= (9 - Uart.bitCount); // add them to the output
Uart.output[Uart.len++] = (Uart.shiftReg & 0xff);
Uart.parityBits <<= 1; // no parity bit - add "0"
- Uart.bitCount--; // last "0" was part of the EOC sequence
+ Uart.bitCount--; // last "0" was part of the EOC sequence
}
return TRUE;
}
Uart.shiftReg = 0;
}
}
- break;
- case MOD_BOTH_HALVES: // Error
- UartReset();
- Uart.highCnt = 6;
- return FALSE;
+ }
}
}
// Note 2: parameter offset is used to determine the position of the parity bits (required for the anticollision command only)
static tDemod Demod;
+// Lookup-Table to decide if 4 raw bits are a modulation.
+// We accept three or four "1" in any position
const bool Mod_Manchester_LUT[] = {
- FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE,
- FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE
+ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,
+ FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE
};
#define IsManchesterModulationNibble1(b) (Mod_Manchester_LUT[(b & 0x00F0) >> 4])
else if ((Demod.twoBits & 0x03B8) == 0x0380) Demod.syncBit = 2;
else if ((Demod.twoBits & 0x01DC) == 0x01C0) Demod.syncBit = 1;
else if ((Demod.twoBits & 0x00EE) == 0x00E0) Demod.syncBit = 0;
- if (Demod.syncBit < 8) {
+ if (Demod.syncBit != 0xFFFF) {
Demod.startTime = non_real_time?non_real_time:(GetCountSspClk() & 0xfffffff8);
Demod.startTime -= Demod.syncBit;
Demod.bitCount = offset; // number of decoded data bits
}
Demod.endTime = Demod.startTime + 8*(9*Demod.len + Demod.bitCount + 1);
} else { // no modulation in both halves - End of communication
- if(Demod.bitCount > 0) { // if we decoded bits
- Demod.shiftReg >>= (9 - Demod.bitCount); // add the remaining decoded bits to the output
- Demod.output[Demod.len++] = Demod.shiftReg & 0xff;
- // No parity bit, so just shift a 0
- Demod.parityBits <<= 1;
+ if (Demod.len > 0 || Demod.bitCount > 0) { // received something
+ if(Demod.bitCount > 0) { // if we decoded bits
+ Demod.shiftReg >>= (9 - Demod.bitCount); // add the remaining decoded bits to the output
+ Demod.output[Demod.len++] = Demod.shiftReg & 0xff;
+ // No parity bit, so just shift a 0
+ Demod.parityBits <<= 1;
+ }
+ return TRUE; // we are finished with decoding the raw data sequence
+ } else { // nothing received. Start over
+ DemodReset();
}
- Demod.state = DEMOD_UNSYNCD; // start from the beginning
- Demod.twoBits = 0;
- return TRUE; // we are finished with decoding the raw data sequence
}
}
LEDsoff();
// init trace buffer
iso14a_clear_trace();
+ iso14a_set_tracing(TRUE);
// We won't start recording the frames that we acquire until we trigger;
// a good trigger condition to get started is probably when we see a
previous_data = *data;
rsamples++;
data++;
- if(data > dmaBuf + DMA_BUFFER_SIZE) {
+ if(data == dmaBuf + DMA_BUFFER_SIZE) {
data = dmaBuf;
}
} // main cycle
i = 1;
}
- // clear receiving shift register and holding register
+ // clear receiving shift register and holding register
while(!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY));
b = AT91C_BASE_SSC->SSC_RHR; (void) b;
while(!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY));
}
void iso14443a_setup(uint8_t fpga_minor_mode) {
+ FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Set up the synchronous serial port
FpgaSetupSsc();
// connect Demodulated Signal to ADC:
DemodReset();
UartReset();
NextTransferTime = 2*DELAY_ARM2AIR_AS_READER;
- iso14a_set_timeout(1050); // 10ms default
+ iso14a_set_timeout(1050); // 10ms default 10*105 =
}
int iso14_apdu(uint8_t * cmd, size_t cmd_len, void * data) {
{
iso14a_command_t param = c->arg[0];
uint8_t *cmd = c->d.asBytes;
- size_t len = c->arg[1];
- size_t lenbits = c->arg[2];
+ size_t len = c->arg[1] & 0xFFFF;
+ size_t lenbits = c->arg[1] >> 16;
uint32_t arg0 = 0;
byte_t buf[USB_CMD_DATA_SIZE];
}
if(param & ISO14A_SET_TIMEOUT) {
- iso14a_timeout = c->arg[2];
+ iso14a_set_timeout(c->arg[2]);
}
if(param & ISO14A_APDU) {
if(param & ISO14A_APPEND_CRC) {
AppendCrc14443a(cmd,len);
len += 2;
+ lenbits += 16;
}
if(lenbits>0) {
+
ReaderTransmitBitsPar(cmd,lenbits,GetParity(cmd,lenbits/8), NULL);
} else {
ReaderTransmit(cmd,len, NULL);
// select card
if (len == 9 &&
(receivedCmd[0] == 0x93 && receivedCmd[1] == 0x70 && memcmp(&receivedCmd[2], rUIDBCC1, 4) == 0)) {
- EmSendCmd(_7BUID?rSAK1:rSAK, sizeof(_7BUID?rSAK1:rSAK));
+ EmSendCmd(_7BUID?rSAK1:rSAK, _7BUID?sizeof(rSAK1):sizeof(rSAK));
cuid = bytes_to_num(rUIDBCC1, 4);
if (!_7BUID) {
cardSTATE = MFEMUL_WORK;
// 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
+ // -- which is the correct response. /piwi
cardSTATE_TO_IDLE();
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE);
LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE);
EmSendCmd(rAUTH_AT, sizeof(rAUTH_AT));
LED_C_ON();
cardSTATE = MFEMUL_WORK;
- if (MF_DBGLEVEL >= 4) Dbprintf("AUTH COMPLETED. sector=%d, key=%d time=%d", cardAUTHSC, cardAUTHKEY, GetTickCount() - authTimer);
+ if (MF_DBGLEVEL >= 4) Dbprintf("AUTH COMPLETED for sector %d with key %c. time=%d",
+ cardAUTHSC, cardAUTHKEY == 0 ? 'A' : 'B',
+ GetTickCount() - authTimer);
break;
}
case MFEMUL_SELECT2:{
crypto1_create(pcs, emlGetKey(cardAUTHSC, cardAUTHKEY));
if (!encrypted_data) { // first authentication
- if (MF_DBGLEVEL >= 2) Dbprintf("Reader authenticating for block %d (0x%02x) with key %d",receivedCmd[1] ,receivedCmd[1],cardAUTHKEY );
+ if (MF_DBGLEVEL >= 4) Dbprintf("Reader authenticating for block %d (0x%02x) with key %d",receivedCmd[1] ,receivedCmd[1],cardAUTHKEY );
crypto1_word(pcs, cuid ^ nonce, 0);//Update crypto state
num_to_bytes(nonce, 4, rAUTH_AT); // Send nonce
} else { // nested authentication
- if (MF_DBGLEVEL >= 2) Dbprintf("Reader doing nested authentication for block %d (0x%02x) with key %d",receivedCmd[1] ,receivedCmd[1],cardAUTHKEY );
+ if (MF_DBGLEVEL >= 4) Dbprintf("Reader doing nested authentication for block %d (0x%02x) with key %d",receivedCmd[1] ,receivedCmd[1],cardAUTHKEY );
ans = nonce ^ crypto1_word(pcs, cuid ^ nonce, 0);
num_to_bytes(ans, 4, rAUTH_AT);
}
if(receivedCmd[0] == 0x30 // read block
|| receivedCmd[0] == 0xA0 // write block
- || receivedCmd[0] == 0xC0
- || receivedCmd[0] == 0xC1
- || receivedCmd[0] == 0xC2 // inc dec restore
+ || receivedCmd[0] == 0xC0 // inc
+ || receivedCmd[0] == 0xC1 // dec
+ || receivedCmd[0] == 0xC2 // restore
|| receivedCmd[0] == 0xB0) { // transfer
if (receivedCmd[1] >= 16 * 4) {
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
}
// read block
if (receivedCmd[0] == 0x30) {
- if (MF_DBGLEVEL >= 2) {
+ if (MF_DBGLEVEL >= 4) {
Dbprintf("Reader reading block %d (0x%02x)",receivedCmd[1],receivedCmd[1]);
}
emlGetMem(response, receivedCmd[1], 1);
}
// write block
if (receivedCmd[0] == 0xA0) {
- if (MF_DBGLEVEL >= 2) Dbprintf("RECV 0xA0 write block %d (%02x)",receivedCmd[1],receivedCmd[1]);
+ if (MF_DBGLEVEL >= 4) Dbprintf("RECV 0xA0 write block %d (%02x)",receivedCmd[1],receivedCmd[1]);
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK));
cardSTATE = MFEMUL_WRITEBL2;
cardWRBL = receivedCmd[1];
}
// increment, decrement, restore
if (receivedCmd[0] == 0xC0 || receivedCmd[0] == 0xC1 || receivedCmd[0] == 0xC2) {
- if (MF_DBGLEVEL >= 2) Dbprintf("RECV 0x%02x inc(0xC1)/dec(0xC0)/restore(0xC2) block %d (%02x)",receivedCmd[0],receivedCmd[1],receivedCmd[1]);
+ if (MF_DBGLEVEL >= 4) Dbprintf("RECV 0x%02x inc(0xC1)/dec(0xC0)/restore(0xC2) block %d (%02x)",receivedCmd[0],receivedCmd[1],receivedCmd[1]);
if (emlCheckValBl(receivedCmd[1])) {
if (MF_DBGLEVEL >= 2) Dbprintf("Reader tried to operate on block, but emlCheckValBl failed, nacking");
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
}
// transfer
if (receivedCmd[0] == 0xB0) {
- if (MF_DBGLEVEL >= 2) Dbprintf("RECV 0x%02x transfer block %d (%02x)",receivedCmd[0],receivedCmd[1],receivedCmd[1]);
+ if (MF_DBGLEVEL >= 4) Dbprintf("RECV 0x%02x transfer block %d (%02x)",receivedCmd[0],receivedCmd[1],receivedCmd[1]);
if (emlSetValBl(cardINTREG, cardINTBLOCK, receivedCmd[1]))
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
else
//May just aswell send the collected ar_nr in the response aswell
cmd_send(CMD_ACK,CMD_SIMULATE_MIFARE_CARD,0,0,&ar_nr_responses,ar_nr_collected*4*4);
}
+
if(flags & FLAG_NR_AR_ATTACK)
{
if(ar_nr_collected > 1) {
Dbprintf("Collected two pairs of AR/NR which can be used to extract keys from reader:");
- Dbprintf("../tools/mfkey/mfkey32 %08x %08x %08x %08x",
+ Dbprintf("../tools/mfkey/mfkey32 %08x %08x %08x %08x %08x %08x",
ar_nr_responses[0], // UID
ar_nr_responses[1], //NT
ar_nr_responses[2], //AR1
} else {
Dbprintf("Failed to obtain two AR/NR pairs!");
if(ar_nr_collected >0) {
- Dbprintf("Only got these: UID=%08d, nonce=%08d, AR1=%08d, NR1=%08d",
+ Dbprintf("Only got these: UID=%08x, nonce=%08x, AR1=%08x, NR1=%08x",
ar_nr_responses[0], // UID
ar_nr_responses[1], //NT
ar_nr_responses[2], //AR1
// C(red) A(yellow) B(green)
LEDsoff();
// init trace buffer
- iso14a_clear_trace();
+ iso14a_clear_trace();
+ iso14a_set_tracing(TRUE);
// The command (reader -> tag) that we're receiving.
// The length of a received command will in most cases be no more than 18 bytes.
previous_data = *data;
sniffCounter++;
data++;
- if(data > dmaBuf + DMA_BUFFER_SIZE) {
+ if(data == dmaBuf + DMA_BUFFER_SIZE) {
data = dmaBuf;
}