First try att merging with head

This commit is contained in:
Martin Holst Swende 2014-10-24 20:46:02 +02:00
commit f97d4e2378
105 changed files with 7541 additions and 1686 deletions

View file

@ -52,10 +52,13 @@ OBJS = $(OBJDIR)/osimage.s19 $(OBJDIR)/fpgaimage.s19
all: $(OBJS)
$(OBJDIR)/fpga.o: fpga.bit
$(OBJCOPY) -O elf32-littlearm -I binary -B arm --redefine-sym _binary____fpga_fpga_bit_start=_binary_fpga_bit_start --redefine-sym _binary____fpga_fpga_bit_end=_binary_fpga_bit_end --prefix-sections=fpga_bit $^ $@
$(OBJDIR)/fpga_lf.o: fpga_lf.bit
$(OBJCOPY) -O elf32-littlearm -I binary -B arm --redefine-sym _binary____fpga_fpga_lf_bit_start=_binary_fpga_lf_bit_start --redefine-sym _binary____fpga_fpga_lf_bit_end=_binary_fpga_lf_bit_end --prefix-sections=fpga_lf_bit $^ $@
$(OBJDIR)/fullimage.elf: $(VERSIONOBJ) $(OBJDIR)/fpga.o $(THUMBOBJ) $(ARMOBJ)
$(OBJDIR)/fpga_hf.o: fpga_hf.bit
$(OBJCOPY) -O elf32-littlearm -I binary -B arm --redefine-sym _binary____fpga_fpga_hf_bit_start=_binary_fpga_hf_bit_start --redefine-sym _binary____fpga_fpga_hf_bit_end=_binary_fpga_hf_bit_end --prefix-sections=fpga_hf_bit $^ $@
$(OBJDIR)/fullimage.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_lf.o $(OBJDIR)/fpga_hf.o $(THUMBOBJ) $(ARMOBJ)
$(CC) $(LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS)
$(OBJDIR)/fpgaimage.elf: $(OBJDIR)/fullimage.elf

View file

@ -214,7 +214,8 @@ void MeasureAntennaTuning(void)
* ( hopefully around 95 if it is tuned to 125kHz!)
*/
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
for (i=255; i>19; i--) {
WDT_HIT();
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
@ -236,6 +237,7 @@ void MeasureAntennaTuning(void)
LED_A_ON();
// Let the FPGA drive the high-frequency antenna around 13.56 MHz.
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
SpinDelay(20);
// Vref = 3300mV, and an 10:1 voltage divider on the input
@ -264,6 +266,7 @@ void MeasureAntennaTuningHf(void)
for (;;) {
// Let the FPGA drive the high-frequency antenna around 13.56 MHz.
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
SpinDelay(20);
// Vref = 3300mV, and an 10:1 voltage divider on the input
@ -286,6 +289,7 @@ void SimulateTagHfListen(void)
// We're using this mode just so that I can test it out; the simulated
// tag mode would work just as well and be simpler.
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | FPGA_HF_READER_RX_XCORR_SNOOP);
// We need to listen to the high-frequency, peak-detected path.
@ -336,7 +340,7 @@ extern struct version_information version_information;
extern char *_bootphase1_version_pointer, _flash_start, _flash_end;
void SendVersion(void)
{
char temp[48]; /* Limited data payload in USB packets */
char temp[256]; /* Limited data payload in USB packets */
DbpString("Prox/RFID mark3 RFID instrument");
/* Try to find the bootrom version information. Expect to find a pointer at
@ -365,6 +369,7 @@ void SendVersion(void)
void SamyRun()
{
DbpString("Stand-alone mode! No PC necessary.");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
// 3 possible options? no just 2 for now
#define OPTS 2
@ -633,6 +638,10 @@ void UsbPacketReceived(uint8_t *packet, int len)
case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
break;
case CMD_LF_SNOOP_RAW_ADC_SAMPLES:
SnoopLFRawAdcSamples(c->arg[0], c->arg[1]);
cmd_send(CMD_ACK,0,0,0,0,0);
break;
case CMD_HID_DEMOD_FSK:
CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag
break;
@ -853,11 +862,14 @@ void UsbPacketReceived(uint8_t *packet, int len)
SnoopIClass();
break;
case CMD_SIMULATE_TAG_ICLASS:
SimulateIClass(c->arg[0], c->d.asBytes);
SimulateIClass(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break;
case CMD_READER_ICLASS:
ReaderIClass(c->arg[0]);
break;
case CMD_READER_ICLASS_REPLAY:
ReaderIClass_Replay(c->arg[0], c->d.asBytes);
break;
#endif
case CMD_SIMULATE_TAG_HF_LISTEN:
@ -923,6 +935,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
break;
case CMD_SET_LF_DIVISOR:
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->arg[0]);
break;
@ -1017,7 +1030,8 @@ void __attribute__((noreturn)) AppMain(void)
AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
// Load the FPGA image, which we have stored in our flash.
FpgaDownloadAndGo();
// (the HF version by default)
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
StartTickCount();

View file

@ -59,7 +59,8 @@ void ToSendStuffBit(int b);
void ToSendReset(void);
void ListenReaderField(int limit);
void AcquireRawAdcSamples125k(int at134khz);
void DoAcquisition125k(void);
void SnoopLFRawAdcSamples(int divisor, int trigger_threshold);
void DoAcquisition125k(int trigger_threshold);
extern int ToSendMax;
extern uint8_t ToSend[];
extern uint32_t BigBuf[];
@ -67,7 +68,8 @@ extern uint32_t BigBuf[];
/// fpga.h
void FpgaSendCommand(uint16_t cmd, uint16_t v);
void FpgaWriteConfWord(uint8_t v);
void FpgaDownloadAndGo(void);
void FpgaDownloadAndGo(int bitstream_version);
int FpgaGatherBitstreamVersion();
void FpgaGatherVersion(char *dst, int len);
void FpgaSetupSsc(void);
void SetupSpi(int mode);
@ -77,31 +79,40 @@ bool FpgaSetupSscDma(uint8_t *buf, int len);
void SetAdcMuxFor(uint32_t whichGpio);
// Definitions for the FPGA commands.
#define FPGA_CMD_SET_CONFREG (1<<12)
#define FPGA_CMD_SET_DIVISOR (2<<12)
#define FPGA_CMD_SET_CONFREG (1<<12)
#define FPGA_CMD_SET_DIVISOR (2<<12)
#define FPGA_CMD_SET_USER_BYTE1 (3<<12)
// Definitions for the FPGA configuration word.
#define FPGA_MAJOR_MODE_LF_READER (0<<5)
#define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<5)
#define FPGA_MAJOR_MODE_HF_READER_TX (2<<5)
#define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (3<<5)
#define FPGA_MAJOR_MODE_HF_SIMULATOR (4<<5)
#define FPGA_MAJOR_MODE_HF_ISO14443A (5<<5)
#define FPGA_MAJOR_MODE_LF_PASSTHRU (6<<5)
#define FPGA_MAJOR_MODE_OFF (7<<5)
// LF
#define FPGA_MAJOR_MODE_LF_ADC (0<<5)
#define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<5)
#define FPGA_MAJOR_MODE_LF_PASSTHRU (2<<5)
// HF
#define FPGA_MAJOR_MODE_HF_READER_TX (0<<5)
#define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (1<<5)
#define FPGA_MAJOR_MODE_HF_SIMULATOR (2<<5)
#define FPGA_MAJOR_MODE_HF_ISO14443A (3<<5)
// BOTH
#define FPGA_MAJOR_MODE_OFF (7<<5)
// Options for LF_ADC
#define FPGA_LF_ADC_READER_FIELD (1<<0)
// Options for LF_EDGE_DETECT
#define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD FPGA_CMD_SET_USER_BYTE1
#define FPGA_LF_EDGE_DETECT_READER_FIELD (1<<0)
#define FPGA_LF_EDGE_DETECT_TOGGLE_MODE (1<<1)
// Options for the HF reader, tx to tag
#define FPGA_HF_READER_TX_SHALLOW_MOD (1<<0)
// Options for the HF reader, correlating against rx from tag
#define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0)
#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1)
#define FPGA_HF_READER_RX_XCORR_QUARTER_FREQ (1<<2)
#define FPGA_HF_READER_RX_XCORR_QUARTER_FREQ (1<<2)
// Options for the HF simulated tag, how to modulate
#define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0)
#define FPGA_HF_SIMULATOR_MODULATE_BPSK (1<<0)
#define FPGA_HF_SIMULATOR_MODULATE_212K (2<<0)
#define FPGA_HF_SIMULATOR_MODULATE_424K (4<<0)
// Options for ISO14443A
#define FPGA_HF_ISO14443A_SNIFFER (0<<0)
#define FPGA_HF_ISO14443A_SNIFFER (0<<0)
#define FPGA_HF_ISO14443A_TAGSIM_LISTEN (1<<0)
#define FPGA_HF_ISO14443A_TAGSIM_MOD (2<<0)
#define FPGA_HF_ISO14443A_READER_LISTEN (3<<0)
@ -146,7 +157,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param);
void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data);
void ReaderIso14443a(UsbCommand * c);
// Also used in iclass.c
bool RAMFUNC LogTrace(const uint8_t * btBytes, uint8_t iLen, uint32_t iSamples, uint32_t dwParity, bool bReader);
bool RAMFUNC LogTrace(const uint8_t * btBytes, uint8_t iLen, uint32_t iSamples, uint32_t dwParity, bool readerToTag);
uint32_t GetParity(const uint8_t * pbtCmd, int iLen);
void iso14a_set_trigger(bool enable);
void iso14a_clear_trace();
@ -188,8 +199,10 @@ void SetDebugIso15693(uint32_t flag);
/// iclass.h
void RAMFUNC SnoopIClass(void);
void SimulateIClass(uint8_t arg0, uint8_t *datain);
void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void ReaderIClass(uint8_t arg0);
void ReaderIClass_Replay(uint8_t arg0,uint8_t *MAC);
void IClass_iso14443A_GetPublic(uint8_t arg0);
// hitag2.h
void SnoopHitag(uint32_t type);

View file

@ -1,5 +1,6 @@
//-----------------------------------------------------------------------------
// Jonathan Westhues, April 2006
// iZsh <izsh at fail0verflow.com>, 2014
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
@ -8,7 +9,6 @@
// Routines to load the FPGA image, and then to configure the FPGA's major
// mode once it is configured.
//-----------------------------------------------------------------------------
#include "proxmark3.h"
#include "apps.h"
#include "util.h"
@ -252,7 +252,7 @@ static void DownloadFPGA(const char *FpgaImage, int FpgaImageLen, int byterevers
static char *bitparse_headers_start;
static char *bitparse_bitstream_end;
static int bitparse_initialized;
static int bitparse_initialized = 0;
/* Simple Xilinx .bit parser. The file starts with the fixed opaque byte sequence
* 00 09 0f f0 0f f0 0f f0 0f f0 00 00 01
* After that the format is 1 byte section type (ASCII character), 2 byte length
@ -322,12 +322,28 @@ int bitparse_find_section(char section_name, char **section_start, unsigned int
// Find out which FPGA image format is stored in flash, then call DownloadFPGA
// with the right parameters to download the image
//-----------------------------------------------------------------------------
extern char _binary_fpga_bit_start, _binary_fpga_bit_end;
void FpgaDownloadAndGo(void)
extern char _binary_fpga_lf_bit_start, _binary_fpga_lf_bit_end;
extern char _binary_fpga_hf_bit_start, _binary_fpga_hf_bit_end;
void FpgaDownloadAndGo(int bitstream_version)
{
void *bit_start;
void *bit_end;
// check whether or not the bitstream is already loaded
if (FpgaGatherBitstreamVersion() == bitstream_version)
return;
if (bitstream_version == FPGA_BITSTREAM_LF) {
bit_start = &_binary_fpga_lf_bit_start;
bit_end = &_binary_fpga_lf_bit_end;
} else if (bitstream_version == FPGA_BITSTREAM_HF) {
bit_start = &_binary_fpga_hf_bit_start;
bit_end = &_binary_fpga_hf_bit_end;
} else
return;
/* Check for the new flash image format: Should have the .bit file at &_binary_fpga_bit_start
*/
if(bitparse_init(&_binary_fpga_bit_start, &_binary_fpga_bit_end)) {
if(bitparse_init(bit_start, bit_end)) {
/* Successfully initialized the .bit parser. Find the 'e' section and
* send its contents to the FPGA.
*/
@ -351,6 +367,17 @@ void FpgaDownloadAndGo(void)
DownloadFPGA((char*)0x102000, 10524*4, 1);
}
int FpgaGatherBitstreamVersion()
{
char temp[256];
FpgaGatherVersion(temp, sizeof (temp));
if (!memcmp("LF", temp, 2))
return FPGA_BITSTREAM_LF;
else if (!memcmp("HF", temp, 2))
return FPGA_BITSTREAM_HF;
return FPGA_BITSTREAM_ERR;
}
void FpgaGatherVersion(char *dst, int len)
{
char *fpga_info;
@ -359,13 +386,15 @@ void FpgaGatherVersion(char *dst, int len)
if(!bitparse_find_section('e', &fpga_info, &fpga_info_len)) {
strncat(dst, "FPGA image: legacy image without version information", len-1);
} else {
strncat(dst, "FPGA image built", len-1);
/* USB packets only have 48 bytes data payload, so be terse */
#if 0
if(bitparse_find_section('a', &fpga_info, &fpga_info_len) && fpga_info[fpga_info_len-1] == 0 ) {
strncat(dst, " from ", len-1);
strncat(dst, fpga_info, len-1);
if (!memcmp("fpga_lf", fpga_info, 7))
strncat(dst, "LF ", len-1);
else if (!memcmp("fpga_hf", fpga_info, 7))
strncat(dst, "HF ", len-1);
}
strncat(dst, "FPGA image built", len-1);
#if 0
if(bitparse_find_section('b', &fpga_info, &fpga_info_len) && fpga_info[fpga_info_len-1] == 0 ) {
strncat(dst, " for ", len-1);
strncat(dst, fpga_info, len-1);

View file

@ -743,6 +743,7 @@ void SnoopHitag(uint32_t type) {
// Set up eavesdropping mode, frequency divisor which will drive the FPGA
// and analog mux selection.
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
@ -966,6 +967,7 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
// Set up simulator mode, frequency divisor which will drive the FPGA
// and analog mux selection.
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
@ -1124,6 +1126,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
bool bStop;
bool bQuitTraceFull = false;
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
// Reset the return status
bSuccessful = false;

View file

@ -41,24 +41,15 @@
#include "util.h"
#include "string.h"
#include "common.h"
#include "cmd.h"
// Needed for CRC in emulation mode;
// same construction as in ISO 14443;
// different initial value (CRC_ICLASS)
#include "iso14443crc.h"
#include "iso15693tools.h"
static int timeout = 4096;
// CARD TO READER
// Sequence D: 11110000 modulation with subcarrier during first half
// Sequence E: 00001111 modulation with subcarrier during second half
// Sequence F: 00000000 no modulation with subcarrier
// READER TO CARD
// Sequence X: 00001100 drop after half a period
// Sequence Y: 00000000 no drop
// Sequence Z: 11000000 drop at start
#define SEC_X 0x0c
#define SEC_Y 0x00
#define SEC_Z 0xc0
static int SendIClassAnswer(uint8_t *resp, int respLen, int delay);
@ -666,12 +657,7 @@ static RAMFUNC int ManchesterDecoding(int v)
//-----------------------------------------------------------------------------
void RAMFUNC SnoopIClass(void)
{
// DEFINED ABOVE
// #define RECV_CMD_OFFSET 3032
// #define RECV_RES_OFFSET 3096
// #define DMA_BUFFER_OFFSET 3160
// #define DMA_BUFFER_SIZE 4096
// #define TRACE_SIZE 3000
// 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
@ -681,14 +667,12 @@ void RAMFUNC SnoopIClass(void)
// The command (reader -> tag) that we're receiving.
// The length of a received command will in most cases be no more than 18 bytes.
// So 32 should be enough!
uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
uint8_t *readerToTagCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
// The response (tag -> reader) that we're receiving.
uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RES_OFFSET);
uint8_t *tagToReaderResponse = (((uint8_t *)BigBuf) + RECV_RES_OFFSET);
// As we receive stuff, we copy it from receivedCmd or receivedResponse
// into trace, along with its length and other annotations.
//uint8_t *trace = (uint8_t *)BigBuf;
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// reset traceLen to 0
iso14a_set_tracing(TRUE);
iso14a_clear_trace();
@ -706,10 +690,8 @@ void RAMFUNC SnoopIClass(void)
int samples = 0;
rsamples = 0;
memset(trace, 0x44, RECV_CMD_OFFSET);
// Set up the demodulator for tag -> reader responses.
Demod.output = receivedResponse;
Demod.output = tagToReaderResponse;
Demod.len = 0;
Demod.state = DEMOD_UNSYNCD;
@ -721,7 +703,7 @@ void RAMFUNC SnoopIClass(void)
// And the reader -> tag commands
memset(&Uart, 0, sizeof(Uart));
Uart.output = receivedCmd;
Uart.output = readerToTagCmd;
Uart.byteCntMax = 32; // was 100 (greg)////////////////////////////////////////////////////////////////////////
Uart.state = STATE_UNSYNCD;
@ -731,6 +713,9 @@ void RAMFUNC SnoopIClass(void)
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER);
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
uint32_t time_0 = GetCountSspClk();
int div = 0;
//int div2 = 0;
int decbyte = 0;
@ -764,20 +749,13 @@ void RAMFUNC SnoopIClass(void)
//samples += 4;
samples += 1;
//div2++;
//if(div2 > 3) {
//div2 = 0;
//decbyte ^= ((smpl & 0x01) << (3 - div));
//decbyte ^= (((smpl & 0x01) | ((smpl & 0x02) >> 1)) << (3 - div)); // better already...
//decbyte ^= (((smpl & 0x01) | ((smpl & 0x02) >> 1) | ((smpl & 0x04) >> 2)) << (3 - div)); // even better...
if(smpl & 0xF) {
decbyte ^= (1 << (3 - div));
}
//decbyte ^= (MajorityNibble[(smpl & 0x0F)] << (3 - div));
// FOR READER SIDE COMMUMICATION...
//decbyte ^= ((smpl & 0x10) << (3 - div));
decbyter <<= 2;
decbyter ^= (smpl & 0x30);
@ -788,21 +766,17 @@ void RAMFUNC SnoopIClass(void)
if(OutOfNDecoding((smpl & 0xF0) >> 4)) {
rsamples = samples - Uart.samples;
LED_C_ON();
//if(triggered) {
trace[traceLen++] = ((rsamples >> 0) & 0xff);
trace[traceLen++] = ((rsamples >> 8) & 0xff);
trace[traceLen++] = ((rsamples >> 16) & 0xff);
trace[traceLen++] = ((rsamples >> 24) & 0xff);
trace[traceLen++] = ((Uart.parityBits >> 0) & 0xff);
trace[traceLen++] = ((Uart.parityBits >> 8) & 0xff);
trace[traceLen++] = ((Uart.parityBits >> 16) & 0xff);
trace[traceLen++] = ((Uart.parityBits >> 24) & 0xff);
trace[traceLen++] = Uart.byteCnt;
memcpy(trace+traceLen, receivedCmd, Uart.byteCnt);
traceLen += Uart.byteCnt;
if(traceLen > TRACE_SIZE) break;
//}
/* And ready to receive another command. */
//if(!LogTrace(Uart.output,Uart.byteCnt, rsamples, Uart.parityBits,TRUE)) break;
//if(!LogTrace(NULL, 0, Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, 0, TRUE)) break;
if(tracing)
{
LogTrace(Uart.output,Uart.byteCnt, (GetCountSspClk()-time_0) << 4, Uart.parityBits,TRUE);
LogTrace(NULL, 0, (GetCountSspClk()-time_0) << 4, 0, TRUE);
}
/* 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. */
@ -819,26 +793,16 @@ void RAMFUNC SnoopIClass(void)
rsamples = samples - Demod.samples;
LED_B_ON();
// timestamp, as a count of samples
trace[traceLen++] = ((rsamples >> 0) & 0xff);
trace[traceLen++] = ((rsamples >> 8) & 0xff);
trace[traceLen++] = ((rsamples >> 16) & 0xff);
trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);
// length
trace[traceLen++] = Demod.len;
memcpy(trace+traceLen, receivedResponse, Demod.len);
traceLen += Demod.len;
if(traceLen > TRACE_SIZE) break;
if(tracing)
{
LogTrace(Demod.output,Demod.len, (GetCountSspClk()-time_0) << 4 , Demod.parityBits,FALSE);
LogTrace(NULL, 0, (GetCountSspClk()-time_0) << 4, 0, FALSE);
}
//triggered = TRUE;
// And ready to receive another response.
memset(&Demod, 0, sizeof(Demod));
Demod.output = receivedResponse;
Demod.output = tagToReaderResponse;
Demod.state = DEMOD_UNSYNCD;
LED_C_OFF();
}
@ -922,6 +886,8 @@ static int GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen)
//-----------------------------------------------------------------------------
static void CodeIClassTagAnswer(const uint8_t *cmd, int len)
{
//So far a dummy implementation, not used
//int lastProxToAirDuration =0;
int i;
ToSendReset();
@ -930,7 +896,7 @@ static void CodeIClassTagAnswer(const uint8_t *cmd, int len)
ToSend[++ToSendMax] = 0x00;
ToSend[++ToSendMax] = 0x00;
ToSend[++ToSendMax] = 0x00;
ToSend[++ToSendMax] = 0xff;
ToSend[++ToSendMax] = 0xff;//Proxtoair duration starts here
ToSend[++ToSendMax] = 0xff;
ToSend[++ToSendMax] = 0xff;
ToSend[++ToSendMax] = 0x00;
@ -958,11 +924,13 @@ static void CodeIClassTagAnswer(const uint8_t *cmd, int len)
ToSend[++ToSendMax] = 0x00;
ToSend[++ToSendMax] = 0xff;
ToSend[++ToSendMax] = 0xff;
ToSend[++ToSendMax] = 0xff;
ToSend[++ToSendMax] = 0xff;
ToSend[++ToSendMax] = 0x00;
ToSend[++ToSendMax] = 0x00;
ToSend[++ToSendMax] = 0x00;
//lastProxToAirDuration = 8*ToSendMax - 3*8 - 3*8;//Not counting zeroes in the beginning or end
// Convert from last byte pos to length
ToSendMax++;
}
@ -970,8 +938,10 @@ static void CodeIClassTagAnswer(const uint8_t *cmd, int len)
// Only SOF
static void CodeIClassTagSOF()
{
ToSendReset();
//So far a dummy implementation, not used
//int lastProxToAirDuration =0;
ToSendReset();
// Send SOF
ToSend[++ToSendMax] = 0x00;
ToSend[++ToSendMax] = 0x00;
@ -981,37 +951,92 @@ static void CodeIClassTagSOF()
ToSend[++ToSendMax] = 0xff;
ToSend[++ToSendMax] = 0x00;
ToSend[++ToSendMax] = 0xff;
// lastProxToAirDuration = 8*ToSendMax - 3*8;//Not counting zeroes in the beginning
// Convert from last byte pos to length
ToSendMax++;
}
//-----------------------------------------------------------------------------
// Simulate iClass Card
// Only CSN (Card Serial Number)
//
//-----------------------------------------------------------------------------
void SimulateIClass(uint8_t arg0, uint8_t *datain)
int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader_mac_buf);
/**
* @brief SimulateIClass simulates an iClass card.
* @param arg0 type of simulation
* - 0 uses the first 8 bytes in usb data as CSN
* - 2 "dismantling iclass"-attack. This mode iterates through all CSN's specified
* in the usb data. This mode collects MAC from the reader, in order to do an offline
* attack on the keys. For more info, see "dismantling iclass" and proxclone.com.
* - Other : Uses the default CSN (031fec8af7ff12e0)
* @param arg1 - number of CSN's contained in datain (applicable for mode 2 only)
* @param arg2
* @param datain
*/
void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
{
uint32_t simType = arg0;
uint32_t numberOfCSNS = arg1;
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Enable and clear the trace
iso14a_set_tracing(TRUE);
iso14a_clear_trace();
uint8_t csn_crc[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 };
if(simType == 0) {
// Use the CSN from commandline
memcpy(csn_crc, datain, 8);
doIClassSimulation(csn_crc,0,NULL);
}else if(simType == 1)
{
doIClassSimulation(csn_crc,0,NULL);
}
else if(simType == 2)
{
uint8_t mac_responses[64] = { 0 };
Dbprintf("Going into attack mode");
// In this mode, a number of csns are within datain. We'll simulate each one, one at a time
// in order to collect MAC's from the reader. This can later be used in an offlne-attack
// in order to obtain the keys, as in the "dismantling iclass"-paper.
int i = 0;
for( ; i < numberOfCSNS && i*8+8 < USB_CMD_DATA_SIZE; i++)
{
// The usb data is 512 bytes, fitting 65 8-byte CSNs in there.
memcpy(csn_crc, datain+(i*8), 8);
if(doIClassSimulation(csn_crc,1,mac_responses))
{
return; // Button pressed
}
}
cmd_send(CMD_ACK,CMD_SIMULATE_TAG_ICLASS,i,0,mac_responses,i*8);
}
else{
// We may want a mode here where we hardcode the csns to use (from proxclone).
// That will speed things up a little, but not required just yet.
Dbprintf("The mode is not implemented, reserved for future use");
}
Dbprintf("Done...");
}
/**
* @brief Does the actual simulation
* @param csn - csn to use
* @param breakAfterMacReceived if true, returns after reader MAC has been received.
*/
int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader_mac_buf)
{
uint8_t simType = arg0;
// Enable and clear the trace
tracing = TRUE;
traceLen = 0;
memset(trace, 0x44, TRACE_SIZE);
// CSN followed by two CRC bytes
uint8_t response2[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t response3[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 };
uint8_t response3[] = { 0,0,0,0,0,0,0,0,0,0};
memcpy(response3,csn,sizeof(response3));
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]);
// e-Purse
uint8_t response4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
if(simType == 0) {
// Use the CSN from commandline
memcpy(response3, datain, 8);
}
// Construct anticollision-CSN
rotateCSN(response3,response2);
@ -1019,6 +1044,7 @@ void SimulateIClass(uint8_t arg0, uint8_t *datain)
ComputeCrc14443(CRC_ICLASS, response2, 8, &response2[8], &response2[9]);
ComputeCrc14443(CRC_ICLASS, response3, 8, &response3[8], &response3[9]);
int exitLoop = 0;
// Reader 0a
// Tag 0f
// Reader 0c
@ -1052,7 +1078,7 @@ void SimulateIClass(uint8_t arg0, uint8_t *datain)
int resp4Len;
// + 1720..
uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
memset(receivedCmd, 0x44, RECV_CMD_SIZE);
int len;
@ -1075,29 +1101,52 @@ void SimulateIClass(uint8_t arg0, uint8_t *datain)
CodeIClassTagAnswer(response4, sizeof(response4));
memcpy(resp4, ToSend, ToSendMax); resp4Len = ToSendMax;
// Start from off (no field generated)
//FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
//SpinDelay(200);
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN);
SpinDelay(100);
StartCountSspClk();
// We need to listen to the high-frequency, peak-detected path.
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
FpgaSetupSsc();
// To control where we are in the protocol
int cmdsRecvd = 0;
uint32_t time_0 = GetCountSspClk();
uint32_t t2r_time =0;
uint32_t r2t_time =0;
LED_A_ON();
for(;;) {
bool buttonPressed = false;
/** Hack for testing
memcpy(reader_mac_buf,csn,8);
exitLoop = true;
end hack **/
while(!exitLoop) {
LED_B_OFF();
//Signal tracer
// Can be used to get a trigger for an oscilloscope..
LED_C_OFF();
if(!GetIClassCommandFromReader(receivedCmd, &len, 100)) {
DbpString("button press");
buttonPressed = true;
break;
}
r2t_time = GetCountSspClk();
//Signal tracer
LED_C_ON();
// Okay, look at the command now.
if(receivedCmd[0] == 0x0a) {
if(receivedCmd[0] == 0x0a ) {
// Reader in anticollission phase
resp = resp1; respLen = resp1Len; //order = 1;
respdata = &sof;
respsize = sizeof(sof);
//resp = resp2; respLen = resp2Len; order = 2;
//DbpString("Hello request from reader:");
} else if(receivedCmd[0] == 0x0c) {
// Reader asks for anticollission CSN
resp = resp2; respLen = resp2Len; //order = 2;
@ -1119,30 +1168,31 @@ void SimulateIClass(uint8_t arg0, uint8_t *datain)
LED_B_ON();
} else if(receivedCmd[0] == 0x05) {
// Reader random and reader MAC!!!
// Lets store this ;-)
/*
Dbprintf(" CSN: %02x %02x %02x %02x %02x %02x %02x %02x",
response3[0], response3[1], response3[2],
response3[3], response3[4], response3[5],
response3[6], response3[7]);
*/
Dbprintf("READER AUTH (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]);
// Do not respond
// We do not know what to answer, so lets keep quit
// We do not know what to answer, so lets keep quiet
resp = resp1; respLen = 0; //order = 5;
respdata = NULL;
respsize = 0;
if (breakAfterMacReceived){
// 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;
}
} else if(receivedCmd[0] == 0x00 && len == 1) {
// Reader ends the session
resp = resp1; respLen = 0; //order = 0;
respdata = NULL;
respsize = 0;
} 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",
len,
@ -1155,9 +1205,9 @@ void SimulateIClass(uint8_t arg0, uint8_t *datain)
respsize = 0;
}
if(cmdsRecvd > 999) {
DbpString("1000 commands later...");
break;
if(cmdsRecvd > 100) {
//DbpString("100 commands later...");
//break;
}
else {
cmdsRecvd++;
@ -1165,64 +1215,68 @@ void SimulateIClass(uint8_t arg0, uint8_t *datain)
if(respLen > 0) {
SendIClassAnswer(resp, respLen, 21);
}
if (tracing) {
LogTrace(receivedCmd,len, rsamples, Uart.parityBits, TRUE);
if (respdata != NULL) {
LogTrace(respdata,respsize, rsamples, SwapBits(GetParity(respdata,respsize),respsize), FALSE);
}
if(traceLen > TRACE_SIZE) {
DbpString("Trace full");
break;
}
t2r_time = GetCountSspClk();
}
if (tracing) {
LogTrace(receivedCmd,len, (r2t_time-time_0)<< 4, Uart.parityBits,TRUE);
LogTrace(NULL,0, (r2t_time-time_0) << 4, 0,TRUE);
if (respdata != NULL) {
LogTrace(respdata,respsize, (t2r_time-time_0) << 4,SwapBits(GetParity(respdata,respsize),respsize),FALSE);
LogTrace(NULL,0, (t2r_time-time_0) << 4,0,FALSE);
}
if(!tracing) {
DbpString("Trace full");
//break;
}
}
memset(receivedCmd, 0x44, RECV_CMD_SIZE);
}
Dbprintf("%x", cmdsRecvd);
//Dbprintf("%x", cmdsRecvd);
LED_A_OFF();
LED_B_OFF();
if(buttonPressed)
{
DbpString("Button pressed");
}
return buttonPressed;
}
static int SendIClassAnswer(uint8_t *resp, int respLen, int delay)
{
int i = 0, u = 0, d = 0;
int i = 0, d=0;//, u = 0, d = 0;
uint8_t b = 0;
// return 0;
// Modulate Manchester
// FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD424);
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD);
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR|FPGA_HF_SIMULATOR_MODULATE_424K);
AT91C_BASE_SSC->SSC_THR = 0x00;
FpgaSetupSsc();
// send cycle
for(;;) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
volatile uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
(void)b;
while(!BUTTON_PRESS()) {
if((AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)){
b = AT91C_BASE_SSC->SSC_RHR; (void) b;
}
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)){
b = 0x00;
if(d < delay) {
b = 0x00;
d++;
}
else if(i >= respLen) {
b = 0x00;
u++;
} else {
b = resp[i];
u++;
if(u > 1) { i++; u = 0; }
else {
if( i < respLen){
b = resp[i];
//Hack
//b = 0xAC;
}
i++;
}
AT91C_BASE_SSC->SSC_THR = b;
}
if(u > 4) break;
}
if(BUTTON_PRESS()) {
break;
}
if (i > respLen +4) break;
}
return 0;
@ -1236,7 +1290,6 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, int delay)
static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int *wait)
{
int c;
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
AT91C_BASE_SSC->SSC_THR = 0x00;
FpgaSetupSsc();
@ -1312,12 +1365,12 @@ void CodeIClassCommand(const uint8_t * cmd, int len)
b = cmd[i];
for(j = 0; j < 4; j++) {
for(k = 0; k < 4; k++) {
if(k == (b & 3)) {
ToSend[++ToSendMax] = 0x0f;
}
else {
ToSend[++ToSendMax] = 0x00;
}
if(k == (b & 3)) {
ToSend[++ToSendMax] = 0x0f;
}
else {
ToSend[++ToSendMax] = 0x00;
}
}
b >>= 2;
}
@ -1413,36 +1466,138 @@ int ReaderReceiveIClass(uint8_t* receivedAnswer)
return Demod.len;
}
void setupIclassReader()
{
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Reset trace buffer
iso14a_set_tracing(TRUE);
iso14a_clear_trace();
// Setup SSC
FpgaSetupSsc();
// Start from off (no field generated)
// Signal field is off with the appropriate LED
LED_D_OFF();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelay(200);
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
// Now give it time to spin up.
// Signal field is on with the appropriate LED
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
SpinDelay(200);
LED_A_ON();
}
// Reader iClass Anticollission
void ReaderIClass(uint8_t arg0) {
uint8_t act_all[] = { 0x0a };
uint8_t identify[] = { 0x0c };
uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t readcheck_cc[]= { 0x88, 0x02 };
uint8_t card_data[24]={0};
uint8_t last_csn[8]={0};
uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes
int read_status= 0;
bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
setupIclassReader();
size_t datasize = 0;
while(!BUTTON_PRESS())
{
WDT_HIT();
// Send act_all
ReaderTransmitIClass(act_all, 1);
// Card present?
if(ReaderReceiveIClass(resp)) {
ReaderTransmitIClass(identify, 1);
if(ReaderReceiveIClass(resp) == 10) {
//Copy the Anti-collision CSN to our select-packet
memcpy(&select[1],resp,8);
//Dbprintf("Anti-collision CSN: %02x %02x %02x %02x %02x %02x %02x %02x",resp[0], resp[1], resp[2],
// resp[3], resp[4], resp[5],
// resp[6], resp[7]);
//Select the card
ReaderTransmitIClass(select, sizeof(select));
if(ReaderReceiveIClass(resp) == 10) {
//Save CSN in response data
memcpy(card_data,resp,8);
datasize += 8;
//Flag that we got to at least stage 1, read CSN
read_status = 1;
// Card selected
//Dbprintf("Readcheck on Sector 2");
ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc));
if(ReaderReceiveIClass(resp) == 8) {
//Save CC (e-purse) in response data
memcpy(card_data+8,resp,8);
datasize += 8;
//Got both
read_status = 2;
}
LED_B_ON();
//Send back to client, but don't bother if we already sent this
if(memcmp(last_csn, card_data, 8) != 0)
cmd_send(CMD_ACK,read_status,0,0,card_data,datasize);
//Save that we already sent this....
if(read_status == 2)
memcpy(last_csn, card_data, 8);
LED_B_OFF();
if(abort_after_read) break;
}
}
}
if(traceLen > TRACE_SIZE) {
DbpString("Trace full");
break;
}
}
LED_A_OFF();
}
void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
uint8_t act_all[] = { 0x0a };
uint8_t identify[] = { 0x0c };
uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t readcheck_cc[]= { 0x88, 0x02 };
uint8_t check[] = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t read[] = { 0x0c, 0x00, 0x00, 0x00 };
uint16_t crc = 0;
uint8_t cardsize=0;
bool read_success=false;
uint8_t mem=0;
static struct memory_t{
int k16;
int book;
int k2;
int lockauth;
int keyaccess;
} memory;
uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes
// Reset trace buffer
memset(trace, 0x44, RECV_CMD_OFFSET);
traceLen = 0;
setupIclassReader();
// Setup SSC
FpgaSetupSsc();
// Start from off (no field generated)
// Signal field is off with the appropriate LED
LED_D_OFF();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelay(200);
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
// Now give it time to spin up.
// Signal field is on with the appropriate LED
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
SpinDelay(200);
LED_A_ON();
for(;;) {
for(int i=0;i<1;i++) {
if(traceLen > TRACE_SIZE) {
DbpString("Trace full");
@ -1467,7 +1622,72 @@ void ReaderIClass(uint8_t arg0) {
resp[3], resp[4], resp[5],
resp[6], resp[7]);
}
// Card selected, whats next... ;-)
// Card selected
Dbprintf("Readcheck on Sector 2");
ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc));
if(ReaderReceiveIClass(resp) == 8) {
Dbprintf(" CC: %02x %02x %02x %02x %02x %02x %02x %02x",
resp[0], resp[1], resp[2],
resp[3], resp[4], resp[5],
resp[6], resp[7]);
}else return;
Dbprintf("Authenticate");
//for now replay captured auth (as cc not updated)
memcpy(check+5,MAC,4);
//Dbprintf(" AA: %02x %02x %02x %02x",
// check[5], check[6], check[7],check[8]);
ReaderTransmitIClass(check, sizeof(check));
if(ReaderReceiveIClass(resp) == 4) {
Dbprintf(" AR: %02x %02x %02x %02x",
resp[0], resp[1], resp[2],resp[3]);
}else {
Dbprintf("Error: Authentication Fail!");
return;
}
Dbprintf("Dump Contents");
//first get configuration block
read_success=false;
read[1]=1;
uint8_t *blockno=&read[1];
crc = iclass_crc16((char *)blockno,1);
read[2] = crc >> 8;
read[3] = crc & 0xff;
while(!read_success){
ReaderTransmitIClass(read, sizeof(read));
if(ReaderReceiveIClass(resp) == 10) {
read_success=true;
mem=resp[5];
memory.k16= (mem & 0x80);
memory.book= (mem & 0x20);
memory.k2= (mem & 0x8);
memory.lockauth= (mem & 0x2);
memory.keyaccess= (mem & 0x1);
}
}
if (memory.k16){
cardsize=255;
}else cardsize=32;
//then loop around remaining blocks
for(uint8_t j=0; j<cardsize; j++){
read_success=false;
uint8_t *blockno=&j;
//crc_data[0]=j;
read[1]=j;
crc = iclass_crc16((char *)blockno,1);
read[2] = crc >> 8;
read[3] = crc & 0xff;
while(!read_success){
ReaderTransmitIClass(read, sizeof(read));
if(ReaderReceiveIClass(resp) == 10) {
read_success=true;
Dbprintf(" %02x: %02x %02x %02x %02x %02x %02x %02x %02x",
j, resp[0], resp[1], resp[2],
resp[3], resp[4], resp[5],
resp[6], resp[7]);
}
}
}
}
}
WDT_HIT();
@ -1476,4 +1696,130 @@ void ReaderIClass(uint8_t arg0) {
LED_A_OFF();
}
//2. Create Read method (cut-down from above) based off responses from 1.
// Since we have the MAC could continue to use replay function.
//3. Create Write method
/*
void IClass_iso14443A_write(uint8_t arg0, uint8_t blockNo, uint8_t *data, uint8_t *MAC) {
uint8_t act_all[] = { 0x0a };
uint8_t identify[] = { 0x0c };
uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t readcheck_cc[]= { 0x88, 0x02 };
uint8_t check[] = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t read[] = { 0x0c, 0x00, 0x00, 0x00 };
uint8_t write[] = { 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint16_t crc = 0;
uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes
// Reset trace buffer
memset(trace, 0x44, RECV_CMD_OFFSET);
traceLen = 0;
// Setup SSC
FpgaSetupSsc();
// Start from off (no field generated)
// Signal field is off with the appropriate LED
LED_D_OFF();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelay(200);
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
// Now give it time to spin up.
// Signal field is on with the appropriate LED
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
SpinDelay(200);
LED_A_ON();
for(int i=0;i<1;i++) {
if(traceLen > TRACE_SIZE) {
DbpString("Trace full");
break;
}
if (BUTTON_PRESS()) break;
// Send act_all
ReaderTransmitIClass(act_all, 1);
// Card present?
if(ReaderReceiveIClass(resp)) {
ReaderTransmitIClass(identify, 1);
if(ReaderReceiveIClass(resp) == 10) {
// Select card
memcpy(&select[1],resp,8);
ReaderTransmitIClass(select, sizeof(select));
if(ReaderReceiveIClass(resp) == 10) {
Dbprintf(" Selected CSN: %02x %02x %02x %02x %02x %02x %02x %02x",
resp[0], resp[1], resp[2],
resp[3], resp[4], resp[5],
resp[6], resp[7]);
}
// Card selected
Dbprintf("Readcheck on Sector 2");
ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc));
if(ReaderReceiveIClass(resp) == 8) {
Dbprintf(" CC: %02x %02x %02x %02x %02x %02x %02x %02x",
resp[0], resp[1], resp[2],
resp[3], resp[4], resp[5],
resp[6], resp[7]);
}else return;
Dbprintf("Authenticate");
//for now replay captured auth (as cc not updated)
memcpy(check+5,MAC,4);
Dbprintf(" AA: %02x %02x %02x %02x",
check[5], check[6], check[7],check[8]);
ReaderTransmitIClass(check, sizeof(check));
if(ReaderReceiveIClass(resp) == 4) {
Dbprintf(" AR: %02x %02x %02x %02x",
resp[0], resp[1], resp[2],resp[3]);
}else {
Dbprintf("Error: Authentication Fail!");
return;
}
Dbprintf("Write Block");
//read configuration for max block number
read_success=false;
read[1]=1;
uint8_t *blockno=&read[1];
crc = iclass_crc16((char *)blockno,1);
read[2] = crc >> 8;
read[3] = crc & 0xff;
while(!read_success){
ReaderTransmitIClass(read, sizeof(read));
if(ReaderReceiveIClass(resp) == 10) {
read_success=true;
mem=resp[5];
memory.k16= (mem & 0x80);
memory.book= (mem & 0x20);
memory.k2= (mem & 0x8);
memory.lockauth= (mem & 0x2);
memory.keyaccess= (mem & 0x1);
}
}
if (memory.k16){
cardsize=255;
}else cardsize=32;
//check card_size
memcpy(write+1,blockNo,1);
memcpy(write+2,data,8);
memcpy(write+10,mac,4);
while(!send_success){
ReaderTransmitIClass(write, sizeof(write));
if(ReaderReceiveIClass(resp) == 10) {
write_success=true;
}
}//
}
WDT_HIT();
}
LED_A_OFF();
}*/

View file

@ -350,6 +350,7 @@ void SimulateIso14443Tag(void)
int cmdsRecvd = 0;
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
memset(receivedCmd, 0x44, 400);
CodeIso14443bAsTag(response1, sizeof(response1));
@ -867,6 +868,7 @@ void ReadSTMemoryIso14443(uint32_t dwLast)
{
uint8_t i = 0x00;
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Make sure that we start from off, since the tags are stateful;
// confusing things will happen if we don't reset them between reads.
LED_D_OFF();
@ -1011,6 +1013,7 @@ void RAMFUNC SnoopIso14443(void)
// response from the tag.
int triggered = TRUE;
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// The command (reader -> tag) that we're working on receiving.
uint8_t *receivedCmd = (uint8_t *)(BigBuf) + DEMOD_TRACE_SIZE;
// The response (tag -> reader) that we're working on receiving.
@ -1196,6 +1199,7 @@ done:
void SendRawCommand14443B(uint32_t datalen, uint32_t recv,uint8_t powerfield, uint8_t data[])
{
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
if(!powerfield)
{
// Make sure that we start from off, since the tags are stateful;

View file

@ -190,8 +190,9 @@ void AppendCrc14443a(uint8_t* data, int len)
}
// 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
@ -203,7 +204,8 @@ bool RAMFUNC LogTrace(const uint8_t * btBytes, uint8_t iLen, uint32_t timestamp,
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);
@ -505,6 +507,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
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
@ -1763,6 +1766,7 @@ int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, u
}
void iso14443a_setup(uint8_t fpga_minor_mode) {
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Set up the synchronous serial port
FpgaSetupSsc();
// connect Demodulated Signal to ADC:
@ -1858,6 +1862,7 @@ void ReaderIso14443a(UsbCommand *c)
if(param & ISO14A_APPEND_CRC) {
AppendCrc14443a(cmd,len);
len += 2;
if (lenbits) lenbits += 16;
}
if(lenbits>0) {
ReaderTransmitBitsPar(cmd,lenbits,GetParity(cmd,lenbits/8), NULL);
@ -2201,9 +2206,12 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
if (MF_DBGLEVEL >= 1) {
if (!_7BUID) {
Dbprintf("4B UID: %02x%02x%02x%02x",rUIDBCC1[0] , rUIDBCC1[1] , rUIDBCC1[2] , rUIDBCC1[3]);
Dbprintf("4B UID: %02x%02x%02x%02x",
rUIDBCC1[0], rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3]);
} else {
Dbprintf("7B UID: (%02x)%02x%02x%02x%02x%02x%02x%02x",rUIDBCC1[0] , rUIDBCC1[1] , rUIDBCC1[2] , rUIDBCC1[3],rUIDBCC2[0],rUIDBCC2[1] ,rUIDBCC2[2] , rUIDBCC2[3]);
Dbprintf("7B UID: (%02x)%02x%02x%02x%02x%02x%02x%02x",
rUIDBCC1[0], rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3],
rUIDBCC2[0], rUIDBCC2[1] ,rUIDBCC2[2], rUIDBCC2[3]);
}
}
@ -2271,7 +2279,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
// 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;
@ -2313,10 +2321,13 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
// test if auth OK
if (cardRr != prng_successor(nonce, 64)){
if (MF_DBGLEVEL >= 2) Dbprintf("AUTH FAILED. cardRr=%08x, succ=%08x",cardRr, prng_successor(nonce, 64));
if (MF_DBGLEVEL >= 2) Dbprintf("AUTH FAILED for sector %d with key %c. cardRr=%08x, succ=%08x",
cardAUTHSC, cardAUTHKEY == 0 ? 'A' : 'B',
cardRr, 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
// -- 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);
@ -2330,7 +2341,9 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
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:{
@ -2388,12 +2401,12 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
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);
}
@ -2424,9 +2437,9 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
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));
@ -2442,7 +2455,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
}
// 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);
@ -2458,7 +2471,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
}
// 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];
@ -2466,7 +2479,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
}
// 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));
@ -2484,7 +2497,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
}
// 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
@ -2619,7 +2632,8 @@ void RAMFUNC SniffMifare(uint8_t param) {
// 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.

View file

@ -606,6 +606,7 @@ void AcquireRawAdcSamplesIso15693(void)
int8_t prev = 0;
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
BuildIdentifyRequest();
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
@ -687,6 +688,7 @@ void RecordRawAdcSamplesIso15693(void)
int8_t prev = 0;
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Setup SSC
FpgaSetupSsc();
@ -753,6 +755,7 @@ void Iso15693InitReader() {
LED_C_OFF();
LED_D_OFF();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Setup SSC
// FpgaSetupSsc();
@ -1015,6 +1018,7 @@ void ReaderIso15693(uint32_t parameter)
// Blank arrays
memset(BigBuf + 3660, 0, 300);
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Setup SSC
FpgaSetupSsc();
@ -1165,6 +1169,7 @@ void SimTagIso15693(uint32_t parameter)
// Blank arrays
memset(answer1, 0, 100);
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Setup SSC
FpgaSetupSsc();

View file

@ -21,7 +21,8 @@ ENTRY(Vector)
SECTIONS
{
.fpgaimage : {
*(fpga_bit.data)
*(fpga_lf_bit.data)
*(fpga_hf_bit.data)
} >fpgaimage :fpgaimage
.start : {

View file

@ -310,6 +310,7 @@ static uint32_t perform_setup_phase_rwd(int iv)
}
static void LegicCommonInit(void) {
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
FpgaSetupSsc();
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
@ -687,6 +688,7 @@ void LegicRfSimulate(int phase, int frame, int reqresp)
legic_frame_drift = frame;
legic_reqresp_drift = reqresp;
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
FpgaSetupSsc();
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_212K);

View file

@ -16,7 +16,7 @@
#include "string.h"
// split into two routines so we can avoid timing issues after sending commands //
void DoAcquisition125k_internal(bool silent)
void DoAcquisition125k_internal(int trigger_threshold,bool silent)
{
uint8_t *dest = (uint8_t *)BigBuf;
int n = sizeof(BigBuf);
@ -31,25 +31,30 @@ void DoAcquisition125k_internal(bool silent)
}
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
i++;
LED_D_OFF();
if (i >= n) break;
if (trigger_threshold != -1 && dest[i] < trigger_threshold)
continue;
else
trigger_threshold = -1;
if (++i >= n) break;
}
}
if( ! silent)
if(!silent)
{
Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...",
dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
}
}
void DoAcquisition125k(void)
void DoAcquisition125k(int trigger_threshold)
{
DoAcquisition125k_internal(false);
DoAcquisition125k_internal(trigger_threshold, false);
}
void SetupToAcquireRawAdcSamples(int divisor)
//void SetupToAcquireRawAdcSamples(int divisor)
void LFSetupFPGAForADC(int divisor, bool lf_field)
{
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
if ( (divisor == 1) || (divisor < 0) || (divisor > 255) )
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
else if (divisor == 0)
@ -57,23 +62,29 @@ void SetupToAcquireRawAdcSamples(int divisor)
else
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0));
// Connect the A/D to the peak-detected low-frequency path.
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Give it a bit of time for the resonant antenna to settle.
SpinDelay(50);
// Now set up the SSC to get the ADC samples that are now streaming at us.
FpgaSetupSsc();
}
void AcquireRawAdcSamples125k(int divisor)
{
SetupToAcquireRawAdcSamples(divisor);
LFSetupFPGAForADC(divisor, true);
// Now call the acquisition routine
DoAcquisition125k_internal(false);
DoAcquisition125k_internal(-1,false);
}
void SnoopLFRawAdcSamples(int divisor, int trigger_threshold)
{
LFSetupFPGAForADC(divisor, false);
DoAcquisition125k(trigger_threshold, false);
}
}
void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command)
@ -81,6 +92,7 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1,
int at134khz;
/* Make sure the tag is reset */
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelay(2500);
@ -95,7 +107,7 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1,
else
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Give it a bit of time for the resonant antenna to settle.
SpinDelay(50);
@ -115,7 +127,7 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1,
else
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
LED_D_ON();
if(*(command++) == '0')
SpinDelayUs(period_0);
@ -130,10 +142,10 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1,
else
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// now do the read
DoAcquisition125k();
DoAcquisition125k(-1);
}
/* blank r/w tag data stream
@ -170,6 +182,7 @@ void ReadTItag(void)
uint32_t threshold = (sampleslo - sampleshi + 1)>>1;
// TI tags charge at 134.2Khz
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
// Place FPGA in passthrough mode, in this mode the CROSS_LO line
@ -377,6 +390,7 @@ void AcquireTiType(void)
// if not provided a valid crc will be computed from the data and written.
void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc)
{
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
if(crc == 0) {
crc = update_crc16(crc, (idlo)&0xff);
crc = update_crc16(crc, (idlo>>8)&0xff);
@ -448,6 +462,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
int i;
uint8_t *tab = (uint8_t *)BigBuf;
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK;
@ -615,7 +630,6 @@ size_t fsk_demod(uint8_t * dest, size_t size)
// threshold essentially we capture zero crossings for later analysis
uint8_t threshold_value = 127;
// sync to first lo-hi transition, and threshold
//Need to threshold first sample
@ -692,7 +706,7 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
while(!BUTTON_PRESS()) {
// Configure to go in 125Khz listen mode
SetupToAcquireRawAdcSamples(0);
LFSetupFPGAForADC(0, true)
WDT_HIT();
if (ledcontrol) LED_A_ON();
@ -788,7 +802,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
while(!BUTTON_PRESS()) {
// Configure to go in 125Khz listen mode
SetupToAcquireRawAdcSamples(0);
LFSetupFPGAForADC(0, true);
WDT_HIT();
if (ledcontrol) LED_A_ON();
@ -911,8 +925,9 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
// Write one bit to card
void T55xxWriteBit(int bit)
{
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
if (bit == 0)
SpinDelayUs(WRITE_0);
else
@ -926,8 +941,9 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod
{
unsigned int i;
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Give it a bit of time for the resonant antenna to settle.
// And for the tag to fully power up
@ -959,7 +975,7 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod
// Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550,
// so wait a little more)
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
SpinDelay(20);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
}
@ -970,6 +986,7 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
uint8_t *dest = (uint8_t *)BigBuf;
int m=0, i=0;
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
m = sizeof(BigBuf);
// Clear destination buffer before sending the command
memset(dest, 128, m);
@ -980,7 +997,7 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
LED_D_ON();
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Give it a bit of time for the resonant antenna to settle.
// And for the tag to fully power up
@ -1006,7 +1023,7 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
// Turn field on to read the response
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Now do the acquisition
i = 0;
@ -1034,6 +1051,7 @@ void T55xxReadTrace(void){
uint8_t *dest = (uint8_t *)BigBuf;
int m=0, i=0;
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
m = sizeof(BigBuf);
// Clear destination buffer before sending the command
memset(dest, 128, m);
@ -1044,7 +1062,7 @@ void T55xxReadTrace(void){
LED_D_ON();
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Give it a bit of time for the resonant antenna to settle.
// And for the tag to fully power up
@ -1060,7 +1078,7 @@ void T55xxReadTrace(void){
// Turn field on to read the response
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Now do the acquisition
i = 0;
@ -1749,8 +1767,9 @@ void SendForward(uint8_t fwd_bit_count) {
LED_D_ON();
//Field on
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Give it a bit of time for the resonant antenna to settle.
// And for the tag to fully power up
@ -1762,7 +1781,7 @@ void SendForward(uint8_t fwd_bit_count) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
SpinDelayUs(55*8); //55 cycles off (8us each)for 4305
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);//field on
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
SpinDelayUs(16*8); //16 cycles on (8us each)
// now start writting
@ -1774,7 +1793,7 @@ void SendForward(uint8_t fwd_bit_count) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
SpinDelayUs(23*8); //16-4 cycles off (8us each)
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);//field on
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
SpinDelayUs(9*8); //16 cycles on (8us each)
}
}

View file

@ -14,7 +14,7 @@
#include "apps.h"
//-----------------------------------------------------------------------------
// Select, Authenticaate, Read an MIFARE tag.
// Select, Authenticate, Read a MIFARE tag.
// read block
//-----------------------------------------------------------------------------
void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
@ -35,7 +35,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
pcs = &mpcs;
// clear trace
iso14a_clear_trace();
iso14a_clear_trace();
// iso14a_set_tracing(false);
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
@ -46,22 +46,22 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
break;
};
if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");
if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");
break;
};
if(mifare_classic_readblock(pcs, cuid, blockNo, dataoutbuf)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Read block error");
if (MF_DBGLEVEL >= 1) Dbprintf("Read block error");
break;
};
if(mifare_classic_halt(pcs, cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break;
};
@ -74,83 +74,75 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");
// add trace trailer
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
// memcpy(ack.d.asBytes, dataoutbuf, 16);
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);
LED_B_OFF();
// Thats it...
// Thats it...
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
// iso14a_set_tracing(TRUE);
}
void MifareUReadBlock(uint8_t arg0,uint8_t *datain)
{
// params
uint8_t blockNo = arg0;
// variables
byte_t isOK = 0;
byte_t dataoutbuf[16];
uint8_t uid[10];
uint32_t cuid;
// clear trace
iso14a_clear_trace();
}
void MifareUReadBlock(uint8_t arg0,uint8_t *datain)
{
// params
uint8_t blockNo = arg0;
// variables
byte_t isOK = 0;
byte_t dataoutbuf[16];
uint8_t uid[10];
uint32_t cuid;
// clear trace
iso14a_clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
break;
};
if(mifare_ultra_readblock(cuid, blockNo, dataoutbuf)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Read block error");
break;
};
if(mifare_ultra_halt(cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break;
};
isOK = 1;
break;
}
if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");
// add trace trailer
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);
LED_B_OFF();
// Thats it...
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
//-----------------------------------------------------------------------------
// Select, Authenticaate, Read an MIFARE tag.
// read sector (data = 4 x 16 bytes = 64 bytes)
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
break;
};
if(mifare_ultra_readblock(cuid, blockNo, dataoutbuf)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Read block error");
break;
};
if(mifare_ultra_halt(cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break;
};
isOK = 1;
break;
}
if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");
// add trace trailer
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);
LED_B_OFF();
// Thats it...
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
//-----------------------------------------------------------------------------
// Select, Authenticate, Read a MIFARE tag.
// read sector (data = 4 x 16 bytes = 64 bytes, or 16 x 16 bytes = 256 bytes)
//-----------------------------------------------------------------------------
void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
{
@ -161,8 +153,8 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
ui64Key = bytes_to_num(datain, 6);
// variables
byte_t isOK = 0;
byte_t dataoutbuf[16 * 4];
byte_t isOK;
byte_t dataoutbuf[16 * 16];
uint8_t uid[10];
uint32_t cuid;
struct Crypto1State mpcs = {0, 0};
@ -170,7 +162,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
pcs = &mpcs;
// clear trace
iso14a_clear_trace();
iso14a_clear_trace();
// iso14a_set_tracing(false);
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
@ -179,135 +171,104 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
LED_B_OFF();
LED_C_OFF();
while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
isOK = 1;
if(!iso14443a_select_card(uid, NULL, &cuid)) {
isOK = 0;
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
break;
};
if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_FIRST)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");
break;
};
if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 0, dataoutbuf + 16 * 0)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Read block 0 error");
break;
};
if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 1, dataoutbuf + 16 * 1)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Read block 1 error");
break;
};
if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 2, dataoutbuf + 16 * 2)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Read block 2 error");
break;
};
if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 3, dataoutbuf + 16 * 3)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Read block 3 error");
break;
};
if(mifare_classic_halt(pcs, cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break;
};
isOK = 1;
break;
}
if(isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) {
isOK = 0;
if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");
}
for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
if(mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf + 16 * blockNo)) {
isOK = 0;
if (MF_DBGLEVEL >= 1) Dbprintf("Read sector %2d block %2d error", sectorNo, blockNo);
break;
}
}
if(mifare_classic_halt(pcs, cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
}
// ----------------------------- crypto1 destroy
crypto1_destroy(pcs);
if (MF_DBGLEVEL >= 2) DbpString("READ SECTOR FINISHED");
// add trace trailer
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
// memcpy(ack.d.asBytes, dataoutbuf, 16 * 2);
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,32);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
// SpinDelay(100);
// memcpy(ack.d.asBytes, dataoutbuf + 16 * 2, 16 * 2);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf+32, 32);
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16*NumBlocksPerSector(sectorNo));
LED_B_OFF();
// Thats it...
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
// iso14a_set_tracing(TRUE);
}
void MifareUReadCard(uint8_t arg0, uint8_t *datain)
{
// params
uint8_t sectorNo = arg0;
// variables
byte_t isOK = 0;
byte_t dataoutbuf[16 * 4];
uint8_t uid[10];
uint32_t cuid;
// clear trace
iso14a_clear_trace();
// iso14a_set_tracing(false);
}
void MifareUReadCard(uint8_t arg0, uint8_t *datain)
{
// params
uint8_t sectorNo = arg0;
// variables
byte_t isOK = 0;
byte_t dataoutbuf[16 * 4];
uint8_t uid[10];
uint32_t cuid;
// clear trace
iso14a_clear_trace();
// iso14a_set_tracing(false);
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
break;
};
for(int sec=0;sec<16;sec++){
if(mifare_ultra_readblock(cuid, sectorNo * 4 + sec, dataoutbuf + 4 * sec)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Read block %d error",sec);
break;
};
}
if(mifare_ultra_halt(cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break;
};
isOK = 1;
break;
}
if (MF_DBGLEVEL >= 2) DbpString("READ CARD FINISHED");
// add trace trailer
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,64);
//cmd_send(CMD_ACK,isOK,0,0,dataoutbuf+32, 32);
LED_B_OFF();
// Thats it...
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
// iso14a_set_tracing(TRUE);
}
//-----------------------------------------------------------------------------
// Select, Authenticaate, Read an MIFARE tag.
// read block
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
break;
};
for(int sec=0;sec<16;sec++){
if(mifare_ultra_readblock(cuid, sectorNo * 4 + sec, dataoutbuf + 4 * sec)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Read block %d error",sec);
break;
};
}
if(mifare_ultra_halt(cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break;
};
isOK = 1;
break;
}
if (MF_DBGLEVEL >= 2) DbpString("READ CARD FINISHED");
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,64);
LED_B_OFF();
// Thats it...
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
//-----------------------------------------------------------------------------
// Select, Authenticate, Write a MIFARE tag.
// read block
//-----------------------------------------------------------------------------
void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
{
@ -368,15 +329,8 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
// add trace trailer
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,0,0);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
LED_B_OFF();
@ -384,143 +338,134 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
// iso14a_set_tracing(TRUE);
}
void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)
{
// params
uint8_t blockNo = arg0;
byte_t blockdata[16];
memset(blockdata,'\0',16);
memcpy(blockdata, datain,16);
// variables
byte_t isOK = 0;
uint8_t uid[10];
uint32_t cuid;
// clear trace
iso14a_clear_trace();
// iso14a_set_tracing(false);
}
void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)
{
// params
uint8_t blockNo = arg0;
byte_t blockdata[16];
memset(blockdata,'\0',16);
memcpy(blockdata, datain,16);
// variables
byte_t isOK = 0;
uint8_t uid[10];
uint32_t cuid;
// clear trace
iso14a_clear_trace();
// iso14a_set_tracing(false);
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
break;
};
if(mifare_ultra_writeblock(cuid, blockNo, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
break;
};
if(mifare_ultra_halt(cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break;
};
isOK = 1;
break;
}
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
// add trace trailer
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,0,0);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
LED_B_OFF();
// Thats it...
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
// iso14a_set_tracing(TRUE);
}
void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
{
// params
uint8_t blockNo = arg0;
byte_t blockdata[4];
memcpy(blockdata, datain,4);
// variables
byte_t isOK = 0;
uint8_t uid[10];
uint32_t cuid;
// clear trace
iso14a_clear_trace();
// iso14a_set_tracing(false);
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
break;
};
if(mifare_ultra_special_writeblock(cuid, blockNo, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
break;
};
if(mifare_ultra_halt(cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break;
};
isOK = 1;
break;
}
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
// add trace trailer
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,0,0);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
LED_B_OFF();
// Thats it...
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
// iso14a_set_tracing(TRUE);
}
// Return 1 if the nonce is invalid else return 0
int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, byte_t * parity) {
return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
break;
};
if(mifare_ultra_writeblock(cuid, blockNo, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
break;
};
if(mifare_ultra_halt(cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break;
};
isOK = 1;
break;
}
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,0,0);
LED_B_OFF();
// Thats it...
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
// iso14a_set_tracing(TRUE);
}
void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
{
// params
uint8_t blockNo = arg0;
byte_t blockdata[4];
memcpy(blockdata, datain,4);
// variables
byte_t isOK = 0;
uint8_t uid[10];
uint32_t cuid;
// clear trace
iso14a_clear_trace();
// iso14a_set_tracing(false);
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
break;
};
if(mifare_ultra_special_writeblock(cuid, blockNo, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
break;
};
if(mifare_ultra_halt(cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break;
};
isOK = 1;
break;
}
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,0,0);
LED_B_OFF();
// Thats it...
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
// iso14a_set_tracing(TRUE);
}
// Return 1 if the nonce is invalid else return 0
int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, byte_t * parity) {
return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \
(oddparity((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \
(oddparity((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0;
}
//-----------------------------------------------------------------------------
// MIFARE nested authentication.
//
@ -769,18 +714,11 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
LED_B_OFF();
LED_C_OFF();
// SpinDelay(300);
for (i = 0; i < keyCount; i++) {
// FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
// SpinDelay(100);
// FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
// prepare next select by sending a HALT. There is no need to power down the card.
if(mifare_classic_halt(pcs, cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Halt error");
}
// SpinDelay(50);
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (OLD_MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card");
break;
@ -798,10 +736,6 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
// ----------------------------- crypto1 destroy
crypto1_destroy(pcs);
// add trace trailer
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,datain + i * 6,6);
LED_B_OFF();
@ -823,6 +757,7 @@ void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
Dbprintf("Debug level: %d", MF_DBGLEVEL);
}
//-----------------------------------------------------------------------------
// Work with emulator memory
//
@ -831,29 +766,29 @@ void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
emlClearMem();
}
void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
emlSetMem(datain, arg0, arg1); // data, block num, blocks count
}
void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
// UsbCommand ack = {CMD_ACK, {arg0, arg1, 0}};
byte_t buf[48];
emlGetMem(buf, arg0, arg1); // data, block num, blocks count
void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
byte_t buf[48];
emlGetMem(buf, arg0, arg1); // data, block num, blocks count (max 4)
LED_B_ON();
cmd_send(CMD_ACK,arg0,arg1,0,buf,48);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
cmd_send(CMD_ACK,arg0,arg1,0,buf,48);
LED_B_OFF();
}
//-----------------------------------------------------------------------------
// Load a card into the emulator memory
//
//-----------------------------------------------------------------------------
void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
int i;
uint8_t sectorNo = 0;
uint8_t numSectors = arg0;
uint8_t keyType = arg1;
uint64_t ui64Key = 0;
uint32_t cuid;
@ -876,63 +811,51 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
LED_B_OFF();
LED_C_OFF();
while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
break;
};
bool isOK = true;
if(!iso14443a_select_card(uid, NULL, &cuid)) {
isOK = false;
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
}
for (i = 0; i < 16; i++) {
sectorNo = i;
ui64Key = emlGetKey(sectorNo, keyType);
if (!i){
if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_FIRST)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%d]. Auth error", i);
break;
}
} else {
if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_NESTED)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%d]. Auth nested error", i);
break;
for (uint8_t sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) {
ui64Key = emlGetKey(sectorNo, keyType);
if (sectorNo == 0){
if(isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) {
isOK = false;
if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%2d]. Auth error", sectorNo);
break;
}
} else {
if(isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED)) {
isOK = false;
if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%2d]. Auth nested error", sectorNo);
break;
}
}
for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
if(isOK && mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) {
isOK = false;
if (MF_DBGLEVEL >= 1) Dbprintf("Error reading sector %2d block %2d", sectorNo, blockNo);
break;
};
if (isOK) {
if (blockNo < NumBlocksPerSector(sectorNo) - 1) {
emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1);
} else { // sector trailer, keep the keys, set only the AC
emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);
emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
}
}
if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 0, dataoutbuf)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Read block 0 error");
break;
};
emlSetMem(dataoutbuf, sectorNo * 4 + 0, 1);
if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 1, dataoutbuf)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Read block 1 error");
break;
};
emlSetMem(dataoutbuf, sectorNo * 4 + 1, 1);
if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 2, dataoutbuf)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Read block 2 error");
break;
};
emlSetMem(dataoutbuf, sectorNo * 4 + 2, 1);
// get block 3 bytes 6-9
if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 3, dataoutbuf)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Read block 3 error");
break;
};
emlGetMem(dataoutbuf2, sectorNo * 4 + 3, 1);
memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);
emlSetMem(dataoutbuf2, sectorNo * 4 + 3, 1);
}
if(mifare_classic_halt(pcs, cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break;
};
break;
}
}
if(mifare_classic_halt(pcs, cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
};
// ----------------------------- crypto1 destroy
crypto1_destroy(pcs);
@ -942,16 +865,8 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
if (MF_DBGLEVEL >= 2) DbpString("EMUL FILL SECTORS FINISHED");
// add trace trailer
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
}
//-----------------------------------------------------------------------------
// MIFARE 1k emulator
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn)
@ -1074,22 +989,8 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
break;
}
// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
// if (isOK) memcpy(ack.d.asBytes, uid, 4);
// add trace trailer
/**
* Removed by Martin, the uid is overwritten with 0x44,
* which can 't be intended.
*
* memset(uid, 0x44, 4);
* LogTrace(uid, 4, 0, 0, TRUE);
**/
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,uid,4);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
cmd_send(CMD_ACK,isOK,0,0,uid,4);
LED_B_OFF();
if ((workFlags & 0x10) || (!isOK)) {
@ -1099,6 +1000,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
}
}
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
// params
@ -1171,20 +1073,8 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
break;
}
// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
// if (isOK) memcpy(ack.d.asBytes, data, 18);
// add trace trailer
/*
* Removed by Martin, this piece of overwrites the 'data' variable
* which is sent two lines down, and is obviously not correct.
*
* memset(data, 0x44, 4);
* LogTrace(data, 4, 0, 0, TRUE);
*/
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,data,18);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
cmd_send(CMD_ACK,isOK,0,0,data,18);
LED_B_OFF();
if ((workFlags & 0x10) || (!isOK)) {

View file

@ -453,6 +453,27 @@ int mifare_ultra_halt(uint32_t uid)
return 0;
}
// Mifare Memory Structure: up to 32 Sectors with 4 blocks each (1k and 2k cards),
// plus evtl. 8 sectors with 16 blocks each (4k cards)
uint8_t NumBlocksPerSector(uint8_t sectorNo)
{
if (sectorNo < 32)
return 4;
else
return 16;
}
uint8_t FirstBlockOfSector(uint8_t sectorNo)
{
if (sectorNo < 32)
return sectorNo * 4;
else
return 32*4 + (sectorNo - 32) * 16;
}
// work with emulator memory
void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
@ -522,7 +543,7 @@ uint64_t emlGetKey(int sectorNum, int keyType) {
uint8_t key[6];
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
memcpy(key, emCARD + 3 * 16 + sectorNum * 4 * 16 + keyType * 10, 6);
memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6);
return bytes_to_num(key, 6);
}

View file

@ -80,6 +80,10 @@ uint8_t* mifare_get_bigbufptr(void);
uint8_t* eml_get_bigbufptr_sendbuf(void);
uint8_t* eml_get_bigbufptr_recbuf(void);
// Mifare memory structure
uint8_t NumBlocksPerSector(uint8_t sectorNo);
uint8_t FirstBlockOfSector(uint8_t sectorNo);
// emulator functions
void emlClearMem(void);
void emlSetMem(uint8_t *data, int blockNum, int blocksCount);

View file

@ -227,27 +227,27 @@ void FormatVersionInformation(char *dst, int len, const char *prefix, void *vers
dst[0] = 0;
strncat(dst, prefix, len);
if(v->magic != VERSION_INFORMATION_MAGIC) {
strncat(dst, "Missing/Invalid version information", len);
strncat(dst, "Missing/Invalid version information", len - strlen(dst) - 1);
return;
}
if(v->versionversion != 1) {
strncat(dst, "Version information not understood", len);
strncat(dst, "Version information not understood", len - strlen(dst) - 1);
return;
}
if(!v->present) {
strncat(dst, "Version information not available", len);
strncat(dst, "Version information not available", len - strlen(dst) - 1);
return;
}
strncat(dst, v->svnversion, len);
strncat(dst, v->gitversion, len - strlen(dst) - 1);
if(v->clean == 0) {
strncat(dst, "-unclean", len);
strncat(dst, "-unclean", len - strlen(dst) - 1);
} else if(v->clean == 2) {
strncat(dst, "-suspect", len);
strncat(dst, "-suspect", len - strlen(dst) - 1);
}
strncat(dst, " ", len);
strncat(dst, v->buildtime, len);
strncat(dst, " ", len - strlen(dst) - 1);
strncat(dst, v->buildtime, len - strlen(dst) - 1);
}
// -------------------------------------------------------------------------