From 39864b0bd41dd5e896bcb8eeabcf2c3932f2203a Mon Sep 17 00:00:00 2001 From: "Merlokbr@gmail.com" Date: Wed, 11 Jul 2012 15:52:33 +0000 Subject: [PATCH] "hf mf sniff" low level logics works. --- armsrc/fpgaloader.c | 7 +- armsrc/iso14443a.c | 44 ++++++----- armsrc/iso14443a.h | 1 + armsrc/mifaresniff.c | 177 +++++++++++++++++++++++++++++++++++++++++++ armsrc/mifaresniff.h | 21 +++++ armsrc/util.h | 1 + client/cmdhfmf.c | 70 ++++++++++++++++- common/iso14443crc.c | 11 ++- common/iso14443crc.h | 4 +- include/proxmark3.h | 11 ++- 10 files changed, 322 insertions(+), 25 deletions(-) diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index caf87ba9..c199b9a8 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -138,11 +138,16 @@ void FpgaSetupSsc(void) //----------------------------------------------------------------------------- void FpgaSetupSscDma(uint8_t *buf, int len) { + AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; + AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) buf; AT91C_BASE_PDC_SSC->PDC_RCR = len; AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) buf; AT91C_BASE_PDC_SSC->PDC_RNCR = len; - AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; + + if (buf != NULL) { + AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; + } } static void DownloadFPGA_byte(unsigned char w) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 4bdbb810..a564a32f 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -656,7 +656,6 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { if (!AT91C_BASE_PDC_SSC->PDC_RCR) { AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dmaBuf; AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE; - Dbprintf("RxEmpty ERROR!!! %d", dataLen); // temporary } // secondary buffer sets as primary, secondary buffer was stopped if (!AT91C_BASE_PDC_SSC->PDC_RNCR) { @@ -2356,7 +2355,8 @@ void RAMFUNC SniffMifare(uint8_t param) { // param: // bit 0 - trigger from first card answer // bit 1 - trigger from first reader 7-bit request - + + // C(red) A(yellow) B(green) LEDsoff(); // init trace buffer traceLen = 0; @@ -2378,7 +2378,6 @@ void RAMFUNC SniffMifare(uint8_t param) { int8_t *data = dmaBuf; int maxDataLen = 0; int dataLen = 0; -// data = dmaBuf; // Set up the demodulator for tag -> reader responses. Demod.output = receivedResponse; @@ -2400,10 +2399,11 @@ void RAMFUNC SniffMifare(uint8_t param) { LED_D_OFF(); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + + // init sniffer + MfSniffInit(); + int sniffCounter = 0; - // Count of samples received so far, so that we can include timing - // information in the trace buffer. - rsamples = 0; // And now we loop, receiving samples. while(true) { if(BUTTON_PRESS()) { @@ -2413,6 +2413,13 @@ void RAMFUNC SniffMifare(uint8_t param) { LED_A_ON(); WDT_HIT(); + + if (++sniffCounter > 65) { + if (MfSniffSend(2000)) { + AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; + } + sniffCounter = 0; + } int register readBufDataP = data - dmaBuf; int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR; @@ -2445,33 +2452,30 @@ void RAMFUNC SniffMifare(uint8_t param) { LED_A_OFF(); - rsamples += 4; if(MillerDecoding((data[0] & 0xF0) >> 4)) { - LED_C_ON(); + LED_C_INV(); // check - if there is a short 7bit request from reader - if ((Uart.byteCnt == 1) && (Uart.bitCnt = 9)) { - - } - if (!LogTrace(receivedCmd, Uart.byteCnt, 0 - Uart.samples, Uart.parityBits, TRUE)) break; + if (MfSniffLogic(receivedCmd, Uart.byteCnt, Uart.bitCnt, TRUE)) break; /* And ready to receive another command. */ Uart.state = STATE_UNSYNCD; - /* And also reset the demod code, which might have been */ - /* false-triggered by the commands from the reader. */ + + /* And also reset the demod code */ Demod.state = DEMOD_UNSYNCD; - LED_B_OFF(); } if(ManchesterDecoding(data[0] & 0x0F)) { - LED_B_ON(); + LED_C_INV(); - if (!LogTrace(receivedResponse, Demod.len, 0 - Demod.samples, Demod.parityBits, FALSE)) break; + if (MfSniffLogic(receivedResponse, Demod.len, Uart.bitCnt, FALSE)) break; // And ready to receive another response. memset(&Demod, 0, sizeof(Demod)); Demod.output = receivedResponse; Demod.state = DEMOD_UNSYNCD; - LED_C_OFF(); + + /* And also reset the uart code */ + Uart.state = STATE_UNSYNCD; } data++; @@ -2484,7 +2488,9 @@ void RAMFUNC SniffMifare(uint8_t param) { done: AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; + MfSniffEnd(); + Dbprintf("maxDataLen=%x, Uart.state=%x, Uart.byteCnt=%x", maxDataLen, Uart.state, Uart.byteCnt); - Dbprintf("Uart.byteCntMax=%x, traceLen=%x, Uart.output[0]=%x", Uart.byteCntMax, traceLen, (int)Uart.output[0]); + Dbprintf("Uart.byteCntMax=%x, traceLen=%x", Uart.byteCntMax, traceLen); LEDsoff(); } \ No newline at end of file diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index d35d8f20..1a5766c8 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -13,6 +13,7 @@ #ifndef __ISO14443A_H #define __ISO14443A_H #include "common.h" +#include "mifaresniff.h" // mifare reader over DMA buffer (SnoopIso14443a())!!! #define MIFARE_BUFF_OFFSET 3560 // \/ \/ \/ diff --git a/armsrc/mifaresniff.c b/armsrc/mifaresniff.c index 25c7780d..aefe6962 100644 --- a/armsrc/mifaresniff.c +++ b/armsrc/mifaresniff.c @@ -11,5 +11,182 @@ #include "mifaresniff.h" #include "apps.h" +static int sniffState = SNF_INIT; +static uint8_t sniffUIDType; +static uint8_t sniffUID[8]; +static uint8_t sniffATQA[2]; +static uint8_t sniffSAK; +static uint8_t sniffBuf[16]; +static int timerData = 0; +int MfSniffInit(void){ + rsamples = 0; + memset(sniffUID, 0x00, 8); + memset(sniffATQA, 0x00, 2); + sniffSAK = 0; + sniffUIDType = SNF_UID_4; + + return 0; +} + +int MfSniffEnd(void){ + UsbCommand ack = {CMD_ACK, {0, 0, 0}}; + + LED_B_ON(); + UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand)); + LED_B_OFF(); + + return 0; +} + +int RAMFUNC MfSniffLogic(const uint8_t * data, int len, int bitCnt, int reader) { + + if ((len == 1) && (bitCnt = 9)) { + sniffState = SNF_INIT; + } + + switch (sniffState) { + case SNF_INIT:{ + if ((reader) && (len == 1) && (bitCnt == 9) && ((data[0] == 0x26) || (data[0] == 0x52))) { + sniffUIDType = SNF_UID_4; + memset(sniffUID, 0x00, 8); + memset(sniffATQA, 0x00, 2); + sniffSAK = 0; + + sniffState = SNF_WUPREQ; + } + break; + } + case SNF_WUPREQ:{ + if ((!reader) && (len == 2)) { + memcpy(sniffATQA, data, 2); + + sniffState = SNF_ATQA; + } + break; + } + case SNF_ATQA:{ + if ((reader) && (len == 2) && (data[0] == 0x93) && (data[1] == 0x20)) { + sniffState = SNF_ANTICOL1; + } + break; + } + case SNF_ANTICOL1:{ + if ((!reader) && (len == 5) && ((data[0] ^ data[1] ^ data[2] ^ data[3]) == data[4])) { + memcpy(sniffUID + 3, data, 4); + + sniffState = SNF_UID1; + } + break; + } + case SNF_UID1:{ + if ((reader) && (len == 9) && (data[0] == 0x93) && (data[1] == 0x70) && (CheckCrc14443(CRC_14443_A, data, 9))) { + sniffState = SNF_SAK; + } + break; + } + case SNF_SAK:{ + if ((!reader) && (len == 3) && (CheckCrc14443(CRC_14443_A, data, 3))) { + sniffSAK = data[0]; + if (sniffUID[3] == 0x88) { + sniffState = SNF_ANTICOL2; + } else { + sniffState = SNF_CARD_IDLE; + } + } + break; + } + case SNF_ANTICOL2:{ + if ((!reader) && (len == 5) && ((data[0] ^ data[1] ^ data[2] ^ data[3]) == data[4])) { + memcpy(sniffUID, data, 4); + sniffUIDType = SNF_UID_7; + + sniffState = SNF_UID2; + } + break; + } + case SNF_UID2:{ + if ((reader) && (len == 9) && (data[0] == 0x95) && (data[1] == 0x70) && (CheckCrc14443(CRC_14443_A, data, 9))) { + sniffState = SNF_SAK; + Dbprintf("SNF_SAK"); + } + break; + } + case SNF_CARD_IDLE:{ + sniffBuf[0] = 0xFF; + sniffBuf[1] = 0xFF; + memcpy(sniffBuf + 2, sniffUID, 7); + memcpy(sniffBuf + 9, sniffATQA, 2); + sniffBuf[11] = sniffSAK; + sniffBuf[12] = 0xFF; + sniffBuf[13] = 0xFF; + LogTrace(sniffBuf, 14, 0, 0, true); + timerData = GetTickCount(); + } + case SNF_CARD_CMD:{ + LogTrace(data, len, 0, 0, true); + + sniffState = SNF_CARD_RESP; + timerData = GetTickCount(); + break; + } + case SNF_CARD_RESP:{ + LogTrace(data, len, 0, 0, false); + + sniffState = SNF_CARD_CMD; + timerData = GetTickCount(); + break; + } + + default: + sniffState = SNF_INIT; + break; + } + + return 0; +} + +int RAMFUNC MfSniffSend(int maxTimeoutMs) { + if (traceLen && (timerData + maxTimeoutMs < GetTickCount())) { + return intMfSniffSend(); + } + return 0; +} + +// internal seding function. not a RAMFUNC. +int intMfSniffSend() { + + int pckSize = 0; + int pckLen = traceLen; + int pckNum = 0; + + if (!traceLen) return 0; + + AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; + + while (pckLen > 0) { + pckSize = min(32, pckLen); + UsbCommand ack = {CMD_ACK, {1, pckSize, pckNum}}; + memcpy(ack.d.asBytes, trace + traceLen - pckLen, pckSize); + + LED_B_ON(); + UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand)); + SpinDelay(20); + LED_B_OFF(); + + pckLen -= pckSize; + pckNum++; + } + + UsbCommand ack = {CMD_ACK, {2, 0, 0}}; + + LED_B_ON(); + UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand)); + LED_B_OFF(); + + traceLen = 0; + memset(trace, 0x44, TRACE_SIZE); + + return 1; +} diff --git a/armsrc/mifaresniff.h b/armsrc/mifaresniff.h index 21692aec..2012f9d7 100644 --- a/armsrc/mifaresniff.h +++ b/armsrc/mifaresniff.h @@ -22,5 +22,26 @@ #include "mifareutil.h" #include "common.h" +#define SNF_INIT 0 +#define SNF_NO_FIELD 1 +#define SNF_WUPREQ 2 +#define SNF_ATQA 3 +#define SNF_ANTICOL1 4 +#define SNF_UID1 5 +#define SNF_ANTICOL2 6 +#define SNF_UID2 7 +#define SNF_SAK 8 +#define SNF_CARD_IDLE 9 +#define SNF_CARD_CMD 10 +#define SNF_CARD_RESP 11 + +#define SNF_UID_4 0 +#define SNF_UID_7 0 + +int MfSniffInit(void); +int RAMFUNC MfSniffLogic(const uint8_t * data, int len, int bitCnt, int reader); +int RAMFUNC MfSniffSend(int maxTimeoutMs); +int intMfSniffSend(); +int MfSniffEnd(void); #endif \ No newline at end of file diff --git a/armsrc/util.h b/armsrc/util.h index 661b472d..21a9b757 100644 --- a/armsrc/util.h +++ b/armsrc/util.h @@ -17,6 +17,7 @@ #define RAMFUNC __attribute((long_call, section(".ramfunc"))) #define BYTEx(x, n) (((x) >> (n * 8)) & 0xff ) +#define min(a, b) (((a) > (b)) ? (b) : (a)) #define LED_RED 1 #define LED_ORANGE 2 diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 8dc59f49..98006d41 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -37,7 +37,6 @@ start: // message printf("-------------------------------------------------------------------------\n"); printf("Executing command. It may take up to 30 min.\n"); - printf("Press the key on proxmark3 device to abort proxmark3.\n"); printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n"); printf("-------------------------------------------------------------------------\n"); @@ -1543,6 +1542,18 @@ int CmdHF14AMfCSave(const char *Cmd) { } int CmdHF14AMfSniff(const char *Cmd){ + int res = 0; + int len = 0; + int blockLen = 0; + int num = 0; + int pckNum = 0; + uint8_t uid[8]; + uint8_t atqa[2]; + uint8_t sak; + bool isTag; + uint8_t buf[3000]; + uint8_t * bufPtr = buf; + memset(buf, 0x00, 3000); if (param_getchar(Cmd, 0) == 'h') { PrintAndLog("Usage: hf mf sniff "); @@ -1550,9 +1561,66 @@ int CmdHF14AMfSniff(const char *Cmd){ return 0; } + printf("-------------------------------------------------------------------------\n"); + printf("Executing command. \n"); + printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n"); + printf("Press the key on pc keyboard to abort the client.\n"); + printf("-------------------------------------------------------------------------\n"); + UsbCommand c = {CMD_MIFARE_SNIFFER, {0, 0, 0}}; SendCommand(&c); + // wait cycle + while (true) { + printf("."); + fflush(stdout); + if (ukbhit()) { + getchar(); + printf("\naborted via keyboard!\n"); + break; + } + + UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 2000); + if (resp != NULL) { + res = resp->arg[0] & 0xff; + len = resp->arg[1]; + num = resp->arg[2]; + + if (res == 0) return 0; + if (res == 1) { + if (num ==0) { + bufPtr = buf; + memset(buf, 0x00, 3000); + } + memcpy(bufPtr, resp->d.asBytes, len); + bufPtr += len; + pckNum++; + } + if (res == 2) { + blockLen = bufPtr - buf; + bufPtr = buf; + printf(">\n"); + PrintAndLog("received trace len: %d packages: %d", blockLen, pckNum); + num = 0; + while (bufPtr - buf + 9 < blockLen) { + isTag = bufPtr[3] & 0x80 ? true:false; + bufPtr += 8; + len = bufPtr[0]; + bufPtr++; + if ((len == 14) && (bufPtr[0] = 0xff) && (bufPtr[1] = 0xff)) { + memcpy(uid, bufPtr + 2, 7); + memcpy(atqa, bufPtr + 2 + 7, 2); + sak = bufPtr[11]; + PrintAndLog("tag select uid:%s atqa:%02x %02x sak:0x%02x", sprint_hex(uid, 7), atqa[0], atqa[1], sak); + } else { + PrintAndLog("%s(%d):%s", isTag ? "TAG":"RDR", num, sprint_hex(bufPtr, len)); + } + bufPtr += len; + num++; + } + } + } // resp not NILL + } // while (true) return 0; } diff --git a/common/iso14443crc.c b/common/iso14443crc.c index b5ffc92d..a6def1a9 100644 --- a/common/iso14443crc.c +++ b/common/iso14443crc.c @@ -18,7 +18,7 @@ static unsigned short UpdateCrc14443(unsigned char ch, unsigned short *lpwCrc) } void ComputeCrc14443(int CrcType, - unsigned char *Data, int Length, + const unsigned char *Data, int Length, unsigned char *TransmitFirst, unsigned char *TransmitSecond) { @@ -37,3 +37,12 @@ void ComputeCrc14443(int CrcType, *TransmitSecond = (unsigned char) ((wCrc >> 8) & 0xFF); return; } + +int CheckCrc14443(int CrcType, const unsigned char *Data, int Length) { + unsigned char b1; + unsigned char b2; + if (Length < 3) return 0; + ComputeCrc14443(CrcType, Data, Length - 2, &b1, &b2); + if ((b1 == Data[Length - 2]) && (b2 == Data[Length - 1])) return 1; + return 0; +} diff --git a/common/iso14443crc.h b/common/iso14443crc.h index e70573ef..87347714 100644 --- a/common/iso14443crc.h +++ b/common/iso14443crc.h @@ -8,6 +8,7 @@ #ifndef __ISO14443CRC_H #define __ISO14443CRC_H +#include "common.h" //----------------------------------------------------------------------------- // Routines to compute the CRCs (two different flavours, just for confusion) @@ -18,8 +19,9 @@ #define CRC_ICLASS 0xE012 /* ICLASS PRERFIX */ void ComputeCrc14443(int CrcType, - unsigned char *Data, int Length, + const unsigned char *Data, int Length, unsigned char *TransmitFirst, unsigned char *TransmitSecond); +int CheckCrc14443(int CrcType, const unsigned char *Data, int Length); #endif diff --git a/include/proxmark3.h b/include/proxmark3.h index a2bad2c5..0431dc80 100644 --- a/include/proxmark3.h +++ b/include/proxmark3.h @@ -51,8 +51,11 @@ #define UDP_CSR_BYTES_RECEIVED(x) (((x) >> 16) & 0x7ff) //************************************************************** -#define LOW(x) AT91C_BASE_PIOA->PIO_CODR = (x) -#define HIGH(x) AT91C_BASE_PIOA->PIO_SODR = (x) +#define LOW(x) AT91C_BASE_PIOA->PIO_CODR = (x) +#define HIGH(x) AT91C_BASE_PIOA->PIO_SODR = (x) +#define GETBIT(x) (AT91C_BASE_PIOA->PIO_ODSR & (x)) ? 1:0 +#define SETBIT(x, y) (y) ? (HIGH(x)):(LOW(x)) +#define INVBIT(x) SETBIT((x), !(GETBIT(x))) #define SPI_FPGA_MODE 0 #define SPI_LCD_MODE 1 @@ -72,12 +75,16 @@ #define LED_A_ON() HIGH(GPIO_LED_A) #define LED_A_OFF() LOW(GPIO_LED_A) +#define LED_A_INV() INVBIT(GPIO_LED_A) #define LED_B_ON() HIGH(GPIO_LED_B) #define LED_B_OFF() LOW(GPIO_LED_B) +#define LED_B_INV() INVBIT(GPIO_LED_B) #define LED_C_ON() HIGH(GPIO_LED_C) #define LED_C_OFF() LOW(GPIO_LED_C) +#define LED_C_INV() INVBIT(GPIO_LED_C) #define LED_D_ON() HIGH(GPIO_LED_D) #define LED_D_OFF() LOW(GPIO_LED_D) +#define LED_D_INV() INVBIT(GPIO_LED_D) #define RELAY_ON() HIGH(GPIO_RELAY) #define RELAY_OFF() LOW(GPIO_RELAY) #define BUTTON_PRESS() !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_BUTTON) -- 2.39.2