From 8a7c6825b53e400cb480d93dab88ddb8c96182d8 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 9 Mar 2019 20:34:41 +0100 Subject: [PATCH] armsrc: fix mix of spaces & tabs --- armsrc/BigBuf.c | 236 +- armsrc/BigBuf.h | 14 +- armsrc/LCD.c | 172 +- armsrc/LCD.h | 190 +- armsrc/appmain.c | 2248 ++++++++-------- armsrc/apps.h | 4 +- armsrc/buzzer.c | 112 +- armsrc/des.c | 450 ++-- armsrc/des.h | 10 +- armsrc/desfire_crypto.c | 78 +- armsrc/desfire_key.c | 42 +- armsrc/desfire_key.h | 22 +- armsrc/epa.c | 728 ++--- armsrc/epa.h | 6 +- armsrc/felica.c | 806 +++--- armsrc/flashmem.c | 620 ++--- armsrc/flashmem.h | 104 +- armsrc/fonts.c | 582 ++-- armsrc/fpgaloader.c | 568 ++-- armsrc/fpgaloader.h | 80 +- armsrc/hfsnoop.c | 90 +- armsrc/hitag2.c | 2722 +++++++++---------- armsrc/hitagS.c | 3524 ++++++++++++------------ armsrc/iclass.c | 3196 +++++++++++----------- armsrc/iso14443a.c | 5317 +++++++++++++++++++------------------ armsrc/iso14443a.h | 96 +- armsrc/iso14443b.c | 2218 ++++++++-------- armsrc/iso14443b.h | 18 +- armsrc/iso15693.c | 1298 ++++----- armsrc/lfops.c | 2981 ++++++++++----------- armsrc/lfsampling.c | 554 ++-- armsrc/lfsampling.h | 6 +- armsrc/mifarecmd.c | 2936 ++++++++++---------- armsrc/mifaredesfire.c | 498 ++-- armsrc/mifaresniff.c | 494 ++-- armsrc/mifaresniff.h | 22 +- armsrc/mifareutil.c | 902 +++---- armsrc/mifareutil.h | 8 +- armsrc/optimized_cipher.c | 258 +- armsrc/optimized_cipher.h | 16 +- armsrc/pcf7931.c | 788 +++--- armsrc/printf.c | 630 ++--- armsrc/start.c | 70 +- armsrc/string.c | 84 +- armsrc/ticks.c | 280 +- armsrc/util.c | 288 +- armsrc/util.h | 4 +- 47 files changed, 18186 insertions(+), 18184 deletions(-) diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index b6c9e544d..26421732c 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -20,7 +20,7 @@ Pointer to highest available memory: BigBuf_hi high BIGBUF_SIZE reserved = BigBuf_malloc() subtracts amount from BigBuf_hi, - low 0x00 + low 0x00 */ // High memory mark @@ -35,92 +35,92 @@ static bool tracing = true; //todo static? // get the address of BigBuf uint8_t *BigBuf_get_addr(void) { - return (uint8_t *)BigBuf; + return (uint8_t *)BigBuf; } // get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done uint8_t *BigBuf_get_EM_addr(void) { - // not yet allocated - if (emulator_memory == NULL) - emulator_memory = BigBuf_malloc(CARD_MEMORY_SIZE); + // not yet allocated + if (emulator_memory == NULL) + emulator_memory = BigBuf_malloc(CARD_MEMORY_SIZE); - return emulator_memory; + return emulator_memory; } // clear ALL of BigBuf void BigBuf_Clear(void) { - BigBuf_Clear_ext(true); + BigBuf_Clear_ext(true); } // clear ALL of BigBuf void BigBuf_Clear_ext(bool verbose) { - memset(BigBuf, 0, BIGBUF_SIZE); - if (verbose) - Dbprintf("Buffer cleared (%i bytes)", BIGBUF_SIZE); + memset(BigBuf, 0, BIGBUF_SIZE); + if (verbose) + Dbprintf("Buffer cleared (%i bytes)", BIGBUF_SIZE); } void BigBuf_Clear_EM(void) { - memset(BigBuf_get_EM_addr(), 0, CARD_MEMORY_SIZE); + memset(BigBuf_get_EM_addr(), 0, CARD_MEMORY_SIZE); } void BigBuf_Clear_keep_EM(void) { - memset(BigBuf, 0, BigBuf_hi); + memset(BigBuf, 0, BigBuf_hi); } // allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory // at the beginning of BigBuf is always for traces/samples uint8_t *BigBuf_malloc(uint16_t chunksize) { - if (BigBuf_hi - chunksize < 0) - return NULL; // no memory left + if (BigBuf_hi - chunksize < 0) + return NULL; // no memory left - chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4 - BigBuf_hi -= chunksize; // aligned to 4 Byte boundary - return (uint8_t *)BigBuf + BigBuf_hi; + chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4 + BigBuf_hi -= chunksize; // aligned to 4 Byte boundary + return (uint8_t *)BigBuf + BigBuf_hi; } // free ALL allocated chunks. The whole BigBuf is available for traces or samples again. void BigBuf_free(void){ - BigBuf_hi = BIGBUF_SIZE; - emulator_memory = NULL; - // shouldn't this empty BigBuf also? + BigBuf_hi = BIGBUF_SIZE; + emulator_memory = NULL; + // shouldn't this empty BigBuf also? } // free allocated chunks EXCEPT the emulator memory void BigBuf_free_keep_EM(void) { - if (emulator_memory != NULL) - BigBuf_hi = emulator_memory - (uint8_t *)BigBuf; - else - BigBuf_hi = BIGBUF_SIZE; + if (emulator_memory != NULL) + BigBuf_hi = emulator_memory - (uint8_t *)BigBuf; + else + BigBuf_hi = BIGBUF_SIZE; - // shouldn't this empty BigBuf also? + // shouldn't this empty BigBuf also? } void BigBuf_print_status(void) { - Dbprintf("Memory"); - Dbprintf(" BIGBUF_SIZE.............%d", BIGBUF_SIZE); - Dbprintf(" Available memory........%d", BigBuf_hi); - Dbprintf("Tracing"); - Dbprintf(" tracing ................%d", tracing); - Dbprintf(" traceLen ...............%d", traceLen); + Dbprintf("Memory"); + Dbprintf(" BIGBUF_SIZE.............%d", BIGBUF_SIZE); + Dbprintf(" Available memory........%d", BigBuf_hi); + Dbprintf("Tracing"); + Dbprintf(" tracing ................%d", tracing); + Dbprintf(" traceLen ...............%d", traceLen); } // return the maximum trace length (i.e. the unallocated size of BigBuf) uint16_t BigBuf_max_traceLen(void) { - return BigBuf_hi; + return BigBuf_hi; } void clear_trace(void) { - traceLen = 0; + traceLen = 0; } void set_tracelen(uint32_t value) { traceLen = value; } void set_tracing(bool enable) { - tracing = enable; + tracing = enable; } bool get_tracing(void) { - return tracing; + return tracing; } /** @@ -128,7 +128,7 @@ bool get_tracing(void) { * @return */ uint32_t BigBuf_get_traceLen(void) { - return traceLen; + return traceLen; } /** @@ -138,111 +138,111 @@ uint32_t BigBuf_get_traceLen(void) { annotation of commands/responses. **/ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag) { - if (!tracing) return false; + if (!tracing) return false; - uint8_t *trace = BigBuf_get_addr(); + uint8_t *trace = BigBuf_get_addr(); - uint32_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity - uint32_t duration = timestamp_end - timestamp_start; + uint32_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity + uint32_t duration = timestamp_end - timestamp_start; - // Return when trace is full - if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= BigBuf_max_traceLen()) { - tracing = false; // don't trace any more - return false; - } - // Traceformat: - // 32 bits timestamp (little endian) - // 16 bits duration (little endian) - // 16 bits data length (little endian, Highest Bit used as readerToTag flag) - // y Bytes data - // x Bytes parity (one byte per 8 bytes data) + // Return when trace is full + if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= BigBuf_max_traceLen()) { + tracing = false; // don't trace any more + return false; + } + // Traceformat: + // 32 bits timestamp (little endian) + // 16 bits duration (little endian) + // 16 bits data length (little endian, Highest Bit used as readerToTag flag) + // y Bytes data + // x Bytes parity (one byte per 8 bytes data) - // timestamp (start) - trace[traceLen++] = ((timestamp_start >> 0) & 0xff); - trace[traceLen++] = ((timestamp_start >> 8) & 0xff); - trace[traceLen++] = ((timestamp_start >> 16) & 0xff); - trace[traceLen++] = ((timestamp_start >> 24) & 0xff); + // timestamp (start) + trace[traceLen++] = ((timestamp_start >> 0) & 0xff); + trace[traceLen++] = ((timestamp_start >> 8) & 0xff); + trace[traceLen++] = ((timestamp_start >> 16) & 0xff); + trace[traceLen++] = ((timestamp_start >> 24) & 0xff); - // duration - trace[traceLen++] = ((duration >> 0) & 0xff); - trace[traceLen++] = ((duration >> 8) & 0xff); + // duration + trace[traceLen++] = ((duration >> 0) & 0xff); + trace[traceLen++] = ((duration >> 8) & 0xff); - // data length - trace[traceLen++] = ((iLen >> 0) & 0xff); - trace[traceLen++] = ((iLen >> 8) & 0xff); + // data length + trace[traceLen++] = ((iLen >> 0) & 0xff); + trace[traceLen++] = ((iLen >> 8) & 0xff); - // readerToTag flag - if (!readerToTag) { - trace[traceLen - 1] |= 0x80; - } + // readerToTag flag + if (!readerToTag) { + trace[traceLen - 1] |= 0x80; + } - // data bytes - if (btBytes != NULL && iLen != 0) { - memcpy(trace + traceLen, btBytes, iLen); - } - traceLen += iLen; + // data bytes + if (btBytes != NULL && iLen != 0) { + memcpy(trace + traceLen, btBytes, iLen); + } + traceLen += iLen; - // parity bytes - if (num_paritybytes != 0) { - if (parity != NULL) { - memcpy(trace + traceLen, parity, num_paritybytes); - } else { - memset(trace + traceLen, 0x00, num_paritybytes); - } - } - traceLen += num_paritybytes; + // parity bytes + if (num_paritybytes != 0) { + if (parity != NULL) { + memcpy(trace + traceLen, parity, num_paritybytes); + } else { + memset(trace + traceLen, 0x00, num_paritybytes); + } + } + traceLen += num_paritybytes; - return true; + return true; } int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int readerToTag) { - /** - Todo, rewrite the logger to use the generic functionality instead. It should be noted, however, - that this logger takes number of bits as argument, not number of bytes. - **/ + /** + Todo, rewrite the logger to use the generic functionality instead. It should be noted, however, + that this logger takes number of bits as argument, not number of bytes. + **/ - if (!tracing) return false; + if (!tracing) return false; - uint8_t *trace = BigBuf_get_addr(); - uint32_t iLen = nbytes(iBits); - // Return when trace is full - if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + iLen > BigBuf_max_traceLen()) return false; + uint8_t *trace = BigBuf_get_addr(); + uint32_t iLen = nbytes(iBits); + // Return when trace is full + if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + iLen > BigBuf_max_traceLen()) return false; - //Hitag traces appear to use this traceformat: - // 32 bits timestamp (little endian,Highest Bit used as readerToTag flag) - // 32 bits parity - // 8 bits size (number of bits in the trace entry, not number of bytes) - // y Bytes data + //Hitag traces appear to use this traceformat: + // 32 bits timestamp (little endian,Highest Bit used as readerToTag flag) + // 32 bits parity + // 8 bits size (number of bits in the trace entry, not number of bytes) + // y Bytes data - rsamples += iSamples; - trace[traceLen++] = ((rsamples >> 0) & 0xff); - trace[traceLen++] = ((rsamples >> 8) & 0xff); - trace[traceLen++] = ((rsamples >> 16) & 0xff); - trace[traceLen++] = ((rsamples >> 24) & 0xff); + rsamples += iSamples; + trace[traceLen++] = ((rsamples >> 0) & 0xff); + trace[traceLen++] = ((rsamples >> 8) & 0xff); + trace[traceLen++] = ((rsamples >> 16) & 0xff); + trace[traceLen++] = ((rsamples >> 24) & 0xff); - if (!readerToTag) { - trace[traceLen - 1] |= 0x80; - } + if (!readerToTag) { + trace[traceLen - 1] |= 0x80; + } - trace[traceLen++] = ((dwParity >> 0) & 0xff); - trace[traceLen++] = ((dwParity >> 8) & 0xff); - trace[traceLen++] = ((dwParity >> 16) & 0xff); - trace[traceLen++] = ((dwParity >> 24) & 0xff); - trace[traceLen++] = iBits; + trace[traceLen++] = ((dwParity >> 0) & 0xff); + trace[traceLen++] = ((dwParity >> 8) & 0xff); + trace[traceLen++] = ((dwParity >> 16) & 0xff); + trace[traceLen++] = ((dwParity >> 24) & 0xff); + trace[traceLen++] = iBits; - memcpy(trace + traceLen, btBytes, iLen); - traceLen += iLen; + memcpy(trace + traceLen, btBytes, iLen); + traceLen += iLen; - return true; + return true; } // Emulator memory uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length){ - uint8_t* mem = BigBuf_get_EM_addr(); - if (offset + length < CARD_MEMORY_SIZE) { - memcpy(mem+offset, data, length); - return 0; - } - Dbprintf("Error, trying to set memory outside of bounds! %d > %d", (offset + length), CARD_MEMORY_SIZE); - return 1; + uint8_t* mem = BigBuf_get_EM_addr(); + if (offset + length < CARD_MEMORY_SIZE) { + memcpy(mem+offset, data, length); + return 0; + } + Dbprintf("Error, trying to set memory outside of bounds! %d > %d", (offset + length), CARD_MEMORY_SIZE); + return 1; } diff --git a/armsrc/BigBuf.h b/armsrc/BigBuf.h index 9b7b33e47..e9a7b8098 100644 --- a/armsrc/BigBuf.h +++ b/armsrc/BigBuf.h @@ -17,13 +17,13 @@ #include "string.h" #include "ticks.h" -#define BIGBUF_SIZE 40000 -#define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame -#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8) -#define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC -#define MAX_MIFARE_PARITY_SIZE 3 // need 18 parity bits for the 18 Byte above. 3 Bytes are enough to store these -#define CARD_MEMORY_SIZE 4096 -#define DMA_BUFFER_SIZE 256 //128 (how big is the dma?!? +#define BIGBUF_SIZE 40000 +#define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame +#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8) +#define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC +#define MAX_MIFARE_PARITY_SIZE 3 // need 18 parity bits for the 18 Byte above. 3 Bytes are enough to store these +#define CARD_MEMORY_SIZE 4096 +#define DMA_BUFFER_SIZE 256 //128 (how big is the dma?!? extern uint8_t *BigBuf_get_addr(void); extern uint8_t *BigBuf_get_EM_addr(void); diff --git a/armsrc/LCD.c b/armsrc/LCD.c index 3e74c77fa..7987da188 100644 --- a/armsrc/LCD.c +++ b/armsrc/LCD.c @@ -9,141 +9,141 @@ void LCDSend(unsigned int data) { - // 9th bit set for data, clear for command - while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete - // For clarity's sake we pass data with 9th bit clear and commands with 9th - // bit set since they're implemented as defines, se we need to invert bit - AT91C_BASE_SPI->SPI_TDR = data^0x100; // Send the data/command + // 9th bit set for data, clear for command + while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete + // For clarity's sake we pass data with 9th bit clear and commands with 9th + // bit set since they're implemented as defines, se we need to invert bit + AT91C_BASE_SPI->SPI_TDR = data^0x100; // Send the data/command } void LCDSetXY(unsigned char x, unsigned char y) { - LCDSend(PPASET); // page start/end ram - LCDSend(y); // Start Page to display to - LCDSend(131); // End Page to display to + LCDSend(PPASET); // page start/end ram + LCDSend(y); // Start Page to display to + LCDSend(131); // End Page to display to - LCDSend(PCASET); // column start/end ram - LCDSend(x); // Start Column to display to - LCDSend(131); // End Column to display to + LCDSend(PCASET); // column start/end ram + LCDSend(x); // Start Column to display to + LCDSend(131); // End Column to display to } void LCDSetPixel(unsigned char x, unsigned char y, unsigned char color) { - LCDSetXY(x,y); // Set position - LCDSend(PRAMWR); // Now write the pixel to the display - LCDSend(color); // Write the data in the specified Color + LCDSetXY(x,y); // Set position + LCDSend(PRAMWR); // Now write the pixel to the display + LCDSend(color); // Write the data in the specified Color } void LCDFill (unsigned char xs,unsigned char ys,unsigned char width,unsigned char height, unsigned char color) { unsigned char i,j; - for (i=0;i < height;i++) // Number of horizontal lines + for (i=0;i < height;i++) // Number of horizontal lines { - LCDSetXY(xs,ys+i); // Goto start of fill area (Top Left) - LCDSend(PRAMWR); // Write to display + LCDSetXY(xs,ys+i); // Goto start of fill area (Top Left) + LCDSend(PRAMWR); // Write to display - for (j=0;j < width;j++) // pixels per line - LCDSend(color); + for (j=0;j < width;j++) // pixels per line + LCDSend(color); } } void LCDString (char *lcd_string, const char *font_style,unsigned char x, unsigned char y, unsigned char fcolor, unsigned char bcolor) { - unsigned int i; - unsigned char mask=0, px, py, xme, yme, offset; - const char *data; + unsigned int i; + unsigned char mask=0, px, py, xme, yme, offset; + const char *data; - data = font_style; // point to the start of the font table + data = font_style; // point to the start of the font table - xme = *data; // get font x width - data++; - yme = *data; // get font y length - data++; - offset = *data; // get data bytes per font + xme = *data; // get font x width + data++; + yme = *data; // get font y length + data++; + offset = *data; // get data bytes per font - do - { - // point to data in table to be loaded - data = (font_style + offset) + (offset * (int)(*lcd_string - 32)); + do + { + // point to data in table to be loaded + data = (font_style + offset) + (offset * (int)(*lcd_string - 32)); - for (i=0;i < yme;i++) { - mask |=0x80; + for (i=0;i < yme;i++) { + mask |=0x80; - for (px=x; px < (x + xme); px++) { - py= y + i; + for (px=x; px < (x + xme); px++) { + py= y + i; - if (*data & mask) LCDSetPixel (px,py,fcolor); - else LCDSetPixel (px,py,bcolor); + if (*data & mask) LCDSetPixel (px,py,fcolor); + else LCDSetPixel (px,py,bcolor); - mask>>=1; - } - data++; - } - x+=xme; + mask>>=1; + } + data++; + } + x+=xme; - lcd_string++; // next character in string + lcd_string++; // next character in string - } while(*lcd_string !='\0'); // keep spitting chars out until end of string + } while(*lcd_string !='\0'); // keep spitting chars out until end of string } void LCDReset(void) { - LED_A_ON(); - SetupSpi(SPI_LCD_MODE); - LOW(GPIO_LRST); - SpinDelay(100); + LED_A_ON(); + SetupSpi(SPI_LCD_MODE); + LOW(GPIO_LRST); + SpinDelay(100); - HIGH(GPIO_LRST); - SpinDelay(100); - LED_A_OFF(); + HIGH(GPIO_LRST); + SpinDelay(100); + LED_A_OFF(); } void LCDInit(void) { - int i; + int i; - LCDReset(); + LCDReset(); - LCDSend(PSWRESET); // software reset - SpinDelay(100); - LCDSend(PSLEEPOUT); // exit sleep mode - LCDSend(PBSTRON); // booster on - LCDSend(PDISPON); // display on - LCDSend(PNORON); // normal on - LCDSend(PMADCTL); // rotate display 180 deg - LCDSend(0xC0); + LCDSend(PSWRESET); // software reset + SpinDelay(100); + LCDSend(PSLEEPOUT); // exit sleep mode + LCDSend(PBSTRON); // booster on + LCDSend(PDISPON); // display on + LCDSend(PNORON); // normal on + LCDSend(PMADCTL); // rotate display 180 deg + LCDSend(0xC0); - LCDSend(PCOLMOD); // color mode - LCDSend(0x02); // 8bpp color mode + LCDSend(PCOLMOD); // color mode + LCDSend(0x02); // 8bpp color mode - LCDSend(PSETCON); // set contrast + LCDSend(PSETCON); // set contrast LCDSend(0xDC); - // clear display + // clear display LCDSetXY(0,0); - LCDSend(PRAMWR); // Write to display - i=LCD_XRES*LCD_YRES; - while(i--) LCDSend(WHITE); + LCDSend(PRAMWR); // Write to display + i=LCD_XRES*LCD_YRES; + while(i--) LCDSend(WHITE); // test text on different colored backgrounds - LCDString(" The quick brown fox ", (char *)&FONT6x8,1,1+8*0,WHITE ,BLACK ); - LCDString(" jumped over the ", (char *)&FONT6x8,1,1+8*1,BLACK ,WHITE ); - LCDString(" lazy dog. ", (char *)&FONT6x8,1,1+8*2,YELLOW ,RED ); - LCDString(" AaBbCcDdEeFfGgHhIiJj ", (char *)&FONT6x8,1,1+8*3,RED ,GREEN ); - LCDString(" KkLlMmNnOoPpQqRrSsTt ", (char *)&FONT6x8,1,1+8*4,MAGENTA,BLUE ); - LCDString("UuVvWwXxYyZz0123456789", (char *)&FONT6x8,1,1+8*5,BLUE ,YELLOW); - LCDString("`-=[]_;',./~!@#$%^&*()", (char *)&FONT6x8,1,1+8*6,BLACK ,CYAN ); - LCDString(" _+{}|:\\\"<>? ",(char *)&FONT6x8,1,1+8*7,BLUE ,MAGENTA); + LCDString(" The quick brown fox ", (char *)&FONT6x8,1,1+8*0,WHITE ,BLACK ); + LCDString(" jumped over the ", (char *)&FONT6x8,1,1+8*1,BLACK ,WHITE ); + LCDString(" lazy dog. ", (char *)&FONT6x8,1,1+8*2,YELLOW ,RED ); + LCDString(" AaBbCcDdEeFfGgHhIiJj ", (char *)&FONT6x8,1,1+8*3,RED ,GREEN ); + LCDString(" KkLlMmNnOoPpQqRrSsTt ", (char *)&FONT6x8,1,1+8*4,MAGENTA,BLUE ); + LCDString("UuVvWwXxYyZz0123456789", (char *)&FONT6x8,1,1+8*5,BLUE ,YELLOW); + LCDString("`-=[]_;',./~!@#$%^&*()", (char *)&FONT6x8,1,1+8*6,BLACK ,CYAN ); + LCDString(" _+{}|:\\\"<>? ", (char *)&FONT6x8,1,1+8*7,BLUE ,MAGENTA); - // color bands - LCDFill(0, 1+8* 8, 132, 8, BLACK); - LCDFill(0, 1+8* 9, 132, 8, WHITE); - LCDFill(0, 1+8*10, 132, 8, RED); - LCDFill(0, 1+8*11, 132, 8, GREEN); - LCDFill(0, 1+8*12, 132, 8, BLUE); - LCDFill(0, 1+8*13, 132, 8, YELLOW); - LCDFill(0, 1+8*14, 132, 8, CYAN); - LCDFill(0, 1+8*15, 132, 8, MAGENTA); + // color bands + LCDFill(0, 1+8* 8, 132, 8, BLACK); + LCDFill(0, 1+8* 9, 132, 8, WHITE); + LCDFill(0, 1+8*10, 132, 8, RED); + LCDFill(0, 1+8*11, 132, 8, GREEN); + LCDFill(0, 1+8*12, 132, 8, BLUE); + LCDFill(0, 1+8*13, 132, 8, YELLOW); + LCDFill(0, 1+8*14, 132, 8, CYAN); + LCDFill(0, 1+8*15, 132, 8, MAGENTA); } diff --git a/armsrc/LCD.h b/armsrc/LCD.h index 2643f66ee..a21c3eeff 100644 --- a/armsrc/LCD.h +++ b/armsrc/LCD.h @@ -14,110 +14,110 @@ #include "fonts.h" // The resolution of the LCD -#define LCD_XRES 132 -#define LCD_YRES 132 +#define LCD_XRES 132 +#define LCD_YRES 132 // 8bpp Color Mode - Some basic colors defined for ease of use // remember 8bpp color = 3xRed, 3xGreen & 2xBlue bits // organised as RRRGGGBB -#define BLACK 0x00 -#define BLUE 0x03 -#define GREEN 0x1C -#define CYAN 0x1F -#define RED 0xE0 -#define MAGENTA 0xE3 -#define YELLOW 0xFC -#define WHITE 0xFF +#define BLACK 0x00 +#define BLUE 0x03 +#define GREEN 0x1C +#define CYAN 0x1F +#define RED 0xE0 +#define MAGENTA 0xE3 +#define YELLOW 0xFC +#define WHITE 0xFF // EPSON LCD command set -#define ECASET 0x115 -#define EPWRCTR 0x120 -#define ENOP 0x125 -#define ERAMWR 0x15C -#define ERAMRD 0x15D -#define EPASET 0x175 -#define EEPSRRD1 0x17C -#define EEPSRRD2 0x17D -#define EVOLCTR 0x181 -#define ETMPGRD 0x182 -#define ESLPOUT 0x194 -#define ESLPIN 0x195 -#define EDISNOR 0x1A6 -#define EDISINV 0x1A7 -#define EPTLIN 0x1A8 -#define EPTLOUT 0x1A9 -#define EASCSET 0x1AA -#define ESCSTART 0x1AB -#define EDISOFF 0x1AE -#define EDISON 0x1AF -#define ECOMSCN 0x1BB -#define EDATCTL 0x1BC -#define EDISCTL 0x1CA -#define EEPCOUT 0x1CC -#define EEPCTIN 0x1CD -#define ERGBSET8 0x1CE -#define EOSCON 0x1D1 -#define EOSCOFF 0x1D2 -#define EVOLUP 0x1D6 -#define EVOLDOWN 0x1D7 -#define ERMWIN 0x1E0 -#define ERMWOUT 0x1EE -#define EEPMWR 0x1FC -#define EEPMRD 0x1FD +#define ECASET 0x115 +#define EPWRCTR 0x120 +#define ENOP 0x125 +#define ERAMWR 0x15C +#define ERAMRD 0x15D +#define EPASET 0x175 +#define EEPSRRD1 0x17C +#define EEPSRRD2 0x17D +#define EVOLCTR 0x181 +#define ETMPGRD 0x182 +#define ESLPOUT 0x194 +#define ESLPIN 0x195 +#define EDISNOR 0x1A6 +#define EDISINV 0x1A7 +#define EPTLIN 0x1A8 +#define EPTLOUT 0x1A9 +#define EASCSET 0x1AA +#define ESCSTART 0x1AB +#define EDISOFF 0x1AE +#define EDISON 0x1AF +#define ECOMSCN 0x1BB +#define EDATCTL 0x1BC +#define EDISCTL 0x1CA +#define EEPCOUT 0x1CC +#define EEPCTIN 0x1CD +#define ERGBSET8 0x1CE +#define EOSCON 0x1D1 +#define EOSCOFF 0x1D2 +#define EVOLUP 0x1D6 +#define EVOLDOWN 0x1D7 +#define ERMWIN 0x1E0 +#define ERMWOUT 0x1EE +#define EEPMWR 0x1FC +#define EEPMRD 0x1FD // PHILIPS LCD command set -#define PNOP 0x100 -#define PSWRESET 0x101 -#define PBSTROFF 0x102 -#define PBSTRON 0x103 -#define PRDDIDIF 0x104 -#define PRDDST 0x109 -#define PSLEEPIN 0x110 -#define PSLEEPOUT 0x111 -#define PPTLON 0x112 -#define PNORON 0x113 -#define PINVOFF 0x120 -#define PINVON 0x121 -#define PDALO 0x122 -#define PDAL 0x123 -#define PSETCON 0x125 -#define PDISPOFF 0x128 -#define PDISPON 0x129 -#define PCASET 0x12A -#define PPASET 0x12B -#define PRAMWR 0x12C -#define PRGBSET 0x12D -#define PPTLAR 0x130 -#define PVSCRDEF 0x133 -#define PTEOFF 0x134 -#define PTEON 0x135 -#define PMADCTL 0x136 -#define PSEP 0x137 -#define PIDMOFF 0x138 -#define PIDMON 0x139 -#define PCOLMOD 0x13A -#define PSETVOP 0x1B0 -#define PBRS 0x1B4 -#define PTRS 0x1B6 -#define PFINV 0x1B9 -#define PDOR 0x1BA -#define PTCDFE 0x1BD -#define PTCVOPE 0x1BF -#define PEC 0x1C0 -#define PSETMUL 0x1C2 -#define PTCVOPAB 0x1C3 -#define PTCVOPCD 0x1C4 -#define PTCDF 0x1C5 -#define PDF8C 0x1C6 -#define PSETBS 0x1C7 -#define PRDTEMP 0x1C8 -#define PNLI 0x1C9 -#define PRDID1 0x1DA -#define PRDID2 0x1DB -#define PRDID3 0x1DC -#define PSFD 0x1EF -#define PECM 0x1F0 +#define PNOP 0x100 +#define PSWRESET 0x101 +#define PBSTROFF 0x102 +#define PBSTRON 0x103 +#define PRDDIDIF 0x104 +#define PRDDST 0x109 +#define PSLEEPIN 0x110 +#define PSLEEPOUT 0x111 +#define PPTLON 0x112 +#define PNORON 0x113 +#define PINVOFF 0x120 +#define PINVON 0x121 +#define PDALO 0x122 +#define PDAL 0x123 +#define PSETCON 0x125 +#define PDISPOFF 0x128 +#define PDISPON 0x129 +#define PCASET 0x12A +#define PPASET 0x12B +#define PRAMWR 0x12C +#define PRGBSET 0x12D +#define PPTLAR 0x130 +#define PVSCRDEF 0x133 +#define PTEOFF 0x134 +#define PTEON 0x135 +#define PMADCTL 0x136 +#define PSEP 0x137 +#define PIDMOFF 0x138 +#define PIDMON 0x139 +#define PCOLMOD 0x13A +#define PSETVOP 0x1B0 +#define PBRS 0x1B4 +#define PTRS 0x1B6 +#define PFINV 0x1B9 +#define PDOR 0x1BA +#define PTCDFE 0x1BD +#define PTCVOPE 0x1BF +#define PEC 0x1C0 +#define PSETMUL 0x1C2 +#define PTCVOPAB 0x1C3 +#define PTCVOPCD 0x1C4 +#define PTCDF 0x1C5 +#define PDF8C 0x1C6 +#define PSETBS 0x1C7 +#define PRDTEMP 0x1C8 +#define PNLI 0x1C9 +#define PRDID1 0x1DA +#define PRDID2 0x1DB +#define PRDID3 0x1DC +#define PSFD 0x1EF +#define PECM 0x1F0 void LCDSend(unsigned int data); void LCDInit(void); diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 68b51913f..2d8730cd7 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -55,55 +55,55 @@ static int ToSendBit; struct common_area common_area __attribute__((section(".commonarea"))); void ToSendReset(void) { - ToSendMax = -1; - ToSendBit = 8; + ToSendMax = -1; + ToSendBit = 8; } void ToSendStuffBit(int b) { - if(ToSendBit >= 8) { - ToSendMax++; - ToSend[ToSendMax] = 0; - ToSendBit = 0; - } + if(ToSendBit >= 8) { + ToSendMax++; + ToSend[ToSendMax] = 0; + ToSendBit = 0; + } - if(b) - ToSend[ToSendMax] |= (1 << (7 - ToSendBit)); + if(b) + ToSend[ToSendMax] |= (1 << (7 - ToSendBit)); - ToSendBit++; + ToSendBit++; - if(ToSendMax >= sizeof(ToSend)) { - ToSendBit = 0; - DbpString("ToSendStuffBit overflowed!"); - } + if(ToSendMax >= sizeof(ToSend)) { + ToSendBit = 0; + DbpString("ToSendStuffBit overflowed!"); + } } void PrintToSendBuffer(void) { - DbpString("Printing ToSendBuffer:"); - Dbhexdump(ToSendMax, ToSend, 0); + DbpString("Printing ToSendBuffer:"); + Dbhexdump(ToSendMax, ToSend, 0); } void print_result(char *name, uint8_t *buf, size_t len) { - uint8_t *p = buf; - uint16_t tmp = len & 0xFFF0; + uint8_t *p = buf; + uint16_t tmp = len & 0xFFF0; - for(; p-buf < tmp; p += 16) { - Dbprintf("[%s: %02d/%02d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", - name, - p-buf, - len, - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15] - ); - } - if (len % 16 != 0) { - char s[46] = {0}; - char *sp = s; - for (; p-buf < len; p++ ) { - sprintf(sp, "%02x ", p[0] ); - sp += 3; - } - Dbprintf("[%s: %02d/%02d] %s", name, p-buf, len, s); - } + for(; p-buf < tmp; p += 16) { + Dbprintf("[%s: %02d/%02d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + name, + p-buf, + len, + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15] + ); + } + if (len % 16 != 0) { + char s[46] = {0}; + char *sp = s; + for (; p-buf < len; p++ ) { + sprintf(sp, "%02x ", p[0] ); + sp += 3; + } + Dbprintf("[%s: %02d/%02d] %s", name, p-buf, len, s); + } } //============================================================================= @@ -112,77 +112,77 @@ void print_result(char *name, uint8_t *buf, size_t len) { void DbpStringEx(char *str, uint32_t cmd) { #if DEBUG - uint8_t len = strlen(str); - cmd_send(CMD_DEBUG_PRINT_STRING, len, cmd, 0, (uint8_t*)str, len); + uint8_t len = strlen(str); + cmd_send(CMD_DEBUG_PRINT_STRING, len, cmd, 0, (uint8_t*)str, len); #endif } void DbpString(char *str) { #if DEBUG - DbpStringEx(str, 0); + DbpStringEx(str, 0); #endif } #if 0 void DbpIntegers(int x1, int x2, int x3) { - cmd_send(CMD_DEBUG_PRINT_INTEGERS,x1,x2,x3,0,0); + cmd_send(CMD_DEBUG_PRINT_INTEGERS,x1,x2,x3,0,0); } #endif void DbprintfEx(uint32_t cmd, const char *fmt, ...) { #if DEBUG - // should probably limit size here; oh well, let's just use a big buffer - char output_string[128] = {0x00}; - va_list ap; - va_start(ap, fmt); - kvsprintf(fmt, output_string, 10, ap); - va_end(ap); + // should probably limit size here; oh well, let's just use a big buffer + char output_string[128] = {0x00}; + va_list ap; + va_start(ap, fmt); + kvsprintf(fmt, output_string, 10, ap); + va_end(ap); - DbpStringEx(output_string, cmd); + DbpStringEx(output_string, cmd); #endif } void Dbprintf(const char *fmt, ...) { #if DEBUG - // should probably limit size here; oh well, let's just use a big buffer - char output_string[128] = {0x00}; - va_list ap; + // should probably limit size here; oh well, let's just use a big buffer + char output_string[128] = {0x00}; + va_list ap; - va_start(ap, fmt); - kvsprintf(fmt, output_string, 10, ap); - va_end(ap); + va_start(ap, fmt); + kvsprintf(fmt, output_string, 10, ap); + va_end(ap); - DbpString(output_string); + DbpString(output_string); #endif } // prints HEX & ASCII void Dbhexdump(int len, uint8_t *d, bool bAsci) { #if DEBUG - int l=0, i; - char ascii[9]; + int l=0, i; + char ascii[9]; - while (len > 0) { + while (len > 0) { - l = (len > 8) ? 8 : len; + l = (len > 8) ? 8 : len; - memcpy(ascii, d, l); - ascii[l] = 0; + memcpy(ascii, d, l); + ascii[l] = 0; - // filter safe ascii - for (i=0; i 126) { ascii[i] = '.'; - } + } } - if (bAsci) - Dbprintf("%-8s %*D", ascii, l, d, " "); - else - Dbprintf("%*D", l, d, " "); + if (bAsci) + Dbprintf("%-8s %*D", ascii, l, d, " "); + else + Dbprintf("%*D", l, d, " "); - len -= 8; - d += 8; - } + len -= 8; + d += 8; + } #endif } @@ -193,47 +193,47 @@ void Dbhexdump(int len, uint8_t *d, bool bAsci) { //----------------------------------------------------------------------------- static uint16_t ReadAdc(int ch) { - // Note: ADC_MODE_PRESCALE and ADC_MODE_SAMPLE_HOLD_TIME are set to the maximum allowed value. - // AMPL_HI is are high impedance (10MOhm || 1MOhm) output, the input capacitance of the ADC is 12pF (typical). This results in a time constant - // of RC = (0.91MOhm) * 12pF = 10.9us. Even after the maximum configurable sample&hold time of 40us the input capacitor will not be fully charged. - // - // The maths are: - // If there is a voltage v_in at the input, the voltage v_cap at the capacitor (this is what we are measuring) will be - // - // v_cap = v_in * (1 - exp(-SHTIM/RC)) = v_in * (1 - exp(-40us/10.9us)) = v_in * 0,97 (i.e. an error of 3%) + // Note: ADC_MODE_PRESCALE and ADC_MODE_SAMPLE_HOLD_TIME are set to the maximum allowed value. + // AMPL_HI is are high impedance (10MOhm || 1MOhm) output, the input capacitance of the ADC is 12pF (typical). This results in a time constant + // of RC = (0.91MOhm) * 12pF = 10.9us. Even after the maximum configurable sample&hold time of 40us the input capacitor will not be fully charged. + // + // The maths are: + // If there is a voltage v_in at the input, the voltage v_cap at the capacitor (this is what we are measuring) will be + // + // v_cap = v_in * (1 - exp(-SHTIM/RC)) = v_in * (1 - exp(-40us/10.9us)) = v_in * 0,97 (i.e. an error of 3%) - AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST; + AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST; AT91C_BASE_ADC->ADC_MR = - ADC_MODE_PRESCALE(63) // ADC_CLK = MCK / ((63+1) * 2) = 48MHz / 128 = 375kHz - | ADC_MODE_STARTUP_TIME(1) // Startup Time = (1+1) * 8 / ADC_CLK = 16 / 375kHz = 42,7us Note: must be > 20us - | ADC_MODE_SAMPLE_HOLD_TIME(15); // Sample & Hold Time SHTIM = 15 / ADC_CLK = 15 / 375kHz = 40us + ADC_MODE_PRESCALE(63) // ADC_CLK = MCK / ((63+1) * 2) = 48MHz / 128 = 375kHz + | ADC_MODE_STARTUP_TIME(1) // Startup Time = (1+1) * 8 / ADC_CLK = 16 / 375kHz = 42,7us Note: must be > 20us + | ADC_MODE_SAMPLE_HOLD_TIME(15); // Sample & Hold Time SHTIM = 15 / ADC_CLK = 15 / 375kHz = 40us - AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ch); - AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; + AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ch); + AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; - while (!(AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ch))) {}; + while (!(AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ch))) {}; - return (AT91C_BASE_ADC->ADC_CDR[ch] & 0x3FF); + return (AT91C_BASE_ADC->ADC_CDR[ch] & 0x3FF); } // was static - merlok uint16_t AvgAdc(int ch) { - uint16_t a = 0; - for(uint8_t i = 0; i < 32; i++) - a += ReadAdc(ch); + uint16_t a = 0; + for(uint8_t i = 0; i < 32; i++) + a += ReadAdc(ch); - //division by 32 - return (a + 15) >> 5; + //division by 32 + return (a + 15) >> 5; } void MeasureAntennaTuning(void) { - uint8_t LF_Results[256]; - uint32_t i, adcval = 0, peak = 0, peakv = 0, peakf = 0; - uint32_t v_lf125 = 0, v_lf134 = 0, v_hf = 0; // in mV + uint8_t LF_Results[256]; + uint32_t i, adcval = 0, peak = 0, peakv = 0, peakf = 0; + uint32_t v_lf125 = 0, v_lf134 = 0, v_hf = 0; // in mV - memset(LF_Results, 0, sizeof(LF_Results)); - LED_B_ON(); + memset(LF_Results, 0, sizeof(LF_Results)); + LED_B_ON(); /* * Sweeps the useful LF range of the proxmark from @@ -244,77 +244,77 @@ void MeasureAntennaTuning(void) { * ( hopefully around 95 if it is tuned to 125kHz!) */ - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - SpinDelay(50); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + SpinDelay(50); - for (i = 255; i >= 19; i--) { - WDT_HIT(); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i); - SpinDelay(20); - adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); + for (i = 255; i >= 19; i--) { + WDT_HIT(); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i); + SpinDelay(20); + adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); if (i == 95) v_lf125 = adcval; // voltage at 125Khz if (i == 89) v_lf134 = adcval; // voltage at 134Khz - LF_Results[i] = adcval >> 9; // scale int to fit in byte for graphing purposes - if(LF_Results[i] > peak) { - peakv = adcval; - peakf = i; - peak = LF_Results[i]; - } - } + LF_Results[i] = adcval >> 9; // scale int to fit in byte for graphing purposes + if(LF_Results[i] > peak) { + peakv = adcval; + peakf = i; + peak = LF_Results[i]; + } + } - 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(50); - v_hf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; + 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(50); + v_hf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; - // RDV40 will hit the roof, try other ADC channel used in that hardware revision. - if ( v_hf > MAX_ADC_HF_VOLTAGE-300 ) { - v_hf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; - } + // RDV40 will hit the roof, try other ADC channel used in that hardware revision. + if ( v_hf > MAX_ADC_HF_VOLTAGE-300 ) { + v_hf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; + } - uint64_t arg0 = v_lf134; - arg0 <<= 32; - arg0 |= v_lf125; + uint64_t arg0 = v_lf134; + arg0 <<= 32; + arg0 |= v_lf125; - uint64_t arg2 = peakv; - arg2 <<= 32; - arg2 |= peakf; + uint64_t arg2 = peakv; + arg2 <<= 32; + arg2 |= peakf; - cmd_send(CMD_MEASURED_ANTENNA_TUNING, arg0, v_hf, arg2, LF_Results, 256); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); + cmd_send(CMD_MEASURED_ANTENNA_TUNING, arg0, v_hf, arg2, LF_Results, 256); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); } void MeasureAntennaTuningHf(void) { - uint16_t volt = 0; // in mV - // 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(50); - volt = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; - bool use_high = ( volt > MAX_ADC_HF_VOLTAGE-300 ); + uint16_t volt = 0; // in mV + // 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(50); + volt = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; + bool use_high = ( volt > MAX_ADC_HF_VOLTAGE-300 ); - while( !BUTTON_PRESS() ){ - SpinDelay(20); - if ( !use_high ) { - volt = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; - } else { - volt = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; - } - DbprintfEx(FLAG_NONEWLINE, "%u mV / %5u V", volt, (uint16_t)(volt/1000)); - } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbprintfEx(FLAG_NOOPT, "\n[+] cancelled", 1); + while( !BUTTON_PRESS() ){ + SpinDelay(20); + if ( !use_high ) { + volt = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; + } else { + volt = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; + } + DbprintfEx(FLAG_NONEWLINE, "%u mV / %5u V", volt, (uint16_t)(volt/1000)); + } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + DbprintfEx(FLAG_NOOPT, "\n[+] cancelled", 1); } void ReadMem(int addr) { - const uint8_t *data = ((uint8_t *)addr); + const uint8_t *data = ((uint8_t *)addr); Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x", addr, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); } @@ -324,64 +324,64 @@ extern struct version_information version_information; /* bootrom version information is pointed to from _bootphase1_version_pointer */ extern char *_bootphase1_version_pointer, _flash_start, _flash_end, _bootrom_start, _bootrom_end, __data_src_start__; void SendVersion(void) { - char temp[USB_CMD_DATA_SIZE]; /* Limited data payload in USB packets */ - char VersionString[USB_CMD_DATA_SIZE] = { '\0' }; + char temp[USB_CMD_DATA_SIZE]; /* Limited data payload in USB packets */ + char VersionString[USB_CMD_DATA_SIZE] = { '\0' }; - /* Try to find the bootrom version information. Expect to find a pointer at - * symbol _bootphase1_version_pointer, perform slight sanity checks on the - * pointer, then use it. - */ - char *bootrom_version = *(char**)&_bootphase1_version_pointer; + /* Try to find the bootrom version information. Expect to find a pointer at + * symbol _bootphase1_version_pointer, perform slight sanity checks on the + * pointer, then use it. + */ + char *bootrom_version = *(char**)&_bootphase1_version_pointer; - strncat(VersionString, " [ ARM ]\n", sizeof(VersionString) - strlen(VersionString) - 1); + strncat(VersionString, " [ ARM ]\n", sizeof(VersionString) - strlen(VersionString) - 1); - if( bootrom_version < &_flash_start || bootrom_version >= &_flash_end ) { - strcat(VersionString, "bootrom version information appears invalid\n"); - } else { - FormatVersionInformation(temp, sizeof(temp), " bootrom: ", bootrom_version); - strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1); - } + if( bootrom_version < &_flash_start || bootrom_version >= &_flash_end ) { + strcat(VersionString, "bootrom version information appears invalid\n"); + } else { + FormatVersionInformation(temp, sizeof(temp), " bootrom: ", bootrom_version); + strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1); + } - FormatVersionInformation(temp, sizeof(temp), " os: ", &version_information); - strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1); + FormatVersionInformation(temp, sizeof(temp), " os: ", &version_information); + strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1); - strncat(VersionString, "\n [ FPGA ]\n", sizeof(VersionString) - strlen(VersionString) - 1); + strncat(VersionString, "\n [ FPGA ]\n", sizeof(VersionString) - strlen(VersionString) - 1); - for (int i = 0; i < fpga_bitstream_num; i++) { - strncat(VersionString, fpga_version_information[i], sizeof(VersionString) - strlen(VersionString) - 1); - if (i < fpga_bitstream_num - 1) { - strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1); - } - } - // Send Chip ID and used flash memory - uint32_t text_and_rodata_section_size = (uint32_t)&__data_src_start__ - (uint32_t)&_flash_start; - uint32_t compressed_data_section_size = common_area.arg1; - cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, 0, VersionString, strlen(VersionString)); + for (int i = 0; i < fpga_bitstream_num; i++) { + strncat(VersionString, fpga_version_information[i], sizeof(VersionString) - strlen(VersionString) - 1); + if (i < fpga_bitstream_num - 1) { + strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1); + } + } + // Send Chip ID and used flash memory + uint32_t text_and_rodata_section_size = (uint32_t)&__data_src_start__ - (uint32_t)&_flash_start; + uint32_t compressed_data_section_size = common_area.arg1; + cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, 0, VersionString, strlen(VersionString)); } // measure the USB Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time. // Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the UsbCommand structure included. void printUSBSpeed(void) { - Dbprintf("USB Speed"); - Dbprintf(" Sending USB packets to client..."); + Dbprintf("USB Speed"); + Dbprintf(" Sending USB packets to client..."); - #define USB_SPEED_TEST_MIN_TIME 1500 // in milliseconds - uint8_t *test_data = BigBuf_get_addr(); - uint32_t end_time; + #define USB_SPEED_TEST_MIN_TIME 1500 // in milliseconds + uint8_t *test_data = BigBuf_get_addr(); + uint32_t end_time; - uint32_t start_time = end_time = GetTickCount(); - uint32_t bytes_transferred = 0; + uint32_t start_time = end_time = GetTickCount(); + uint32_t bytes_transferred = 0; - LED_B_ON(); - while (end_time < start_time + USB_SPEED_TEST_MIN_TIME) { - cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, 0, USB_CMD_DATA_SIZE, 0, test_data, USB_CMD_DATA_SIZE); - end_time = GetTickCount(); - bytes_transferred += USB_CMD_DATA_SIZE; - } - LED_B_OFF(); + LED_B_ON(); + while (end_time < start_time + USB_SPEED_TEST_MIN_TIME) { + cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, 0, USB_CMD_DATA_SIZE, 0, test_data, USB_CMD_DATA_SIZE); + end_time = GetTickCount(); + bytes_transferred += USB_CMD_DATA_SIZE; + } + LED_B_OFF(); - Dbprintf(" Time elapsed............%dms", end_time - start_time); - Dbprintf(" Bytes transferred.......%d", bytes_transferred); + Dbprintf(" Time elapsed............%dms", end_time - start_time); + Dbprintf(" Bytes transferred.......%d", bytes_transferred); Dbprintf(" USB Transfer Speed PM3 -> Client = %d Bytes/s", 1000 * bytes_transferred / (end_time - start_time)); } @@ -389,81 +389,81 @@ void printUSBSpeed(void) { * Prints runtime information about the PM3. **/ void SendStatus(void) { - BigBuf_print_status(); - Fpga_print_status(); + BigBuf_print_status(); + Fpga_print_status(); #ifdef WITH_FLASH - Flashmem_print_status(); + Flashmem_print_status(); #endif #ifdef WITH_SMARTCARD - I2C_print_status(); + I2C_print_status(); #endif #ifdef WITH_LF - printConfig(); // LF Sampling config - printT55xxConfig(); // LF T55XX Config + printConfig(); // LF Sampling config + printT55xxConfig(); // LF T55XX Config #endif - printUSBSpeed(); - Dbprintf("Various"); - Dbprintf(" MF_DBGLEVEL.............%d", MF_DBGLEVEL); - Dbprintf(" ToSendMax...............%d", ToSendMax); - Dbprintf(" ToSendBit...............%d", ToSendBit); - Dbprintf(" ToSend BUFFERSIZE.......%d", TOSEND_BUFFER_SIZE); - printStandAloneModes(); - cmd_send(CMD_ACK, 1, 0, 0, 0, 0); + printUSBSpeed(); + Dbprintf("Various"); + Dbprintf(" MF_DBGLEVEL.............%d", MF_DBGLEVEL); + Dbprintf(" ToSendMax...............%d", ToSendMax); + Dbprintf(" ToSendBit...............%d", ToSendBit); + Dbprintf(" ToSend BUFFERSIZE.......%d", TOSEND_BUFFER_SIZE); + printStandAloneModes(); + cmd_send(CMD_ACK, 1, 0, 0, 0, 0); } // Show some leds in a pattern to identify StandAlone mod is running void StandAloneMode(void) { - DbpString("Stand-alone mode! No PC necessary."); + DbpString("Stand-alone mode! No PC necessary."); - SpinDown(50); + SpinDown(50); SpinOff(50); SpinUp(50); SpinOff(50); SpinDown(50); - SpinDelay(500); + SpinDelay(500); } // detection of which Standalone Modes is installed // (iceman) void printStandAloneModes(void) { - DbpString("Installed StandAlone Mode"); + DbpString("Installed StandAlone Mode"); #if defined(WITH_LF_ICERUN) - DbpString(" LF sniff/clone/simulation - aka IceRun (iceman)"); + DbpString(" LF sniff/clone/simulation - aka IceRun (iceman)"); #endif #if defined(WITH_HF_YOUNG) - DbpString(" HF Mifare sniff/simulation - (Craig Young)"); + DbpString(" HF Mifare sniff/simulation - (Craig Young)"); #endif #if defined(WITH_LF_SAMYRUN) - DbpString(" LF HID26 standalone - aka SamyRun (Samy Kamkar)"); + DbpString(" LF HID26 standalone - aka SamyRun (Samy Kamkar)"); #endif #if defined(WITH_LF_PROXBRUTE) - DbpString(" LF HID ProxII bruteforce - aka Proxbrute (Brad Antoniewicz)"); + DbpString(" LF HID ProxII bruteforce - aka Proxbrute (Brad Antoniewicz)"); #endif #if defined(WITH_LF_HIDBRUTE) - DbpString(" LF HID corporate 1000 bruteforce - aka Corporatebrute (Federico dotta & Maurizio Agazzini)"); + DbpString(" LF HID corporate 1000 bruteforce - aka Corporatebrute (Federico dotta & Maurizio Agazzini)"); #endif #if defined(WITH_HF_MATTYRUN) - DbpString(" HF Mifare sniff/clone - aka MattyRun (Matías A. Ré Medina)"); + DbpString(" HF Mifare sniff/clone - aka MattyRun (Matías A. Ré Medina)"); #endif #if defined(WITH_HF_COLIN) DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)"); #endif #if defined(WITH_HF_BOG) - DbpString(" HF 14a sniff standalone with ULC/ULEV1/NTAG auth storing in flashmem - aka BogitoRun (Bogito)"); + DbpString(" HF 14a sniff standalone with ULC/ULEV1/NTAG auth storing in flashmem - aka BogitoRun (Bogito)"); #endif - //DbpString("Running "); - //Dbprintf(" Is Device attached to USB| %s", USB_ATTACHED() ? "Yes" : "No"); - //Dbprintf(" Is Device attached to FPC| %s", 0 ? "Yes" : "No"); - //Dbprintf(" Is USB_reconnect value | %d", GetUSBreconnect() ); - //Dbprintf(" Is USB_configured value | %d", GetUSBconfigured() ); + //DbpString("Running "); + //Dbprintf(" Is Device attached to USB| %s", USB_ATTACHED() ? "Yes" : "No"); + //Dbprintf(" Is Device attached to FPC| %s", 0 ? "Yes" : "No"); + //Dbprintf(" Is USB_reconnect value | %d", GetUSBreconnect() ); + //Dbprintf(" Is USB_configured value | %d", GetUSBconfigured() ); - //.. add your own standalone detection based on with compiler directive you are used. - // don't "reuse" the already taken ones, this will make things easier when trying to detect the different modes - // 2017-08-06 must adapt the makefile and have individual compilation flags for all mods - // + //.. add your own standalone detection based on with compiler directive you are used. + // don't "reuse" the already taken ones, this will make things easier when trying to detect the different modes + // 2017-08-06 must adapt the makefile and have individual compilation flags for all mods + // } /* @@ -492,369 +492,369 @@ at the same place! :-) LIGHT SCHEME USED: */ static const char LIGHT_SCHEME[] = { - 0x0, /* ---- | No field detected */ - 0x1, /* X--- | 14% of maximum current detected */ - 0x2, /* -X-- | 29% of maximum current detected */ - 0x4, /* --X- | 43% of maximum current detected */ - 0x8, /* ---X | 57% of maximum current detected */ - 0xC, /* --XX | 71% of maximum current detected */ - 0xE, /* -XXX | 86% of maximum current detected */ - 0xF, /* XXXX | 100% of maximum current detected */ + 0x0, /* ---- | No field detected */ + 0x1, /* X--- | 14% of maximum current detected */ + 0x2, /* -X-- | 29% of maximum current detected */ + 0x4, /* --X- | 43% of maximum current detected */ + 0x8, /* ---X | 57% of maximum current detected */ + 0xC, /* --XX | 71% of maximum current detected */ + 0xE, /* -XXX | 86% of maximum current detected */ + 0xF, /* XXXX | 100% of maximum current detected */ }; static const int LIGHT_LEN = sizeof(LIGHT_SCHEME)/sizeof(LIGHT_SCHEME[0]); void ListenReaderField(int limit) { -#define LF_ONLY 1 -#define HF_ONLY 2 -#define REPORT_CHANGE 10 // report new values only if they have changed at least by REPORT_CHANGE +#define LF_ONLY 1 +#define HF_ONLY 2 +#define REPORT_CHANGE 10 // report new values only if they have changed at least by REPORT_CHANGE - uint16_t lf_av, lf_av_new, lf_baseline = 0, lf_max; - uint16_t hf_av, hf_av_new, hf_baseline = 0, hf_max; - uint16_t mode = 1, display_val, display_max, i; + uint16_t lf_av, lf_av_new, lf_baseline = 0, lf_max; + uint16_t hf_av, hf_av_new, hf_baseline = 0, hf_max; + uint16_t mode = 1, display_val, display_max, i; - // switch off FPGA - we don't want to measure our own signal - // 20180315 - iceman, why load this before and then turn off? - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // switch off FPGA - we don't want to measure our own signal + // 20180315 - iceman, why load this before and then turn off? + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); + LEDsoff(); - lf_av = lf_max = AvgAdc(ADC_CHAN_LF); + lf_av = lf_max = AvgAdc(ADC_CHAN_LF); - if (limit != HF_ONLY) { - Dbprintf("LF 125/134kHz Baseline: %dmV", (MAX_ADC_LF_VOLTAGE * lf_av) >> 10); - lf_baseline = lf_av; - } + if (limit != HF_ONLY) { + Dbprintf("LF 125/134kHz Baseline: %dmV", (MAX_ADC_LF_VOLTAGE * lf_av) >> 10); + lf_baseline = lf_av; + } - hf_av = hf_max = AvgAdc(ADC_CHAN_HF); + hf_av = hf_max = AvgAdc(ADC_CHAN_HF); - // iceman, useless, since we are measuring readerfield, not our field. My tests shows a max of 20v from a reader. - // RDV40 will hit the roof, try other ADC channel used in that hardware revision. - bool use_high = ( ((MAX_ADC_HF_VOLTAGE * hf_max) >> 10) > MAX_ADC_HF_VOLTAGE-300 ); - if ( use_high ) { - hf_av = hf_max = AvgAdc(ADC_CHAN_HF_RDV40); - } + // iceman, useless, since we are measuring readerfield, not our field. My tests shows a max of 20v from a reader. + // RDV40 will hit the roof, try other ADC channel used in that hardware revision. + bool use_high = ( ((MAX_ADC_HF_VOLTAGE * hf_max) >> 10) > MAX_ADC_HF_VOLTAGE-300 ); + if ( use_high ) { + hf_av = hf_max = AvgAdc(ADC_CHAN_HF_RDV40); + } - if (limit != LF_ONLY) { - Dbprintf("HF 13.56MHz Baseline: %dmV", (MAX_ADC_HF_VOLTAGE * hf_av) >> 10); - hf_baseline = hf_av; - } + if (limit != LF_ONLY) { + Dbprintf("HF 13.56MHz Baseline: %dmV", (MAX_ADC_HF_VOLTAGE * hf_av) >> 10); + hf_baseline = hf_av; + } - for(;;) { - // Switch modes with button - if (BUTTON_PRESS()) { - SpinDelay(500); - switch (mode) { - case 1: - mode = 2; - DbpString("Signal Strength Mode"); - break; - case 2: - default: - DbpString("Stopped"); - LEDsoff(); - return; - break; - } - } - WDT_HIT(); + for(;;) { + // Switch modes with button + if (BUTTON_PRESS()) { + SpinDelay(500); + switch (mode) { + case 1: + mode = 2; + DbpString("Signal Strength Mode"); + break; + case 2: + default: + DbpString("Stopped"); + LEDsoff(); + return; + break; + } + } + WDT_HIT(); - if (limit != HF_ONLY) { - if(mode == 1) { - if (ABS(lf_av - lf_baseline) > REPORT_CHANGE) - LED_D_ON(); - else - LED_D_OFF(); - } + if (limit != HF_ONLY) { + if(mode == 1) { + if (ABS(lf_av - lf_baseline) > REPORT_CHANGE) + LED_D_ON(); + else + LED_D_OFF(); + } - lf_av_new = AvgAdc(ADC_CHAN_LF); - // see if there's a significant change - if (ABS(lf_av - lf_av_new) > REPORT_CHANGE) { - Dbprintf("LF 125/134kHz Field Change: %5dmV", (MAX_ADC_LF_VOLTAGE * lf_av_new) >> 10); - lf_av = lf_av_new; - if (lf_av > lf_max) - lf_max = lf_av; - } - } + lf_av_new = AvgAdc(ADC_CHAN_LF); + // see if there's a significant change + if (ABS(lf_av - lf_av_new) > REPORT_CHANGE) { + Dbprintf("LF 125/134kHz Field Change: %5dmV", (MAX_ADC_LF_VOLTAGE * lf_av_new) >> 10); + lf_av = lf_av_new; + if (lf_av > lf_max) + lf_max = lf_av; + } + } - if (limit != LF_ONLY) { - if (mode == 1){ - if (ABS(hf_av - hf_baseline) > REPORT_CHANGE) - LED_B_ON(); - else - LED_B_OFF(); - } + if (limit != LF_ONLY) { + if (mode == 1){ + if (ABS(hf_av - hf_baseline) > REPORT_CHANGE) + LED_B_ON(); + else + LED_B_OFF(); + } - hf_av_new = (use_high) ? AvgAdc(ADC_CHAN_HF_RDV40) : AvgAdc(ADC_CHAN_HF); + hf_av_new = (use_high) ? AvgAdc(ADC_CHAN_HF_RDV40) : AvgAdc(ADC_CHAN_HF); - // see if there's a significant change - if(ABS(hf_av - hf_av_new) > REPORT_CHANGE) { - Dbprintf("HF 13.56MHz Field Change: %5dmV", (MAX_ADC_HF_VOLTAGE * hf_av_new) >> 10); - hf_av = hf_av_new; - if (hf_av > hf_max) - hf_max = hf_av; - } - } + // see if there's a significant change + if(ABS(hf_av - hf_av_new) > REPORT_CHANGE) { + Dbprintf("HF 13.56MHz Field Change: %5dmV", (MAX_ADC_HF_VOLTAGE * hf_av_new) >> 10); + hf_av = hf_av_new; + if (hf_av > hf_max) + hf_max = hf_av; + } + } - if (mode == 2) { - if (limit == LF_ONLY) { - display_val = lf_av; - display_max = lf_max; - } else if (limit == HF_ONLY) { - display_val = hf_av; - display_max = hf_max; - } else { /* Pick one at random */ - if( (hf_max - hf_baseline) > (lf_max - lf_baseline) ) { - display_val = hf_av; - display_max = hf_max; - } else { - display_val = lf_av; - display_max = lf_max; - } - } - for (i=0; i= ((display_max/LIGHT_LEN)*i) && display_val <= ((display_max/LIGHT_LEN)*(i+1))) { - if (LIGHT_SCHEME[i] & 0x1) LED_C_ON(); else LED_C_OFF(); - if (LIGHT_SCHEME[i] & 0x2) LED_A_ON(); else LED_A_OFF(); - if (LIGHT_SCHEME[i] & 0x4) LED_B_ON(); else LED_B_OFF(); - if (LIGHT_SCHEME[i] & 0x8) LED_D_ON(); else LED_D_OFF(); - break; - } - } - } - } + if (mode == 2) { + if (limit == LF_ONLY) { + display_val = lf_av; + display_max = lf_max; + } else if (limit == HF_ONLY) { + display_val = hf_av; + display_max = hf_max; + } else { /* Pick one at random */ + if( (hf_max - hf_baseline) > (lf_max - lf_baseline) ) { + display_val = hf_av; + display_max = hf_max; + } else { + display_val = lf_av; + display_max = lf_max; + } + } + for (i=0; i= ((display_max/LIGHT_LEN)*i) && display_val <= ((display_max/LIGHT_LEN)*(i+1))) { + if (LIGHT_SCHEME[i] & 0x1) LED_C_ON(); else LED_C_OFF(); + if (LIGHT_SCHEME[i] & 0x2) LED_A_ON(); else LED_A_OFF(); + if (LIGHT_SCHEME[i] & 0x4) LED_B_ON(); else LED_B_OFF(); + if (LIGHT_SCHEME[i] & 0x8) LED_D_ON(); else LED_D_OFF(); + break; + } + } + } + } } void UsbPacketReceived(uint8_t *packet, int len) { - UsbCommand *c = (UsbCommand *)packet; + UsbCommand *c = (UsbCommand *)packet; - //Dbprintf("received %d bytes, with command: 0x%04x and args: %d %d %d", len, c->cmd, c->arg[0], c->arg[1], c->arg[2]); + //Dbprintf("received %d bytes, with command: 0x%04x and args: %d %d %d", len, c->cmd, c->arg[0], c->arg[1], c->arg[2]); - switch(c->cmd) { + switch(c->cmd) { #ifdef WITH_LF - case CMD_SET_LF_T55XX_CONFIG: - setT55xxConfig( c->arg[0], (t55xx_config *) c->d.asBytes); - break; - case CMD_SET_LF_SAMPLING_CONFIG: - setSamplingConfig((sample_config *) c->d.asBytes); - break; - case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K: { - uint32_t bits = SampleLF(c->arg[0], c->arg[1]); - cmd_send(CMD_ACK, bits, 0, 0, 0, 0); - break; - } - 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: { - uint32_t bits = SnoopLF(); - cmd_send(CMD_ACK, bits, 0, 0, 0, 0); - break; - } - case CMD_HID_DEMOD_FSK: { - uint32_t high, low; - CmdHIDdemodFSK(c->arg[0], &high, &low, 1); - break; - } - case CMD_HID_SIM_TAG: - CmdHIDsimTAG(c->arg[0], c->arg[1], 1); - break; - case CMD_FSK_SIM_TAG: - CmdFSKsimTAG(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - case CMD_ASK_SIM_TAG: - CmdASKsimTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - case CMD_PSK_SIM_TAG: - CmdPSKsimTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - case CMD_HID_CLONE_TAG: - CopyHIDtoT55x7(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]); - break; - case CMD_IO_DEMOD_FSK: { - uint32_t high, low; - CmdIOdemodFSK(c->arg[0], &high, &low, 1); - break; - } - case CMD_IO_CLONE_TAG: - CopyIOtoT55x7(c->arg[0], c->arg[1]); - break; - case CMD_EM410X_DEMOD: { - uint32_t high; - uint64_t low; - CmdEM410xdemod(c->arg[0], &high, &low, 1); - break; - } - case CMD_EM410X_WRITE_TAG: - WriteEM410x(c->arg[0], c->arg[1], c->arg[2]); - break; - case CMD_READ_TI_TYPE: - ReadTItag(); - break; - case CMD_WRITE_TI_TYPE: - WriteTItag(c->arg[0],c->arg[1],c->arg[2]); - break; - case CMD_SIMULATE_TAG_125K: - LED_A_ON(); - SimulateTagLowFrequency(c->arg[0], c->arg[1], 1); - LED_A_OFF(); - break; - case CMD_LF_SIMULATE_BIDIR: - SimulateTagLowFrequencyBidir(c->arg[0], c->arg[1]); - break; - case CMD_INDALA_CLONE_TAG: - CopyIndala64toT55x7(c->arg[0], c->arg[1]); - break; - case CMD_INDALA_CLONE_TAG_L: - CopyIndala224toT55x7( - c->d.asDwords[0], c->d.asDwords[1], c->d.asDwords[2], c->d.asDwords[3], - c->d.asDwords[4], c->d.asDwords[5], c->d.asDwords[6] - ); - break; - case CMD_T55XX_READ_BLOCK: { - T55xxReadBlock(c->arg[0], c->arg[1], c->arg[2]); - break; - } - case CMD_T55XX_WRITE_BLOCK: - T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]); - break; - case CMD_T55XX_WAKEUP: - T55xxWakeUp(c->arg[0]); - break; - case CMD_T55XX_RESET_READ: - T55xxResetRead(); - break; - case CMD_T55XX_CHKPWDS: - T55xx_ChkPwds(); - break; - case CMD_PCF7931_READ: - ReadPCF7931(); - break; - case CMD_PCF7931_WRITE: - WritePCF7931( - c->d.asBytes[0], c->d.asBytes[1], c->d.asBytes[2], c->d.asBytes[3], - c->d.asBytes[4], c->d.asBytes[5], c->d.asBytes[6], c->d.asBytes[9], - c->d.asBytes[7] - 128, c->d.asBytes[8] - 128, - c->arg[0], - c->arg[1], - c->arg[2] - ); - break; - case CMD_EM4X_READ_WORD: - EM4xReadWord(c->arg[0], c->arg[1], c->arg[2]); - break; - case CMD_EM4X_WRITE_WORD: - EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2]); - break; - case CMD_AWID_DEMOD_FSK: { - uint32_t high, low; - // Set realtime AWID demodulation - CmdAWIDdemodFSK(c->arg[0], &high, &low, 1); - break; - } - case CMD_VIKING_CLONE_TAG: - CopyVikingtoT55xx(c->arg[0], c->arg[1], c->arg[2]); + case CMD_SET_LF_T55XX_CONFIG: + setT55xxConfig( c->arg[0], (t55xx_config *) c->d.asBytes); + break; + case CMD_SET_LF_SAMPLING_CONFIG: + setSamplingConfig((sample_config *) c->d.asBytes); + break; + case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K: { + uint32_t bits = SampleLF(c->arg[0], c->arg[1]); + cmd_send(CMD_ACK, bits, 0, 0, 0, 0); + break; + } + 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: { + uint32_t bits = SnoopLF(); + cmd_send(CMD_ACK, bits, 0, 0, 0, 0); + break; + } + case CMD_HID_DEMOD_FSK: { + uint32_t high, low; + CmdHIDdemodFSK(c->arg[0], &high, &low, 1); + break; + } + case CMD_HID_SIM_TAG: + CmdHIDsimTAG(c->arg[0], c->arg[1], 1); + break; + case CMD_FSK_SIM_TAG: + CmdFSKsimTAG(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_ASK_SIM_TAG: + CmdASKsimTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_PSK_SIM_TAG: + CmdPSKsimTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_HID_CLONE_TAG: + CopyHIDtoT55x7(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]); + break; + case CMD_IO_DEMOD_FSK: { + uint32_t high, low; + CmdIOdemodFSK(c->arg[0], &high, &low, 1); + break; + } + case CMD_IO_CLONE_TAG: + CopyIOtoT55x7(c->arg[0], c->arg[1]); + break; + case CMD_EM410X_DEMOD: { + uint32_t high; + uint64_t low; + CmdEM410xdemod(c->arg[0], &high, &low, 1); + break; + } + case CMD_EM410X_WRITE_TAG: + WriteEM410x(c->arg[0], c->arg[1], c->arg[2]); + break; + case CMD_READ_TI_TYPE: + ReadTItag(); + break; + case CMD_WRITE_TI_TYPE: + WriteTItag(c->arg[0],c->arg[1],c->arg[2]); + break; + case CMD_SIMULATE_TAG_125K: + LED_A_ON(); + SimulateTagLowFrequency(c->arg[0], c->arg[1], 1); + LED_A_OFF(); + break; + case CMD_LF_SIMULATE_BIDIR: + SimulateTagLowFrequencyBidir(c->arg[0], c->arg[1]); + break; + case CMD_INDALA_CLONE_TAG: + CopyIndala64toT55x7(c->arg[0], c->arg[1]); + break; + case CMD_INDALA_CLONE_TAG_L: + CopyIndala224toT55x7( + c->d.asDwords[0], c->d.asDwords[1], c->d.asDwords[2], c->d.asDwords[3], + c->d.asDwords[4], c->d.asDwords[5], c->d.asDwords[6] + ); + break; + case CMD_T55XX_READ_BLOCK: { + T55xxReadBlock(c->arg[0], c->arg[1], c->arg[2]); + break; + } + case CMD_T55XX_WRITE_BLOCK: + T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]); + break; + case CMD_T55XX_WAKEUP: + T55xxWakeUp(c->arg[0]); + break; + case CMD_T55XX_RESET_READ: + T55xxResetRead(); + break; + case CMD_T55XX_CHKPWDS: + T55xx_ChkPwds(); + break; + case CMD_PCF7931_READ: + ReadPCF7931(); + break; + case CMD_PCF7931_WRITE: + WritePCF7931( + c->d.asBytes[0], c->d.asBytes[1], c->d.asBytes[2], c->d.asBytes[3], + c->d.asBytes[4], c->d.asBytes[5], c->d.asBytes[6], c->d.asBytes[9], + c->d.asBytes[7] - 128, c->d.asBytes[8] - 128, + c->arg[0], + c->arg[1], + c->arg[2] + ); + break; + case CMD_EM4X_READ_WORD: + EM4xReadWord(c->arg[0], c->arg[1], c->arg[2]); + break; + case CMD_EM4X_WRITE_WORD: + EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2]); + break; + case CMD_AWID_DEMOD_FSK: { + uint32_t high, low; + // Set realtime AWID demodulation + CmdAWIDdemodFSK(c->arg[0], &high, &low, 1); + break; + } + case CMD_VIKING_CLONE_TAG: + CopyVikingtoT55xx(c->arg[0], c->arg[1], c->arg[2]); + break; + case CMD_COTAG: + Cotag(c->arg[0]); break; - case CMD_COTAG: - Cotag(c->arg[0]); - break; #endif #ifdef WITH_HITAG - case CMD_SNOOP_HITAG: // Eavesdrop Hitag tag, args = type - SnoopHitag(c->arg[0]); - break; - case CMD_SIMULATE_HITAG: // Simulate Hitag tag, args = memory content - SimulateHitagTag((bool)c->arg[0],(byte_t*)c->d.asBytes); - break; - case CMD_READER_HITAG: // Reader for Hitag tags, args = type and function - ReaderHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes); - break; - case CMD_SIMULATE_HITAG_S:// Simulate Hitag s tag, args = memory content - SimulateHitagSTag((bool)c->arg[0],(byte_t*)c->d.asBytes); - break; - case CMD_TEST_HITAGS_TRACES:// Tests every challenge within the given file - check_challenges((bool)c->arg[0],(byte_t*)c->d.asBytes); - break; - case CMD_READ_HITAG_S: //Reader for only Hitag S tags, args = key or challenge - ReadHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes); - break; - case CMD_WR_HITAG_S: //writer for Hitag tags args=data to write,page and key or challenge - if ((hitag_function)c->arg[0] < 10) { - WritePageHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes,c->arg[2]); - } else if ((hitag_function)c->arg[0] >= 10) { - WriterHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes, c->arg[2]); - } - break; + case CMD_SNOOP_HITAG: // Eavesdrop Hitag tag, args = type + SnoopHitag(c->arg[0]); + break; + case CMD_SIMULATE_HITAG: // Simulate Hitag tag, args = memory content + SimulateHitagTag((bool)c->arg[0],(byte_t*)c->d.asBytes); + break; + case CMD_READER_HITAG: // Reader for Hitag tags, args = type and function + ReaderHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes); + break; + case CMD_SIMULATE_HITAG_S:// Simulate Hitag s tag, args = memory content + SimulateHitagSTag((bool)c->arg[0],(byte_t*)c->d.asBytes); + break; + case CMD_TEST_HITAGS_TRACES:// Tests every challenge within the given file + check_challenges((bool)c->arg[0],(byte_t*)c->d.asBytes); + break; + case CMD_READ_HITAG_S: //Reader for only Hitag S tags, args = key or challenge + ReadHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes); + break; + case CMD_WR_HITAG_S: //writer for Hitag tags args=data to write,page and key or challenge + if ((hitag_function)c->arg[0] < 10) { + WritePageHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes,c->arg[2]); + } else if ((hitag_function)c->arg[0] >= 10) { + WriterHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes, c->arg[2]); + } + break; #endif #ifdef WITH_ISO15693 - case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693: - AcquireRawAdcSamplesIso15693(); - break; - case CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693: - RecordRawAdcSamplesIso15693(); - break; - case CMD_ISO_15693_COMMAND: - DirectTag15693Command(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - case CMD_ISO_15693_FIND_AFI: - BruteforceIso15693Afi(c->arg[0]); - break; - case CMD_READER_ISO_15693: - ReaderIso15693(c->arg[0]); - break; - case CMD_SIMTAG_ISO_15693: - SimTagIso15693(c->arg[0], c->d.asBytes); - break; + case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693: + AcquireRawAdcSamplesIso15693(); + break; + case CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693: + RecordRawAdcSamplesIso15693(); + break; + case CMD_ISO_15693_COMMAND: + DirectTag15693Command(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_ISO_15693_FIND_AFI: + BruteforceIso15693Afi(c->arg[0]); + break; + case CMD_READER_ISO_15693: + ReaderIso15693(c->arg[0]); + break; + case CMD_SIMTAG_ISO_15693: + SimTagIso15693(c->arg[0], c->d.asBytes); + break; #endif #ifdef WITH_LEGICRF - case CMD_SIMULATE_TAG_LEGIC_RF: - LegicRfSimulate(c->arg[0]); - break; - case CMD_WRITER_LEGIC_RF: - LegicRfWriter(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - case CMD_READER_LEGIC_RF: - LegicRfReader(c->arg[0], c->arg[1], c->arg[2]); - break; - case CMD_LEGIC_INFO: - LegicRfInfo(); - break; - case CMD_LEGIC_ESET: - //----------------------------------------------------------------------------- - // Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_HF) here although FPGA is not - // involved in dealing with emulator memory. But if it is called later, it might - // destroy the Emulator Memory. - //----------------------------------------------------------------------------- - // arg0 = offset - // arg1 = num of bytes - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - emlSet(c->d.asBytes, c->arg[0], c->arg[1]); - break; + case CMD_SIMULATE_TAG_LEGIC_RF: + LegicRfSimulate(c->arg[0]); + break; + case CMD_WRITER_LEGIC_RF: + LegicRfWriter(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_READER_LEGIC_RF: + LegicRfReader(c->arg[0], c->arg[1], c->arg[2]); + break; + case CMD_LEGIC_INFO: + LegicRfInfo(); + break; + case CMD_LEGIC_ESET: + //----------------------------------------------------------------------------- + // Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_HF) here although FPGA is not + // involved in dealing with emulator memory. But if it is called later, it might + // destroy the Emulator Memory. + //----------------------------------------------------------------------------- + // arg0 = offset + // arg1 = num of bytes + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + emlSet(c->d.asBytes, c->arg[0], c->arg[1]); + break; #endif #ifdef WITH_ISO14443b - case CMD_READ_SRI_TAG: - ReadSTMemoryIso14443b(c->arg[0]); - break; - case CMD_SNOOP_ISO_14443B: - SniffIso14443b(); - break; - case CMD_SIMULATE_TAG_ISO_14443B: - SimulateIso14443bTag(c->arg[0]); - break; - case CMD_ISO_14443B_COMMAND: - //SendRawCommand14443B(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes); - SendRawCommand14443B_Ex(c); - break; + case CMD_READ_SRI_TAG: + ReadSTMemoryIso14443b(c->arg[0]); + break; + case CMD_SNOOP_ISO_14443B: + SniffIso14443b(); + break; + case CMD_SIMULATE_TAG_ISO_14443B: + SimulateIso14443bTag(c->arg[0]); + break; + case CMD_ISO_14443B_COMMAND: + //SendRawCommand14443B(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes); + SendRawCommand14443B_Ex(c); + break; #endif #ifdef WITH_FELICA - case CMD_FELICA_COMMAND: - felica_sendraw(c); - break; + case CMD_FELICA_COMMAND: + felica_sendraw(c); + break; case CMD_FELICA_LITE_SIM: felica_sim_lite(c->arg[0]); break; @@ -862,701 +862,701 @@ void UsbPacketReceived(uint8_t *packet, int len) { felica_sniff(c->arg[0], c->arg[1]); break; case CMD_FELICA_LITE_DUMP: - felica_dump_lite_s(); + felica_dump_lite_s(); break; #endif #ifdef WITH_ISO14443a - case CMD_SNOOP_ISO_14443a: - SniffIso14443a(c->arg[0]); - break; - case CMD_READER_ISO_14443a: - ReaderIso14443a(c); - break; - case CMD_SIMULATE_TAG_ISO_14443a: - SimulateIso14443aTag(c->arg[0], c->arg[1], c->d.asBytes); // ## Simulate iso14443a tag - pass tag type & UID - break; - case CMD_ANTIFUZZ_ISO_14443a: - iso14443a_antifuzz(c->arg[0]); - break; - case CMD_EPA_PACE_COLLECT_NONCE: - EPA_PACE_Collect_Nonce(c); - break; - case CMD_EPA_PACE_REPLAY: - EPA_PACE_Replay(c); - break; - case CMD_READER_MIFARE: + case CMD_SNOOP_ISO_14443a: + SniffIso14443a(c->arg[0]); + break; + case CMD_READER_ISO_14443a: + ReaderIso14443a(c); + break; + case CMD_SIMULATE_TAG_ISO_14443a: + SimulateIso14443aTag(c->arg[0], c->arg[1], c->d.asBytes); // ## Simulate iso14443a tag - pass tag type & UID + break; + case CMD_ANTIFUZZ_ISO_14443a: + iso14443a_antifuzz(c->arg[0]); + break; + case CMD_EPA_PACE_COLLECT_NONCE: + EPA_PACE_Collect_Nonce(c); + break; + case CMD_EPA_PACE_REPLAY: + EPA_PACE_Replay(c); + break; + case CMD_READER_MIFARE: ReaderMifare(c->arg[0], c->arg[1], c->arg[2]); - break; - case CMD_MIFARE_READBL: - MifareReadBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - case CMD_MIFAREU_READBL: - MifareUReadBlock(c->arg[0],c->arg[1], c->d.asBytes); - break; - case CMD_MIFAREUC_AUTH: - MifareUC_Auth(c->arg[0],c->d.asBytes); - break; - case CMD_MIFAREU_READCARD: - MifareUReadCard(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - case CMD_MIFAREUC_SETPWD: - MifareUSetPwd(c->arg[0], c->d.asBytes); - break; - case CMD_MIFARE_READSC: - MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - case CMD_MIFARE_WRITEBL: - MifareWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - //case CMD_MIFAREU_WRITEBL_COMPAT: - //MifareUWriteBlockCompat(c->arg[0], c->d.asBytes); - //break; - case CMD_MIFAREU_WRITEBL: - MifareUWriteBlock(c->arg[0], c->arg[1], c->d.asBytes); - break; - case CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES: - MifareAcquireEncryptedNonces(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - case CMD_MIFARE_ACQUIRE_NONCES: - MifareAcquireNonces(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - case CMD_MIFARE_NESTED: - MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - case CMD_MIFARE_CHKKEYS: { - MifareChkKeys(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - } - case CMD_MIFARE_CHKKEYS_FAST: { - MifareChkKeys_fast(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - } - case CMD_SIMULATE_MIFARE_CARD: - Mifare1ksim(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; + break; + case CMD_MIFARE_READBL: + MifareReadBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_MIFAREU_READBL: + MifareUReadBlock(c->arg[0],c->arg[1], c->d.asBytes); + break; + case CMD_MIFAREUC_AUTH: + MifareUC_Auth(c->arg[0],c->d.asBytes); + break; + case CMD_MIFAREU_READCARD: + MifareUReadCard(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_MIFAREUC_SETPWD: + MifareUSetPwd(c->arg[0], c->d.asBytes); + break; + case CMD_MIFARE_READSC: + MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_MIFARE_WRITEBL: + MifareWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + //case CMD_MIFAREU_WRITEBL_COMPAT: + //MifareUWriteBlockCompat(c->arg[0], c->d.asBytes); + //break; + case CMD_MIFAREU_WRITEBL: + MifareUWriteBlock(c->arg[0], c->arg[1], c->d.asBytes); + break; + case CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES: + MifareAcquireEncryptedNonces(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_MIFARE_ACQUIRE_NONCES: + MifareAcquireNonces(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_MIFARE_NESTED: + MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_MIFARE_CHKKEYS: { + MifareChkKeys(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + } + case CMD_MIFARE_CHKKEYS_FAST: { + MifareChkKeys_fast(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + } + case CMD_SIMULATE_MIFARE_CARD: + Mifare1ksim(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; - // emulator - case CMD_MIFARE_SET_DBGMODE: - MifareSetDbgLvl(c->arg[0]); - break; - case CMD_MIFARE_EML_MEMCLR: - MifareEMemClr(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - case CMD_MIFARE_EML_MEMSET: - MifareEMemSet(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - case CMD_MIFARE_EML_MEMGET: - MifareEMemGet(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - case CMD_MIFARE_EML_CARDLOAD: - MifareECardLoad(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; + // emulator + case CMD_MIFARE_SET_DBGMODE: + MifareSetDbgLvl(c->arg[0]); + break; + case CMD_MIFARE_EML_MEMCLR: + MifareEMemClr(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_MIFARE_EML_MEMSET: + MifareEMemSet(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_MIFARE_EML_MEMGET: + MifareEMemGet(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_MIFARE_EML_CARDLOAD: + MifareECardLoad(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; - // Work with "magic Chinese" card - case CMD_MIFARE_CSETBLOCK: - MifareCSetBlock(c->arg[0], c->arg[1], c->d.asBytes); - break; - case CMD_MIFARE_CGETBLOCK: - MifareCGetBlock(c->arg[0], c->arg[1], c->d.asBytes); - break; - case CMD_MIFARE_CIDENT: - MifareCIdent(); - break; - // mifare sniffer -// case CMD_MIFARE_SNIFFER: - //SniffMifare(c->arg[0]); -// break; - case CMD_MIFARE_SETMOD: - MifareSetMod(c->arg[0], c->d.asBytes); - break; - //mifare desfire - case CMD_MIFARE_DESFIRE_READBL: - break; - case CMD_MIFARE_DESFIRE_WRITEBL: - break; - case CMD_MIFARE_DESFIRE_AUTH1: - MifareDES_Auth1(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); - break; - case CMD_MIFARE_DESFIRE_AUTH2: - //MifareDES_Auth2(c->arg[0],c->d.asBytes); - break; - case CMD_MIFARE_DES_READER: - //readermifaredes(c->arg[0], c->arg[1], c->d.asBytes); - break; - case CMD_MIFARE_DESFIRE_INFO: - MifareDesfireGetInformation(); - break; - case CMD_MIFARE_DESFIRE: - MifareSendCommand(c->arg[0], c->arg[1], c->d.asBytes); - break; - case CMD_MIFARE_COLLECT_NONCES: - break; - case CMD_MIFARE_NACK_DETECT: - DetectNACKbug(); - break; + // Work with "magic Chinese" card + case CMD_MIFARE_CSETBLOCK: + MifareCSetBlock(c->arg[0], c->arg[1], c->d.asBytes); + break; + case CMD_MIFARE_CGETBLOCK: + MifareCGetBlock(c->arg[0], c->arg[1], c->d.asBytes); + break; + case CMD_MIFARE_CIDENT: + MifareCIdent(); + break; + // mifare sniffer +// case CMD_MIFARE_SNIFFER: +// SniffMifare(c->arg[0]); +// break; + case CMD_MIFARE_SETMOD: + MifareSetMod(c->arg[0], c->d.asBytes); + break; + //mifare desfire + case CMD_MIFARE_DESFIRE_READBL: + break; + case CMD_MIFARE_DESFIRE_WRITEBL: + break; + case CMD_MIFARE_DESFIRE_AUTH1: + MifareDES_Auth1(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_MIFARE_DESFIRE_AUTH2: + //MifareDES_Auth2(c->arg[0],c->d.asBytes); + break; + case CMD_MIFARE_DES_READER: + //readermifaredes(c->arg[0], c->arg[1], c->d.asBytes); + break; + case CMD_MIFARE_DESFIRE_INFO: + MifareDesfireGetInformation(); + break; + case CMD_MIFARE_DESFIRE: + MifareSendCommand(c->arg[0], c->arg[1], c->d.asBytes); + break; + case CMD_MIFARE_COLLECT_NONCES: + break; + case CMD_MIFARE_NACK_DETECT: + DetectNACKbug(); + break; #endif #ifdef WITH_ICLASS - // Makes use of ISO14443a FPGA Firmware - case CMD_SNOOP_ICLASS: - SniffIClass(); - break; - case CMD_SIMULATE_TAG_ICLASS: - 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; - case CMD_ICLASS_EML_MEMSET: - //iceman, should call FPGADOWNLOAD before, since it corrupts BigBuf - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - emlSet(c->d.asBytes, c->arg[0], c->arg[1]); - break; - case CMD_ICLASS_WRITEBLOCK: - iClass_WriteBlock(c->arg[0], c->d.asBytes); - break; - case CMD_ICLASS_READCHECK: // auth step 1 - iClass_ReadCheck(c->arg[0], c->arg[1]); - break; - case CMD_ICLASS_READBLOCK: - iClass_ReadBlk(c->arg[0]); - break; - case CMD_ICLASS_AUTHENTICATION: //check - iClass_Authentication(c->d.asBytes); - break; - case CMD_ICLASS_CHECK_KEYS: - iClass_Authentication_fast(c->arg[0], c->arg[1], c->d.asBytes); - break; - case CMD_ICLASS_DUMP: - iClass_Dump(c->arg[0], c->arg[1]); - break; - case CMD_ICLASS_CLONE: - iClass_Clone(c->arg[0], c->arg[1], c->d.asBytes); - break; + // Makes use of ISO14443a FPGA Firmware + case CMD_SNOOP_ICLASS: + SniffIClass(); + break; + case CMD_SIMULATE_TAG_ICLASS: + 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; + case CMD_ICLASS_EML_MEMSET: + //iceman, should call FPGADOWNLOAD before, since it corrupts BigBuf + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + emlSet(c->d.asBytes, c->arg[0], c->arg[1]); + break; + case CMD_ICLASS_WRITEBLOCK: + iClass_WriteBlock(c->arg[0], c->d.asBytes); + break; + case CMD_ICLASS_READCHECK: // auth step 1 + iClass_ReadCheck(c->arg[0], c->arg[1]); + break; + case CMD_ICLASS_READBLOCK: + iClass_ReadBlk(c->arg[0]); + break; + case CMD_ICLASS_AUTHENTICATION: //check + iClass_Authentication(c->d.asBytes); + break; + case CMD_ICLASS_CHECK_KEYS: + iClass_Authentication_fast(c->arg[0], c->arg[1], c->d.asBytes); + break; + case CMD_ICLASS_DUMP: + iClass_Dump(c->arg[0], c->arg[1]); + break; + case CMD_ICLASS_CLONE: + iClass_Clone(c->arg[0], c->arg[1], c->d.asBytes); + break; #endif #ifdef WITH_HFSNOOP - case CMD_HF_SNIFFER: - HfSnoop(c->arg[0], c->arg[1]); - break; + case CMD_HF_SNIFFER: + HfSnoop(c->arg[0], c->arg[1]); + break; #endif #ifdef WITH_SMARTCARD - case CMD_SMART_ATR: { - SmartCardAtr(); - break; - } - case CMD_SMART_SETBAUD:{ - SmartCardSetBaud(c->arg[0]); - break; - } - case CMD_SMART_SETCLOCK:{ - SmartCardSetClock(c->arg[0]); - break; - } - case CMD_SMART_RAW: { - SmartCardRaw(c->arg[0], c->arg[1], c->d.asBytes); + case CMD_SMART_ATR: { + SmartCardAtr(); break; } - case CMD_SMART_UPLOAD: { - // upload file from client - uint8_t *mem = BigBuf_get_addr(); - memcpy( mem + c->arg[0], c->d.asBytes, USB_CMD_DATA_SIZE); - cmd_send(CMD_ACK,1,0,0,0,0); - break; - } - case CMD_SMART_UPGRADE: { - SmartCardUpgrade(c->arg[0]); + case CMD_SMART_SETBAUD:{ + SmartCardSetBaud(c->arg[0]); break; - } + } + case CMD_SMART_SETCLOCK:{ + SmartCardSetClock(c->arg[0]); + break; + } + case CMD_SMART_RAW: { + SmartCardRaw(c->arg[0], c->arg[1], c->d.asBytes); + break; + } + case CMD_SMART_UPLOAD: { + // upload file from client + uint8_t *mem = BigBuf_get_addr(); + memcpy( mem + c->arg[0], c->d.asBytes, USB_CMD_DATA_SIZE); + cmd_send(CMD_ACK,1,0,0,0,0); + break; + } + case CMD_SMART_UPGRADE: { + SmartCardUpgrade(c->arg[0]); + break; + } #endif #ifdef WITH_FPC - case CMD_FPC_SEND: { + case CMD_FPC_SEND: { - StartTicks(); - DbpString("Mutual USB/FPC sending from device to client"); + StartTicks(); + DbpString("Mutual USB/FPC sending from device to client"); - /* - char at[11] = {'\0'}; - static const char* s_at = "AT+BAUD8\0D\0A"; - strncat(at, s_at, sizeof(at) - strlen(at) - 1); - DbpString("Try AT baud rate setting"); - usart_init(); - int16_t res = usart_writebuffer((uint8_t*)&at, sizeof(at)); - WaitMS(1); - Dbprintf("SEND %d | %c%c%c%c%c%c%c%c%c%c%c", res, at[0], at[1], at[2], at[3], at[4], at[5], at[6], at[7], at[8], at[9], at[10]); + /* + char at[11] = {'\0'}; + static const char* s_at = "AT+BAUD8\0D\0A"; + strncat(at, s_at, sizeof(at) - strlen(at) - 1); + DbpString("Try AT baud rate setting"); + usart_init(); + int16_t res = usart_writebuffer((uint8_t*)&at, sizeof(at)); + WaitMS(1); + Dbprintf("SEND %d | %c%c%c%c%c%c%c%c%c%c%c", res, at[0], at[1], at[2], at[3], at[4], at[5], at[6], at[7], at[8], at[9], at[10]); - uint8_t my_rx[20]; - memset(my_rx, 0, sizeof(my_rx)); - res = usart_readbuffer(my_rx, sizeof(my_rx)); - WaitMS(1); - Dbprintf("GOT %d | %c%c%c%c%c%c%c%c", res, my_rx[0], my_rx[1], my_rx[2], my_rx[3], my_rx[4], my_rx[5], my_rx[6], my_rx[7]); - */ + uint8_t my_rx[20]; + memset(my_rx, 0, sizeof(my_rx)); + res = usart_readbuffer(my_rx, sizeof(my_rx)); + WaitMS(1); + Dbprintf("GOT %d | %c%c%c%c%c%c%c%c", res, my_rx[0], my_rx[1], my_rx[2], my_rx[3], my_rx[4], my_rx[5], my_rx[6], my_rx[7]); + */ - char dest[USB_CMD_DATA_SIZE] = { '\0' }; - static const char* welcome = "Proxmark3 Serial interface via FPC ready\n"; - strncat(dest, welcome, sizeof(dest) - strlen(dest) - 1); - sprintf(dest + strlen(dest) - 1, "| bytes 0x%02x 0x%02x 0x%02x 0x%02x \n" - , c->d.asBytes[0] - , c->d.asBytes[1] - , c->d.asBytes[2] - , c->d.asBytes[3] - ); + char dest[USB_CMD_DATA_SIZE] = { '\0' }; + static const char* welcome = "Proxmark3 Serial interface via FPC ready\n"; + strncat(dest, welcome, sizeof(dest) - strlen(dest) - 1); + sprintf(dest + strlen(dest) - 1, "| bytes 0x%02x 0x%02x 0x%02x 0x%02x \n" + , c->d.asBytes[0] + , c->d.asBytes[1] + , c->d.asBytes[2] + , c->d.asBytes[3] + ); - UsbCommand txcmd = { CMD_DEBUG_PRINT_STRING, { strlen(dest), 0, 0 } }; - memcpy(txcmd.d.asBytes, dest, sizeof(dest)); + UsbCommand txcmd = { CMD_DEBUG_PRINT_STRING, { strlen(dest), 0, 0 } }; + memcpy(txcmd.d.asBytes, dest, sizeof(dest)); - LED_A_ON(); + LED_A_ON(); - usart_init(); - usart_writebuffer((uint8_t*)&txcmd, sizeof(UsbCommand)); + usart_init(); + usart_writebuffer((uint8_t*)&txcmd, sizeof(UsbCommand)); - //usb - cmd_send(CMD_DEBUG_PRINT_STRING, strlen(dest), 0, 0, dest, strlen(dest)); - LED_A_OFF(); + //usb + cmd_send(CMD_DEBUG_PRINT_STRING, strlen(dest), 0, 0, dest, strlen(dest)); + LED_A_OFF(); - /* - uint8_t my_rx[sizeof(UsbCommand)]; - while (!BUTTON_PRESS() && !usb_poll_validate_length()) { - LED_B_INV(); - if (usart_readbuffer(my_rx, sizeof(UsbCommand)) ) { - //UsbPacketReceived(my_rx, sizeof(my_rx)); + /* + uint8_t my_rx[sizeof(UsbCommand)]; + while (!BUTTON_PRESS() && !usb_poll_validate_length()) { + LED_B_INV(); + if (usart_readbuffer(my_rx, sizeof(UsbCommand)) ) { + //UsbPacketReceived(my_rx, sizeof(my_rx)); - UsbCommand *my = (UsbCommand *)my_rx; - if (mc->cmd > 0 ) { - Dbprintf("received command: 0x%04x and args: %d %d %d", my->cmd, my->arg[0], my->arg[1], my->arg[2]); - } - } - } - */ + UsbCommand *my = (UsbCommand *)my_rx; + if (mc->cmd > 0 ) { + Dbprintf("received command: 0x%04x and args: %d %d %d", my->cmd, my->arg[0], my->arg[1], my->arg[2]); + } + } + } + */ - //cmd_send(CMD_DEBUG_PRINT_STRING, strlen(dest), 0, 0, dest, strlen(dest)); + //cmd_send(CMD_DEBUG_PRINT_STRING, strlen(dest), 0, 0, dest, strlen(dest)); - cmd_send(CMD_ACK,0,0,0,0,0); - StopTicks(); - break; - } + cmd_send(CMD_ACK,0,0,0,0,0); + StopTicks(); + break; + } #endif - case CMD_BUFF_CLEAR: - BigBuf_Clear(); - BigBuf_free(); - break; + case CMD_BUFF_CLEAR: + BigBuf_Clear(); + BigBuf_free(); + break; - case CMD_MEASURE_ANTENNA_TUNING: - MeasureAntennaTuning(); - break; + case CMD_MEASURE_ANTENNA_TUNING: + MeasureAntennaTuning(); + break; - case CMD_MEASURE_ANTENNA_TUNING_HF: - MeasureAntennaTuningHf(); - break; + case CMD_MEASURE_ANTENNA_TUNING_HF: + MeasureAntennaTuningHf(); + break; - case CMD_LISTEN_READER_FIELD: - ListenReaderField(c->arg[0]); - break; + case CMD_LISTEN_READER_FIELD: + ListenReaderField(c->arg[0]); + break; - case CMD_FPGA_MAJOR_MODE_OFF: // ## FPGA Control - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(200); - LED_D_OFF(); // LED D indicates field ON or OFF - break; + case CMD_FPGA_MAJOR_MODE_OFF: // ## FPGA Control + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(200); + LED_D_OFF(); // LED D indicates field ON or OFF + break; #ifdef WITH_LF - case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K: { - LED_B_ON(); - uint8_t *mem = BigBuf_get_addr(); - bool isok = false; - size_t len = 0; - uint32_t startidx = c->arg[0]; - uint32_t numofbytes = c->arg[1]; - // arg0 = startindex - // arg1 = length bytes to transfer - // arg2 = BigBuf tracelen - //Dbprintf("transfer to client parameters: %" PRIu32 " | %" PRIu32 " | %" PRIu32, startidx, numofbytes, c->arg[2]); + case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K: { + LED_B_ON(); + uint8_t *mem = BigBuf_get_addr(); + bool isok = false; + size_t len = 0; + uint32_t startidx = c->arg[0]; + uint32_t numofbytes = c->arg[1]; + // arg0 = startindex + // arg1 = length bytes to transfer + // arg2 = BigBuf tracelen + //Dbprintf("transfer to client parameters: %" PRIu32 " | %" PRIu32 " | %" PRIu32, startidx, numofbytes, c->arg[2]); - for(size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) { - len = MIN( (numofbytes - i), USB_CMD_DATA_SIZE); - isok = cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, i, len, BigBuf_get_traceLen(), mem + startidx + i, len); - if (isok != 0) - Dbprintf("transfer to client failed :: | bytes between %d - %d (%d)", i, i+len, len); - } - // Trigger a finish downloading signal with an ACK frame - // iceman, when did sending samplingconfig array got attached here?!? - // arg0 = status of download transfer - // arg1 = RFU - // arg2 = tracelen? - // asbytes = samplingconfig array - cmd_send(CMD_ACK, 1, 0, BigBuf_get_traceLen(), getSamplingConfig(), sizeof(sample_config)); - LED_B_OFF(); - break; - } + for(size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) { + len = MIN( (numofbytes - i), USB_CMD_DATA_SIZE); + isok = cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, i, len, BigBuf_get_traceLen(), mem + startidx + i, len); + if (isok != 0) + Dbprintf("transfer to client failed :: | bytes between %d - %d (%d)", i, i+len, len); + } + // Trigger a finish downloading signal with an ACK frame + // iceman, when did sending samplingconfig array got attached here?!? + // arg0 = status of download transfer + // arg1 = RFU + // arg2 = tracelen? + // asbytes = samplingconfig array + cmd_send(CMD_ACK, 1, 0, BigBuf_get_traceLen(), getSamplingConfig(), sizeof(sample_config)); + LED_B_OFF(); + break; + } #endif - case CMD_UPLOAD_SIM_SAMPLES_125K: { - // iceman; since changing fpga_bitstreams clears bigbuff, Its better to call it before. - // to be able to use this one for uploading data to device - // arg1 = 0 upload for LF usage - // 1 upload for HF usage - #define FPGA_LF 1 - if ( c->arg[1] == FPGA_LF ) - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - else - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + case CMD_UPLOAD_SIM_SAMPLES_125K: { + // iceman; since changing fpga_bitstreams clears bigbuff, Its better to call it before. + // to be able to use this one for uploading data to device + // arg1 = 0 upload for LF usage + // 1 upload for HF usage + #define FPGA_LF 1 + if ( c->arg[1] == FPGA_LF ) + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + else + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - uint8_t *mem = BigBuf_get_addr(); - memcpy( mem + c->arg[0], c->d.asBytes, USB_CMD_DATA_SIZE); - cmd_send(CMD_ACK,1,0,0,0,0); - break; - } - case CMD_DOWNLOAD_EML_BIGBUF: { - LED_B_ON(); - uint8_t *mem = BigBuf_get_EM_addr(); - bool isok = false; - size_t len = 0; - uint32_t startidx = c->arg[0]; - uint32_t numofbytes = c->arg[1]; + uint8_t *mem = BigBuf_get_addr(); + memcpy( mem + c->arg[0], c->d.asBytes, USB_CMD_DATA_SIZE); + cmd_send(CMD_ACK,1,0,0,0,0); + break; + } + case CMD_DOWNLOAD_EML_BIGBUF: { + LED_B_ON(); + uint8_t *mem = BigBuf_get_EM_addr(); + bool isok = false; + size_t len = 0; + uint32_t startidx = c->arg[0]; + uint32_t numofbytes = c->arg[1]; - // arg0 = startindex - // arg1 = length bytes to transfer - // arg2 = RFU + // arg0 = startindex + // arg1 = length bytes to transfer + // arg2 = RFU - for (size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) { - len = MIN((numofbytes - i), USB_CMD_DATA_SIZE); - isok = cmd_send(CMD_DOWNLOADED_EML_BIGBUF, i, len, 0, mem + startidx + i, len); - if (isok != 0) - Dbprintf("transfer to client failed :: | bytes between %d - %d (%d)", i, i+len, len); - } - // Trigger a finish downloading signal with an ACK frame - cmd_send(CMD_ACK, 1, 0, 0, 0, 0); - LED_B_OFF(); - break; - } - case CMD_READ_MEM: - ReadMem(c->arg[0]); - break; + for (size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) { + len = MIN((numofbytes - i), USB_CMD_DATA_SIZE); + isok = cmd_send(CMD_DOWNLOADED_EML_BIGBUF, i, len, 0, mem + startidx + i, len); + if (isok != 0) + Dbprintf("transfer to client failed :: | bytes between %d - %d (%d)", i, i+len, len); + } + // Trigger a finish downloading signal with an ACK frame + cmd_send(CMD_ACK, 1, 0, 0, 0, 0); + LED_B_OFF(); + break; + } + case CMD_READ_MEM: + ReadMem(c->arg[0]); + break; #ifdef WITH_FLASH - case CMD_FLASHMEM_SET_SPIBAUDRATE: - FlashmemSetSpiBaudrate(c->arg[0]); - break; - case CMD_FLASHMEM_READ: { - LED_B_ON(); - uint16_t isok = 0; - uint32_t startidx = c->arg[0]; - uint16_t len = c->arg[1]; + case CMD_FLASHMEM_SET_SPIBAUDRATE: + FlashmemSetSpiBaudrate(c->arg[0]); + break; + case CMD_FLASHMEM_READ: { + LED_B_ON(); + uint16_t isok = 0; + uint32_t startidx = c->arg[0]; + uint16_t len = c->arg[1]; - Dbprintf("FlashMem read | %d - %d | ", startidx, len); + Dbprintf("FlashMem read | %d - %d | ", startidx, len); - size_t size = MIN(USB_CMD_DATA_SIZE, len); + size_t size = MIN(USB_CMD_DATA_SIZE, len); - if (!FlashInit()) { - break; - } + if (!FlashInit()) { + break; + } - uint8_t *mem = BigBuf_malloc(size); + uint8_t *mem = BigBuf_malloc(size); - for(size_t i = 0; i < len; i += size) { - len = MIN((len - i), size); + for(size_t i = 0; i < len; i += size) { + len = MIN((len - i), size); - Dbprintf("FlashMem reading | %d | %d | %d |", startidx + i, i, len); - isok = Flash_ReadDataCont(startidx + i, mem, len); - if ( isok == len ) { - print_result("Chunk: ", mem, len); - } else { - Dbprintf("FlashMem reading failed | %d | %d", len, isok); - break; - } - } - BigBuf_free(); - FlashStop(); - LED_B_OFF(); - break; - } - case CMD_FLASHMEM_WRITE: { - LED_B_ON(); - uint8_t isok = 0; - uint16_t res = 0; - uint32_t startidx = c->arg[0]; - uint16_t len = c->arg[1]; - uint8_t* data = c->d.asBytes; + Dbprintf("FlashMem reading | %d | %d | %d |", startidx + i, i, len); + isok = Flash_ReadDataCont(startidx + i, mem, len); + if ( isok == len ) { + print_result("Chunk: ", mem, len); + } else { + Dbprintf("FlashMem reading failed | %d | %d", len, isok); + break; + } + } + BigBuf_free(); + FlashStop(); + LED_B_OFF(); + break; + } + case CMD_FLASHMEM_WRITE: { + LED_B_ON(); + uint8_t isok = 0; + uint16_t res = 0; + uint32_t startidx = c->arg[0]; + uint16_t len = c->arg[1]; + uint8_t* data = c->d.asBytes; - uint32_t tmp = startidx + len; + uint32_t tmp = startidx + len; - if (!FlashInit()) { - break; - } + if (!FlashInit()) { + break; + } - Flash_CheckBusy(BUSY_TIMEOUT); - Flash_WriteEnable(); + Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); - if ( startidx == DEFAULT_T55XX_KEYS_OFFSET ) - Flash_Erase4k(3, 0xC); - else if (startidx == DEFAULT_MF_KEYS_OFFSET ) - Flash_Erase4k(3, 0xB); - else if (startidx == DEFAULT_ICLASS_KEYS_OFFSET) - Flash_Erase4k(3, 0xA); + if ( startidx == DEFAULT_T55XX_KEYS_OFFSET ) + Flash_Erase4k(3, 0xC); + else if (startidx == DEFAULT_MF_KEYS_OFFSET ) + Flash_Erase4k(3, 0xB); + else if (startidx == DEFAULT_ICLASS_KEYS_OFFSET) + Flash_Erase4k(3, 0xA); - Flash_CheckBusy(BUSY_TIMEOUT); - Flash_WriteEnable(); + Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); - // inside 256b page? - if ( (tmp & 0xFF) != 0) { + // inside 256b page? + if ( (tmp & 0xFF) != 0) { - // is offset+len larger than a page - tmp = (startidx & 0xFF ) + len; - if (tmp > 0xFF ) { + // is offset+len larger than a page + tmp = (startidx & 0xFF ) + len; + if (tmp > 0xFF ) { - // data spread over two pages. + // data spread over two pages. - // offset xxxx10, - uint8_t first_len = (~startidx & 0xFF)+1; + // offset xxxx10, + uint8_t first_len = (~startidx & 0xFF)+1; - // first mem page - res = Flash_WriteDataCont(startidx, data, first_len); + // first mem page + res = Flash_WriteDataCont(startidx, data, first_len); - // second mem page - res = Flash_WriteDataCont(startidx + first_len, data + first_len, len - first_len); + // second mem page + res = Flash_WriteDataCont(startidx + first_len, data + first_len, len - first_len); - isok = (res == (len - first_len)) ? 1 : 0; + isok = (res == (len - first_len)) ? 1 : 0; - } else { - res = Flash_WriteDataCont(startidx, data, len); - isok = (res == len) ? 1 : 0; - } - } else { - res = Flash_WriteDataCont(startidx, data, len); - isok = (res == len) ? 1 : 0; - } - FlashStop(); + } else { + res = Flash_WriteDataCont(startidx, data, len); + isok = (res == len) ? 1 : 0; + } + } else { + res = Flash_WriteDataCont(startidx, data, len); + isok = (res == len) ? 1 : 0; + } + FlashStop(); - cmd_send(CMD_ACK, isok, 0, 0, 0, 0); - LED_B_OFF(); - break; - } - case CMD_FLASHMEM_WIPE: { - LED_B_ON(); - uint8_t page = c->arg[0]; - uint8_t initalwipe = c->arg[1]; - bool isok = false; - if ( initalwipe ) { - isok = Flash_WipeMemory(); - cmd_send(CMD_ACK, isok, 0, 0, 0, 0); - LED_B_OFF(); - break; - } - if ( page < 3) - isok = Flash_WipeMemoryPage(page); + cmd_send(CMD_ACK, isok, 0, 0, 0, 0); + LED_B_OFF(); + break; + } + case CMD_FLASHMEM_WIPE: { + LED_B_ON(); + uint8_t page = c->arg[0]; + uint8_t initalwipe = c->arg[1]; + bool isok = false; + if ( initalwipe ) { + isok = Flash_WipeMemory(); + cmd_send(CMD_ACK, isok, 0, 0, 0, 0); + LED_B_OFF(); + break; + } + if ( page < 3) + isok = Flash_WipeMemoryPage(page); - cmd_send(CMD_ACK, isok, 0, 0, 0, 0); - LED_B_OFF(); - break; - } - case CMD_FLASHMEM_DOWNLOAD: { + cmd_send(CMD_ACK, isok, 0, 0, 0, 0); + LED_B_OFF(); + break; + } + case CMD_FLASHMEM_DOWNLOAD: { - LED_B_ON(); - uint8_t *mem = BigBuf_malloc(USB_CMD_DATA_SIZE); - bool isok = false; - size_t len = 0; - uint32_t startidx = c->arg[0]; - uint32_t numofbytes = c->arg[1]; - // arg0 = startindex - // arg1 = length bytes to transfer - // arg2 = RFU + LED_B_ON(); + uint8_t *mem = BigBuf_malloc(USB_CMD_DATA_SIZE); + bool isok = false; + size_t len = 0; + uint32_t startidx = c->arg[0]; + uint32_t numofbytes = c->arg[1]; + // arg0 = startindex + // arg1 = length bytes to transfer + // arg2 = RFU - if (!FlashInit()) { - break; - } + if (!FlashInit()) { + break; + } - for (size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) { - len = MIN((numofbytes - i), USB_CMD_DATA_SIZE); + for (size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) { + len = MIN((numofbytes - i), USB_CMD_DATA_SIZE); - isok = Flash_ReadDataCont(startidx + i, mem, len); - if (!isok ) - Dbprintf("reading flash memory failed :: | bytes between %d - %d", i, len); + isok = Flash_ReadDataCont(startidx + i, mem, len); + if (!isok ) + Dbprintf("reading flash memory failed :: | bytes between %d - %d", i, len); - isok = cmd_send(CMD_FLASHMEM_DOWNLOADED, i, len, 0, mem, len); - if (isok != 0) - Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len); - } - FlashStop(); + isok = cmd_send(CMD_FLASHMEM_DOWNLOADED, i, len, 0, mem, len); + if (isok != 0) + Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len); + } + FlashStop(); - cmd_send(CMD_ACK, 1, 0, 0, 0, 0); - LED_B_OFF(); - break; - } - case CMD_FLASHMEM_INFO: { + cmd_send(CMD_ACK, 1, 0, 0, 0, 0); + LED_B_OFF(); + break; + } + case CMD_FLASHMEM_INFO: { - LED_B_ON(); - rdv40_validation_t *info = (rdv40_validation_t*)BigBuf_malloc( sizeof(rdv40_validation_t) ); + LED_B_ON(); + rdv40_validation_t *info = (rdv40_validation_t*)BigBuf_malloc( sizeof(rdv40_validation_t) ); - bool isok = Flash_ReadData(FLASH_MEM_SIGNATURE_OFFSET, info->signature, FLASH_MEM_SIGNATURE_LEN); + bool isok = Flash_ReadData(FLASH_MEM_SIGNATURE_OFFSET, info->signature, FLASH_MEM_SIGNATURE_LEN); - if (FlashInit()) { - Flash_UniqueID( info->flashid); - FlashStop(); - } - cmd_send(CMD_ACK, isok, 0, 0, info, sizeof(rdv40_validation_t)); - BigBuf_free(); + if (FlashInit()) { + Flash_UniqueID( info->flashid); + FlashStop(); + } + cmd_send(CMD_ACK, isok, 0, 0, info, sizeof(rdv40_validation_t)); + BigBuf_free(); - LED_B_OFF(); - break; - } + LED_B_OFF(); + break; + } #endif - case CMD_SET_LF_DIVISOR: - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->arg[0]); - break; + case CMD_SET_LF_DIVISOR: + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->arg[0]); + break; - case CMD_SET_ADC_MUX: - switch(c->arg[0]) { - case 0: SetAdcMuxFor(GPIO_MUXSEL_LOPKD); break; - case 2: SetAdcMuxFor(GPIO_MUXSEL_HIPKD); break; + case CMD_SET_ADC_MUX: + switch(c->arg[0]) { + case 0: SetAdcMuxFor(GPIO_MUXSEL_LOPKD); break; + case 2: SetAdcMuxFor(GPIO_MUXSEL_HIPKD); break; #ifndef WITH_FPC - case 1: SetAdcMuxFor(GPIO_MUXSEL_LORAW); break; - case 3: SetAdcMuxFor(GPIO_MUXSEL_HIRAW); break; + case 1: SetAdcMuxFor(GPIO_MUXSEL_LORAW); break; + case 3: SetAdcMuxFor(GPIO_MUXSEL_HIRAW); break; #endif - } - break; + } + break; - case CMD_VERSION: - SendVersion(); - break; - case CMD_STATUS: - SendStatus(); - break; - case CMD_PING: - cmd_send(CMD_ACK,0,0,0,0,0); - break; + case CMD_VERSION: + SendVersion(); + break; + case CMD_STATUS: + SendStatus(); + break; + case CMD_PING: + cmd_send(CMD_ACK,0,0,0,0,0); + break; #ifdef WITH_LCD - case CMD_LCD_RESET: - LCDReset(); - break; - case CMD_LCD: - LCDSend(c->arg[0]); - break; + case CMD_LCD_RESET: + LCDReset(); + break; + case CMD_LCD: + LCDSend(c->arg[0]); + break; #endif - case CMD_SETUP_WRITE: - case CMD_FINISH_WRITE: - case CMD_HARDWARE_RESET: - usb_disable(); + case CMD_SETUP_WRITE: + case CMD_FINISH_WRITE: + case CMD_HARDWARE_RESET: + usb_disable(); - // (iceman) why this wait? - SpinDelay(1000); - AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST; - // We're going to reset, and the bootrom will take control. - for(;;) {} - break; + // (iceman) why this wait? + SpinDelay(1000); + AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST; + // We're going to reset, and the bootrom will take control. + for(;;) {} + break; - case CMD_START_FLASH: - if(common_area.flags.bootrom_present) { - common_area.command = COMMON_AREA_COMMAND_ENTER_FLASH_MODE; - } - usb_disable(); - AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST; - // We're going to flash, and the bootrom will take control. - for(;;) {} - break; + case CMD_START_FLASH: + if(common_area.flags.bootrom_present) { + common_area.command = COMMON_AREA_COMMAND_ENTER_FLASH_MODE; + } + usb_disable(); + AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST; + // We're going to flash, and the bootrom will take control. + for(;;) {} + break; - case CMD_DEVICE_INFO: { - uint32_t dev_info = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS; - if (common_area.flags.bootrom_present) { - dev_info |= DEVICE_INFO_FLAG_BOOTROM_PRESENT; - } - cmd_send(CMD_DEVICE_INFO,dev_info,0,0,0,0); - break; - } - default: - Dbprintf("%s: 0x%04x","unknown command:", c->cmd); - break; - } + case CMD_DEVICE_INFO: { + uint32_t dev_info = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS; + if (common_area.flags.bootrom_present) { + dev_info |= DEVICE_INFO_FLAG_BOOTROM_PRESENT; + } + cmd_send(CMD_DEVICE_INFO,dev_info,0,0,0,0); + break; + } + default: + Dbprintf("%s: 0x%04x","unknown command:", c->cmd); + break; + } } void __attribute__((noreturn)) AppMain(void) { - SpinDelay(100); - clear_trace(); + SpinDelay(100); + clear_trace(); - if(common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) { - /* Initialize common area */ - memset(&common_area, 0, sizeof(common_area)); - common_area.magic = COMMON_AREA_MAGIC; - common_area.version = 1; - } - common_area.flags.osimage_present = 1; + if(common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) { + /* Initialize common area */ + memset(&common_area, 0, sizeof(common_area)); + common_area.magic = COMMON_AREA_MAGIC; + common_area.version = 1; + } + common_area.flags.osimage_present = 1; - LEDsoff(); + LEDsoff(); - // The FPGA gets its clock from us from PCK0 output, so set that up. - AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0; - AT91C_BASE_PIOA->PIO_PDR = GPIO_PCK0; - AT91C_BASE_PMC->PMC_SCER |= AT91C_PMC_PCK0; - // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz - AT91C_BASE_PMC->PMC_PCKR[0] = AT91C_PMC_CSS_PLL_CLK | AT91C_PMC_PRES_CLK_4; // 4 for 24Mhz pck0, 2 for 48 MHZ pck0 - AT91C_BASE_PIOA->PIO_OER = GPIO_PCK0; + // The FPGA gets its clock from us from PCK0 output, so set that up. + AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0; + AT91C_BASE_PIOA->PIO_PDR = GPIO_PCK0; + AT91C_BASE_PMC->PMC_SCER |= AT91C_PMC_PCK0; + // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz + AT91C_BASE_PMC->PMC_PCKR[0] = AT91C_PMC_CSS_PLL_CLK | AT91C_PMC_PRES_CLK_4; // 4 for 24Mhz pck0, 2 for 48 MHZ pck0 + AT91C_BASE_PIOA->PIO_OER = GPIO_PCK0; - // Reset SPI - AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; - AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; // errata says it needs twice to be correctly set. + // Reset SPI + AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; + AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; // errata says it needs twice to be correctly set. - // Reset SSC - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; + // Reset SSC + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; - // Configure MUX - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + // Configure MUX + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - // Load the FPGA image, which we have stored in our flash. - // (the HF version by default) - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + // Load the FPGA image, which we have stored in our flash. + // (the HF version by default) + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - StartTickCount(); + StartTickCount(); #ifdef WITH_LCD - LCDInit(); + LCDInit(); #endif #ifdef WITH_SMARTCARD - I2C_init(); + I2C_init(); #endif #ifdef WITH_FPC - usart_init(); + usart_init(); #endif #ifdef WITH_FLASH - loadT55xxConfig(); + loadT55xxConfig(); #endif - // This is made as late as possible to ensure enumeration without timeout - // against device such as http://www.hobbytronics.co.uk/usb-host-board-v2 - usb_disable(); - usb_enable(); + // This is made as late as possible to ensure enumeration without timeout + // against device such as http://www.hobbytronics.co.uk/usb-host-board-v2 + usb_disable(); + usb_enable(); - uint8_t rx[sizeof(UsbCommand)]; + uint8_t rx[sizeof(UsbCommand)]; - for(;;) { - WDT_HIT(); + for(;;) { + WDT_HIT(); - // Check if there is a usb packet available - if (usb_poll_validate_length()) { - if (usb_read(rx, sizeof(rx)) ) - UsbPacketReceived(rx, sizeof(rx)); - } + // Check if there is a usb packet available + if (usb_poll_validate_length()) { + if (usb_read(rx, sizeof(rx)) ) + UsbPacketReceived(rx, sizeof(rx)); + } #ifdef WITH_FPC - // Check is there is FPC package available - /* - usart_init(); - if (usart_readbuffer(rx, sizeof(rx)) ) - UsbPacketReceived(rx, sizeof(rx) ); - */ + // Check is there is FPC package available + /* + usart_init(); + if (usart_readbuffer(rx, sizeof(rx)) ) + UsbPacketReceived(rx, sizeof(rx) ); + */ #endif - // Press button for one second to enter a possible standalone mode - if (BUTTON_HELD(1000) > 0) { + // Press button for one second to enter a possible standalone mode + if (BUTTON_HELD(1000) > 0) { /* * So this is the trigger to execute a standalone mod. Generic entrypoint by following the standalone/standalone.h headerfile @@ -1564,13 +1564,13 @@ void __attribute__((noreturn)) AppMain(void) { * Since the standalone is either LF or HF, the somewhat bisarr defines below exists. */ #if defined (WITH_LF) && ( defined (WITH_LF_SAMYRUN) || defined (WITH_LF_HIDBRUTE) || defined (WITH_LF_PROXBRUTE) ) - RunMod(); + RunMod(); #endif #if defined (WITH_ISO14443a) && ( defined (WITH_HF_YOUNG) || defined(WITH_HF_COLIN) || defined(WITH_HF_MATTYRUN) || defined(WITH_HF_BOG) ) - RunMod(); + RunMod(); #endif - } - } + } + } } diff --git a/armsrc/apps.h b/armsrc/apps.h index 276331575..4a775702a 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -202,8 +202,8 @@ void cmac (const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t // iso15693.h void RecordRawAdcSamplesIso15693(void); void AcquireRawAdcSamplesIso15693(void); -void ReaderIso15693(uint32_t parameter); // Simulate an ISO15693 reader - greg -void SimTagIso15693(uint32_t parameter, uint8_t *uid); // simulate an ISO15693 tag - greg +void ReaderIso15693(uint32_t parameter); // Simulate an ISO15693 reader - greg +void SimTagIso15693(uint32_t parameter, uint8_t *uid); // simulate an ISO15693 tag - greg void BruteforceIso15693Afi(uint32_t speed); // find an AFI of a tag - atrox void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t *data); // send arbitrary commands from CLI - atrox void Iso15693InitReader(void); diff --git a/armsrc/buzzer.c b/armsrc/buzzer.c index 5f29c6472..987d8fade 100644 --- a/armsrc/buzzer.c +++ b/armsrc/buzzer.c @@ -2,9 +2,9 @@ void Ring_BEE_ONCE(uint16_t music_note) { BEE_ON(); - SpinDelayUs(music_note); - BEE_OFF(); - SpinDelayUs(music_note); + SpinDelayUs(music_note); + BEE_OFF(); + SpinDelayUs(music_note); } void ring_2_7khz(uint16_t count) { @@ -12,9 +12,9 @@ void ring_2_7khz(uint16_t count) { } void Ring_BEE_TIME(uint16_t music_note,uint16_t count) { - for(uint16_t i=0 ; i < count; i++) - Ring_BEE_ONCE(music_note); - SpinDelay(9); + for(uint16_t i=0 ; i < count; i++) + Ring_BEE_ONCE(music_note); + SpinDelay(9); } void Ring_ALL(uint16_t count) { @@ -29,58 +29,58 @@ void Ring_ALL(uint16_t count) { } void Ring_Little_Star(uint16_t count) { - Ring_BEE_TIME(note_1,count); - Ring_BEE_TIME(note_1,count); - Ring_BEE_TIME(note_5,count); - Ring_BEE_TIME(note_5,count); - Ring_BEE_TIME(note_6,count); - Ring_BEE_TIME(note_6,count); - Ring_BEE_TIME(note_5,2*count); - LED_A_ON(); - /* - Ring_BEE_TIME(note_4,count); - Ring_BEE_TIME(note_4,count); - Ring_BEE_TIME(note_3,count); - Ring_BEE_TIME(note_3,count); - Ring_BEE_TIME(note_2,count); - Ring_BEE_TIME(note_2,count); - Ring_BEE_TIME(note_1,2*count); - LED_A_OFF(); + Ring_BEE_TIME(note_1,count); + Ring_BEE_TIME(note_1,count); + Ring_BEE_TIME(note_5,count); + Ring_BEE_TIME(note_5,count); + Ring_BEE_TIME(note_6,count); + Ring_BEE_TIME(note_6,count); + Ring_BEE_TIME(note_5,2*count); + LED_A_ON(); + /* + Ring_BEE_TIME(note_4,count); + Ring_BEE_TIME(note_4,count); + Ring_BEE_TIME(note_3,count); + Ring_BEE_TIME(note_3,count); + Ring_BEE_TIME(note_2,count); + Ring_BEE_TIME(note_2,count); + Ring_BEE_TIME(note_1,2*count); + LED_A_OFF(); - Ring_BEE_TIME(note_5,count); - Ring_BEE_TIME(note_5,count); - Ring_BEE_TIME(note_4,count); - Ring_BEE_TIME(note_4,count); - Ring_BEE_TIME(note_3,count); - Ring_BEE_TIME(note_3,count); - Ring_BEE_TIME(note_2,2*count); - LED_A_ON(); + Ring_BEE_TIME(note_5,count); + Ring_BEE_TIME(note_5,count); + Ring_BEE_TIME(note_4,count); + Ring_BEE_TIME(note_4,count); + Ring_BEE_TIME(note_3,count); + Ring_BEE_TIME(note_3,count); + Ring_BEE_TIME(note_2,2*count); + LED_A_ON(); - Ring_BEE_TIME(note_5,count); - Ring_BEE_TIME(note_5,count); - Ring_BEE_TIME(note_4,count); - Ring_BEE_TIME(note_4,count); - Ring_BEE_TIME(note_3,count); - Ring_BEE_TIME(note_3,count); - Ring_BEE_TIME(note_2,2*count); - LED_A_OFF(); + Ring_BEE_TIME(note_5,count); + Ring_BEE_TIME(note_5,count); + Ring_BEE_TIME(note_4,count); + Ring_BEE_TIME(note_4,count); + Ring_BEE_TIME(note_3,count); + Ring_BEE_TIME(note_3,count); + Ring_BEE_TIME(note_2,2*count); + LED_A_OFF(); - Ring_BEE_TIME(note_1,count); - Ring_BEE_TIME(note_1,count); - Ring_BEE_TIME(note_5,count); - Ring_BEE_TIME(note_5,count); - Ring_BEE_TIME(note_6,count); - Ring_BEE_TIME(note_6,count); - Ring_BEE_TIME(note_5,2*count); - LED_A_ON(); + Ring_BEE_TIME(note_1,count); + Ring_BEE_TIME(note_1,count); + Ring_BEE_TIME(note_5,count); + Ring_BEE_TIME(note_5,count); + Ring_BEE_TIME(note_6,count); + Ring_BEE_TIME(note_6,count); + Ring_BEE_TIME(note_5,2*count); + LED_A_ON(); - Ring_BEE_TIME(note_4,count); - Ring_BEE_TIME(note_4,count); - Ring_BEE_TIME(note_3,count); - Ring_BEE_TIME(note_3,count); - Ring_BEE_TIME(note_2,count); - Ring_BEE_TIME(note_2,count); - Ring_BEE_TIME(note_1,2*count); - LED_B_ON(); - */ + Ring_BEE_TIME(note_4,count); + Ring_BEE_TIME(note_4,count); + Ring_BEE_TIME(note_3,count); + Ring_BEE_TIME(note_3,count); + Ring_BEE_TIME(note_2,count); + Ring_BEE_TIME(note_2,count); + Ring_BEE_TIME(note_1,2*count); + LED_B_ON(); + */ } \ No newline at end of file diff --git a/armsrc/des.c b/armsrc/des.c index be5670e69..a8c416f06 100644 --- a/armsrc/des.c +++ b/armsrc/des.c @@ -22,7 +22,7 @@ * \email daniel.otte@rub.de * \date 2007-06-16 * \brief DES and EDE-DES implementation - * \license GPLv3 or later + * \license GPLv3 or later * */ @@ -72,111 +72,111 @@ const uint8_t sbox[256] = { }; const uint8_t e_permtab[] ={ - 4, 6, /* 4 bytes in 6 bytes out*/ - 32, 1, 2, 3, 4, 5, - 4, 5, 6, 7, 8, 9, - 8, 9, 10, 11, 12, 13, - 12, 13, 14, 15, 16, 17, - 16, 17, 18, 19, 20, 21, - 20, 21, 22, 23, 24, 25, - 24, 25, 26, 27, 28, 29, - 28, 29, 30, 31, 32, 1 + 4, 6, /* 4 bytes in 6 bytes out*/ + 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1 }; const uint8_t p_permtab[] ={ - 4, 4, /* 32 bit -> 32 bit */ - 16, 7, 20, 21, - 29, 12, 28, 17, - 1, 15, 23, 26, - 5, 18, 31, 10, - 2, 8, 24, 14, - 32, 27, 3, 9, - 19, 13, 30, 6, - 22, 11, 4, 25 + 4, 4, /* 32 bit -> 32 bit */ + 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25 }; const uint8_t ip_permtab[] ={ - 8, 8, /* 64 bit -> 64 bit */ - 58, 50, 42, 34, 26, 18, 10, 2, - 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, - 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, - 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, - 63, 55, 47, 39, 31, 23, 15, 7 + 8, 8, /* 64 bit -> 64 bit */ + 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7 }; const uint8_t inv_ip_permtab[] ={ - 8, 8, /* 64 bit -> 64 bit */ - 40, 8, 48, 16, 56, 24, 64, 32, - 39, 7, 47, 15, 55, 23, 63, 31, - 38, 6, 46, 14, 54, 22, 62, 30, - 37, 5, 45, 13, 53, 21, 61, 29, - 36, 4, 44, 12, 52, 20, 60, 28, - 35, 3, 43, 11, 51, 19, 59, 27, - 34, 2, 42, 10, 50, 18, 58, 26, - 33, 1, 41, 9, 49, 17, 57, 25 + 8, 8, /* 64 bit -> 64 bit */ + 40, 8, 48, 16, 56, 24, 64, 32, + 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25 }; const uint8_t pc1_permtab[] ={ - 8, 7, /* 64 bit -> 56 bit*/ - 57, 49, 41, 33, 25, 17, 9, - 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, - 19, 11, 3, 60, 52, 44, 36, - 63, 55, 47, 39, 31, 23, 15, - 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, - 21, 13, 5, 28, 20, 12, 4 + 8, 7, /* 64 bit -> 56 bit*/ + 57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4 }; const uint8_t pc2_permtab[] ={ - 7, 6, /* 56 bit -> 48 bit */ - 14, 17, 11, 24, 1, 5, - 3, 28, 15, 6, 21, 10, - 23, 19, 12, 4, 26, 8, - 16, 7, 27, 20, 13, 2, - 41, 52, 31, 37, 47, 55, - 30, 40, 51, 45, 33, 48, - 44, 49, 39, 56, 34, 53, - 46, 42, 50, 36, 29, 32 + 7, 6, /* 56 bit -> 48 bit */ + 14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32 }; const uint8_t splitin6bitword_permtab[] = { - 8, 8, /* 64 bit -> 64 bit */ - 64, 64, 1, 6, 2, 3, 4, 5, - 64, 64, 7, 12, 8, 9, 10, 11, - 64, 64, 13, 18, 14, 15, 16, 17, - 64, 64, 19, 24, 20, 21, 22, 23, - 64, 64, 25, 30, 26, 27, 28, 29, - 64, 64, 31, 36, 32, 33, 34, 35, - 64, 64, 37, 42, 38, 39, 40, 41, - 64, 64, 43, 48, 44, 45, 46, 47 + 8, 8, /* 64 bit -> 64 bit */ + 64, 64, 1, 6, 2, 3, 4, 5, + 64, 64, 7, 12, 8, 9, 10, 11, + 64, 64, 13, 18, 14, 15, 16, 17, + 64, 64, 19, 24, 20, 21, 22, 23, + 64, 64, 25, 30, 26, 27, 28, 29, + 64, 64, 31, 36, 32, 33, 34, 35, + 64, 64, 37, 42, 38, 39, 40, 41, + 64, 64, 43, 48, 44, 45, 46, 47 }; const uint8_t shiftkey_permtab[] = { - 7, 7, /* 56 bit -> 56 bit */ - 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 1, - 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 29 + 7, 7, /* 56 bit -> 56 bit */ + 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 1, + 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 29 }; const uint8_t shiftkeyinv_permtab[] = { - 7, 7, - 28, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, - 56, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55 + 7, 7, + 28, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, + 56, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55 }; /* @@ -203,241 +203,241 @@ const uint8_t shiftkeyinv_permtab[] = { /******************************************************************************/ void permute(const uint8_t *ptable, const uint8_t *in, uint8_t *out){ - uint8_t ob; /* in-bytes and out-bytes */ - uint8_t byte, bit; /* counter for bit and byte */ - ob = ptable[1]; - ptable = &(ptable[2]); - for(byte=0; byte>(x%8)) ){ - t|=0x01; - } - } - out[byte]=t; - } + uint8_t ob; /* in-bytes and out-bytes */ + uint8_t byte, bit; /* counter for bit and byte */ + ob = ptable[1]; + ptable = &(ptable[2]); + for(byte=0; byte>(x%8)) ){ + t|=0x01; + } + } + out[byte]=t; + } } /******************************************************************************/ void changeendian32(uint32_t * a){ - *a = (*a & 0x000000FF) << 24 | - (*a & 0x0000FF00) << 8 | - (*a & 0x00FF0000) >> 8 | - (*a & 0xFF000000) >> 24; + *a = (*a & 0x000000FF) << 24 | + (*a & 0x0000FF00) << 8 | + (*a & 0x00FF0000) >> 8 | + (*a & 0xFF000000) >> 24; } /******************************************************************************/ static inline void shiftkey(uint8_t *key){ - uint8_t k[7]; - memcpy(k, key, 7); - permute((uint8_t*)shiftkey_permtab, k, key); + uint8_t k[7]; + memcpy(k, key, 7); + permute((uint8_t*)shiftkey_permtab, k, key); } /******************************************************************************/ static inline void shiftkey_inv(uint8_t *key){ - uint8_t k[7]; - memcpy(k, key, 7); - permute((uint8_t*)shiftkeyinv_permtab, k, key); + uint8_t k[7]; + memcpy(k, key, 7); + permute((uint8_t*)shiftkeyinv_permtab, k, key); } /******************************************************************************/ static inline uint64_t splitin6bitwords(uint64_t a){ - uint64_t ret=0; - a &= 0x0000ffffffffffffLL; - permute((uint8_t*)splitin6bitword_permtab, (uint8_t*)&a, (uint8_t*)&ret); - return ret; + uint64_t ret=0; + a &= 0x0000ffffffffffffLL; + permute((uint8_t*)splitin6bitword_permtab, (uint8_t*)&a, (uint8_t*)&ret); + return ret; } /******************************************************************************/ static inline uint8_t substitute(uint8_t a, uint8_t * sbp){ - uint8_t x; - x = sbp[a>>1]; - x = (a&1)?x&0x0F:x>>4; - return x; + uint8_t x; + x = sbp[a>>1]; + x = (a&1)?x&0x0F:x>>4; + return x; } /******************************************************************************/ uint32_t des_f(uint32_t r, uint8_t* kr){ - uint8_t i; - uint32_t t=0,ret; - uint64_t data; - uint8_t *sbp; /* sboxpointer */ - permute((uint8_t*)e_permtab, (uint8_t*)&r, (uint8_t*)&data); - for(i=0; i<6; ++i) - ((uint8_t*)&data)[i] ^= kr[i]; + uint8_t i; + uint32_t t=0,ret; + uint64_t data; + uint8_t *sbp; /* sboxpointer */ + permute((uint8_t*)e_permtab, (uint8_t*)&r, (uint8_t*)&data); + for(i=0; i<6; ++i) + ((uint8_t*)&data)[i] ^= kr[i]; - /* Sbox substitution */ - data = splitin6bitwords(data); - sbp=(uint8_t*)sbox; - for(i=0; i<8; ++i){ - uint8_t x; - x = substitute(((uint8_t*)&data)[i], sbp); - t<<=4; - t |= x; - sbp += 32; - } - changeendian32(&t); + /* Sbox substitution */ + data = splitin6bitwords(data); + sbp=(uint8_t*)sbox; + for(i=0; i<8; ++i){ + uint8_t x; + x = substitute(((uint8_t*)&data)[i], sbp); + t<<=4; + t |= x; + sbp += 32; + } + changeendian32(&t); - permute((uint8_t*)p_permtab,(uint8_t*)&t, (uint8_t*)&ret); + permute((uint8_t*)p_permtab,(uint8_t*)&t, (uint8_t*)&ret); - return ret; + return ret; } /******************************************************************************/ typedef struct { - union { - uint8_t v8[8]; - uint32_t v32[2]; - } d; + union { + uint8_t v8[8]; + uint32_t v32[2]; + } d; } data_t; #define R (data.d.v32[1]) #define L (data.d.v32[0]) void des_enc(void* out, const void* in, const void* key){ - uint8_t kr[6], k[7]; - uint8_t i; - data_t data; + uint8_t kr[6], k[7]; + uint8_t i; + data_t data; - permute((uint8_t*)ip_permtab, (uint8_t*)in, data.d.v8); - permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k); + permute((uint8_t*)ip_permtab, (uint8_t*)in, data.d.v8); + permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k); - for(i=0; i<8; ++i){ - shiftkey(k); - if(ROTTABLE&((1<<((i<<1)+0))) ) - shiftkey(k); - permute((uint8_t*)pc2_permtab, k, kr); - L ^= des_f(R, kr); + for(i=0; i<8; ++i){ + shiftkey(k); + if(ROTTABLE&((1<<((i<<1)+0))) ) + shiftkey(k); + permute((uint8_t*)pc2_permtab, k, kr); + L ^= des_f(R, kr); - shiftkey(k); - if(ROTTABLE&((1<<((i<<1)+1))) ) - shiftkey(k); - permute((uint8_t*)pc2_permtab, k, kr); - R ^= des_f(L, kr); + shiftkey(k); + if(ROTTABLE&((1<<((i<<1)+1))) ) + shiftkey(k); + permute((uint8_t*)pc2_permtab, k, kr); + R ^= des_f(L, kr); - } - /* L <-> R*/ - R ^= L; - L ^= R; - R ^= L; + } + /* L <-> R*/ + R ^= L; + L ^= R; + R ^= L; - permute((uint8_t*)inv_ip_permtab, data.d.v8, (uint8_t*)out); + permute((uint8_t*)inv_ip_permtab, data.d.v8, (uint8_t*)out); } /******************************************************************************/ void des_dec(void* out, const void* in, const uint8_t* key){ - uint8_t kr[6],k[7]; - int8_t i; - data_t data; + uint8_t kr[6],k[7]; + int8_t i; + data_t data; - permute((uint8_t*)ip_permtab, (uint8_t*)in, data.d.v8); - permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k); - for(i=7; i>=0; --i){ + permute((uint8_t*)ip_permtab, (uint8_t*)in, data.d.v8); + permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k); + for(i=7; i>=0; --i){ - permute((uint8_t*)pc2_permtab, k, kr); - L ^= des_f(R, kr); - shiftkey_inv(k); - if(ROTTABLE&((1<<((i<<1)+1))) ){ - shiftkey_inv(k); - } + permute((uint8_t*)pc2_permtab, k, kr); + L ^= des_f(R, kr); + shiftkey_inv(k); + if(ROTTABLE&((1<<((i<<1)+1))) ){ + shiftkey_inv(k); + } - permute((uint8_t*)pc2_permtab, k, kr); - R ^= des_f(L, kr); - shiftkey_inv(k); - if(ROTTABLE&((1<<((i<<1)+0))) ){ - shiftkey_inv(k); - } + permute((uint8_t*)pc2_permtab, k, kr); + R ^= des_f(L, kr); + shiftkey_inv(k); + if(ROTTABLE&((1<<((i<<1)+0))) ){ + shiftkey_inv(k); + } - } - /* L <-> R*/ - R ^= L; - L ^= R; - R ^= L; + } + /* L <-> R*/ + R ^= L; + L ^= R; + R ^= L; - permute((uint8_t*)inv_ip_permtab, data.d.v8, (uint8_t*)out); + permute((uint8_t*)inv_ip_permtab, data.d.v8, (uint8_t*)out); } /******************************************************************************/ void tdes_enc(void* out, void* in, const void* key){ - des_enc(out, in, (uint8_t*)key + 0); - des_dec(out, out, (uint8_t*)key + 8); - des_enc(out, out, (uint8_t*)key +16); + des_enc(out, in, (uint8_t*)key + 0); + des_dec(out, out, (uint8_t*)key + 8); + des_enc(out, out, (uint8_t*)key +16); } /******************************************************************************/ void tdes_dec(void* out, void* in, const uint8_t* key){ - des_dec(out, in, (uint8_t*)key +16); - des_enc(out, out, (uint8_t*)key + 8); - des_dec(out, out, (uint8_t*)key + 0); + des_dec(out, in, (uint8_t*)key +16); + des_enc(out, out, (uint8_t*)key + 8); + des_dec(out, out, (uint8_t*)key + 0); } void tdes_2key_enc(void* out, const void* in, size_t length, const void* key, unsigned char iv[8]){ - if( length % 8 ) return; + if( length % 8 ) return; - uint8_t i; - uint8_t* tin = (uint8_t*) in; - uint8_t* tout = (uint8_t*) out; + uint8_t i; + uint8_t* tin = (uint8_t*) in; + uint8_t* tout = (uint8_t*) out; - while( length > 0 ) - { - for( i = 0; i < 8; i++ ) - tout[i] = (unsigned char)( tin[i] ^ iv[i] ); + while( length > 0 ) + { + for( i = 0; i < 8; i++ ) + tout[i] = (unsigned char)( tin[i] ^ iv[i] ); - des_enc(tout, tin, (uint8_t*)key + 0); - des_dec(tout, tout, (uint8_t*)key + 8); - des_enc(tout, tout, (uint8_t*)key + 0); + des_enc(tout, tin, (uint8_t*)key + 0); + des_dec(tout, tout, (uint8_t*)key + 8); + des_enc(tout, tout, (uint8_t*)key + 0); - memcpy( iv, tout, 8 ); + memcpy( iv, tout, 8 ); - tin += 8; - tout += 8; - length -= 8; - } + tin += 8; + tout += 8; + length -= 8; + } } void tdes_2key_dec(void* out, const void* in, size_t length, const void* key, unsigned char iv[8]){ - if( length % 8 ) return; + if( length % 8 ) return; - uint8_t i; - unsigned char temp[8]; - uint8_t* tin = (uint8_t*) in; - uint8_t* tout = (uint8_t*) out; + uint8_t i; + unsigned char temp[8]; + uint8_t* tin = (uint8_t*) in; + uint8_t* tout = (uint8_t*) out; - while( length > 0 ) - { - memcpy( temp, tin, 8 ); + while( length > 0 ) + { + memcpy( temp, tin, 8 ); - des_dec(tout, tin, (uint8_t*)key + 0); - des_enc(tout, tout, (uint8_t*)key + 8); - des_dec(tout, tout, (uint8_t*)key + 0); + des_dec(tout, tin, (uint8_t*)key + 0); + des_enc(tout, tout, (uint8_t*)key + 8); + des_dec(tout, tout, (uint8_t*)key + 0); - for( i = 0; i < 8; i++ ) - tout[i] = (unsigned char)( tout[i] ^ iv[i] ); + for( i = 0; i < 8; i++ ) + tout[i] = (unsigned char)( tout[i] ^ iv[i] ); - memcpy( iv, temp, 8 ); + memcpy( iv, temp, 8 ); - tin += 8; - tout += 8; - length -= 8; - } + tin += 8; + tout += 8; + length -= 8; + } } diff --git a/armsrc/des.h b/armsrc/des.h index 22735f2f3..2afe39b14 100644 --- a/armsrc/des.h +++ b/armsrc/des.h @@ -17,11 +17,11 @@ along with this program. If not, see . */ /** - * \file des.h - * \author Daniel Otte - * \date 2007-06-16 - * \brief des and tdes declarations - * \license GPLv3 or later + * \file des.h + * \author Daniel Otte + * \date 2007-06-16 + * \brief des and tdes declarations + * \license GPLv3 or later * */ #ifndef __DES_H_ diff --git a/armsrc/desfire_crypto.c b/armsrc/desfire_crypto.c index d79ecc8e3..dd958d3ea 100644 --- a/armsrc/desfire_crypto.c +++ b/armsrc/desfire_crypto.c @@ -85,20 +85,20 @@ void cmac (const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t l mifare_cypher_blocks_chained (NULL, key, ivect, buffer, len, MCD_SEND, MCO_ENCYPHER); memcpy (cmac, ivect, kbs); - free(buffer); + free(buffer); } size_t key_block_size (const desfirekey_t key) { size_t block_size = 8; switch (key->type) { - case T_DES: - case T_3DES: - case T_3K3DES: - block_size = 8; - break; - case T_AES: - block_size = 16; - break; + case T_DES: + case T_3DES: + case T_3K3DES: + block_size = 8; + break; + case T_AES: + block_size = 16; + break; } return block_size; } @@ -211,7 +211,7 @@ void* mifare_cryto_preprocess_data (desfiretag_t tag, void *data, size_t *nbytes break; // Append MAC size_t bla = maced_data_length (DESFIRE(tag)->session_key, *nbytes - offset) + offset; - bla++; + bla++; memcpy (res + *nbytes, mac, 4); @@ -224,7 +224,7 @@ void* mifare_cryto_preprocess_data (desfiretag_t tag, void *data, size_t *nbytes if (append_mac) { size_t len = maced_data_length (key, *nbytes); - ++len; + ++len; memcpy (res, data, *nbytes); memcpy (res + *nbytes, DESFIRE (tag)->cmac, CMAC_LENGTH); *nbytes += CMAC_LENGTH; @@ -448,7 +448,7 @@ void* mifare_cryto_postprocess_data (desfiretag_t tag, void *data, size_t *nbyte case AS_LEGACY: AddCrc14A( (uint8_t*)res, end_crc_pos); end_crc_pos = crc_pos + 2; - // + // crc = crc16; @@ -529,11 +529,11 @@ void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect switch (operation) { case MCO_ENCYPHER: //DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); - des_enc(edata, data, key->data); + des_enc(edata, data, key->data); break; case MCO_DECYPHER: //DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); - des_dec(edata, data, key->data); + des_dec(edata, data, key->data); break; } break; @@ -543,27 +543,27 @@ void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT); // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); - tdes_enc(edata,data, key->data); + tdes_enc(edata,data, key->data); break; case MCO_DECYPHER: // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT); // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); - tdes_dec(data, edata, key->data); + tdes_dec(data, edata, key->data); break; } break; case T_3K3DES: switch (operation) { case MCO_ENCYPHER: - tdes_enc(edata,data, key->data); + tdes_enc(edata,data, key->data); // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT); // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_ENCRYPT); break; case MCO_DECYPHER: - tdes_dec(data, edata, key->data); - // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_DECRYPT); + tdes_dec(data, edata, key->data); + // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_DECRYPT); // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT); // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); break; @@ -571,21 +571,21 @@ void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect break; case T_AES: switch (operation) - { - case MCO_ENCYPHER: - { - AesCtx ctx; - AesCtxIni(&ctx, ivect, key->data, KEY128,CBC); - AesEncrypt(&ctx, data, edata, sizeof(edata) ); - break; - } - case MCO_DECYPHER: - { - AesCtx ctx; - AesCtxIni(&ctx, ivect, key->data, KEY128,CBC); - AesDecrypt(&ctx, edata, data, sizeof(edata)); - break; - } + { + case MCO_ENCYPHER: + { + AesCtx ctx; + AesCtxIni(&ctx, ivect, key->data, KEY128,CBC); + AesEncrypt(&ctx, data, edata, sizeof(edata) ); + break; + } + case MCO_DECYPHER: + { + AesCtx ctx; + AesCtxIni(&ctx, ivect, key->data, KEY128,CBC); + AesDecrypt(&ctx, edata, data, sizeof(edata)); + break; + } } break; } @@ -620,11 +620,11 @@ void mifare_cypher_blocks_chained (desfiretag_t tag, desfirekey_t key, uint8_t * ivect = DESFIRE (tag)->ivect; switch (DESFIRE (tag)->authentication_scheme) { - case AS_LEGACY: - memset (ivect, 0, MAX_CRYPTO_BLOCK_SIZE); - break; - case AS_NEW: - break; + case AS_LEGACY: + memset (ivect, 0, MAX_CRYPTO_BLOCK_SIZE); + break; + case AS_NEW: + break; } } diff --git a/armsrc/desfire_key.c b/armsrc/desfire_key.c index a4ed05f68..f8ea8c794 100644 --- a/armsrc/desfire_key.c +++ b/armsrc/desfire_key.c @@ -38,12 +38,12 @@ void Desfire_des_key_new (const uint8_t value[8], desfirekey_t key) { } void Desfire_des_key_new_with_version (const uint8_t value[8], desfirekey_t key) { - if ( key != NULL) { - key->type = T_DES; - memcpy (key->data, value, 8); - memcpy (key->data+8, value, 8); - update_key_schedules (key); - } + if ( key != NULL) { + key->type = T_DES; + memcpy (key->data, value, 8); + memcpy (key->data+8, value, 8); + update_key_schedules (key); + } } void Desfire_3des_key_new (const uint8_t value[16], desfirekey_t key) { @@ -58,11 +58,11 @@ void Desfire_3des_key_new (const uint8_t value[16], desfirekey_t key) { void Desfire_3des_key_new_with_version (const uint8_t value[16], desfirekey_t key) { if ( key != NULL ){ - key->type = T_3DES; - memcpy (key->data, value, 16); - memcpy (key->data + 16, value, 8); - update_key_schedules (key); - } + key->type = T_3DES; + memcpy (key->data, value, 16); + memcpy (key->data + 16, value, 8); + update_key_schedules (key); + } } void Desfire_3k3des_key_new (const uint8_t value[24], desfirekey_t key) { @@ -74,11 +74,11 @@ void Desfire_3k3des_key_new (const uint8_t value[24], desfirekey_t key) { } void Desfire_3k3des_key_new_with_version (const uint8_t value[24], desfirekey_t key) { - if ( key != NULL){ - key->type = T_3K3DES; - memcpy (key->data, value, 24); - update_key_schedules (key); - } + if ( key != NULL){ + key->type = T_3K3DES; + memcpy (key->data, value, 24); + update_key_schedules (key); + } } void Desfire_aes_key_new (const uint8_t value[16], desfirekey_t key) { @@ -87,11 +87,11 @@ void Desfire_3k3des_key_new_with_version (const uint8_t value[24], desfirekey_t void Desfire_aes_key_new_with_version (const uint8_t value[16], uint8_t version, desfirekey_t key) { - if (key != NULL) { - memcpy (key->data, value, 16); - key->type = T_AES; - key->aes_version = version; - } + if (key != NULL) { + memcpy (key->data, value, 16); + key->type = T_AES; + key->aes_version = version; + } } uint8_t Desfire_key_get_version (desfirekey_t key) { diff --git a/armsrc/desfire_key.h b/armsrc/desfire_key.h index 4e6fdaea9..cb0e8b250 100644 --- a/armsrc/desfire_key.h +++ b/armsrc/desfire_key.h @@ -6,15 +6,15 @@ #include "iso14443a.h" #include "desfire.h" //#include "mifare.h" // iso14a_card_select_t struct -void Desfire_des_key_new (const uint8_t value[8], desfirekey_t key); -void Desfire_3des_key_new (const uint8_t value[16], desfirekey_t key); -void Desfire_des_key_new_with_version (const uint8_t value[8], desfirekey_t key); -void Desfire_3des_key_new_with_version (const uint8_t value[16], desfirekey_t key); -void Desfire_3k3des_key_new (const uint8_t value[24], desfirekey_t key); -void Desfire_3k3des_key_new_with_version (const uint8_t value[24], desfirekey_t key); -void Desfire_aes_key_new (const uint8_t value[16], desfirekey_t key); -void Desfire_aes_key_new_with_version (const uint8_t value[16], uint8_t version,desfirekey_t key); -uint8_t Desfire_key_get_version (desfirekey_t key); -void Desfire_key_set_version (desfirekey_t key, uint8_t version); -void Desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key); +void Desfire_des_key_new (const uint8_t value[8], desfirekey_t key); +void Desfire_3des_key_new (const uint8_t value[16], desfirekey_t key); +void Desfire_des_key_new_with_version (const uint8_t value[8], desfirekey_t key); +void Desfire_3des_key_new_with_version (const uint8_t value[16], desfirekey_t key); +void Desfire_3k3des_key_new (const uint8_t value[24], desfirekey_t key); +void Desfire_3k3des_key_new_with_version (const uint8_t value[24], desfirekey_t key); +void Desfire_aes_key_new (const uint8_t value[16], desfirekey_t key); +void Desfire_aes_key_new_with_version (const uint8_t value[16], uint8_t version,desfirekey_t key); +uint8_t Desfire_key_get_version (desfirekey_t key); +void Desfire_key_set_version (desfirekey_t key, uint8_t version); +void Desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key); #endif \ No newline at end of file diff --git a/armsrc/epa.c b/armsrc/epa.c index 80d51e553..63a57d46b 100644 --- a/armsrc/epa.c +++ b/armsrc/epa.c @@ -21,41 +21,41 @@ static const uint8_t pps[] = {0xD0, 0x11, 0x00, 0x52, 0xA6}; // General Authenticate (request encrypted nonce) WITHOUT the Le at the end static const uint8_t apdu_general_authenticate_pace_get_nonce[] = { - 0x10, // CLA - 0x86, // INS - 0x00, // P1 - 0x00, // P2 - 0x02, // Lc - 0x7C, // Type: Dynamic Authentication Data - 0x00, // Length: 0 bytes + 0x10, // CLA + 0x86, // INS + 0x00, // P1 + 0x00, // P2 + 0x02, // Lc + 0x7C, // Type: Dynamic Authentication Data + 0x00, // Length: 0 bytes }; // MSE: Set AT (only CLA, INS, P1 and P2) static const uint8_t apdu_mse_set_at_start[] = { - 0x00, // CLA - 0x22, // INS - 0xC1, // P1 - 0xA4, // P2 + 0x00, // CLA + 0x22, // INS + 0xC1, // P1 + 0xA4, // P2 }; // SELECT BINARY with the ID for EF.CardAccess static const uint8_t apdu_select_binary_cardaccess[] = { - 0x00, // CLA - 0xA4, // INS - 0x02, // P1 - 0x0C, // P2 - 0x02, // Lc - 0x01, // ID - 0x1C // ID + 0x00, // CLA + 0xA4, // INS + 0x02, // P1 + 0x0C, // P2 + 0x02, // Lc + 0x01, // ID + 0x1C // ID }; // READ BINARY static const uint8_t apdu_read_binary[] = { - 0x00, // CLA - 0xB0, // INS - 0x00, // P1 - 0x00, // P2 - 0x38 // Le + 0x00, // CLA + 0xB0, // INS + 0x00, // P1 + 0x00, // P2 + 0x38 // Le }; @@ -84,14 +84,14 @@ static uint8_t apdu_replay_general_authenticate_pace_mutual_authenticate[75]; static uint8_t apdu_replay_general_authenticate_pace_perform_key_agreement[18]; // pointers to the APDUs (for iterations) static struct { - uint8_t len; - uint8_t *data; + uint8_t len; + uint8_t *data; } const apdus_replay[] = { - {sizeof(apdu_replay_mse_set_at_pace), apdu_replay_mse_set_at_pace}, - {sizeof(apdu_replay_general_authenticate_pace_get_nonce), apdu_replay_general_authenticate_pace_get_nonce}, - {sizeof(apdu_replay_general_authenticate_pace_map_nonce), apdu_replay_general_authenticate_pace_map_nonce}, - {sizeof(apdu_replay_general_authenticate_pace_mutual_authenticate), apdu_replay_general_authenticate_pace_mutual_authenticate}, - {sizeof(apdu_replay_general_authenticate_pace_perform_key_agreement), apdu_replay_general_authenticate_pace_perform_key_agreement} + {sizeof(apdu_replay_mse_set_at_pace), apdu_replay_mse_set_at_pace}, + {sizeof(apdu_replay_general_authenticate_pace_get_nonce), apdu_replay_general_authenticate_pace_get_nonce}, + {sizeof(apdu_replay_general_authenticate_pace_map_nonce), apdu_replay_general_authenticate_pace_map_nonce}, + {sizeof(apdu_replay_general_authenticate_pace_mutual_authenticate), apdu_replay_general_authenticate_pace_mutual_authenticate}, + {sizeof(apdu_replay_general_authenticate_pace_perform_key_agreement), apdu_replay_general_authenticate_pace_perform_key_agreement} }; // lengths of the replay APDUs @@ -105,18 +105,18 @@ static char iso_type = 0; //----------------------------------------------------------------------------- int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response) { - switch(iso_type) - { - case 'a': - return iso14_apdu(apdu, (uint16_t) length, false, response, NULL); - break; - case 'b': - return iso14443b_apdu(apdu, length, response); - break; - default: - return 0; - break; - } + switch(iso_type) + { + case 'a': + return iso14_apdu(apdu, (uint16_t) length, false, response, NULL); + break; + case 'b': + return iso14443b_apdu(apdu, length, response); + break; + default: + return 0; + break; + } } //----------------------------------------------------------------------------- @@ -124,9 +124,9 @@ int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response) //----------------------------------------------------------------------------- void EPA_Finish() { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - iso_type = 0; + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + iso_type = 0; } //----------------------------------------------------------------------------- @@ -146,68 +146,68 @@ size_t EPA_Parse_CardAccess(uint8_t *data, size_t length, pace_version_info_t *pace_info) { - size_t index = 0; + size_t index = 0; - while (index <= length - 2) { - // determine type of element - // SET or SEQUENCE - if (data[index] == 0x31 || data[index] == 0x30) { - // enter the set (skip tag + length) - index += 2; - // check for extended length - if ((data[index - 1] & 0x80) != 0) { - index += (data[index-1] & 0x7F); - } - } - // OID - else if (data[index] == 0x06) { - // is this a PACE OID? - if (data[index + 1] == 0x0A // length matches - && memcmp(data + index + 2, - oid_pace_start, - sizeof(oid_pace_start)) == 0 // content matches - && pace_info != NULL) - { - // first, clear the pace_info struct - memset(pace_info, 0, sizeof(pace_version_info_t)); - memcpy(pace_info->oid, data + index + 2, sizeof(pace_info->oid)); - // a PACE OID is followed by the version - index += data[index + 1] + 2; - if (data[index] == 02 && data[index + 1] == 01) { - pace_info->version = data[index + 2]; - index += 3; - } - else { - return index; - } - // after that there might(!) be the parameter ID - if (data[index] == 02 && data[index + 1] == 01) { - pace_info->parameter_id = data[index + 2]; - index += 3; - } - } - else { - // skip this OID - index += 2 + data[index + 1]; - } - } - // if the length is 0, something is wrong - // TODO: This needs to be extended to support long tags - else if (data[index + 1] == 0) { - return index; - } - else { - // skip this part - // TODO: This needs to be extended to support long tags - // TODO: This needs to be extended to support unknown elements with - // a size > 0x7F - index += 2 + data[index + 1]; - } - } + while (index <= length - 2) { + // determine type of element + // SET or SEQUENCE + if (data[index] == 0x31 || data[index] == 0x30) { + // enter the set (skip tag + length) + index += 2; + // check for extended length + if ((data[index - 1] & 0x80) != 0) { + index += (data[index-1] & 0x7F); + } + } + // OID + else if (data[index] == 0x06) { + // is this a PACE OID? + if (data[index + 1] == 0x0A // length matches + && memcmp(data + index + 2, + oid_pace_start, + sizeof(oid_pace_start)) == 0 // content matches + && pace_info != NULL) + { + // first, clear the pace_info struct + memset(pace_info, 0, sizeof(pace_version_info_t)); + memcpy(pace_info->oid, data + index + 2, sizeof(pace_info->oid)); + // a PACE OID is followed by the version + index += data[index + 1] + 2; + if (data[index] == 02 && data[index + 1] == 01) { + pace_info->version = data[index + 2]; + index += 3; + } + else { + return index; + } + // after that there might(!) be the parameter ID + if (data[index] == 02 && data[index + 1] == 01) { + pace_info->parameter_id = data[index + 2]; + index += 3; + } + } + else { + // skip this OID + index += 2 + data[index + 1]; + } + } + // if the length is 0, something is wrong + // TODO: This needs to be extended to support long tags + else if (data[index + 1] == 0) { + return index; + } + else { + // skip this part + // TODO: This needs to be extended to support long tags + // TODO: This needs to be extended to support unknown elements with + // a size > 0x7F + index += 2 + data[index + 1]; + } + } - // TODO: We should check whether we reached the end in error, but for that - // we need a better parser (e.g. with states like IN_SET or IN_PACE_INFO) - return 0; + // TODO: We should check whether we reached the end in error, but for that + // we need a better parser (e.g. with states like IN_SET or IN_PACE_INFO) + return 0; } //----------------------------------------------------------------------------- @@ -217,42 +217,42 @@ size_t EPA_Parse_CardAccess(uint8_t *data, //----------------------------------------------------------------------------- int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length) { - // the response APDU of the card - // since the card doesn't always care for the expected length we send it, - // we reserve 262 bytes here just to be safe (256-byte APDU + SW + ISO frame) - uint8_t response_apdu[262]; - int rapdu_length = 0; + // the response APDU of the card + // since the card doesn't always care for the expected length we send it, + // we reserve 262 bytes here just to be safe (256-byte APDU + SW + ISO frame) + uint8_t response_apdu[262]; + int rapdu_length = 0; - // select the file EF.CardAccess - rapdu_length = EPA_APDU((uint8_t *)apdu_select_binary_cardaccess, - sizeof(apdu_select_binary_cardaccess), - response_apdu); - if (rapdu_length < 6 - || response_apdu[rapdu_length - 4] != 0x90 - || response_apdu[rapdu_length - 3] != 0x00) - { - DbpString("Failed to select EF.CardAccess!"); - return -1; - } + // select the file EF.CardAccess + rapdu_length = EPA_APDU((uint8_t *)apdu_select_binary_cardaccess, + sizeof(apdu_select_binary_cardaccess), + response_apdu); + if (rapdu_length < 6 + || response_apdu[rapdu_length - 4] != 0x90 + || response_apdu[rapdu_length - 3] != 0x00) + { + DbpString("Failed to select EF.CardAccess!"); + return -1; + } - // read the file - rapdu_length = EPA_APDU((uint8_t *)apdu_read_binary, - sizeof(apdu_read_binary), - response_apdu); - if (rapdu_length <= 6 - || response_apdu[rapdu_length - 4] != 0x90 - || response_apdu[rapdu_length - 3] != 0x00) - { - Dbprintf("Failed to read EF.CardAccess!"); - return -1; - } + // read the file + rapdu_length = EPA_APDU((uint8_t *)apdu_read_binary, + sizeof(apdu_read_binary), + response_apdu); + if (rapdu_length <= 6 + || response_apdu[rapdu_length - 4] != 0x90 + || response_apdu[rapdu_length - 3] != 0x00) + { + Dbprintf("Failed to read EF.CardAccess!"); + return -1; + } - // copy the content into the buffer - // length of data available: apdu_length - 4 (ISO frame) - 2 (SW) - size_t to_copy = rapdu_length - 6; - to_copy = to_copy < max_length ? to_copy : max_length; - memcpy(buffer, response_apdu+2, to_copy); - return to_copy; + // copy the content into the buffer + // length of data available: apdu_length - 4 (ISO frame) - 2 (SW) + size_t to_copy = rapdu_length - 6; + to_copy = to_copy < max_length ? to_copy : max_length; + memcpy(buffer, response_apdu+2, to_copy); + return to_copy; } //----------------------------------------------------------------------------- @@ -261,11 +261,11 @@ int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length) //----------------------------------------------------------------------------- static void EPA_PACE_Collect_Nonce_Abort(uint8_t step, int func_return) { - // power down the field - EPA_Finish(); + // power down the field + EPA_Finish(); - // send the USB packet - cmd_send(CMD_ACK,step,func_return,0,0,0); + // send the USB packet + cmd_send(CMD_ACK,step,func_return,0,0,0); } //----------------------------------------------------------------------------- @@ -273,68 +273,68 @@ static void EPA_PACE_Collect_Nonce_Abort(uint8_t step, int func_return) //----------------------------------------------------------------------------- void EPA_PACE_Collect_Nonce(UsbCommand *c) { - /* - * ack layout: - * arg: - * 1. element - * step where the error occured or 0 if no error occured + /* + * ack layout: + * arg: + * 1. element + * step where the error occured or 0 if no error occured * 2. element * return code of the last executed function - * d: - * Encrypted nonce - */ + * d: + * Encrypted nonce + */ - // return value of a function - int func_return = 0; + // return value of a function + int func_return = 0; - // set up communication - func_return = EPA_Setup(); - if (func_return != 0) { - EPA_PACE_Collect_Nonce_Abort(1, func_return); - return; - } + // set up communication + func_return = EPA_Setup(); + if (func_return != 0) { + EPA_PACE_Collect_Nonce_Abort(1, func_return); + return; + } - // read the CardAccess file - // this array will hold the CardAccess file - uint8_t card_access[256] = {0}; - int card_access_length = EPA_Read_CardAccess(card_access, 256); - // the response has to be at least this big to hold the OID - if (card_access_length < 18) { - EPA_PACE_Collect_Nonce_Abort(2, card_access_length); - return; - } + // read the CardAccess file + // this array will hold the CardAccess file + uint8_t card_access[256] = {0}; + int card_access_length = EPA_Read_CardAccess(card_access, 256); + // the response has to be at least this big to hold the OID + if (card_access_length < 18) { + EPA_PACE_Collect_Nonce_Abort(2, card_access_length); + return; + } - // this will hold the PACE info of the card - pace_version_info_t pace_version_info; - // search for the PACE OID - func_return = EPA_Parse_CardAccess(card_access, - card_access_length, - &pace_version_info); - if (func_return != 0 || pace_version_info.version == 0) { - EPA_PACE_Collect_Nonce_Abort(3, func_return); - return; - } + // this will hold the PACE info of the card + pace_version_info_t pace_version_info; + // search for the PACE OID + func_return = EPA_Parse_CardAccess(card_access, + card_access_length, + &pace_version_info); + if (func_return != 0 || pace_version_info.version == 0) { + EPA_PACE_Collect_Nonce_Abort(3, func_return); + return; + } - // initiate the PACE protocol - // use the CAN for the password since that doesn't change - func_return = EPA_PACE_MSE_Set_AT(pace_version_info, 2); + // initiate the PACE protocol + // use the CAN for the password since that doesn't change + func_return = EPA_PACE_MSE_Set_AT(pace_version_info, 2); - // now get the nonce - uint8_t nonce[256] = {0}; - uint8_t requested_size = (uint8_t)c->arg[0]; - func_return = EPA_PACE_Get_Nonce(requested_size, nonce); - // check if the command succeeded - if (func_return < 0) - { - EPA_PACE_Collect_Nonce_Abort(4, func_return); - return; - } + // now get the nonce + uint8_t nonce[256] = {0}; + uint8_t requested_size = (uint8_t)c->arg[0]; + func_return = EPA_PACE_Get_Nonce(requested_size, nonce); + // check if the command succeeded + if (func_return < 0) + { + EPA_PACE_Collect_Nonce_Abort(4, func_return); + return; + } - // all done, return - EPA_Finish(); + // all done, return + EPA_Finish(); - // save received information - cmd_send(CMD_ACK,0,func_return,0,nonce,func_return); + // save received information + cmd_send(CMD_ACK,0,func_return,0,nonce,func_return); } //----------------------------------------------------------------------------- @@ -347,44 +347,44 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c) //----------------------------------------------------------------------------- int EPA_PACE_Get_Nonce(uint8_t requested_length, uint8_t *nonce) { - // build the APDU - uint8_t apdu[sizeof(apdu_general_authenticate_pace_get_nonce) + 1]; - // copy the constant part - memcpy(apdu, - apdu_general_authenticate_pace_get_nonce, - sizeof(apdu_general_authenticate_pace_get_nonce)); - // append Le (requested length + 2 due to tag/length taking 2 bytes) in RAPDU - apdu[sizeof(apdu_general_authenticate_pace_get_nonce)] = requested_length + 4; + // build the APDU + uint8_t apdu[sizeof(apdu_general_authenticate_pace_get_nonce) + 1]; + // copy the constant part + memcpy(apdu, + apdu_general_authenticate_pace_get_nonce, + sizeof(apdu_general_authenticate_pace_get_nonce)); + // append Le (requested length + 2 due to tag/length taking 2 bytes) in RAPDU + apdu[sizeof(apdu_general_authenticate_pace_get_nonce)] = requested_length + 4; - // send it - uint8_t response_apdu[262]; - int send_return = EPA_APDU(apdu, - sizeof(apdu), - response_apdu); - // check if the command succeeded - if (send_return < 6 - || response_apdu[send_return - 4] != 0x90 - || response_apdu[send_return - 3] != 0x00) - { - return -1; - } + // send it + uint8_t response_apdu[262]; + int send_return = EPA_APDU(apdu, + sizeof(apdu), + response_apdu); + // check if the command succeeded + if (send_return < 6 + || response_apdu[send_return - 4] != 0x90 + || response_apdu[send_return - 3] != 0x00) + { + return -1; + } - // if there is no nonce in the RAPDU, return here - if (send_return < 10) - { - // no error - return 0; - } - // get the actual length of the nonce - uint8_t nonce_length = response_apdu[5]; - if (nonce_length > send_return - 10) - { - nonce_length = send_return - 10; - } - // copy the nonce - memcpy(nonce, response_apdu + 6, nonce_length); + // if there is no nonce in the RAPDU, return here + if (send_return < 10) + { + // no error + return 0; + } + // get the actual length of the nonce + uint8_t nonce_length = response_apdu[5]; + if (nonce_length > send_return - 10) + { + nonce_length = send_return - 10; + } + // copy the nonce + memcpy(nonce, response_apdu + 6, nonce_length); - return nonce_length; + return nonce_length; } //----------------------------------------------------------------------------- @@ -393,53 +393,53 @@ int EPA_PACE_Get_Nonce(uint8_t requested_length, uint8_t *nonce) //----------------------------------------------------------------------------- int EPA_PACE_MSE_Set_AT(pace_version_info_t pace_version_info, uint8_t password) { - // create the MSE: Set AT APDU - uint8_t apdu[23]; - // the minimum length (will be increased as more data is added) - size_t apdu_length = 20; - // copy the constant part - memcpy(apdu, - apdu_mse_set_at_start, - sizeof(apdu_mse_set_at_start)); - // type: OID - apdu[5] = 0x80; - // length of the OID - apdu[6] = sizeof(pace_version_info.oid); - // copy the OID - memcpy(apdu + 7, - pace_version_info.oid, - sizeof(pace_version_info.oid)); - // type: password - apdu[17] = 0x83; - // length: 1 - apdu[18] = 1; - // password - apdu[19] = password; - // if standardized domain parameters are used, copy the ID - if (pace_version_info.parameter_id != 0) { - apdu_length += 3; - // type: domain parameter - apdu[20] = 0x84; - // length: 1 - apdu[21] = 1; - // copy the parameter ID - apdu[22] = pace_version_info.parameter_id; - } - // now set Lc to the actual length - apdu[4] = apdu_length - 5; - // send it - uint8_t response_apdu[6]; - int send_return = EPA_APDU(apdu, - apdu_length, - response_apdu); - // check if the command succeeded - if (send_return != 6 - || response_apdu[send_return - 4] != 0x90 - || response_apdu[send_return - 3] != 0x00) - { - return 1; - } - return 0; + // create the MSE: Set AT APDU + uint8_t apdu[23]; + // the minimum length (will be increased as more data is added) + size_t apdu_length = 20; + // copy the constant part + memcpy(apdu, + apdu_mse_set_at_start, + sizeof(apdu_mse_set_at_start)); + // type: OID + apdu[5] = 0x80; + // length of the OID + apdu[6] = sizeof(pace_version_info.oid); + // copy the OID + memcpy(apdu + 7, + pace_version_info.oid, + sizeof(pace_version_info.oid)); + // type: password + apdu[17] = 0x83; + // length: 1 + apdu[18] = 1; + // password + apdu[19] = password; + // if standardized domain parameters are used, copy the ID + if (pace_version_info.parameter_id != 0) { + apdu_length += 3; + // type: domain parameter + apdu[20] = 0x84; + // length: 1 + apdu[21] = 1; + // copy the parameter ID + apdu[22] = pace_version_info.parameter_id; + } + // now set Lc to the actual length + apdu[4] = apdu_length - 5; + // send it + uint8_t response_apdu[6]; + int send_return = EPA_APDU(apdu, + apdu_length, + response_apdu); + // check if the command succeeded + if (send_return != 6 + || response_apdu[send_return - 4] != 0x90 + || response_apdu[send_return - 3] != 0x00) + { + return 1; + } + return 0; } //----------------------------------------------------------------------------- @@ -447,66 +447,66 @@ int EPA_PACE_MSE_Set_AT(pace_version_info_t pace_version_info, uint8_t password) //----------------------------------------------------------------------------- void EPA_PACE_Replay(UsbCommand *c) { - uint32_t timings[sizeof(apdu_lengths_replay) / sizeof(apdu_lengths_replay[0])] = {0}; + uint32_t timings[sizeof(apdu_lengths_replay) / sizeof(apdu_lengths_replay[0])] = {0}; - // if an APDU has been passed, save it - if (c->arg[0] != 0) { - // make sure it's not too big - if(c->arg[2] > apdus_replay[c->arg[0] - 1].len) - { - cmd_send(CMD_ACK, 1, 0, 0, NULL, 0); - } - memcpy(apdus_replay[c->arg[0] - 1].data + c->arg[1], - c->d.asBytes, - c->arg[2]); - // save/update APDU length - if (c->arg[1] == 0) { - apdu_lengths_replay[c->arg[0] - 1] = c->arg[2]; - } else { - apdu_lengths_replay[c->arg[0] - 1] += c->arg[2]; - } - cmd_send(CMD_ACK, 0, 0, 0, NULL, 0); - return; - } + // if an APDU has been passed, save it + if (c->arg[0] != 0) { + // make sure it's not too big + if(c->arg[2] > apdus_replay[c->arg[0] - 1].len) + { + cmd_send(CMD_ACK, 1, 0, 0, NULL, 0); + } + memcpy(apdus_replay[c->arg[0] - 1].data + c->arg[1], + c->d.asBytes, + c->arg[2]); + // save/update APDU length + if (c->arg[1] == 0) { + apdu_lengths_replay[c->arg[0] - 1] = c->arg[2]; + } else { + apdu_lengths_replay[c->arg[0] - 1] += c->arg[2]; + } + cmd_send(CMD_ACK, 0, 0, 0, NULL, 0); + return; + } - // return value of a function - int func_return; + // return value of a function + int func_return; - // set up communication - func_return = EPA_Setup(); - if (func_return != 0) { - EPA_Finish(); - cmd_send(CMD_ACK, 2, func_return, 0, NULL, 0); - return; - } + // set up communication + func_return = EPA_Setup(); + if (func_return != 0) { + EPA_Finish(); + cmd_send(CMD_ACK, 2, func_return, 0, NULL, 0); + return; + } - // increase the timeout (at least some cards really do need this!)///////////// - // iso14a_set_timeout(0x0003FFFF); + // increase the timeout (at least some cards really do need this!)///////////// + // iso14a_set_timeout(0x0003FFFF); - // response APDU - uint8_t response_apdu[300] = {0}; + // response APDU + uint8_t response_apdu[300] = {0}; - // now replay the data and measure the timings - for (int i = 0; i < sizeof(apdu_lengths_replay); i++) { - StartCountUS(); - func_return = EPA_APDU(apdus_replay[i].data, - apdu_lengths_replay[i], - response_apdu); - timings[i] = GetCountUS(); - // every step but the last one should succeed - if (i < sizeof(apdu_lengths_replay) - 1 - && (func_return < 6 - || response_apdu[func_return - 4] != 0x90 - || response_apdu[func_return - 3] != 0x00)) - { - EPA_Finish(); - cmd_send(CMD_ACK, 3 + i, func_return, 0, timings, 20); - return; - } - } - EPA_Finish(); - cmd_send(CMD_ACK,0,0,0,timings,20); - return; + // now replay the data and measure the timings + for (int i = 0; i < sizeof(apdu_lengths_replay); i++) { + StartCountUS(); + func_return = EPA_APDU(apdus_replay[i].data, + apdu_lengths_replay[i], + response_apdu); + timings[i] = GetCountUS(); + // every step but the last one should succeed + if (i < sizeof(apdu_lengths_replay) - 1 + && (func_return < 6 + || response_apdu[func_return - 4] != 0x90 + || response_apdu[func_return - 3] != 0x00)) + { + EPA_Finish(); + cmd_send(CMD_ACK, 3 + i, func_return, 0, timings, 20); + return; + } + } + EPA_Finish(); + cmd_send(CMD_ACK,0,0,0,timings,20); + return; } //----------------------------------------------------------------------------- @@ -515,40 +515,40 @@ void EPA_PACE_Replay(UsbCommand *c) //----------------------------------------------------------------------------- int EPA_Setup() { - int return_code = 0; - uint8_t uid[10]; - uint8_t pps_response[3]; - uint8_t pps_response_par[1]; - iso14a_card_select_t card_a_info; - iso14b_card_select_t card_b_info; + int return_code = 0; + uint8_t uid[10]; + uint8_t pps_response[3]; + uint8_t pps_response_par[1]; + iso14a_card_select_t card_a_info; + iso14b_card_select_t card_b_info; - // first, look for type A cards - // power up the field - iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); - // select the card - return_code = iso14443a_select_card(uid, &card_a_info, NULL, true, 0, false); - if (return_code == 1) { - // send the PPS request - ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL); - return_code = ReaderReceive(pps_response, pps_response_par); - if (return_code != 3 || pps_response[0] != 0xD0) { - return return_code == 0 ? 2 : return_code; - } - Dbprintf("ISO 14443 Type A"); - iso_type = 'a'; - return 0; - } + // first, look for type A cards + // power up the field + iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); + // select the card + return_code = iso14443a_select_card(uid, &card_a_info, NULL, true, 0, false); + if (return_code == 1) { + // send the PPS request + ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL); + return_code = ReaderReceive(pps_response, pps_response_par); + if (return_code != 3 || pps_response[0] != 0xD0) { + return return_code == 0 ? 2 : return_code; + } + Dbprintf("ISO 14443 Type A"); + iso_type = 'a'; + return 0; + } - // if we're here, there is no type A card, so we look for type B - // power up the field - iso14443b_setup(); - // select the card - return_code = iso14443b_select_card( &card_b_info ); - if (return_code == 0) { - Dbprintf("ISO 14443 Type B"); - iso_type = 'b'; - return 0; - } - Dbprintf("No card found."); - return 1; + // if we're here, there is no type A card, so we look for type B + // power up the field + iso14443b_setup(); + // select the card + return_code = iso14443b_select_card( &card_b_info ); + if (return_code == 0) { + Dbprintf("ISO 14443 Type B"); + iso_type = 'b'; + return 0; + } + Dbprintf("No card found."); + return 1; } diff --git a/armsrc/epa.h b/armsrc/epa.h index 550af8200..a0701ab57 100644 --- a/armsrc/epa.h +++ b/armsrc/epa.h @@ -18,9 +18,9 @@ // this struct is used by EPA_Parse_CardAccess and contains info about the // PACE protocol supported by the chip typedef struct { - uint8_t oid[10]; - uint8_t version; - uint8_t parameter_id; + uint8_t oid[10]; + uint8_t version; + uint8_t parameter_id; } pace_version_info_t; // note: EPA_PACE_Collect_Nonce and EPA_PACE_Replay are declared in apps.h diff --git a/armsrc/felica.c b/armsrc/felica.c index 6b2bb5bfb..07aa763c9 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -2,9 +2,9 @@ #include "apps.h" #include "BigBuf.h" #include "util.h" -#include "usb_cdc.h" // for usb_poll_validate_length +#include "usb_cdc.h" // for usb_poll_validate_length #include "protocols.h" -#include "crc16.h" // crc16 ccitt +#include "crc16.h" // crc16 ccitt // FeliCa timings // minimum time between the start bits of consecutive transfers from reader to tag: 6800 carrier (13.56Mhz) cycles @@ -23,7 +23,7 @@ #endif // CRC skips two first sync bits in data buffer -#define AddCrc(data, len) compute_crc(CRC_FELICA, (data)+2, (len),(data)+(len)+2, (data)+(len)+3) +#define AddCrc(data, len) compute_crc(CRC_FELICA, (data)+2, (len),(data)+(len)+2, (data)+(len)+3) static uint32_t felica_timeout; static uint32_t felica_nexttransfertime; @@ -35,11 +35,11 @@ static void TransmitFor18092_AsReader(uint8_t * frame, int len, uint32_t *timing bool WaitForFelicaReply(uint16_t maxbytes); void iso18092_set_timeout(uint32_t timeout) { - felica_timeout = timeout + (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/(16*8) + 2; + felica_timeout = timeout + (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/(16*8) + 2; } uint32_t iso18092_get_timeout(void) { - return felica_timeout - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/(16*8) - 2; + return felica_timeout - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/(16*8) - 2; } #ifndef FELICA_MAX_FRAME_SIZE @@ -62,11 +62,11 @@ static struct { uint16_t shiftReg; //for synchronization and offset calculation int posCnt; - bool crc_ok; + bool crc_ok; int rem_len; uint16_t len; uint8_t byte_offset; - uint8_t *framebytes; + uint8_t *framebytes; //should be enough. maxlen is 255, 254 for data, 2 for sync, 2 for crc // 0,1 -> SYNC, 2 - len, 3-(len+1)->data, then crc } FelicaFrame; @@ -84,13 +84,13 @@ static void FelicaFrameReset() { FelicaFrame.byte_offset = 0; } static void FelicaFrameinit(uint8_t *data) { - FelicaFrame.framebytes = data; - FelicaFrameReset(); + FelicaFrame.framebytes = data; + FelicaFrameReset(); } //shift byte into frame, reversing it at the same time static void shiftInByte(uint8_t bt) { - uint8_t j; + uint8_t j; for(j=0; j < FelicaFrame.byte_offset; j++) { FelicaFrame.framebytes[FelicaFrame.posCnt] = ( FelicaFrame.framebytes[FelicaFrame.posCnt]<<1 ) + (bt & 1); bt >>= 1; @@ -105,85 +105,85 @@ static void shiftInByte(uint8_t bt) { static void Process18092Byte(uint8_t bt) { switch (FelicaFrame.state) { - case STATE_UNSYNCD: { - //almost any nonzero byte can be start of SYNC. SYNC should be preceded by zeros, but that is not alsways the case - if (bt > 0) { - FelicaFrame.shiftReg = reflect8(bt); - FelicaFrame.state = STATE_TRYING_SYNC; - } - break; - } - case STATE_TRYING_SYNC: { - if (bt == 0) { - //desync - FelicaFrame.shiftReg = bt; - FelicaFrame.state = STATE_UNSYNCD; - } else { - for (uint8_t i=0; i<8; i++) { + case STATE_UNSYNCD: { + //almost any nonzero byte can be start of SYNC. SYNC should be preceded by zeros, but that is not alsways the case + if (bt > 0) { + FelicaFrame.shiftReg = reflect8(bt); + FelicaFrame.state = STATE_TRYING_SYNC; + } + break; + } + case STATE_TRYING_SYNC: { + if (bt == 0) { + //desync + FelicaFrame.shiftReg = bt; + FelicaFrame.state = STATE_UNSYNCD; + } else { + for (uint8_t i=0; i<8; i++) { - if (FelicaFrame.shiftReg == SYNC_16BIT) { - //SYNC done! - FelicaFrame.state = STATE_GET_LENGTH; - FelicaFrame.framebytes[0] = 0xb2; - FelicaFrame.framebytes[1] = 0x4d; - FelicaFrame.byte_offset = i; - //shift in remaining byte, slowly... - for(uint8_t j=i; j<8; j++) { - FelicaFrame.framebytes[2] = (FelicaFrame.framebytes[2] << 1) + (bt & 1); - bt >>= 1; - } + if (FelicaFrame.shiftReg == SYNC_16BIT) { + //SYNC done! + FelicaFrame.state = STATE_GET_LENGTH; + FelicaFrame.framebytes[0] = 0xb2; + FelicaFrame.framebytes[1] = 0x4d; + FelicaFrame.byte_offset = i; + //shift in remaining byte, slowly... + for(uint8_t j=i; j<8; j++) { + FelicaFrame.framebytes[2] = (FelicaFrame.framebytes[2] << 1) + (bt & 1); + bt >>= 1; + } - FelicaFrame.posCnt = 2; - if (i==0) - break; - } - FelicaFrame.shiftReg = (FelicaFrame.shiftReg << 1) + (bt & 1); - bt >>= 1; - } + FelicaFrame.posCnt = 2; + if (i==0) + break; + } + FelicaFrame.shiftReg = (FelicaFrame.shiftReg << 1) + (bt & 1); + bt >>= 1; + } - //that byte was last byte of sync - if (FelicaFrame.shiftReg == SYNC_16BIT) { - //Force SYNC on next byte - FelicaFrame.state = STATE_GET_LENGTH; - FelicaFrame.framebytes[0] = 0xb2; - FelicaFrame.framebytes[1] = 0x4d; - FelicaFrame.byte_offset = 0; - FelicaFrame.posCnt = 1; - } - } - break; - } - case STATE_GET_LENGTH: { - shiftInByte(bt); - FelicaFrame.rem_len = FelicaFrame.framebytes[2] - 1; - FelicaFrame.len = FelicaFrame.framebytes[2] + 4; //with crc and sync - FelicaFrame.state = STATE_GET_DATA; - break; - } - case STATE_GET_DATA: { - shiftInByte(bt); - if (FelicaFrame.rem_len <= 0) { - FelicaFrame.state = STATE_GET_CRC; - FelicaFrame.rem_len = 2; - } - break; - } - case STATE_GET_CRC: { - shiftInByte(bt); + //that byte was last byte of sync + if (FelicaFrame.shiftReg == SYNC_16BIT) { + //Force SYNC on next byte + FelicaFrame.state = STATE_GET_LENGTH; + FelicaFrame.framebytes[0] = 0xb2; + FelicaFrame.framebytes[1] = 0x4d; + FelicaFrame.byte_offset = 0; + FelicaFrame.posCnt = 1; + } + } + break; + } + case STATE_GET_LENGTH: { + shiftInByte(bt); + FelicaFrame.rem_len = FelicaFrame.framebytes[2] - 1; + FelicaFrame.len = FelicaFrame.framebytes[2] + 4; //with crc and sync + FelicaFrame.state = STATE_GET_DATA; + break; + } + case STATE_GET_DATA: { + shiftInByte(bt); + if (FelicaFrame.rem_len <= 0) { + FelicaFrame.state = STATE_GET_CRC; + FelicaFrame.rem_len = 2; + } + break; + } + case STATE_GET_CRC: { + shiftInByte(bt); - if ( FelicaFrame.rem_len <= 0 ) { - // skip sync 2bytes. IF ok, residue should be 0x0000 - FelicaFrame.crc_ok = check_crc(CRC_FELICA, FelicaFrame.framebytes+2, FelicaFrame.len-2); - FelicaFrame.state = STATE_FULL; - FelicaFrame.rem_len = 0; - if (MF_DBGLEVEL > 3) Dbprintf("[+] got 2 crc bytes [%s]", (FelicaFrame.crc_ok) ? "OK" : "No" ); - } - break; - } - case STATE_FULL: //ignore byte. Don't forget to clear frame to receive next one... - default: - break; - } + if ( FelicaFrame.rem_len <= 0 ) { + // skip sync 2bytes. IF ok, residue should be 0x0000 + FelicaFrame.crc_ok = check_crc(CRC_FELICA, FelicaFrame.framebytes+2, FelicaFrame.len-2); + FelicaFrame.state = STATE_FULL; + FelicaFrame.rem_len = 0; + if (MF_DBGLEVEL > 3) Dbprintf("[+] got 2 crc bytes [%s]", (FelicaFrame.crc_ok) ? "OK" : "No" ); + } + break; + } + case STATE_FULL: //ignore byte. Don't forget to clear frame to receive next one... + default: + break; + } } /* Perform FeliCa polling card @@ -192,64 +192,64 @@ static void Process18092Byte(uint8_t bt) { */ static uint8_t felica_select_card(felica_card_select_t *card) { - // POLL command - // 0xB2 0x4B = sync code - // 0x06 = len - // 0x00 = rfu - // 0xff = system service - // 0xff = system service - // 0x00 = - // b7 = automatic switching of data rate - // b6-b2 = reserved - // b1 = fc/32 (414kbps) - // b0 = fc/64 (212kbps) - // 0x00 = timeslot - // 0x09 0x21 = crc - static uint8_t poll[10] = {0xb2,0x4d,0x06,FELICA_POLL_REQ,0xFF,0xFF,0x00,0x00,0x09,0x21}; + // POLL command + // 0xB2 0x4B = sync code + // 0x06 = len + // 0x00 = rfu + // 0xff = system service + // 0xff = system service + // 0x00 = + // b7 = automatic switching of data rate + // b6-b2 = reserved + // b1 = fc/32 (414kbps) + // b0 = fc/64 (212kbps) + // 0x00 = timeslot + // 0x09 0x21 = crc + static uint8_t poll[10] = {0xb2,0x4d,0x06,FELICA_POLL_REQ,0xFF,0xFF,0x00,0x00,0x09,0x21}; - int len = 20; + int len = 20; - // We try 20 times, or if answer was received. - do { - // end-of-reception response packet data, wait approx. 501μs - // end-of-transmission command packet data, wait approx. 197μs - // polling card - TransmitFor18092_AsReader(poll, sizeof(poll), NULL, 1, 0); + // We try 20 times, or if answer was received. + do { + // end-of-reception response packet data, wait approx. 501μs + // end-of-transmission command packet data, wait approx. 197μs + // polling card + TransmitFor18092_AsReader(poll, sizeof(poll), NULL, 1, 0); - // polling card, break if success - if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK) - break; + // polling card, break if success + if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK) + break; - WDT_HIT(); + WDT_HIT(); - } while (--len); + } while (--len); - // timed-out - if ( len == 0 ) - return 1; + // timed-out + if ( len == 0 ) + return 1; - // wrong answer - if (FelicaFrame.framebytes[3] != FELICA_POLL_ACK) - return 2; + // wrong answer + if (FelicaFrame.framebytes[3] != FELICA_POLL_ACK) + return 2; - // VALIDATE CRC residue is 0, hence if crc is a value it failed. - if (!check_crc(CRC_FELICA, FelicaFrame.framebytes+2, FelicaFrame.len-2)) - return 3; + // VALIDATE CRC residue is 0, hence if crc is a value it failed. + if (!check_crc(CRC_FELICA, FelicaFrame.framebytes+2, FelicaFrame.len-2)) + return 3; - // copy UID - // idm 8 - if (card) { - memcpy(card->IDm, FelicaFrame.framebytes + 4, 8); - memcpy(card->PMm, FelicaFrame.framebytes + 4 + 8, 8); - //memcpy(card->servicecode, FelicaFrame.framebytes + 4 + 8 + 8, 2); - memcpy(card->code, card->IDm, 2); - memcpy(card->uid, card->IDm + 2, 6); - memcpy(card->iccode, card->PMm, 2); - memcpy(card->mrt, card->PMm+2, 6); + // copy UID + // idm 8 + if (card) { + memcpy(card->IDm, FelicaFrame.framebytes + 4, 8); + memcpy(card->PMm, FelicaFrame.framebytes + 4 + 8, 8); + //memcpy(card->servicecode, FelicaFrame.framebytes + 4 + 8 + 8, 2); + memcpy(card->code, card->IDm, 2); + memcpy(card->uid, card->IDm + 2, 6); + memcpy(card->iccode, card->PMm, 2); + memcpy(card->mrt, card->PMm+2, 6); - } - // more status bytes? - return 0; + } + // more status bytes? + return 0; } // poll-0: 0xb2,0x4d,0x06,0x00,0xff,0xff,0x00,0x00,0x09,0x21, @@ -274,34 +274,34 @@ static void BuildFliteRdblk(uint8_t* idm, int blocknum, uint16_t *blocks ) { frameSpace[c++] = 0xb2; frameSpace[c++] = 0x4d; - c++; //set length later + c++; //set length later - frameSpace[c++] = FELICA_RDBLK_REQ; //command number + frameSpace[c++] = FELICA_RDBLK_REQ; //command number - //card IDm, from poll - frameSpace[c++] = idm[0]; - frameSpace[c++] = idm[1]; - frameSpace[c++] = idm[2]; - frameSpace[c++] = idm[3]; - frameSpace[c++] = idm[4]; - frameSpace[c++] = idm[5]; - frameSpace[c++] = idm[6]; - frameSpace[c++] = idm[7]; + //card IDm, from poll + frameSpace[c++] = idm[0]; + frameSpace[c++] = idm[1]; + frameSpace[c++] = idm[2]; + frameSpace[c++] = idm[3]; + frameSpace[c++] = idm[4]; + frameSpace[c++] = idm[5]; + frameSpace[c++] = idm[6]; + frameSpace[c++] = idm[7]; - //number of services + //number of services frameSpace[c++] = 0x01; - //service code - frameSpace[c++] = (SERVICE_FELICA_LITE_READONLY >> 8); + //service code + frameSpace[c++] = (SERVICE_FELICA_LITE_READONLY >> 8); frameSpace[c++] = SERVICE_FELICA_LITE_READONLY & 0xFF; - //number of blocks + //number of blocks frameSpace[c++] = blocknum; for (i=0; i < blocknum; i++) { - //3-byte block - if (blocks[i] >= 256) { + //3-byte block + if (blocks[i] >= 256) { frameSpace[c++] = 0x00; frameSpace[c++] = (blocks[i] >> 8); //block number, little endian.... frameSpace[c++] = (blocks[i] & 0xff); @@ -311,70 +311,70 @@ static void BuildFliteRdblk(uint8_t* idm, int blocknum, uint16_t *blocks ) { } } - //set length + //set length frameSpace[2] = c-2; AddCrc(frameSpace, c-2); } static void TransmitFor18092_AsReader(uint8_t * frame, int len, uint32_t *timing, uint8_t power, uint8_t highspeed) { - uint8_t flags = FPGA_MAJOR_MODE_ISO18092; + uint8_t flags = FPGA_MAJOR_MODE_ISO18092; - if ( power ) - flags |= FPGA_HF_ISO18092_FLAG_READER; - if (highspeed) - flags |= FPGA_HF_ISO18092_FLAG_424K; + if ( power ) + flags |= FPGA_HF_ISO18092_FLAG_READER; + if (highspeed) + flags |= FPGA_HF_ISO18092_FLAG_424K; - FpgaWriteConfWord(flags); + FpgaWriteConfWord(flags); - uint32_t curr_transfer_time = ((MAX(felica_nexttransfertime, GetCountSspClk()) & 0xfffffff8) + 8); + uint32_t curr_transfer_time = ((MAX(felica_nexttransfertime, GetCountSspClk()) & 0xfffffff8) + 8); - while (GetCountSspClk() < curr_transfer_time) {}; + while (GetCountSspClk() < curr_transfer_time) {}; - felica_lasttime_prox2air_start = curr_transfer_time; + felica_lasttime_prox2air_start = curr_transfer_time; // preamble - // sending 0x00 0x00 0x00 0x00 0x00 0x00 - uint16_t c = 0; - while (c < 6) { + // sending 0x00 0x00 0x00 0x00 0x00 0x00 + uint16_t c = 0; + while (c < 6) { - // keep tx buffer in a defined state anyway. - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0x00; - c++; - } - } - // sending sync code + // keep tx buffer in a defined state anyway. + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = 0x00; + c++; + } + } + // sending sync code - // sending data - c = 0; - while (c < len) { + // sending data + c = 0; + while (c < len) { - // Put byte into tx holding register as soon as it is ready - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = frame[c++]; - } - } + // Put byte into tx holding register as soon as it is ready + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = frame[c++]; + } + } /**/ - while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) {}; - AT91C_BASE_SSC->SSC_THR = 0x00; //minimum delay + while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) {}; + AT91C_BASE_SSC->SSC_THR = 0x00; //minimum delay - while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) {}; - AT91C_BASE_SSC->SSC_THR = 0x00; //spin + while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) {}; + AT91C_BASE_SSC->SSC_THR = 0x00; //spin /**/ - // log - LogTrace( - frame, - len, - (felica_lasttime_prox2air_start<<4) + DELAY_ARM2AIR_AS_READER, - ((felica_lasttime_prox2air_start + felica_lasttime_prox2air_start)<<4) + DELAY_ARM2AIR_AS_READER, - NULL, - true - ); + // log + LogTrace( + frame, + len, + (felica_lasttime_prox2air_start<<4) + DELAY_ARM2AIR_AS_READER, + ((felica_lasttime_prox2air_start + felica_lasttime_prox2air_start)<<4) + DELAY_ARM2AIR_AS_READER, + NULL, + true + ); - felica_nexttransfertime = MAX(felica_nexttransfertime ,felica_lasttime_prox2air_start + FELICA_REQUEST_GUARD_TIME); + felica_nexttransfertime = MAX(felica_nexttransfertime ,felica_lasttime_prox2air_start + FELICA_REQUEST_GUARD_TIME); } // Wait for tag reply @@ -382,161 +382,161 @@ static void TransmitFor18092_AsReader(uint8_t * frame, int len, uint32_t *timing // or return TRUE when command is captured bool WaitForFelicaReply(uint16_t maxbytes) { - uint32_t c = 0; + uint32_t c = 0; - // power, no modulation - FpgaWriteConfWord(FPGA_MAJOR_MODE_ISO18092 | FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); + // power, no modulation + FpgaWriteConfWord(FPGA_MAJOR_MODE_ISO18092 | FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); - FelicaFrameReset(); + FelicaFrameReset(); - // clear RXRDY: - uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + // clear RXRDY: + uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - uint32_t timeout = iso18092_get_timeout(); - for(;;) { + uint32_t timeout = iso18092_get_timeout(); + for(;;) { WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - b = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); - Process18092Byte(b); - if (FelicaFrame.state == STATE_FULL) { - felica_nexttransfertime = - MAX( - felica_nexttransfertime, - (GetCountSspClk() & 0xfffffff8) - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/16 + FELICA_FRAME_DELAY_TIME - ) - ; + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + b = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); + Process18092Byte(b); + if (FelicaFrame.state == STATE_FULL) { + felica_nexttransfertime = + MAX( + felica_nexttransfertime, + (GetCountSspClk() & 0xfffffff8) - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/16 + FELICA_FRAME_DELAY_TIME + ) + ; - LogTrace( - FelicaFrame.framebytes, - FelicaFrame.len, - ((GetCountSspClk() & 0xfffffff8)<<4) - DELAY_AIR2ARM_AS_READER - timeout, - ((GetCountSspClk() & 0xfffffff8)<<4) - DELAY_AIR2ARM_AS_READER, - NULL, - false - ); - return true; - } else if (c++ > timeout && FelicaFrame.state == STATE_UNSYNCD) { - return false; - } else if (FelicaFrame.state == STATE_GET_CRC) { - Dbprintf(" Frame: "); - Dbhexdump(16, FelicaFrame.framebytes, 0); - //return false; - } - } - } - return false; + LogTrace( + FelicaFrame.framebytes, + FelicaFrame.len, + ((GetCountSspClk() & 0xfffffff8)<<4) - DELAY_AIR2ARM_AS_READER - timeout, + ((GetCountSspClk() & 0xfffffff8)<<4) - DELAY_AIR2ARM_AS_READER, + NULL, + false + ); + return true; + } else if (c++ > timeout && FelicaFrame.state == STATE_UNSYNCD) { + return false; + } else if (FelicaFrame.state == STATE_GET_CRC) { + Dbprintf(" Frame: "); + Dbhexdump(16, FelicaFrame.framebytes, 0); + //return false; + } + } + } + return false; } // Set up FeliCa communication (similar to iso14443a_setup) // field is setup for "Sending as Reader" static void iso18092_setup(uint8_t fpga_minor_mode) { - LEDsoff(); - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + LEDsoff(); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - // allocate command receive buffer - BigBuf_free(); BigBuf_Clear_ext(false); + // allocate command receive buffer + BigBuf_free(); BigBuf_Clear_ext(false); - // Initialize Demod and Uart structs - //DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); - FelicaFrameinit(BigBuf_malloc(FELICA_MAX_FRAME_SIZE)); + // Initialize Demod and Uart structs + //DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); + FelicaFrameinit(BigBuf_malloc(FELICA_MAX_FRAME_SIZE)); - felica_nexttransfertime = 2 * DELAY_ARM2AIR_AS_READER; - iso18092_set_timeout(2120); // 106 * 20ms maximum start-up time of card + felica_nexttransfertime = 2 * DELAY_ARM2AIR_AS_READER; + iso18092_set_timeout(2120); // 106 * 20ms maximum start-up time of card - init_table(CRC_FELICA); + init_table(CRC_FELICA); - // connect Demodulated Signal to ADC: - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + // connect Demodulated Signal to ADC: + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - // Set up the synchronous serial port - FpgaSetupSsc(); + // Set up the synchronous serial port + FpgaSetupSsc(); - // LSB transfer. Remember to set it back to MSB with - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); + // LSB transfer. Remember to set it back to MSB with + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); - // Signal field is on with the appropriate LED - FpgaWriteConfWord(FPGA_MAJOR_MODE_ISO18092 | fpga_minor_mode); + // Signal field is on with the appropriate LED + FpgaWriteConfWord(FPGA_MAJOR_MODE_ISO18092 | fpga_minor_mode); - //20.4 ms generate field, start sending polling command afterwars. - SpinDelay(100); + //20.4 ms generate field, start sending polling command afterwars. + SpinDelay(100); - // Start the timer - StartCountSspClk(); + // Start the timer + StartCountSspClk(); - LED_D_ON(); + LED_D_ON(); } //----------------------------------------------------------------------------- // RAW FeliCa commands. Send out commands and store answers. //----------------------------------------------------------------------------- -// arg0 FeliCa flags -// arg1 len of commandbytes +// arg0 FeliCa flags +// arg1 len of commandbytes // d.asBytes command bytes to send void felica_sendraw(UsbCommand *c) { - if (MF_DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Enter"); + if (MF_DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Enter"); - felica_command_t param = c->arg[0]; - size_t len = c->arg[1] & 0xffff; - uint8_t *cmd = c->d.asBytes; - uint32_t arg0 = 0; + felica_command_t param = c->arg[0]; + size_t len = c->arg[1] & 0xffff; + uint8_t *cmd = c->d.asBytes; + uint32_t arg0 = 0; - felica_card_select_t card; + felica_card_select_t card; - if ((param & FELICA_CONNECT)) - clear_trace(); + if ((param & FELICA_CONNECT)) + clear_trace(); - set_tracing(true); + set_tracing(true); - if ((param & FELICA_CONNECT)) { - iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); + if ((param & FELICA_CONNECT)) { + iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); - // notify client selecting status. - // if failed selecting, turn off antenna and quite. - if( !(param & FELICA_NO_SELECT) ) { - arg0 = felica_select_card(&card); - cmd_send(CMD_ACK, arg0, sizeof(card.uid), 0, &card, sizeof(felica_card_select_t)); - if ( arg0 > 0 ) - goto OUT; - } - } + // notify client selecting status. + // if failed selecting, turn off antenna and quite. + if( !(param & FELICA_NO_SELECT) ) { + arg0 = felica_select_card(&card); + cmd_send(CMD_ACK, arg0, sizeof(card.uid), 0, &card, sizeof(felica_card_select_t)); + if ( arg0 > 0 ) + goto OUT; + } + } - if ((param & FELICA_RAW)) { + if ((param & FELICA_RAW)) { - // 2 sync, 1 len, 2crc == 5 - uint8_t *buf = BigBuf_malloc(len+5); - // add sync bits - buf[0] = 0xb2; - buf[1] = 0x4d; - buf[2] = len; + // 2 sync, 1 len, 2crc == 5 + uint8_t *buf = BigBuf_malloc(len+5); + // add sync bits + buf[0] = 0xb2; + buf[1] = 0x4d; + buf[2] = len; - // copy command - memcpy(buf+2, cmd, len); + // copy command + memcpy(buf+2, cmd, len); - if ((param & FELICA_APPEND_CRC)) { - // Don't append crc on empty bytearray... - if ( len > 0 ) { - AddCrc(buf, len); - len += 2; - } - } + if ((param & FELICA_APPEND_CRC)) { + // Don't append crc on empty bytearray... + if ( len > 0 ) { + AddCrc(buf, len); + len += 2; + } + } - TransmitFor18092_AsReader(buf, buf[2]+4, NULL, 1, 0); - arg0 = !WaitForFelicaReply(1024); - cmd_send(CMD_ACK, arg0, 0, 0, FelicaFrame.framebytes+2, FelicaFrame.len-2); - } + TransmitFor18092_AsReader(buf, buf[2]+4, NULL, 1, 0); + arg0 = !WaitForFelicaReply(1024); + cmd_send(CMD_ACK, arg0, 0, 0, FelicaFrame.framebytes+2, FelicaFrame.len-2); + } - if ((param & FELICA_NO_DISCONNECT)) - return; + if ((param & FELICA_NO_DISCONNECT)) + return; OUT: - switch_off(); + switch_off(); - //Resetting Frame mode (First set in fpgaloader.c) + //Resetting Frame mode (First set in fpgaloader.c) AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); - if (MF_DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Exit"); + if (MF_DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Exit"); } void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { @@ -545,11 +545,11 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { Dbprintf("Snoop FelicaLiteS: Getting first %d frames, Skipping %d triggers.\n", samplesToSkip, triggersToSkip); - iso18092_setup( FPGA_HF_ISO18092_FLAG_NOMOD); + iso18092_setup( FPGA_HF_ISO18092_FLAG_NOMOD); //the frame bits are slow enough. int n = BigBuf_max_traceLen() / sizeof(uint8_t); // take all memory - int numbts = 0; + int numbts = 0; uint8_t *dest = (uint8_t *)BigBuf_get_addr(); uint8_t *destend = dest + n-2; @@ -557,13 +557,13 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { while (dest <= destend) { WDT_HIT(); - if( BUTTON_PRESS()) break; + if( BUTTON_PRESS()) break; if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { uint8_t dist = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); Process18092Byte(dist); - //to be sure we are in frame + //to be sure we are in frame if (FelicaFrame.state == STATE_GET_LENGTH) { //length is after 48 (PRE)+16 (SYNC) - 64 ticks +maybe offset? not 100% uint16_t distance = GetCountSspClk() - endframe - 64 + (FelicaFrame.byte_offset > 0 ? (8-FelicaFrame.byte_offset) : 0); @@ -572,7 +572,7 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { *dest = (distance & 0xff); dest++; } - //crc NOT checked + //crc NOT checked if (FelicaFrame.state == STATE_FULL) { endframe = GetCountSspClk(); //*dest = FelicaFrame.crc_ok; //kind of wasteful @@ -590,19 +590,19 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { numbts += FelicaFrame.len; - FelicaFrameReset(); + FelicaFrameReset(); } } } - switch_off(); + switch_off(); //reset framing AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); set_tracelen(numbts); Dbprintf("Felica sniffing done, tracelen: %i, use hf list felica for annotations", BigBuf_get_traceLen()); - cmd_send(CMD_ACK,1, numbts,0,0,0); + cmd_send(CMD_ACK,1, numbts,0,0,0); } #define R_POLL0_LEN 0x16 @@ -615,19 +615,19 @@ void felica_sim_lite(uint64_t nfcid) { int i, curlen = 0; uint8_t *curresp = 0; - uint8_t ndef[8]; - num_to_bytes(nfcid, 8, ndef); + uint8_t ndef[8]; + num_to_bytes(nfcid, 8, ndef); - //prepare our 3 responses... + //prepare our 3 responses... uint8_t resp_poll0[R_POLL0_LEN] = { 0xb2,0x4d,0x12,FELICA_POLL_ACK,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf1,0x00,0x00,0x00,0x01,0x43,0x00,0xb3,0x7f}; uint8_t resp_poll1[R_POLL1_LEN] = { 0xb2,0x4d,0x14,FELICA_POLL_ACK,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf1,0x00,0x00,0x00,0x01,0x43,0x00, 0x88,0xb4,0xb3,0x7f}; uint8_t resp_readblk[R_READBLK_LEN] = { 0xb2,0x4d,0x1d,FELICA_RDBLK_ACK,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x10,0x04,0x01,0x00,0x0d,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x23,0xcb,0x6e}; - //NFC tag 3/ ISo technically. Many overlapping standards + //NFC tag 3/ ISo technically. Many overlapping standards DbpString("Felica Lite-S sim start"); Dbprintf("NDEF2 UID: %02x %02x %02x %02x %02x %02x %02x %02x", - ndef[0], ndef[1], ndef[2], ndef[3], ndef[4], ndef[5], ndef[6], ndef[7] - ); + ndef[0], ndef[1], ndef[2], ndef[3], ndef[4], ndef[5], ndef[6], ndef[7] + ); //fill in blanks for( i=0; i<8; i++) { @@ -641,21 +641,21 @@ void felica_sim_lite(uint64_t nfcid) { AddCrc(resp_poll1, resp_poll1[2]); AddCrc(resp_readblk, resp_readblk[2]); - iso18092_setup( FPGA_HF_ISO18092_FLAG_NOMOD); + iso18092_setup( FPGA_HF_ISO18092_FLAG_NOMOD); - bool listenmode = true; - //uint32_t frtm = GetCountSspClk(); + bool listenmode = true; + //uint32_t frtm = GetCountSspClk(); for(;;) { - if( BUTTON_PRESS()) break; + if( BUTTON_PRESS()) break; WDT_HIT(); if (listenmode) { //waiting for request... if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - uint8_t dist = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); - //frtm = GetCountSspClk(); - Process18092Byte(dist); + uint8_t dist = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); + //frtm = GetCountSspClk(); + Process18092Byte(dist); if (FelicaFrame.state == STATE_FULL) { @@ -663,17 +663,17 @@ void felica_sim_lite(uint64_t nfcid) { if (FelicaFrame.framebytes[2] == 6 && FelicaFrame.framebytes[3] == 0) { - //polling... there are two types of polling we answer to - if (FelicaFrame.framebytes[6] == 0) { - curresp = resp_poll0; - curlen = R_POLL0_LEN; - listenmode = false; - } - if (FelicaFrame.framebytes[6] == 1) { - curresp = resp_poll1; - curlen = R_POLL1_LEN; - listenmode = true; - } + //polling... there are two types of polling we answer to + if (FelicaFrame.framebytes[6] == 0) { + curresp = resp_poll0; + curlen = R_POLL0_LEN; + listenmode = false; + } + if (FelicaFrame.framebytes[6] == 1) { + curresp = resp_poll1; + curlen = R_POLL1_LEN; + listenmode = true; + } } if (FelicaFrame.framebytes[2] > 5 && FelicaFrame.framebytes[3] == 0x06) { @@ -687,30 +687,30 @@ void felica_sim_lite(uint64_t nfcid) { FelicaFrameReset(); } else { //frame invalid, clear it out to allow for the next one - FelicaFrameReset(); - } - } - } - } - if (!listenmode) { - //trying to answer... here to start answering immediately. - //this one is a bit finicky. Seems that being a bit late is better than earlier - //TransmitFor18092_AsReader(curresp, curlen, frtm+512, 0, 0); - TransmitFor18092_AsReader(curresp, curlen, NULL, 0, 0); + FelicaFrameReset(); + } + } + } + } + if (!listenmode) { + //trying to answer... here to start answering immediately. + //this one is a bit finicky. Seems that being a bit late is better than earlier + //TransmitFor18092_AsReader(curresp, curlen, frtm+512, 0, 0); + TransmitFor18092_AsReader(curresp, curlen, NULL, 0, 0); - //switch back - FpgaWriteConfWord(FPGA_MAJOR_MODE_ISO18092 | FPGA_HF_ISO18092_FLAG_NOMOD); + //switch back + FpgaWriteConfWord(FPGA_MAJOR_MODE_ISO18092 | FPGA_HF_ISO18092_FLAG_NOMOD); - FelicaFrameReset(); - listenmode = true; - curlen = 0; - curresp = NULL; + FelicaFrameReset(); + listenmode = true; + curlen = 0; + curresp = NULL; } } switch_off(); - //reset framing + //reset framing AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); DbpString("Felica Lite-S sim end"); @@ -718,80 +718,80 @@ void felica_sim_lite(uint64_t nfcid) { void felica_dump_lite_s() { - uint8_t ndef[8]; - uint8_t poll[10] = { 0xb2,0x4d,0x06,FELICA_POLL_REQ,0xff,0xff,0x00,0x00,0x09,0x21}; - uint16_t liteblks[28] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x90,0x91,0x92,0xa0}; + uint8_t ndef[8]; + uint8_t poll[10] = { 0xb2,0x4d,0x06,FELICA_POLL_REQ,0xff,0xff,0x00,0x00,0x09,0x21}; + uint16_t liteblks[28] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x90,0x91,0x92,0xa0}; - // setup device. - iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); + // setup device. + iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); - uint8_t blknum; - bool isOK = false; - uint16_t cnt = 0, cntfails = 0; - uint8_t *dest = BigBuf_get_addr(); + uint8_t blknum; + bool isOK = false; + uint16_t cnt = 0, cntfails = 0; + uint8_t *dest = BigBuf_get_addr(); - while (!BUTTON_PRESS() && !usb_poll_validate_length()) { + while (!BUTTON_PRESS() && !usb_poll_validate_length()) { - WDT_HIT(); + WDT_HIT(); - // polling? - //TransmitFor18092_AsReader(poll, 10, GetCountSspClk()+512, 1, 0); - TransmitFor18092_AsReader(poll, 10, NULL, 1, 0); + // polling? + //TransmitFor18092_AsReader(poll, 10, GetCountSspClk()+512, 1, 0); + TransmitFor18092_AsReader(poll, 10, NULL, 1, 0); - if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK) { + if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK) { - // copy 8bytes to ndef. - memcpy(ndef, FelicaFrame.framebytes + 4, 8); - // for (c=0; c < 8; c++) - // ndef[c] = FelicaFrame.framebytes[c+4]; + // copy 8bytes to ndef. + memcpy(ndef, FelicaFrame.framebytes + 4, 8); + // for (c=0; c < 8; c++) + // ndef[c] = FelicaFrame.framebytes[c+4]; - for (blknum=0; blknum < sizeof(liteblks); ) { + for (blknum=0; blknum < sizeof(liteblks); ) { - // block to read. - BuildFliteRdblk(ndef, 1, &liteblks[blknum]); + // block to read. + BuildFliteRdblk(ndef, 1, &liteblks[blknum]); - //TransmitFor18092_AsReader(frameSpace, frameSpace[2]+4, GetCountSspClk()+512, 1, 0); - TransmitFor18092_AsReader(frameSpace, frameSpace[2]+4, NULL, 1, 0); + //TransmitFor18092_AsReader(frameSpace, frameSpace[2]+4, GetCountSspClk()+512, 1, 0); + TransmitFor18092_AsReader(frameSpace, frameSpace[2]+4, NULL, 1, 0); - // read block - if (WaitForFelicaReply(1024) && FelicaFrame.framebytes[3] == FELICA_RDBLK_ACK) { + // read block + if (WaitForFelicaReply(1024) && FelicaFrame.framebytes[3] == FELICA_RDBLK_ACK) { - dest[cnt++] = liteblks[blknum]; + dest[cnt++] = liteblks[blknum]; - uint8_t *fb = FelicaFrame.framebytes; - dest[cnt++] = fb[12]; - dest[cnt++] = fb[13]; + uint8_t *fb = FelicaFrame.framebytes; + dest[cnt++] = fb[12]; + dest[cnt++] = fb[13]; - //memcpy(dest+cnt, FelicaFrame.framebytes + 15, 16); - //cnt += 16; - for(uint8_t j=0; j < 16; j++) - dest[cnt++] = fb[15+j]; + //memcpy(dest+cnt, FelicaFrame.framebytes + 15, 16); + //cnt += 16; + for(uint8_t j=0; j < 16; j++) + dest[cnt++] = fb[15+j]; - blknum++; - cntfails = 0; + blknum++; + cntfails = 0; - // // print raw log. - // Dbprintf("LEN %u | Dump bytes count %u ", FelicaFrame.len, cnt); - Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes+15, 0); - } else { - cntfails++; - if (cntfails > 12) { - blknum++; - cntfails = 0; - } - } - } - isOK = true; - break; - } - } + // // print raw log. + // Dbprintf("LEN %u | Dump bytes count %u ", FelicaFrame.len, cnt); + Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes+15, 0); + } else { + cntfails++; + if (cntfails > 12) { + blknum++; + cntfails = 0; + } + } + } + isOK = true; + break; + } + } - switch_off(); + switch_off(); - //Resetting Frame mode (First set in fpgaloader.c) + //Resetting Frame mode (First set in fpgaloader.c) AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); - //setting tracelen - important! it was set by buffer overflow before + //setting tracelen - important! it was set by buffer overflow before set_tracelen(cnt); - cmd_send(CMD_ACK, isOK, cnt, 0, 0, 0); + cmd_send(CMD_ACK, isOK, cnt, 0, 0, 0); } diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index c3b7a6e82..1c9304c43 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -18,118 +18,118 @@ void FlashmemSetSpiBaudrate(uint32_t baudrate){ Dbprintf("Spi Baudrate : %dMhz", FLASHMEM_SPIBAUDRATE/1000000); } -// initialize +// initialize bool FlashInit() { - FlashSetup(FLASHMEM_SPIBAUDRATE); + FlashSetup(FLASHMEM_SPIBAUDRATE); - StartTicks(); + StartTicks(); - if (Flash_CheckBusy(BUSY_TIMEOUT)) { - StopTicks(); - return false; - } + if (Flash_CheckBusy(BUSY_TIMEOUT)) { + StopTicks(); + return false; + } - return true; + return true; } void FlashSetup(uint32_t baudrate){ //WDT_DISABLE AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS; - // PA10 -> SPI_NCS2 chip select (FLASHMEM) - // PA11 -> SPI_NCS0 chip select (FPGA) - // PA12 -> SPI_MISO Master-In Slave-Out - // PA13 -> SPI_MOSI Master-Out Slave-In - // PA14 -> SPI_SPCK Serial Clock + // PA10 -> SPI_NCS2 chip select (FLASHMEM) + // PA11 -> SPI_NCS0 chip select (FPGA) + // PA12 -> SPI_MISO Master-In Slave-Out + // PA13 -> SPI_MOSI Master-Out Slave-In + // PA14 -> SPI_SPCK Serial Clock - // Disable PIO control of the following pins, allows use by the SPI peripheral - AT91C_BASE_PIOA->PIO_PDR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2); + // Disable PIO control of the following pins, allows use by the SPI peripheral + AT91C_BASE_PIOA->PIO_PDR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2); - // Pull-up Enable - AT91C_BASE_PIOA->PIO_PPUER |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2); + // Pull-up Enable + AT91C_BASE_PIOA->PIO_PPUER |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2); - // Peripheral A - AT91C_BASE_PIOA->PIO_ASR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK); + // Peripheral A + AT91C_BASE_PIOA->PIO_ASR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK); - // Peripheral B - AT91C_BASE_PIOA->PIO_BSR |= GPIO_NCS2; + // Peripheral B + AT91C_BASE_PIOA->PIO_BSR |= GPIO_NCS2; - //enable the SPI Peripheral clock - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI); + //enable the SPI Peripheral clock + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI); - //reset spi needs double SWRST, see atmel's errata on this case - AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; - AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; + //reset spi needs double SWRST, see atmel's errata on this case + AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; + AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; - // Enable SPI - AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN; + // Enable SPI + AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN; - // NPCS2 Mode 0 - AT91C_BASE_SPI->SPI_MR = - (0 << 24) | // Delay between chip selects = DYLBCS/MCK BUT: - // If DLYBCS is less than or equal to six, six MCK periods - // will be inserted by default. - SPI_PCS(SPI_CSR_NUM) | // Peripheral Chip Select (selects SPI_NCS2 or PA10) - ( 0 << 7) | // Disable LLB (1=MOSI2MISO test mode) - ( 1 << 4) | // Disable ModeFault Protection - ( 0 << 3) | // makes spi operate at MCK (1 is MCK/2) - ( 0 << 2) | // Chip selects connected directly to peripheral - AT91C_SPI_PS_FIXED | // Fixed Peripheral Select - AT91C_SPI_MSTR; // Master Mode + // NPCS2 Mode 0 + AT91C_BASE_SPI->SPI_MR = + (0 << 24) | // Delay between chip selects = DYLBCS/MCK BUT: + // If DLYBCS is less than or equal to six, six MCK periods + // will be inserted by default. + SPI_PCS(SPI_CSR_NUM) | // Peripheral Chip Select (selects SPI_NCS2 or PA10) + ( 0 << 7) | // Disable LLB (1=MOSI2MISO test mode) + ( 1 << 4) | // Disable ModeFault Protection + ( 0 << 3) | // makes spi operate at MCK (1 is MCK/2) + ( 0 << 2) | // Chip selects connected directly to peripheral + AT91C_SPI_PS_FIXED | // Fixed Peripheral Select + AT91C_SPI_MSTR; // Master Mode - uint8_t csaat = 1; - uint32_t dlybct = 0; + uint8_t csaat = 1; + uint32_t dlybct = 0; if (baudrate > FLASH_MINFAST) { - baudrate = FLASH_FASTBAUD; - //csaat = 0; - dlybct = 1500; - } + baudrate = FLASH_FASTBAUD; + //csaat = 0; + dlybct = 1500; + } - AT91C_BASE_SPI->SPI_CSR[2] = - SPI_DLYBCT(dlybct,MCK) | // Delay between Consecutive Transfers (32 MCK periods) - SPI_DLYBS(0,MCK) | // Delay Beforce SPCK CLock - SPI_SCBR(baudrate,MCK) | // SPI Baudrate Selection - AT91C_SPI_BITS_8 | // Bits per Transfer (8 bits) - //AT91C_SPI_CSAAT | // Chip Select inactive after transfer - // 40.4.6.2 SPI: Bad tx_ready Behavior when CSAAT = 1 and SCBR = 1 - // If the SPI is programmed with CSAAT = 1, SCBR(baudrate) = 1 and two transfers are performed consecutively on - // the same slave with an IDLE state between them, the tx_ready signal does not rise after the second data has been - // transferred in the shifter. This can imply for example, that the second data is sent twice. - // COLIN :: For now we STILL use CSAAT=1 to avoid having to (de)assert NPCS manually via PIO lines and we deal with delay - ( csaat << 3) | - /* Spi modes: - Mode CPOL CPHA NCPHA - 0 0 0 1 clock normally low read on rising edge - 1 0 1 0 clock normally low read on falling edge - 2 1 0 1 clock normally high read on falling edge - 3 1 1 0 clock normally high read on rising edge - However, page 512 of the AT91SAM7Sx datasheet say "Note that in SPI - master mode the ATSAM7S512/256/128/64/321/32 does not sample the data - (MISO) on the opposite edge where data clocks out (MOSI) but the same - edge is used as shown in Figure 36-3 and Figure 36-4." Figure 36-3 - shows that CPOL=NCPHA=0 or CPOL=NCPHA=1 samples on the rising edge and - that the data changes sometime after the rising edge (about 2 ns). To - be consistent with normal SPI operation, it is probably safe to say - that the data changes on the falling edge and should be sampled on the - rising edge. Therefore, it appears that NCPHA should be treated the - same as CPHA. Thus: - Mode CPOL CPHA NCPHA - 0 0 0 0 clock normally low read on rising edge - 1 0 1 1 clock normally low read on falling edge - 2 1 0 0 clock normally high read on falling edge - 3 1 1 1 clock normally high read on rising edge - */ - ( 0 << 1) | // Clock Phase data captured on leading edge, changes on following edge - ( 0 << 0); // Clock Polarity inactive state is logic 0 + AT91C_BASE_SPI->SPI_CSR[2] = + SPI_DLYBCT(dlybct,MCK)| // Delay between Consecutive Transfers (32 MCK periods) + SPI_DLYBS(0,MCK) | // Delay Beforce SPCK CLock + SPI_SCBR(baudrate,MCK)| // SPI Baudrate Selection + AT91C_SPI_BITS_8 | // Bits per Transfer (8 bits) + //AT91C_SPI_CSAAT | // Chip Select inactive after transfer + // 40.4.6.2 SPI: Bad tx_ready Behavior when CSAAT = 1 and SCBR = 1 + // If the SPI is programmed with CSAAT = 1, SCBR(baudrate) = 1 and two transfers are performed consecutively on + // the same slave with an IDLE state between them, the tx_ready signal does not rise after the second data has been + // transferred in the shifter. This can imply for example, that the second data is sent twice. + // COLIN :: For now we STILL use CSAAT=1 to avoid having to (de)assert NPCS manually via PIO lines and we deal with delay + ( csaat << 3) | + /* Spi modes: + Mode CPOL CPHA NCPHA + 0 0 0 1 clock normally low read on rising edge + 1 0 1 0 clock normally low read on falling edge + 2 1 0 1 clock normally high read on falling edge + 3 1 1 0 clock normally high read on rising edge + However, page 512 of the AT91SAM7Sx datasheet say "Note that in SPI + master mode the ATSAM7S512/256/128/64/321/32 does not sample the data + (MISO) on the opposite edge where data clocks out (MOSI) but the same + edge is used as shown in Figure 36-3 and Figure 36-4." Figure 36-3 + shows that CPOL=NCPHA=0 or CPOL=NCPHA=1 samples on the rising edge and + that the data changes sometime after the rising edge (about 2 ns). To + be consistent with normal SPI operation, it is probably safe to say + that the data changes on the falling edge and should be sampled on the + rising edge. Therefore, it appears that NCPHA should be treated the + same as CPHA. Thus: + Mode CPOL CPHA NCPHA + 0 0 0 0 clock normally low read on rising edge + 1 0 1 1 clock normally low read on falling edge + 2 1 0 0 clock normally high read on falling edge + 3 1 1 1 clock normally high read on rising edge + */ + ( 0 << 1) | // Clock Phase data captured on leading edge, changes on following edge + ( 0 << 0); // Clock Polarity inactive state is logic 0 - // read first, empty buffer - if (AT91C_BASE_SPI->SPI_RDR == 0) {}; + // read first, empty buffer + if (AT91C_BASE_SPI->SPI_RDR == 0) {}; } void FlashStop(void) { - //Bof - //* Reset all the Chip Select register + //Bof + //* Reset all the Chip Select register AT91C_BASE_SPI->SPI_CSR[0] = 0; AT91C_BASE_SPI->SPI_CSR[1] = 0; AT91C_BASE_SPI->SPI_CSR[2] = 0; @@ -141,164 +141,164 @@ void FlashStop(void) { // Disable all interrupts AT91C_BASE_SPI->SPI_IDR = 0xFFFFFFFF; - // SPI disable - AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS; + // SPI disable + AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS; - if ( MF_DBGLEVEL > 3 ) Dbprintf("FlashStop"); + if ( MF_DBGLEVEL > 3 ) Dbprintf("FlashStop"); - StopTicks(); + StopTicks(); } -// send one byte over SPI +// send one byte over SPI uint16_t FlashSendByte(uint32_t data) { - // wait until SPI is ready for transfer - //if you are checking for incoming data returned then the TXEMPTY flag is redundant - //while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0) {}; + // wait until SPI is ready for transfer + //if you are checking for incoming data returned then the TXEMPTY flag is redundant + //while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0) {}; - // send the data - AT91C_BASE_SPI->SPI_TDR = data; + // send the data + AT91C_BASE_SPI->SPI_TDR = data; //while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE) == 0){}; - // wait recive transfer is complete - while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF) == 0){}; + // wait recive transfer is complete + while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF) == 0){}; - // reading incoming data - return ((AT91C_BASE_SPI->SPI_RDR) & 0xFFFF); + // reading incoming data + return ((AT91C_BASE_SPI->SPI_RDR) & 0xFFFF); } -// send last byte over SPI +// send last byte over SPI uint16_t FlashSendLastByte(uint32_t data) { - return FlashSendByte(data | AT91C_SPI_LASTXFER); + return FlashSendByte(data | AT91C_SPI_LASTXFER); } -// read state register 1 +// read state register 1 uint8_t Flash_ReadStat1(void) { - FlashSendByte(READSTAT1); - return FlashSendLastByte(0xFF); + FlashSendByte(READSTAT1); + return FlashSendLastByte(0xFF); } bool Flash_CheckBusy(uint32_t timeout) { - WaitUS(WINBOND_WRITE_DELAY); - StartCountUS(); - uint32_t _time = GetCountUS(); + WaitUS(WINBOND_WRITE_DELAY); + StartCountUS(); + uint32_t _time = GetCountUS(); - if ( MF_DBGLEVEL > 3 ) Dbprintf("Checkbusy in..."); + if ( MF_DBGLEVEL > 3 ) Dbprintf("Checkbusy in..."); - do - { - if (!(Flash_ReadStat1() & BUSY)) - { - return false; - } - } while ((GetCountUS() - _time) < timeout); + do + { + if (!(Flash_ReadStat1() & BUSY)) + { + return false; + } + } while ((GetCountUS() - _time) < timeout); - if (timeout <= (GetCountUS() - _time)) - { - return true; - } + if (timeout <= (GetCountUS() - _time)) + { + return true; + } - return false; + return false; } // read ID out uint8_t Flash_ReadID(void) { - if (Flash_CheckBusy(BUSY_TIMEOUT)) return 0; + if (Flash_CheckBusy(BUSY_TIMEOUT)) return 0; - // Manufacture ID / device ID - FlashSendByte(ID); - FlashSendByte(0x00); - FlashSendByte(0x00); - FlashSendByte(0x00); + // Manufacture ID / device ID + FlashSendByte(ID); + FlashSendByte(0x00); + FlashSendByte(0x00); + FlashSendByte(0x00); uint8_t man_id = FlashSendByte(0xFF); - uint8_t dev_id = FlashSendLastByte(0xFF); + uint8_t dev_id = FlashSendLastByte(0xFF); - if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash ReadID | Man ID %02x | Device ID %02x", man_id, dev_id); + if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash ReadID | Man ID %02x | Device ID %02x", man_id, dev_id); - if ( (man_id == WINBOND_MANID ) && (dev_id == WINBOND_DEVID) ) - return dev_id; + if ( (man_id == WINBOND_MANID ) && (dev_id == WINBOND_DEVID) ) + return dev_id; - return 0; + return 0; } // read unique id for chip. void Flash_UniqueID(uint8_t *uid) { - if (Flash_CheckBusy(BUSY_TIMEOUT)) return; + if (Flash_CheckBusy(BUSY_TIMEOUT)) return; - // reading unique serial number - FlashSendByte(UNIQUE_ID); - FlashSendByte(0xFF); - FlashSendByte(0xFF); - FlashSendByte(0xFF); - FlashSendByte(0xFF); + // reading unique serial number + FlashSendByte(UNIQUE_ID); + FlashSendByte(0xFF); + FlashSendByte(0xFF); + FlashSendByte(0xFF); + FlashSendByte(0xFF); - uid[7] = FlashSendByte(0xFF); - uid[6] = FlashSendByte(0xFF); - uid[5] = FlashSendByte(0xFF); - uid[4] = FlashSendByte(0xFF); + uid[7] = FlashSendByte(0xFF); + uid[6] = FlashSendByte(0xFF); + uid[5] = FlashSendByte(0xFF); + uid[4] = FlashSendByte(0xFF); uid[3] = FlashSendByte(0xFF); - uid[2] = FlashSendByte(0xFF); - uid[1] = FlashSendByte(0xFF); - uid[0] = FlashSendLastByte(0xFF); + uid[2] = FlashSendByte(0xFF); + uid[1] = FlashSendByte(0xFF); + uid[0] = FlashSendLastByte(0xFF); } uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) { - if (!FlashInit()) return 0; + if (!FlashInit()) return 0; - // length should never be zero - if (!len || Flash_CheckBusy(BUSY_TIMEOUT)) return 0; + // length should never be zero + if (!len || Flash_CheckBusy(BUSY_TIMEOUT)) return 0; uint8_t cmd = (FASTFLASH) ? FASTREAD : READDATA; - FlashSendByte(cmd); - Flash_TransferAdresse(address); + FlashSendByte(cmd); + Flash_TransferAdresse(address); - if (FASTFLASH){ - FlashSendByte(DUMMYBYTE); - } + if (FASTFLASH){ + FlashSendByte(DUMMYBYTE); + } - uint16_t i = 0; - for (; i < (len - 1); i++) - out[i] = FlashSendByte(0xFF); + uint16_t i = 0; + for (; i < (len - 1); i++) + out[i] = FlashSendByte(0xFF); - out[i] = FlashSendLastByte(0xFF); - FlashStop(); - return len; + out[i] = FlashSendLastByte(0xFF); + FlashStop(); + return len; } void Flash_TransferAdresse(uint32_t address){ - FlashSendByte((address >> 16) & 0xFF); - FlashSendByte((address >> 8) & 0xFF); - FlashSendByte((address >> 0) & 0xFF); + FlashSendByte((address >> 16) & 0xFF); + FlashSendByte((address >> 8) & 0xFF); + FlashSendByte((address >> 0) & 0xFF); } /* This ensure we can ReadData without having to cycle through initialization everytime */ uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) { - // length should never be zero - if (!len) return 0; + // length should never be zero + if (!len) return 0; uint8_t cmd = (FASTFLASH) ? FASTREAD : READDATA; - FlashSendByte(cmd); - Flash_TransferAdresse(address); + FlashSendByte(cmd); + Flash_TransferAdresse(address); if (FASTFLASH){ - FlashSendByte(DUMMYBYTE); - } + FlashSendByte(DUMMYBYTE); + } - uint16_t i = 0; - for (; i < (len - 1); i++) - out[i] = FlashSendByte(0xFF); + uint16_t i = 0; + for (; i < (len - 1); i++) + out[i] = FlashSendByte(0xFF); - out[i] = FlashSendLastByte(0xFF); - return len; + out[i] = FlashSendLastByte(0xFF); + return len; } @@ -307,89 +307,89 @@ uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) { // if len > 256, it might wrap around and overwrite pos 0. uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) { - // length should never be zero - if (!len) - return 0; + // length should never be zero + if (!len) + return 0; - // Max 256 bytes write - if (((address & 0xFF) + len) > 256) { - Dbprintf("Flash_WriteData 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF)+len, len ); - return 0; - } + // Max 256 bytes write + if (((address & 0xFF) + len) > 256) { + Dbprintf("Flash_WriteData 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF)+len, len ); + return 0; + } - // out-of-range - if ( (( address >> 16 ) & 0xFF ) > MAX_BLOCKS) { - Dbprintf("Flash_WriteData, block out-of-range"); - return 0; - } + // out-of-range + if ( (( address >> 16 ) & 0xFF ) > MAX_BLOCKS) { + Dbprintf("Flash_WriteData, block out-of-range"); + return 0; + } - if (!FlashInit()) { - if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail"); - return 0; - } + if (!FlashInit()) { + if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail"); + return 0; + } - Flash_CheckBusy(BUSY_TIMEOUT); + Flash_CheckBusy(BUSY_TIMEOUT); - Flash_WriteEnable(); + Flash_WriteEnable(); - FlashSendByte(PAGEPROG); - FlashSendByte((address >> 16) & 0xFF); - FlashSendByte((address >> 8) & 0xFF); - FlashSendByte((address >> 0) & 0xFF); + FlashSendByte(PAGEPROG); + FlashSendByte((address >> 16) & 0xFF); + FlashSendByte((address >> 8) & 0xFF); + FlashSendByte((address >> 0) & 0xFF); - uint16_t i = 0; - for (; i < (len - 1); i++) - FlashSendByte(in[i]); + uint16_t i = 0; + for (; i < (len - 1); i++) + FlashSendByte(in[i]); - FlashSendLastByte(in[i]); + FlashSendLastByte(in[i]); - FlashStop(); - return len; + FlashStop(); + return len; } // length should never be zero -// Max 256 bytes write +// Max 256 bytes write // out-of-range uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) { - if (!len) - return 0; + if (!len) + return 0; - if (((address & 0xFF) + len) > 256) { - Dbprintf("Flash_WriteDataCont 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF)+len, len ); - return 0; - } + if (((address & 0xFF) + len) > 256) { + Dbprintf("Flash_WriteDataCont 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF)+len, len ); + return 0; + } - if ( (( address >> 16 ) & 0xFF ) > MAX_BLOCKS) { - Dbprintf("Flash_WriteDataCont, block out-of-range"); - return 0; - } + if ( (( address >> 16 ) & 0xFF ) > MAX_BLOCKS) { + Dbprintf("Flash_WriteDataCont, block out-of-range"); + return 0; + } - FlashSendByte(PAGEPROG); - FlashSendByte((address >> 16) & 0xFF); - FlashSendByte((address >> 8) & 0xFF); - FlashSendByte((address >> 0) & 0xFF); + FlashSendByte(PAGEPROG); + FlashSendByte((address >> 16) & 0xFF); + FlashSendByte((address >> 8) & 0xFF); + FlashSendByte((address >> 0) & 0xFF); - uint16_t i = 0; - for (; i < (len - 1); i++) - FlashSendByte(in[i]); + uint16_t i = 0; + for (; i < (len - 1); i++) + FlashSendByte(in[i]); - FlashSendLastByte(in[i]); - return len; + FlashSendLastByte(in[i]); + return len; } // assumes valid start 256 based 00 address // uint16_t Flash_Write(uint32_t address, uint8_t *in, uint16_t len) { - bool isok; - uint16_t res, bytes_sent = 0, bytes_remaining = len; + bool isok; + uint16_t res, bytes_sent = 0, bytes_remaining = len; uint8_t buf[FLASH_MEM_BLOCK_SIZE]; while (bytes_remaining > 0) { - Flash_CheckBusy(BUSY_TIMEOUT); - Flash_WriteEnable(); + Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining); @@ -397,85 +397,85 @@ uint16_t Flash_Write(uint32_t address, uint8_t *in, uint16_t len) { res = Flash_WriteDataCont(address + bytes_sent, buf, bytes_in_packet); - bytes_remaining -= bytes_in_packet; + bytes_remaining -= bytes_in_packet; bytes_sent += bytes_in_packet; isok = (res == bytes_in_packet); if (!isok) - goto out; + goto out; } out: - FlashStop(); - return len; + FlashStop(); + return len; } bool Flash_WipeMemoryPage(uint8_t page) { - if (!FlashInit()) { - if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail"); - return false; - } - Flash_ReadStat1(); + if (!FlashInit()) { + if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail"); + return false; + } + Flash_ReadStat1(); - // Each block is 64Kb. One block erase takes 1s ( 1000ms ) - Flash_WriteEnable(); Flash_Erase64k(page); Flash_CheckBusy(BUSY_TIMEOUT); + // Each block is 64Kb. One block erase takes 1s ( 1000ms ) + Flash_WriteEnable(); Flash_Erase64k(page); Flash_CheckBusy(BUSY_TIMEOUT); - FlashStop(); - return true; + FlashStop(); + return true; } // Wipes flash memory completely, fills with 0xFF bool Flash_WipeMemory() { - if (!FlashInit()) { - if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail"); - return false; - } - Flash_ReadStat1(); + if (!FlashInit()) { + if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail"); + return false; + } + Flash_ReadStat1(); - // Each block is 64Kb. Four blocks - // one block erase takes 1s ( 1000ms ) - Flash_WriteEnable(); Flash_Erase64k(0); Flash_CheckBusy(BUSY_TIMEOUT); - Flash_WriteEnable(); Flash_Erase64k(1); Flash_CheckBusy(BUSY_TIMEOUT); - Flash_WriteEnable(); Flash_Erase64k(2); Flash_CheckBusy(BUSY_TIMEOUT); - Flash_WriteEnable(); Flash_Erase64k(3); Flash_CheckBusy(BUSY_TIMEOUT); + // Each block is 64Kb. Four blocks + // one block erase takes 1s ( 1000ms ) + Flash_WriteEnable(); Flash_Erase64k(0); Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); Flash_Erase64k(1); Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); Flash_Erase64k(2); Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); Flash_Erase64k(3); Flash_CheckBusy(BUSY_TIMEOUT); - FlashStop(); - return true; + FlashStop(); + return true; } -// enable the flash write +// enable the flash write void Flash_WriteEnable() { - FlashSendLastByte(WRITEENABLE); - if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash Write enabled"); + FlashSendLastByte(WRITEENABLE); + if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash Write enabled"); } -// erase 4K at one time +// erase 4K at one time // execution time: 0.8ms / 800us bool Flash_Erase4k(uint8_t block, uint8_t sector) { - if (block > MAX_BLOCKS || sector > MAX_SECTORS) return false; + if (block > MAX_BLOCKS || sector > MAX_SECTORS) return false; - FlashSendByte(SECTORERASE); - FlashSendByte(block); - FlashSendByte(sector << 4); - FlashSendLastByte(00); - return true; + FlashSendByte(SECTORERASE); + FlashSendByte(block); + FlashSendByte(sector << 4); + FlashSendLastByte(00); + return true; } /* -// erase 32K at one time +// erase 32K at one time // execution time: 0,3s / 300ms bool Flash_Erase32k(uint32_t address) { - if (address & (32*1024 - 1)) { - if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase32k : Address is not align at 4096"); - return false; - } - FlashSendByte(BLOCK32ERASE); - FlashSendByte((address >> 16) & 0xFF); - FlashSendByte((address >> 8) & 0xFF); - FlashSendLastByte((address >> 0) & 0xFF); - return true; + if (address & (32*1024 - 1)) { + if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase32k : Address is not align at 4096"); + return false; + } + FlashSendByte(BLOCK32ERASE); + FlashSendByte((address >> 16) & 0xFF); + FlashSendByte((address >> 8) & 0xFF); + FlashSendLastByte((address >> 0) & 0xFF); + return true; } */ @@ -489,52 +489,52 @@ bool Flash_Erase32k(uint32_t address) { // 0x03 00 00 -- 0x 03 FF FF == block 3 bool Flash_Erase64k(uint8_t block) { - if (block > MAX_BLOCKS) return false; + if (block > MAX_BLOCKS) return false; - FlashSendByte(BLOCK64ERASE); - FlashSendByte(block); - FlashSendByte(0x00); - FlashSendLastByte(0x00); - return true; + FlashSendByte(BLOCK64ERASE); + FlashSendByte(block); + FlashSendByte(0x00); + FlashSendLastByte(0x00); + return true; } -// Erase chip +// Erase chip void Flash_EraseChip(void) { - FlashSendLastByte(CHIPERASE); + FlashSendLastByte(CHIPERASE); } void Flashmem_print_status(void) { - DbpString("Flash memory"); - Dbprintf(" Baudrate................%dMHz",FLASHMEM_SPIBAUDRATE/1000000); + DbpString("Flash memory"); + Dbprintf(" Baudrate................%dMHz",FLASHMEM_SPIBAUDRATE/1000000); - if (!FlashInit()) { - DbpString(" Init....................FAIL"); - return; - } - DbpString(" Init....................OK"); + if (!FlashInit()) { + DbpString(" Init....................FAIL"); + return; + } + DbpString(" Init....................OK"); - uint8_t dev_id = Flash_ReadID(); - switch (dev_id) { - case 0x11 : - DbpString(" Memory size.............2 mbits / 256kb"); - break; - case 0x10 : - DbpString(" Memory size..... .......1 mbits / 128kb"); - break; - case 0x05 : - DbpString(" Memory size.............512 kbits / 64kb"); - break; - default : - DbpString(" Device ID............... --> Unknown <--"); - break; - } + uint8_t dev_id = Flash_ReadID(); + switch (dev_id) { + case 0x11 : + DbpString(" Memory size.............2 mbits / 256kb"); + break; + case 0x10 : + DbpString(" Memory size..... .......1 mbits / 128kb"); + break; + case 0x05 : + DbpString(" Memory size.............512 kbits / 64kb"); + break; + default : + DbpString(" Device ID............... --> Unknown <--"); + break; + } - uint8_t uid[8] = {0,0,0,0,0,0,0,0}; - Flash_UniqueID(uid); - Dbprintf(" Unique ID...............0x%02x%02x%02x%02x%02x%02x%02x%02x", - uid[7], uid[6], uid[5], uid[4], - uid[3], uid[2], uid[1], uid[0] - ); + uint8_t uid[8] = {0,0,0,0,0,0,0,0}; + Flash_UniqueID(uid); + Dbprintf(" Unique ID...............0x%02x%02x%02x%02x%02x%02x%02x%02x", + uid[7], uid[6], uid[5], uid[4], + uid[3], uid[2], uid[1], uid[0] + ); - FlashStop(); + FlashStop(); } diff --git a/armsrc/flashmem.h b/armsrc/flashmem.h index da81363c0..4af499d3a 100644 --- a/armsrc/flashmem.h +++ b/armsrc/flashmem.h @@ -23,7 +23,7 @@ * . */ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Common Instructions // +// Common Instructions // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// #ifndef __FLASHMEM_H #define __FLASHMEM_H @@ -32,74 +32,74 @@ #include "apps.h" #include "ticks.h" -// Used Command -#define ID 0x90 -#define MANID 0x90 -#define JEDECID 0x9F +// Used Command +#define ID 0x90 +#define MANID 0x90 +#define JEDECID 0x9F -#define READSTAT1 0x05 -#define READSTAT2 0x35 -#define WRITESTAT 0x01 +#define READSTAT1 0x05 +#define READSTAT2 0x35 +#define WRITESTAT 0x01 -#define WRITEDISABLE 0x04 -#define WRITEENABLE 0x06 +#define WRITEDISABLE 0x04 +#define WRITEENABLE 0x06 -#define READDATA 0x03 -#define FASTREAD 0x0B -#define PAGEPROG 0x02 +#define READDATA 0x03 +#define FASTREAD 0x0B +#define PAGEPROG 0x02 -#define SECTORERASE 0x20 -#define BLOCK32ERASE 0x52 -#define BLOCK64ERASE 0xD8 -#define CHIPERASE 0xC7 +#define SECTORERASE 0x20 +#define BLOCK32ERASE 0x52 +#define BLOCK64ERASE 0xD8 +#define CHIPERASE 0xC7 -#define UNIQUE_ID 0x4B +#define UNIQUE_ID 0x4B -// Not used or not support command -#define RELEASE 0xAB -#define POWERDOWN 0xB9 -#define SUSPEND 0x75 -#define RESUME 0x7A +// Not used or not support command +#define RELEASE 0xAB +#define POWERDOWN 0xB9 +#define SUSPEND 0x75 +#define RESUME 0x7A -#define BUSY_TIMEOUT 1000000000L +#define BUSY_TIMEOUT 1000000000L -#define WINBOND_MANID 0xEF -#define WINBOND_DEVID 0x11 -#define PAGESIZE 0x100 +#define WINBOND_MANID 0xEF +#define WINBOND_DEVID 0x11 +#define PAGESIZE 0x100 #define WINBOND_WRITE_DELAY 0x02 -#define SPI_CLK 48000000 +#define SPI_CLK 48000000 -#define BUSY 0x01 -#define WRTEN 0x02 -#define SUS 0x40 +#define BUSY 0x01 +#define WRTEN 0x02 +#define SUS 0x40 -#define DUMMYBYTE 0xEE -#define NULLBYTE 0x00 -#define NULLINT 0x0000 -#define NO_CONTINUE 0x00 -#define PASS 0x01 -#define FAIL 0x00 -#define maxAddress capacity +#define DUMMYBYTE 0xEE +#define NULLBYTE 0x00 +#define NULLINT 0x0000 +#define NO_CONTINUE 0x00 +#define PASS 0x01 +#define FAIL 0x00 +#define maxAddress capacity //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// List of Error codes // +// List of Error codes // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -#define SUCCESS 0x00 -#define CALLBEGIN 0x01 -#define UNKNOWNCHIP 0x02 -#define UNKNOWNCAP 0x03 -#define CHIPBUSY 0x04 -#define OUTOFBOUNDS 0x05 -#define CANTENWRITE 0x06 -#define PREVWRITTEN 0x07 -#define LOWRAM 0x08 -#define NOSUSPEND 0x09 -#define UNKNOWNERROR 0xFF +#define SUCCESS 0x00 +#define CALLBEGIN 0x01 +#define UNKNOWNCHIP 0x02 +#define UNKNOWNCAP 0x03 +#define CHIPBUSY 0x04 +#define OUTOFBOUNDS 0x05 +#define CANTENWRITE 0x06 +#define PREVWRITTEN 0x07 +#define LOWRAM 0x08 +#define NOSUSPEND 0x09 +#define UNKNOWNERROR 0xFF // List of blocks -#define MAX_BLOCKS 4 -#define MAX_SECTORS 16 +#define MAX_BLOCKS 4 +#define MAX_SECTORS 16 diff --git a/armsrc/fonts.c b/armsrc/fonts.c index d79a61d84..1e4b418c9 100644 --- a/armsrc/fonts.c +++ b/armsrc/fonts.c @@ -7,302 +7,302 @@ //----------------------------------------------------------------------------- const char FONT6x8[97][8] = { - {0x06,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, bytes per char - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space - {0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00}, // ! - {0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00}, // " - {0x50,0x50,0xF8,0x50,0xF8,0x50,0x50,0x00}, // # - {0x20,0x78,0xA0,0x70,0x28,0xF0,0x20,0x00}, // $ - {0xC0,0xC8,0x10,0x20,0x40,0x98,0x18,0x00}, // % - {0x40,0xA0,0xA0,0x40,0xA8,0x90,0x68,0x00}, // & - {0x30,0x30,0x20,0x40,0x00,0x00,0x00,0x00}, // ' - {0x10,0x20,0x40,0x40,0x40,0x20,0x10,0x00}, // ( - {0x40,0x20,0x10,0x10,0x10,0x20,0x40,0x00}, // ) - {0x00,0x20,0xA8,0x70,0x70,0xA8,0x20,0x00}, // * - {0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00}, // + - {0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40}, // , - {0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00}, // - - {0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00}, // . - {0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00}, // / - {0x70,0x88,0x88,0xA8,0x88,0x88,0x70,0x00}, // 0 - {0x20,0x60,0x20,0x20,0x20,0x20,0x70,0x00}, // 1 - {0x70,0x88,0x08,0x70,0x80,0x80,0xF8,0x00}, // 2 - {0xF8,0x08,0x10,0x30,0x08,0x88,0x70,0x00}, // 3 - {0x10,0x30,0x50,0x90,0xF8,0x10,0x10,0x00}, // 4 - {0xF8,0x80,0xF0,0x08,0x08,0x88,0x70,0x00}, // 5 - {0x38,0x40,0x80,0xF0,0x88,0x88,0x70,0x00}, // 6 - {0xF8,0x08,0x08,0x10,0x20,0x40,0x80,0x00}, // 7 - {0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00}, // 8 - {0x70,0x88,0x88,0x78,0x08,0x10,0xE0,0x00}, // 9 - {0x00,0x00,0x20,0x00,0x20,0x00,0x00,0x00}, // : - {0x00,0x00,0x20,0x00,0x20,0x20,0x40,0x00}, // ; - {0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x00}, // < - {0x00,0x00,0xF8,0x00,0xF8,0x00,0x00,0x00}, // = - {0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00}, // > - {0x70,0x88,0x08,0x30,0x20,0x00,0x20,0x00}, // ? - {0x70,0x88,0xA8,0xB8,0xB0,0x80,0x78,0x00}, // @ - {0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00}, // A - {0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x00}, // B - {0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00}, // C - {0xF0,0x88,0x88,0x88,0x88,0x88,0xF0,0x00}, // D - {0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00}, // E - {0xF8,0x80,0x80,0xF0,0x80,0x80,0x80,0x00}, // F - {0x78,0x88,0x80,0x80,0x98,0x88,0x78,0x00}, // G - {0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x00}, // H - {0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00}, // I - {0x38,0x10,0x10,0x10,0x10,0x90,0x60,0x00}, // J - {0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x00}, // K - {0x80,0x80,0x80,0x80,0x80,0x80,0xF8,0x00}, // L - {0x88,0xD8,0xA8,0xA8,0xA8,0x88,0x88,0x00}, // M - {0x88,0x88,0xC8,0xA8,0x98,0x88,0x88,0x00}, // N - {0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00}, // O - {0xF0,0x88,0x88,0xF0,0x80,0x80,0x80,0x00}, // P - {0x70,0x88,0x88,0x88,0xA8,0x90,0x68,0x00}, // Q - {0xF0,0x88,0x88,0xF0,0xA0,0x90,0x88,0x00}, // R - {0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00}, // S - {0xF8,0xA8,0x20,0x20,0x20,0x20,0x20,0x00}, // T - {0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00}, // U - {0x88,0x88,0x88,0x88,0x88,0x50,0x20,0x00}, // V - {0x88,0x88,0x88,0xA8,0xA8,0xA8,0x50,0x00}, // W - {0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x00}, // X - {0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00}, // Y - {0xF8,0x08,0x10,0x70,0x40,0x80,0xF8,0x00}, // Z - {0x78,0x40,0x40,0x40,0x40,0x40,0x78,0x00}, // [ - {0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00}, // backslash - {0x78,0x08,0x08,0x08,0x08,0x08,0x78,0x00}, // ] - {0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00}, // ^ - {0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00}, // _ - {0x60,0x60,0x20,0x10,0x00,0x00,0x00,0x00}, // ` - {0x00,0x00,0x60,0x10,0x70,0x90,0x78,0x00}, // a - {0x80,0x80,0xB0,0xC8,0x88,0xC8,0xB0,0x00}, // b - {0x00,0x00,0x70,0x88,0x80,0x88,0x70,0x00}, // c - {0x08,0x08,0x68,0x98,0x88,0x98,0x68,0x00}, // d - {0x00,0x00,0x70,0x88,0xF8,0x80,0x70,0x00}, // e - {0x10,0x28,0x20,0x70,0x20,0x20,0x20,0x00}, // f - {0x00,0x00,0x70,0x98,0x98,0x68,0x08,0x70}, // g - {0x80,0x80,0xB0,0xC8,0x88,0x88,0x88,0x00}, // h - {0x20,0x00,0x60,0x20,0x20,0x20,0x70,0x00}, // i - {0x10,0x00,0x10,0x10,0x10,0x90,0x60,0x00}, // j - {0x80,0x80,0x90,0xA0,0xC0,0xA0,0x90,0x00}, // k - {0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00}, // l - {0x00,0x00,0xD0,0xA8,0xA8,0xA8,0xA8,0x00}, // m - {0x00,0x00,0xB0,0xC8,0x88,0x88,0x88,0x00}, // n - {0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00}, // o - {0x00,0x00,0xB0,0xC8,0xC8,0xB0,0x80,0x80}, // p - {0x00,0x00,0x68,0x98,0x98,0x68,0x08,0x08}, // q - {0x00,0x00,0xB0,0xC8,0x80,0x80,0x80,0x00}, // r - {0x00,0x00,0x78,0x80,0x70,0x08,0xF0,0x00}, // s - {0x20,0x20,0xF8,0x20,0x20,0x28,0x10,0x00}, // t - {0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x00}, // u - {0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x00}, // v - {0x00,0x00,0x88,0x88,0xA8,0xA8,0x50,0x00}, // w - {0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00}, // x - {0x00,0x00,0x88,0x88,0x78,0x08,0x88,0x70}, // y - {0x00,0x00,0xF8,0x10,0x20,0x40,0xF8,0x00}, // z - {0x10,0x20,0x20,0x40,0x20,0x20,0x10,0x00}, // { - {0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x00}, // | - {0x40,0x20,0x20,0x10,0x20,0x20,0x40,0x00}, // } - {0x40,0xA8,0x10,0x00,0x00,0x00,0x00,0x00}, // ~ - {0x70,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00} // DEL + {0x06,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, bytes per char + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space + {0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00}, // ! + {0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00}, // " + {0x50,0x50,0xF8,0x50,0xF8,0x50,0x50,0x00}, // # + {0x20,0x78,0xA0,0x70,0x28,0xF0,0x20,0x00}, // $ + {0xC0,0xC8,0x10,0x20,0x40,0x98,0x18,0x00}, // % + {0x40,0xA0,0xA0,0x40,0xA8,0x90,0x68,0x00}, // & + {0x30,0x30,0x20,0x40,0x00,0x00,0x00,0x00}, // ' + {0x10,0x20,0x40,0x40,0x40,0x20,0x10,0x00}, // ( + {0x40,0x20,0x10,0x10,0x10,0x20,0x40,0x00}, // ) + {0x00,0x20,0xA8,0x70,0x70,0xA8,0x20,0x00}, // * + {0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00}, // + + {0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40}, // , + {0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00}, // - + {0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00}, // . + {0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00}, // / + {0x70,0x88,0x88,0xA8,0x88,0x88,0x70,0x00}, // 0 + {0x20,0x60,0x20,0x20,0x20,0x20,0x70,0x00}, // 1 + {0x70,0x88,0x08,0x70,0x80,0x80,0xF8,0x00}, // 2 + {0xF8,0x08,0x10,0x30,0x08,0x88,0x70,0x00}, // 3 + {0x10,0x30,0x50,0x90,0xF8,0x10,0x10,0x00}, // 4 + {0xF8,0x80,0xF0,0x08,0x08,0x88,0x70,0x00}, // 5 + {0x38,0x40,0x80,0xF0,0x88,0x88,0x70,0x00}, // 6 + {0xF8,0x08,0x08,0x10,0x20,0x40,0x80,0x00}, // 7 + {0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00}, // 8 + {0x70,0x88,0x88,0x78,0x08,0x10,0xE0,0x00}, // 9 + {0x00,0x00,0x20,0x00,0x20,0x00,0x00,0x00}, // : + {0x00,0x00,0x20,0x00,0x20,0x20,0x40,0x00}, // ; + {0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x00}, // < + {0x00,0x00,0xF8,0x00,0xF8,0x00,0x00,0x00}, // = + {0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00}, // > + {0x70,0x88,0x08,0x30,0x20,0x00,0x20,0x00}, // ? + {0x70,0x88,0xA8,0xB8,0xB0,0x80,0x78,0x00}, // @ + {0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00}, // A + {0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x00}, // B + {0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00}, // C + {0xF0,0x88,0x88,0x88,0x88,0x88,0xF0,0x00}, // D + {0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00}, // E + {0xF8,0x80,0x80,0xF0,0x80,0x80,0x80,0x00}, // F + {0x78,0x88,0x80,0x80,0x98,0x88,0x78,0x00}, // G + {0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x00}, // H + {0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00}, // I + {0x38,0x10,0x10,0x10,0x10,0x90,0x60,0x00}, // J + {0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x00}, // K + {0x80,0x80,0x80,0x80,0x80,0x80,0xF8,0x00}, // L + {0x88,0xD8,0xA8,0xA8,0xA8,0x88,0x88,0x00}, // M + {0x88,0x88,0xC8,0xA8,0x98,0x88,0x88,0x00}, // N + {0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00}, // O + {0xF0,0x88,0x88,0xF0,0x80,0x80,0x80,0x00}, // P + {0x70,0x88,0x88,0x88,0xA8,0x90,0x68,0x00}, // Q + {0xF0,0x88,0x88,0xF0,0xA0,0x90,0x88,0x00}, // R + {0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00}, // S + {0xF8,0xA8,0x20,0x20,0x20,0x20,0x20,0x00}, // T + {0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00}, // U + {0x88,0x88,0x88,0x88,0x88,0x50,0x20,0x00}, // V + {0x88,0x88,0x88,0xA8,0xA8,0xA8,0x50,0x00}, // W + {0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x00}, // X + {0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00}, // Y + {0xF8,0x08,0x10,0x70,0x40,0x80,0xF8,0x00}, // Z + {0x78,0x40,0x40,0x40,0x40,0x40,0x78,0x00}, // [ + {0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00}, // backslash + {0x78,0x08,0x08,0x08,0x08,0x08,0x78,0x00}, // ] + {0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00}, // ^ + {0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00}, // _ + {0x60,0x60,0x20,0x10,0x00,0x00,0x00,0x00}, // ` + {0x00,0x00,0x60,0x10,0x70,0x90,0x78,0x00}, // a + {0x80,0x80,0xB0,0xC8,0x88,0xC8,0xB0,0x00}, // b + {0x00,0x00,0x70,0x88,0x80,0x88,0x70,0x00}, // c + {0x08,0x08,0x68,0x98,0x88,0x98,0x68,0x00}, // d + {0x00,0x00,0x70,0x88,0xF8,0x80,0x70,0x00}, // e + {0x10,0x28,0x20,0x70,0x20,0x20,0x20,0x00}, // f + {0x00,0x00,0x70,0x98,0x98,0x68,0x08,0x70}, // g + {0x80,0x80,0xB0,0xC8,0x88,0x88,0x88,0x00}, // h + {0x20,0x00,0x60,0x20,0x20,0x20,0x70,0x00}, // i + {0x10,0x00,0x10,0x10,0x10,0x90,0x60,0x00}, // j + {0x80,0x80,0x90,0xA0,0xC0,0xA0,0x90,0x00}, // k + {0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00}, // l + {0x00,0x00,0xD0,0xA8,0xA8,0xA8,0xA8,0x00}, // m + {0x00,0x00,0xB0,0xC8,0x88,0x88,0x88,0x00}, // n + {0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00}, // o + {0x00,0x00,0xB0,0xC8,0xC8,0xB0,0x80,0x80}, // p + {0x00,0x00,0x68,0x98,0x98,0x68,0x08,0x08}, // q + {0x00,0x00,0xB0,0xC8,0x80,0x80,0x80,0x00}, // r + {0x00,0x00,0x78,0x80,0x70,0x08,0xF0,0x00}, // s + {0x20,0x20,0xF8,0x20,0x20,0x28,0x10,0x00}, // t + {0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x00}, // u + {0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x00}, // v + {0x00,0x00,0x88,0x88,0xA8,0xA8,0x50,0x00}, // w + {0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00}, // x + {0x00,0x00,0x88,0x88,0x78,0x08,0x88,0x70}, // y + {0x00,0x00,0xF8,0x10,0x20,0x40,0xF8,0x00}, // z + {0x10,0x20,0x20,0x40,0x20,0x20,0x10,0x00}, // { + {0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x00}, // | + {0x40,0x20,0x20,0x10,0x20,0x20,0x40,0x00}, // } + {0x40,0xA8,0x10,0x00,0x00,0x00,0x00,0x00}, // ~ + {0x70,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00} // DEL }; /* const char FONT8x8F[97][8] = { - {0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, bytes per char - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space - {0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00}, // ! - {0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}, // " - {0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00}, // # - {0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00}, // $ - {0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00}, // % - {0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00}, // & - {0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00}, // ' - {0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00}, // ( - {0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00}, // ) - {0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00}, // * - {0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00}, // + - {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30}, // , - {0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00}, // - - {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00}, // . - {0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00}, // / - {0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00}, // 0 - {0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00}, // 1 - {0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00}, // 2 - {0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00}, // 3 - {0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00}, // 4 - {0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00}, // 5 - {0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00}, // 6 - {0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00}, // 7 - {0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00}, // 8 - {0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00}, // 9 - {0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00}, // : - {0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30}, // ; - {0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00}, // < - {0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00}, // = - {0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00}, // > - {0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00}, // ? - {0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00}, // @ - {0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00}, // A - {0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00}, // B - {0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00}, // C - {0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00}, // D - {0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00}, // E - {0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00}, // F - {0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00}, // G - {0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}, // H - {0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // I - {0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00}, // J - {0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00}, // K - {0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00}, // L - {0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00}, // M - {0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00}, // N - {0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00}, // O - {0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00}, // P - {0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00}, // Q - {0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00}, // R - {0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00}, // S - {0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00}, // T - {0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00}, // U - {0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00}, // V - {0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00}, // W - {0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00}, // X - {0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00}, // Y - {0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00}, // Z - {0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00}, // [ - {0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00}, // backslash - {0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00}, // ] - {0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00}, // ^ - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF}, // _ - {0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00}, // ` - {0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00}, // a - {0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00}, // b - {0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00}, // c - {0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00}, // d - {0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00}, // e - {0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00}, // f - {0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C}, // g - {0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00}, // h - {0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00}, // i - {0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C}, // j - {0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00}, // k - {0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // l - {0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00}, // m - {0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00}, // n - {0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00}, // o - {0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78}, // p - {0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F}, // q - {0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00}, // r - {0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00}, // s - {0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00}, // t - {0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00}, // u - {0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00}, // v - {0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00}, // w - {0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00}, // x - {0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C}, // y - {0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00}, // z - {0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00}, // { - {0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00}, // | - {0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00}, // } - {0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00}, // ~ - {0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00} // DEL + {0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, bytes per char + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space + {0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00}, // ! + {0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}, // " + {0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00}, // # + {0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00}, // $ + {0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00}, // % + {0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00}, // & + {0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00}, // ' + {0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00}, // ( + {0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00}, // ) + {0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00}, // * + {0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00}, // + + {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30}, // , + {0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00}, // - + {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00}, // . + {0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00}, // / + {0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00}, // 0 + {0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00}, // 1 + {0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00}, // 2 + {0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00}, // 3 + {0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00}, // 4 + {0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00}, // 5 + {0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00}, // 6 + {0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00}, // 7 + {0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00}, // 8 + {0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00}, // 9 + {0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00}, // : + {0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30}, // ; + {0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00}, // < + {0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00}, // = + {0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00}, // > + {0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00}, // ? + {0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00}, // @ + {0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00}, // A + {0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00}, // B + {0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00}, // C + {0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00}, // D + {0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00}, // E + {0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00}, // F + {0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00}, // G + {0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}, // H + {0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // I + {0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00}, // J + {0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00}, // K + {0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00}, // L + {0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00}, // M + {0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00}, // N + {0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00}, // O + {0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00}, // P + {0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00}, // Q + {0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00}, // R + {0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00}, // S + {0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00}, // T + {0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00}, // U + {0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00}, // V + {0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00}, // W + {0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00}, // X + {0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00}, // Y + {0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00}, // Z + {0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00}, // [ + {0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00}, // backslash + {0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00}, // ] + {0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00}, // ^ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF}, // _ + {0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00}, // ` + {0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00}, // a + {0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00}, // b + {0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00}, // c + {0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00}, // d + {0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00}, // e + {0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00}, // f + {0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C}, // g + {0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00}, // h + {0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00}, // i + {0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C}, // j + {0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00}, // k + {0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // l + {0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00}, // m + {0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00}, // n + {0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00}, // o + {0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78}, // p + {0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F}, // q + {0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00}, // r + {0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00}, // s + {0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00}, // t + {0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00}, // u + {0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00}, // v + {0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00}, // w + {0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00}, // x + {0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C}, // y + {0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00}, // z + {0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00}, // { + {0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00}, // | + {0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00}, // } + {0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00}, // ~ + {0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00} // DEL }; const char FONT8x16[97][16] = { - {0x08,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // columns, rows, bytes per char - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space - {0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, // ! - {0x00,0x63,0x63,0x63,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // " - {0x00,0x00,0x00,0x36,0x36,0x7F,0x36,0x36,0x36,0x7F,0x36,0x36,0x00,0x00,0x00,0x00}, // # - {0x0C,0x0C,0x3E,0x63,0x61,0x60,0x3E,0x03,0x03,0x43,0x63,0x3E,0x0C,0x0C,0x00,0x00}, // $ - {0x00,0x00,0x00,0x00,0x00,0x61,0x63,0x06,0x0C,0x18,0x33,0x63,0x00,0x00,0x00,0x00}, // % - {0x00,0x00,0x00,0x1C,0x36,0x36,0x1C,0x3B,0x6E,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, // & - {0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // ' - {0x00,0x00,0x0C,0x18,0x18,0x30,0x30,0x30,0x30,0x18,0x18,0x0C,0x00,0x00,0x00,0x00}, // ( - {0x00,0x00,0x18,0x0C,0x0C,0x06,0x06,0x06,0x06,0x0C,0x0C,0x18,0x00,0x00,0x00,0x00}, // ) - {0x00,0x00,0x00,0x00,0x42,0x66,0x3C,0xFF,0x3C,0x66,0x42,0x00,0x00,0x00,0x00,0x00}, // * - {0x00,0x00,0x00,0x00,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00}, // + - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00}, // , - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // - - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, // . - {0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x70,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00}, // / - {0x00,0x00,0x3E,0x63,0x63,0x63,0x6B,0x6B,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // 0 - {0x00,0x00,0x0C,0x1C,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3F,0x00,0x00,0x00,0x00}, // 1 - {0x00,0x00,0x3E,0x63,0x03,0x06,0x0C,0x18,0x30,0x61,0x63,0x7F,0x00,0x00,0x00,0x00}, // 2 - {0x00,0x00,0x3E,0x63,0x03,0x03,0x1E,0x03,0x03,0x03,0x63,0x3E,0x00,0x00,0x00,0x00}, // 3 - {0x00,0x00,0x06,0x0E,0x1E,0x36,0x66,0x66,0x7F,0x06,0x06,0x0F,0x00,0x00,0x00,0x00}, // 4 - {0x00,0x00,0x7F,0x60,0x60,0x60,0x7E,0x03,0x03,0x63,0x73,0x3E,0x00,0x00,0x00,0x00}, // 5 - {0x00,0x00,0x1C,0x30,0x60,0x60,0x7E,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // 6 - {0x00,0x00,0x7F,0x63,0x03,0x06,0x06,0x0C,0x0C,0x18,0x18,0x18,0x00,0x00,0x00,0x00}, // 7 - {0x00,0x00,0x3E,0x63,0x63,0x63,0x3E,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // 8 - {0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x3F,0x03,0x03,0x06,0x3C,0x00,0x00,0x00,0x00}, // 9 - {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, // : - {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00}, // ; - {0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00}, // < - {0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00}, // = - {0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00}, // > - {0x00,0x00,0x3E,0x63,0x63,0x06,0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x00,0x00,0x00,0x00}, // ? - {0x00,0x00,0x3E,0x63,0x63,0x6F,0x6B,0x6B,0x6E,0x60,0x60,0x3E,0x00,0x00,0x00,0x00}, // @ - {0x00,0x00,0x08,0x1C,0x36,0x63,0x63,0x63,0x7F,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, // A - {0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x33,0x33,0x33,0x33,0x7E,0x00,0x00,0x00,0x00}, // B - {0x00,0x00,0x1E,0x33,0x61,0x60,0x60,0x60,0x60,0x61,0x33,0x1E,0x00,0x00,0x00,0x00}, // C - {0x00,0x00,0x7C,0x36,0x33,0x33,0x33,0x33,0x33,0x33,0x36,0x7C,0x00,0x00,0x00,0x00}, // D - {0x00,0x00,0x7F,0x33,0x31,0x34,0x3C,0x34,0x30,0x31,0x33,0x7F,0x00,0x00,0x00,0x00}, // E - {0x00,0x00,0x7F,0x33,0x31,0x34,0x3C,0x34,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, // F - {0x00,0x00,0x1E,0x33,0x61,0x60,0x60,0x6F,0x63,0x63,0x37,0x1D,0x00,0x00,0x00,0x00}, // G - {0x00,0x00,0x63,0x63,0x63,0x63,0x7F,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, // H - {0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, // I - {0x00,0x00,0x0F,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,0x00,0x00,0x00}, // J - {0x00,0x00,0x73,0x33,0x36,0x36,0x3C,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00}, // K - {0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x33,0x7F,0x00,0x00,0x00,0x00}, // L - {0x00,0x00,0x63,0x77,0x7F,0x6B,0x63,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, // M - {0x00,0x00,0x63,0x63,0x73,0x7B,0x7F,0x6F,0x67,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, // N - {0x00,0x00,0x1C,0x36,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1C,0x00,0x00,0x00,0x00}, // O - {0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, // P - {0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x63,0x63,0x6B,0x6F,0x3E,0x06,0x07,0x00,0x00}, // Q - {0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00}, // R - {0x00,0x00,0x3E,0x63,0x63,0x30,0x1C,0x06,0x03,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // S - {0x00,0x00,0xFF,0xDB,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, // T - {0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // U - {0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1C,0x08,0x00,0x00,0x00,0x00}, // V - {0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x6B,0x6B,0x7F,0x36,0x36,0x00,0x00,0x00,0x00}, // W - {0x00,0x00,0xC3,0xC3,0x66,0x3C,0x18,0x18,0x3C,0x66,0xC3,0xC3,0x00,0x00,0x00,0x00}, // X - {0x00,0x00,0xC3,0xC3,0xC3,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, // Y - {0x00,0x00,0x7F,0x63,0x43,0x06,0x0C,0x18,0x30,0x61,0x63,0x7F,0x00,0x00,0x00,0x00}, // Z - {0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00}, // [ - {0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,0x00}, // backslash - {0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00}, // ] - {0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // ^ - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00}, // _ - {0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // ` - {0x00,0x00,0x00,0x00,0x00,0x3C,0x46,0x06,0x3E,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, // a - {0x00,0x00,0x70,0x30,0x30,0x3C,0x36,0x33,0x33,0x33,0x33,0x6E,0x00,0x00,0x00,0x00}, // b - {0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x60,0x60,0x60,0x63,0x3E,0x00,0x00,0x00,0x00}, // c - {0x00,0x00,0x0E,0x06,0x06,0x1E,0x36,0x66,0x66,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, // d - {0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x63,0x7E,0x60,0x63,0x3E,0x00,0x00,0x00,0x00}, // e - {0x00,0x00,0x1C,0x36,0x32,0x30,0x7C,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, // f - {0x00,0x00,0x00,0x00,0x00,0x3B,0x66,0x66,0x66,0x66,0x3E,0x06,0x66,0x3C,0x00,0x00}, // g - {0x00,0x00,0x70,0x30,0x30,0x36,0x3B,0x33,0x33,0x33,0x33,0x73,0x00,0x00,0x00,0x00}, // h - {0x00,0x00,0x0C,0x0C,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00}, // i - {0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,0x00}, // j - {0x00,0x00,0x70,0x30,0x30,0x33,0x33,0x36,0x3C,0x36,0x33,0x73,0x00,0x00,0x00,0x00}, // k - {0x00,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00}, // l - {0x00,0x00,0x00,0x00,0x00,0x6E,0x7F,0x6B,0x6B,0x6B,0x6B,0x6B,0x00,0x00,0x00,0x00}, // m - {0x00,0x00,0x00,0x00,0x00,0x6E,0x33,0x33,0x33,0x33,0x33,0x33,0x00,0x00,0x00,0x00}, // n - {0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // o - {0x00,0x00,0x00,0x00,0x00,0x6E,0x33,0x33,0x33,0x33,0x3E,0x30,0x30,0x78,0x00,0x00}, // p - {0x00,0x00,0x00,0x00,0x00,0x3B,0x66,0x66,0x66,0x66,0x3E,0x06,0x06,0x0F,0x00,0x00}, // q - {0x00,0x00,0x00,0x00,0x00,0x6E,0x3B,0x33,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, // r - {0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x38,0x0E,0x03,0x63,0x3E,0x00,0x00,0x00,0x00}, // s - {0x00,0x00,0x08,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x1B,0x0E,0x00,0x00,0x00,0x00}, // t - {0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, // u - {0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x36,0x36,0x1C,0x1C,0x08,0x00,0x00,0x00,0x00}, // v - {0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x6B,0x6B,0x7F,0x36,0x00,0x00,0x00,0x00}, // w - {0x00,0x00,0x00,0x00,0x00,0x63,0x36,0x1C,0x1C,0x1C,0x36,0x63,0x00,0x00,0x00,0x00}, // x - {0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x3F,0x03,0x06,0x3C,0x00,0x00}, // y - {0x00,0x00,0x00,0x00,0x00,0x7F,0x66,0x0C,0x18,0x30,0x63,0x7F,0x00,0x00,0x00,0x00}, // z - {0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00}, // { - {0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00}, // | - {0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00}, // } - {0x00,0x00,0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // ~ - {0x00,0x70,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} // DEL + {0x08,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // columns, rows, bytes per char + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space + {0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, // ! + {0x00,0x63,0x63,0x63,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // " + {0x00,0x00,0x00,0x36,0x36,0x7F,0x36,0x36,0x36,0x7F,0x36,0x36,0x00,0x00,0x00,0x00}, // # + {0x0C,0x0C,0x3E,0x63,0x61,0x60,0x3E,0x03,0x03,0x43,0x63,0x3E,0x0C,0x0C,0x00,0x00}, // $ + {0x00,0x00,0x00,0x00,0x00,0x61,0x63,0x06,0x0C,0x18,0x33,0x63,0x00,0x00,0x00,0x00}, // % + {0x00,0x00,0x00,0x1C,0x36,0x36,0x1C,0x3B,0x6E,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, // & + {0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // ' + {0x00,0x00,0x0C,0x18,0x18,0x30,0x30,0x30,0x30,0x18,0x18,0x0C,0x00,0x00,0x00,0x00}, // ( + {0x00,0x00,0x18,0x0C,0x0C,0x06,0x06,0x06,0x06,0x0C,0x0C,0x18,0x00,0x00,0x00,0x00}, // ) + {0x00,0x00,0x00,0x00,0x42,0x66,0x3C,0xFF,0x3C,0x66,0x42,0x00,0x00,0x00,0x00,0x00}, // * + {0x00,0x00,0x00,0x00,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00}, // + + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00}, // , + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // - + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, // . + {0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x70,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00}, // / + {0x00,0x00,0x3E,0x63,0x63,0x63,0x6B,0x6B,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // 0 + {0x00,0x00,0x0C,0x1C,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3F,0x00,0x00,0x00,0x00}, // 1 + {0x00,0x00,0x3E,0x63,0x03,0x06,0x0C,0x18,0x30,0x61,0x63,0x7F,0x00,0x00,0x00,0x00}, // 2 + {0x00,0x00,0x3E,0x63,0x03,0x03,0x1E,0x03,0x03,0x03,0x63,0x3E,0x00,0x00,0x00,0x00}, // 3 + {0x00,0x00,0x06,0x0E,0x1E,0x36,0x66,0x66,0x7F,0x06,0x06,0x0F,0x00,0x00,0x00,0x00}, // 4 + {0x00,0x00,0x7F,0x60,0x60,0x60,0x7E,0x03,0x03,0x63,0x73,0x3E,0x00,0x00,0x00,0x00}, // 5 + {0x00,0x00,0x1C,0x30,0x60,0x60,0x7E,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // 6 + {0x00,0x00,0x7F,0x63,0x03,0x06,0x06,0x0C,0x0C,0x18,0x18,0x18,0x00,0x00,0x00,0x00}, // 7 + {0x00,0x00,0x3E,0x63,0x63,0x63,0x3E,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // 8 + {0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x3F,0x03,0x03,0x06,0x3C,0x00,0x00,0x00,0x00}, // 9 + {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, // : + {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00}, // ; + {0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00}, // < + {0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00}, // = + {0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00}, // > + {0x00,0x00,0x3E,0x63,0x63,0x06,0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x00,0x00,0x00,0x00}, // ? + {0x00,0x00,0x3E,0x63,0x63,0x6F,0x6B,0x6B,0x6E,0x60,0x60,0x3E,0x00,0x00,0x00,0x00}, // @ + {0x00,0x00,0x08,0x1C,0x36,0x63,0x63,0x63,0x7F,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, // A + {0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x33,0x33,0x33,0x33,0x7E,0x00,0x00,0x00,0x00}, // B + {0x00,0x00,0x1E,0x33,0x61,0x60,0x60,0x60,0x60,0x61,0x33,0x1E,0x00,0x00,0x00,0x00}, // C + {0x00,0x00,0x7C,0x36,0x33,0x33,0x33,0x33,0x33,0x33,0x36,0x7C,0x00,0x00,0x00,0x00}, // D + {0x00,0x00,0x7F,0x33,0x31,0x34,0x3C,0x34,0x30,0x31,0x33,0x7F,0x00,0x00,0x00,0x00}, // E + {0x00,0x00,0x7F,0x33,0x31,0x34,0x3C,0x34,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, // F + {0x00,0x00,0x1E,0x33,0x61,0x60,0x60,0x6F,0x63,0x63,0x37,0x1D,0x00,0x00,0x00,0x00}, // G + {0x00,0x00,0x63,0x63,0x63,0x63,0x7F,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, // H + {0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, // I + {0x00,0x00,0x0F,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,0x00,0x00,0x00}, // J + {0x00,0x00,0x73,0x33,0x36,0x36,0x3C,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00}, // K + {0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x33,0x7F,0x00,0x00,0x00,0x00}, // L + {0x00,0x00,0x63,0x77,0x7F,0x6B,0x63,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, // M + {0x00,0x00,0x63,0x63,0x73,0x7B,0x7F,0x6F,0x67,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, // N + {0x00,0x00,0x1C,0x36,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1C,0x00,0x00,0x00,0x00}, // O + {0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, // P + {0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x63,0x63,0x6B,0x6F,0x3E,0x06,0x07,0x00,0x00}, // Q + {0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00}, // R + {0x00,0x00,0x3E,0x63,0x63,0x30,0x1C,0x06,0x03,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // S + {0x00,0x00,0xFF,0xDB,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, // T + {0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // U + {0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1C,0x08,0x00,0x00,0x00,0x00}, // V + {0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x6B,0x6B,0x7F,0x36,0x36,0x00,0x00,0x00,0x00}, // W + {0x00,0x00,0xC3,0xC3,0x66,0x3C,0x18,0x18,0x3C,0x66,0xC3,0xC3,0x00,0x00,0x00,0x00}, // X + {0x00,0x00,0xC3,0xC3,0xC3,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, // Y + {0x00,0x00,0x7F,0x63,0x43,0x06,0x0C,0x18,0x30,0x61,0x63,0x7F,0x00,0x00,0x00,0x00}, // Z + {0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00}, // [ + {0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,0x00}, // backslash + {0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00}, // ] + {0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // ^ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00}, // _ + {0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // ` + {0x00,0x00,0x00,0x00,0x00,0x3C,0x46,0x06,0x3E,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, // a + {0x00,0x00,0x70,0x30,0x30,0x3C,0x36,0x33,0x33,0x33,0x33,0x6E,0x00,0x00,0x00,0x00}, // b + {0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x60,0x60,0x60,0x63,0x3E,0x00,0x00,0x00,0x00}, // c + {0x00,0x00,0x0E,0x06,0x06,0x1E,0x36,0x66,0x66,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, // d + {0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x63,0x7E,0x60,0x63,0x3E,0x00,0x00,0x00,0x00}, // e + {0x00,0x00,0x1C,0x36,0x32,0x30,0x7C,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, // f + {0x00,0x00,0x00,0x00,0x00,0x3B,0x66,0x66,0x66,0x66,0x3E,0x06,0x66,0x3C,0x00,0x00}, // g + {0x00,0x00,0x70,0x30,0x30,0x36,0x3B,0x33,0x33,0x33,0x33,0x73,0x00,0x00,0x00,0x00}, // h + {0x00,0x00,0x0C,0x0C,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00}, // i + {0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,0x00}, // j + {0x00,0x00,0x70,0x30,0x30,0x33,0x33,0x36,0x3C,0x36,0x33,0x73,0x00,0x00,0x00,0x00}, // k + {0x00,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00}, // l + {0x00,0x00,0x00,0x00,0x00,0x6E,0x7F,0x6B,0x6B,0x6B,0x6B,0x6B,0x00,0x00,0x00,0x00}, // m + {0x00,0x00,0x00,0x00,0x00,0x6E,0x33,0x33,0x33,0x33,0x33,0x33,0x00,0x00,0x00,0x00}, // n + {0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // o + {0x00,0x00,0x00,0x00,0x00,0x6E,0x33,0x33,0x33,0x33,0x3E,0x30,0x30,0x78,0x00,0x00}, // p + {0x00,0x00,0x00,0x00,0x00,0x3B,0x66,0x66,0x66,0x66,0x3E,0x06,0x06,0x0F,0x00,0x00}, // q + {0x00,0x00,0x00,0x00,0x00,0x6E,0x3B,0x33,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, // r + {0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x38,0x0E,0x03,0x63,0x3E,0x00,0x00,0x00,0x00}, // s + {0x00,0x00,0x08,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x1B,0x0E,0x00,0x00,0x00,0x00}, // t + {0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, // u + {0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x36,0x36,0x1C,0x1C,0x08,0x00,0x00,0x00,0x00}, // v + {0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x6B,0x6B,0x7F,0x36,0x00,0x00,0x00,0x00}, // w + {0x00,0x00,0x00,0x00,0x00,0x63,0x36,0x1C,0x1C,0x1C,0x36,0x63,0x00,0x00,0x00,0x00}, // x + {0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x3F,0x03,0x06,0x3C,0x00,0x00}, // y + {0x00,0x00,0x00,0x00,0x00,0x7F,0x66,0x0C,0x18,0x30,0x63,0x7F,0x00,0x00,0x00,0x00}, // z + {0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00}, // { + {0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00}, // | + {0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00}, // } + {0x00,0x00,0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // ~ + {0x00,0x70,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} // DEL }; */ diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index 18430b78b..2af6fd0ec 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -21,7 +21,7 @@ extern uint8_t _binary_obj_fpga_all_bit_z_start, _binary_obj_fpga_all_bit_z_end; static uint8_t *fpga_image_ptr = NULL; static uint32_t uncompressed_bytes_cnt; -#define OUTPUT_BUFFER_LEN 80 +#define OUTPUT_BUFFER_LEN 80 //----------------------------------------------------------------------------- // Set up the Serial Peripheral Interface as master @@ -29,7 +29,7 @@ static uint32_t uncompressed_bytes_cnt; // May also be used to write to other SPI attached devices like an LCD //----------------------------------------------------------------------------- static void DisableSpi(void) { - //* Reset all the Chip Select register + //* Reset all the Chip Select register AT91C_BASE_SPI->SPI_CSR[0] = 0; AT91C_BASE_SPI->SPI_CSR[1] = 0; AT91C_BASE_SPI->SPI_CSR[2] = 0; @@ -41,77 +41,77 @@ static void DisableSpi(void) { // Disable all interrupts AT91C_BASE_SPI->SPI_IDR = 0xFFFFFFFF; - // SPI disable - AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS; + // SPI disable + AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS; } void SetupSpi(int mode) { - // PA1 -> SPI_NCS3 chip select (MEM) - // PA10 -> SPI_NCS2 chip select (LCD) - // PA11 -> SPI_NCS0 chip select (FPGA) - // PA12 -> SPI_MISO Master-In Slave-Out - // PA13 -> SPI_MOSI Master-Out Slave-In - // PA14 -> SPI_SPCK Serial Clock + // PA1 -> SPI_NCS3 chip select (MEM) + // PA10 -> SPI_NCS2 chip select (LCD) + // PA11 -> SPI_NCS0 chip select (FPGA) + // PA12 -> SPI_MISO Master-In Slave-Out + // PA13 -> SPI_MOSI Master-Out Slave-In + // PA14 -> SPI_SPCK Serial Clock - // Disable PIO control of the following pins, allows use by the SPI peripheral - AT91C_BASE_PIOA->PIO_PDR = GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK; + // Disable PIO control of the following pins, allows use by the SPI peripheral + AT91C_BASE_PIOA->PIO_PDR = GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK; - // Peripheral A - AT91C_BASE_PIOA->PIO_ASR = GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK; + // Peripheral A + AT91C_BASE_PIOA->PIO_ASR = GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK; - // Peripheral B - //AT91C_BASE_PIOA->PIO_BSR |= GPIO_NCS2; + // Peripheral B + //AT91C_BASE_PIOA->PIO_BSR |= GPIO_NCS2; - //enable the SPI Peripheral clock - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI); - // Enable SPI - AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN; + //enable the SPI Peripheral clock + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI); + // Enable SPI + AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN; - switch (mode) { - case SPI_FPGA_MODE: - AT91C_BASE_SPI->SPI_MR = - ( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods) - (0xE << 16) | // Peripheral Chip Select (selects FPGA SPI_NCS0 or PA11) - ( 0 << 7) | // Local Loopback Disabled - AT91C_SPI_MODFDIS | // Mode Fault Detection disabled - ( 0 << 2) | // Chip selects connected directly to peripheral - AT91C_SPI_PS_FIXED | // Fixed Peripheral Select - AT91C_SPI_MSTR; // Master Mode + switch (mode) { + case SPI_FPGA_MODE: + AT91C_BASE_SPI->SPI_MR = + ( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods) + (0xE << 16) | // Peripheral Chip Select (selects FPGA SPI_NCS0 or PA11) + ( 0 << 7) | // Local Loopback Disabled + AT91C_SPI_MODFDIS | // Mode Fault Detection disabled + ( 0 << 2) | // Chip selects connected directly to peripheral + AT91C_SPI_PS_FIXED | // Fixed Peripheral Select + AT91C_SPI_MSTR; // Master Mode - AT91C_BASE_SPI->SPI_CSR[0] = - ( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods) - ( 1 << 16) | // Delay Before SPCK (1 MCK period) - ( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud - AT91C_SPI_BITS_16 | // Bits per Transfer (16 bits) - ( 0 << 3) | // Chip Select inactive after transfer - AT91C_SPI_NCPHA | // Clock Phase data captured on leading edge, changes on following edge - ( 0 << 0); // Clock Polarity inactive state is logic 0 - break; + AT91C_BASE_SPI->SPI_CSR[0] = + ( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods) + ( 1 << 16) | // Delay Before SPCK (1 MCK period) + ( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud + AT91C_SPI_BITS_16 | // Bits per Transfer (16 bits) + ( 0 << 3) | // Chip Select inactive after transfer + AT91C_SPI_NCPHA | // Clock Phase data captured on leading edge, changes on following edge + ( 0 << 0); // Clock Polarity inactive state is logic 0 + break; /* - case SPI_LCD_MODE: - AT91C_BASE_SPI->SPI_MR = - ( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods) - (0xB << 16) | // Peripheral Chip Select (selects LCD SPI_NCS2 or PA10) - ( 0 << 7) | // Local Loopback Disabled - ( 1 << 4) | // Mode Fault Detection disabled - ( 0 << 2) | // Chip selects connected directly to peripheral - ( 0 << 1) | // Fixed Peripheral Select - ( 1 << 0); // Master Mode + case SPI_LCD_MODE: + AT91C_BASE_SPI->SPI_MR = + ( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods) + (0xB << 16) | // Peripheral Chip Select (selects LCD SPI_NCS2 or PA10) + ( 0 << 7) | // Local Loopback Disabled + ( 1 << 4) | // Mode Fault Detection disabled + ( 0 << 2) | // Chip selects connected directly to peripheral + ( 0 << 1) | // Fixed Peripheral Select + ( 1 << 0); // Master Mode - AT91C_BASE_SPI->SPI_CSR[2] = - ( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods) - ( 1 << 16) | // Delay Before SPCK (1 MCK period) - ( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud - AT91C_SPI_BITS_9 | // Bits per Transfer (9 bits) - ( 0 << 3) | // Chip Select inactive after transfer - ( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge - ( 0 << 0); // Clock Polarity inactive state is logic 0 - break; + AT91C_BASE_SPI->SPI_CSR[2] = + ( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods) + ( 1 << 16) | // Delay Before SPCK (1 MCK period) + ( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud + AT91C_SPI_BITS_9 | // Bits per Transfer (9 bits) + ( 0 << 3) | // Chip Select inactive after transfer + ( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge + ( 0 << 0); // Clock Polarity inactive state is logic 0 + break; */ - default: - DisableSpi(); - break; - } + default: + DisableSpi(); + break; + } } //----------------------------------------------------------------------------- @@ -119,35 +119,35 @@ void SetupSpi(int mode) { // always use when we are talking to the FPGA. Both RX and TX are enabled. //----------------------------------------------------------------------------- void FpgaSetupSsc(void) { - // First configure the GPIOs, and get ourselves a clock. - AT91C_BASE_PIOA->PIO_ASR = - GPIO_SSC_FRAME | - GPIO_SSC_DIN | - GPIO_SSC_DOUT | - GPIO_SSC_CLK; - AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; + // First configure the GPIOs, and get ourselves a clock. + AT91C_BASE_PIOA->PIO_ASR = + GPIO_SSC_FRAME | + GPIO_SSC_DIN | + GPIO_SSC_DOUT | + GPIO_SSC_CLK; + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SSC); + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SSC); - // Now set up the SSC proper, starting from a known state. - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; + // Now set up the SSC proper, starting from a known state. + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; - // RX clock comes from TX clock, RX starts when TX starts, data changes - // on RX clock rising edge, sampled on falling edge - AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(1) | SSC_CLOCK_MODE_START(1); + // RX clock comes from TX clock, RX starts when TX starts, data changes + // on RX clock rising edge, sampled on falling edge + AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(1) | SSC_CLOCK_MODE_START(1); - // 8 bits per transfer, no loopback, MSB first, 1 transfer per sync - // pulse, no output sync - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); + // 8 bits per transfer, no loopback, MSB first, 1 transfer per sync + // pulse, no output sync + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); - // clock comes from TK pin, no clock output, outputs change on falling - // edge of TK, sample on rising edge of TK, start on positive-going edge of sync - AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) | SSC_CLOCK_MODE_START(5); + // clock comes from TK pin, no clock output, outputs change on falling + // edge of TK, sample on rising edge of TK, start on positive-going edge of sync + AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) | SSC_CLOCK_MODE_START(5); - // tx framing is the same as the rx framing - AT91C_BASE_SSC->SSC_TFMR = AT91C_BASE_SSC->SSC_RFMR; + // tx framing is the same as the rx framing + AT91C_BASE_SSC->SSC_TFMR = AT91C_BASE_SSC->SSC_RFMR; - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; } //----------------------------------------------------------------------------- @@ -157,15 +157,15 @@ void FpgaSetupSsc(void) { // is in apps.h, because it should be inlined, for speed. //----------------------------------------------------------------------------- bool FpgaSetupSscDma(uint8_t *buf, int len) { - if (buf == NULL) return false; + if (buf == NULL) return false; - FpgaDisableSscDma(); - AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) buf; // transfer to this memory address - AT91C_BASE_PDC_SSC->PDC_RCR = len; // transfer this many bytes - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) buf; // next transfer to same memory address - AT91C_BASE_PDC_SSC->PDC_RNCR = len; // ... with same number of bytes - FpgaEnableSscDma(); - return true; + FpgaDisableSscDma(); + AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) buf; // transfer to this memory address + AT91C_BASE_PDC_SSC->PDC_RCR = len; // transfer this many bytes + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) buf; // next transfer to same memory address + AT91C_BASE_PDC_SSC->PDC_RNCR = len; // ... with same number of bytes + FpgaEnableSscDma(); + return true; } //---------------------------------------------------------------------------- @@ -173,20 +173,20 @@ bool FpgaSetupSscDma(uint8_t *buf, int len) { // each call. //---------------------------------------------------------------------------- static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8_t *output_buffer) { - if (fpga_image_ptr == compressed_fpga_stream->next_out) { // need more data - compressed_fpga_stream->next_out = output_buffer; - compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN; - fpga_image_ptr = output_buffer; - int res = inflate(compressed_fpga_stream, Z_SYNC_FLUSH); + if (fpga_image_ptr == compressed_fpga_stream->next_out) { // need more data + compressed_fpga_stream->next_out = output_buffer; + compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN; + fpga_image_ptr = output_buffer; + int res = inflate(compressed_fpga_stream, Z_SYNC_FLUSH); - if (res != Z_OK) - Dbprintf("inflate returned: %d, %s", res, compressed_fpga_stream->msg); + if (res != Z_OK) + Dbprintf("inflate returned: %d, %s", res, compressed_fpga_stream->msg); - if (res < 0) - return res; - } - uncompressed_bytes_cnt++; - return *fpga_image_ptr++; + if (res < 0) + return res; + } + uncompressed_bytes_cnt++; + return *fpga_image_ptr++; } //---------------------------------------------------------------------------- @@ -195,140 +195,140 @@ static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8 // 288 bytes from FPGA file 1, followed by 288 bytes from FGPA file 2, etc. //---------------------------------------------------------------------------- static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { - while((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % fpga_bitstream_num != (bitstream_version - 1)) { - // skip undesired data belonging to other bitstream_versions - get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer); - } + while((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % fpga_bitstream_num != (bitstream_version - 1)) { + // skip undesired data belonging to other bitstream_versions + get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer); + } - return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer); + return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer); } static voidpf fpga_inflate_malloc(voidpf opaque, uInt items, uInt size) { - return BigBuf_malloc(items*size); + return BigBuf_malloc(items*size); } // free eventually allocated BigBuf memory static void fpga_inflate_free(voidpf opaque, voidpf address) { - BigBuf_free(); BigBuf_Clear_ext(false); + BigBuf_free(); BigBuf_Clear_ext(false); } //---------------------------------------------------------------------------- // Initialize decompression of the respective (HF or LF) FPGA stream //---------------------------------------------------------------------------- static bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { - uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE]; + uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE]; - uncompressed_bytes_cnt = 0; + uncompressed_bytes_cnt = 0; - // initialize z_stream structure for inflate: - compressed_fpga_stream->next_in = &_binary_obj_fpga_all_bit_z_start; - compressed_fpga_stream->avail_in = &_binary_obj_fpga_all_bit_z_end - &_binary_obj_fpga_all_bit_z_start; - compressed_fpga_stream->next_out = output_buffer; - compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN; - compressed_fpga_stream->zalloc = &fpga_inflate_malloc; - compressed_fpga_stream->zfree = &fpga_inflate_free; + // initialize z_stream structure for inflate: + compressed_fpga_stream->next_in = &_binary_obj_fpga_all_bit_z_start; + compressed_fpga_stream->avail_in = &_binary_obj_fpga_all_bit_z_end - &_binary_obj_fpga_all_bit_z_start; + compressed_fpga_stream->next_out = output_buffer; + compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN; + compressed_fpga_stream->zalloc = &fpga_inflate_malloc; + compressed_fpga_stream->zfree = &fpga_inflate_free; - inflateInit2(compressed_fpga_stream, 0); + inflateInit2(compressed_fpga_stream, 0); - fpga_image_ptr = output_buffer; + fpga_image_ptr = output_buffer; - for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++) - header[i] = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); + for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++) + header[i] = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); - // Check for a valid .bit file (starts with bitparse_fixed_header) - if (memcmp(bitparse_fixed_header, header, FPGA_BITSTREAM_FIXED_HEADER_SIZE) == 0) - return true; + // Check for a valid .bit file (starts with bitparse_fixed_header) + if (memcmp(bitparse_fixed_header, header, FPGA_BITSTREAM_FIXED_HEADER_SIZE) == 0) + return true; - return false; + return false; } static void DownloadFPGA_byte( uint8_t w) { #define SEND_BIT(x) { if(w & (1<PIO_OER = GPIO_FPGA_ON; - AT91C_BASE_PIOA->PIO_PER = GPIO_FPGA_ON; - HIGH(GPIO_FPGA_ON); // ensure everything is powered on + AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON; + AT91C_BASE_PIOA->PIO_PER = GPIO_FPGA_ON; + HIGH(GPIO_FPGA_ON); // ensure everything is powered on - SpinDelay(50); + SpinDelay(50); - LED_D_ON(); + LED_D_ON(); - // These pins are inputs + // These pins are inputs AT91C_BASE_PIOA->PIO_ODR = - GPIO_FPGA_NINIT | - GPIO_FPGA_DONE; - // PIO controls the following pins + GPIO_FPGA_NINIT | + GPIO_FPGA_DONE; + // PIO controls the following pins AT91C_BASE_PIOA->PIO_PER = - GPIO_FPGA_NINIT | - GPIO_FPGA_DONE; - // Enable pull-ups - AT91C_BASE_PIOA->PIO_PPUER = - GPIO_FPGA_NINIT | - GPIO_FPGA_DONE; + GPIO_FPGA_NINIT | + GPIO_FPGA_DONE; + // Enable pull-ups + AT91C_BASE_PIOA->PIO_PPUER = + GPIO_FPGA_NINIT | + GPIO_FPGA_DONE; - // setup initial logic state - HIGH(GPIO_FPGA_NPROGRAM); - LOW(GPIO_FPGA_CCLK); - LOW(GPIO_FPGA_DIN); - // These pins are outputs - AT91C_BASE_PIOA->PIO_OER = - GPIO_FPGA_NPROGRAM | - GPIO_FPGA_CCLK | - GPIO_FPGA_DIN; + // setup initial logic state + HIGH(GPIO_FPGA_NPROGRAM); + LOW(GPIO_FPGA_CCLK); + LOW(GPIO_FPGA_DIN); + // These pins are outputs + AT91C_BASE_PIOA->PIO_OER = + GPIO_FPGA_NPROGRAM | + GPIO_FPGA_CCLK | + GPIO_FPGA_DIN; - // enter FPGA configuration mode - LOW(GPIO_FPGA_NPROGRAM); - SpinDelay(50); - HIGH(GPIO_FPGA_NPROGRAM); + // enter FPGA configuration mode + LOW(GPIO_FPGA_NPROGRAM); + SpinDelay(50); + HIGH(GPIO_FPGA_NPROGRAM); - i = 100000; - // wait for FPGA ready to accept data signal - while ((i) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_NINIT ) ) ) { - i--; - } + i = 100000; + // wait for FPGA ready to accept data signal + while ((i) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_NINIT ) ) ) { + i--; + } - // crude error indicator, leave both red LEDs on and return - if (i==0){ - LED_C_ON(); - LED_D_ON(); - return; - } + // crude error indicator, leave both red LEDs on and return + if (i==0){ + LED_C_ON(); + LED_D_ON(); + return; + } - for (i = 0; i < FpgaImageLen; i++) { - int b = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); - if (b < 0) { - Dbprintf("Error %d during FpgaDownload", b); - break; - } - DownloadFPGA_byte(b); - } + for (i = 0; i < FpgaImageLen; i++) { + int b = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); + if (b < 0) { + Dbprintf("Error %d during FpgaDownload", b); + break; + } + DownloadFPGA_byte(b); + } - // continue to clock FPGA until ready signal goes high - i = 100000; - while ( (i--) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_DONE ) ) ) { - HIGH(GPIO_FPGA_CCLK); - LOW(GPIO_FPGA_CCLK); - } - // crude error indicator, leave both red LEDs on and return - if (i==0){ - LED_C_ON(); - LED_D_ON(); - return; - } - LED_D_OFF(); + // continue to clock FPGA until ready signal goes high + i = 100000; + while ( (i--) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_DONE ) ) ) { + HIGH(GPIO_FPGA_CCLK); + LOW(GPIO_FPGA_CCLK); + } + // crude error indicator, leave both red LEDs on and return + if (i==0){ + LED_C_ON(); + LED_D_ON(); + return; + } + LED_D_OFF(); } /* Simple Xilinx .bit parser. The file starts with the fixed opaque byte sequence @@ -338,48 +338,48 @@ static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp comp * length. */ static int bitparse_find_section(int bitstream_version, char section_name, uint32_t *section_length, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { - int result = 0; - #define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section - uint16_t numbytes = 0; - while(numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH) { - char current_name = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); - numbytes++; - uint32_t current_length = 0; - if (current_name < 'a' || current_name > 'e') { - /* Strange section name, abort */ - break; - } - current_length = 0; - switch (current_name) { - case 'e': - /* Four byte length field */ - current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 24; - current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 16; - numbytes += 2; - default: /* Fall through, two byte length field */ - current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 8; - current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 0; - numbytes += 2; - } + int result = 0; + #define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section + uint16_t numbytes = 0; + while(numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH) { + char current_name = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); + numbytes++; + uint32_t current_length = 0; + if (current_name < 'a' || current_name > 'e') { + /* Strange section name, abort */ + break; + } + current_length = 0; + switch (current_name) { + case 'e': + /* Four byte length field */ + current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 24; + current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 16; + numbytes += 2; + default: /* Fall through, two byte length field */ + current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 8; + current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 0; + numbytes += 2; + } - if (current_name != 'e' && current_length > 255) { - /* Maybe a parse error */ - break; - } + if (current_name != 'e' && current_length > 255) { + /* Maybe a parse error */ + break; + } - if (current_name == section_name) { - /* Found it */ - *section_length = current_length; - result = 1; - break; - } + if (current_name == section_name) { + /* Found it */ + *section_length = current_length; + result = 1; + break; + } - for (uint16_t i = 0; i < current_length && numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH; i++) { - get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); - numbytes++; - } - } - return result; + for (uint16_t i = 0; i < current_length && numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH; i++) { + get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); + numbytes++; + } + } + return result; } //---------------------------------------------------------------------------- @@ -388,34 +388,34 @@ static int bitparse_find_section(int bitstream_version, char section_name, uint3 //---------------------------------------------------------------------------- void FpgaDownloadAndGo(int bitstream_version) { - // check whether or not the bitstream is already loaded - if (downloaded_bitstream == bitstream_version) - return; + // check whether or not the bitstream is already loaded + if (downloaded_bitstream == bitstream_version) + return; - z_stream compressed_fpga_stream; - uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00}; + z_stream compressed_fpga_stream; + uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00}; - bool verbose = (MF_DBGLEVEL > 3); + bool verbose = (MF_DBGLEVEL > 3); - // make sure that we have enough memory to decompress - BigBuf_free(); BigBuf_Clear_ext(verbose); + // make sure that we have enough memory to decompress + BigBuf_free(); BigBuf_Clear_ext(verbose); - if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer)) - return; + if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer)) + return; - uint32_t bitstream_length; - if (bitparse_find_section(bitstream_version, 'e', &bitstream_length, &compressed_fpga_stream, output_buffer)) { - DownloadFPGA(bitstream_version, bitstream_length, &compressed_fpga_stream, output_buffer); - downloaded_bitstream = bitstream_version; - } + uint32_t bitstream_length; + if (bitparse_find_section(bitstream_version, 'e', &bitstream_length, &compressed_fpga_stream, output_buffer)) { + DownloadFPGA(bitstream_version, bitstream_length, &compressed_fpga_stream, output_buffer); + downloaded_bitstream = bitstream_version; + } - inflateEnd(&compressed_fpga_stream); + inflateEnd(&compressed_fpga_stream); - // turn off antenna - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // turn off antenna + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - // free eventually allocated BigBuf memory - BigBuf_free(); BigBuf_Clear_ext(false); + // free eventually allocated BigBuf memory + BigBuf_free(); BigBuf_Clear_ext(false); } //----------------------------------------------------------------------------- @@ -424,10 +424,10 @@ void FpgaDownloadAndGo(int bitstream_version) { // where C is the 4 bit command and D is the 12 bit data //----------------------------------------------------------------------------- void FpgaSendCommand(uint16_t cmd, uint16_t v) { - SetupSpi(SPI_FPGA_MODE); - while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete - AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER | cmd | v; // send the data - while (!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF)) {}; // wait till transfer is complete + SetupSpi(SPI_FPGA_MODE); + while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete + AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER | cmd | v; // send the data + while (!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF)) {}; // wait till transfer is complete } //----------------------------------------------------------------------------- // Write the FPGA setup word (that determines what mode the logic is in, read @@ -435,7 +435,7 @@ void FpgaSendCommand(uint16_t cmd, uint16_t v) { // avoid changing this function's occurence everywhere in the source code. //----------------------------------------------------------------------------- void FpgaWriteConfWord(uint8_t v) { - FpgaSendCommand(FPGA_CMD_SET_CONFREG, v); + FpgaSendCommand(FPGA_CMD_SET_CONFREG, v); } //----------------------------------------------------------------------------- @@ -444,35 +444,35 @@ void FpgaWriteConfWord(uint8_t v) { // the samples from the ADC always flow through the FPGA. //----------------------------------------------------------------------------- void SetAdcMuxFor(uint32_t whichGpio) { - AT91C_BASE_PIOA->PIO_OER = - GPIO_MUXSEL_HIPKD | - GPIO_MUXSEL_LOPKD | - GPIO_MUXSEL_LORAW | - GPIO_MUXSEL_HIRAW; + AT91C_BASE_PIOA->PIO_OER = + GPIO_MUXSEL_HIPKD | + GPIO_MUXSEL_LOPKD | + GPIO_MUXSEL_LORAW | + GPIO_MUXSEL_HIRAW; - AT91C_BASE_PIOA->PIO_PER = - GPIO_MUXSEL_HIPKD | - GPIO_MUXSEL_LOPKD | - GPIO_MUXSEL_LORAW | - GPIO_MUXSEL_HIRAW; + AT91C_BASE_PIOA->PIO_PER = + GPIO_MUXSEL_HIPKD | + GPIO_MUXSEL_LOPKD | + GPIO_MUXSEL_LORAW | + GPIO_MUXSEL_HIRAW; - LOW(GPIO_MUXSEL_HIPKD); - LOW(GPIO_MUXSEL_LOPKD); + LOW(GPIO_MUXSEL_HIPKD); + LOW(GPIO_MUXSEL_LOPKD); #ifndef WITH_FPC - LOW(GPIO_MUXSEL_HIRAW); - LOW(GPIO_MUXSEL_LORAW); + LOW(GPIO_MUXSEL_HIRAW); + LOW(GPIO_MUXSEL_LORAW); #endif - HIGH(whichGpio); + HIGH(whichGpio); } void Fpga_print_status(void) { - Dbprintf("Currently loaded FPGA image"); - Dbprintf(" mode....................%s", fpga_version_information[downloaded_bitstream-1]); + Dbprintf("Currently loaded FPGA image"); + Dbprintf(" mode....................%s", fpga_version_information[downloaded_bitstream-1]); } int FpgaGetCurrent(void) { - return downloaded_bitstream; + return downloaded_bitstream; } // Turns off the antenna, @@ -480,10 +480,10 @@ int FpgaGetCurrent(void) { // if HF, Disable SSC DMA // turn off trace and leds off. void switch_off(void) { - if (MF_DBGLEVEL > 3) Dbprintf("switch_off"); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - if (downloaded_bitstream == FPGA_BITSTREAM_HF ) - FpgaDisableSscDma(); - set_tracing(false); - LEDsoff(); + if (MF_DBGLEVEL > 3) Dbprintf("switch_off"); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + if (downloaded_bitstream == FPGA_BITSTREAM_HF ) + FpgaDisableSscDma(); + set_tracing(false); + LEDsoff(); } diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index 7f9ec28e6..ef278cc3e 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -16,11 +16,11 @@ #include #include "apps.h" #include "fpga.h" -#include "common.h" // standard definitions -#include "proxmark3.h" // common area +#include "common.h" // standard definitions +#include "proxmark3.h" // common area #include "string.h" -#include "BigBuf.h" // bigbuf mem -#include "zlib.h" // uncompress +#include "BigBuf.h" // bigbuf mem +#include "zlib.h" // uncompress void FpgaSendCommand(uint16_t cmd, uint16_t v); @@ -32,7 +32,7 @@ void SetupSpi(int mode); bool FpgaSetupSscDma(uint8_t *buf, int len); void Fpga_print_status(void); int FpgaGetCurrent(void); -#define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; +#define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; #define FpgaEnableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; void SetAdcMuxFor(uint32_t whichGpio); @@ -45,56 +45,56 @@ extern void switch_off(void); //#define FPGA_BITSTREAM_FELICA 3 // Definitions for the FPGA commands. -#define FPGA_CMD_SET_CONFREG (1<<12) -#define FPGA_CMD_SET_DIVISOR (2<<12) -#define FPGA_CMD_SET_USER_BYTE1 (3<<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. // 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) +#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) -#define FPGA_MAJOR_MODE_HF_SNOOP (4<<5) -#define FPGA_MAJOR_MODE_HF_FELICA (5<<5) +#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) +#define FPGA_MAJOR_MODE_HF_SNOOP (4<<5) +#define FPGA_MAJOR_MODE_HF_FELICA (5<<5) // BOTH -#define FPGA_MAJOR_MODE_OFF_LF (6<<5) -#define FPGA_MAJOR_MODE_OFF (7<<5) +#define FPGA_MAJOR_MODE_OFF_LF (6<<5) +#define FPGA_MAJOR_MODE_OFF (7<<5) // Options for LF_ADC -#define FPGA_LF_ADC_READER_FIELD (1<<0) +#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) +#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) +#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 (1<<2) +#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 (1<<2) // Options for the HF simulated tag, how to modulate -#define FPGA_HF_SIMULATOR_NO_MODULATION 0x0 // 0000 -#define FPGA_HF_SIMULATOR_MODULATE_BPSK 0x1 // 0001 -#define FPGA_HF_SIMULATOR_MODULATE_212K 0x2 // 0010 -#define FPGA_HF_SIMULATOR_MODULATE_424K 0x4 // 0100 -#define FPGA_HF_SIMULATOR_MODULATE_424K_8BIT 0x5 // 0101 +#define FPGA_HF_SIMULATOR_NO_MODULATION 0x0 // 0000 +#define FPGA_HF_SIMULATOR_MODULATE_BPSK 0x1 // 0001 +#define FPGA_HF_SIMULATOR_MODULATE_212K 0x2 // 0010 +#define FPGA_HF_SIMULATOR_MODULATE_424K 0x4 // 0100 +#define FPGA_HF_SIMULATOR_MODULATE_424K_8BIT 0x5 // 0101 // no 848K // Options for ISO14443A -#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) -#define FPGA_HF_ISO14443A_READER_MOD (4<<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) +#define FPGA_HF_ISO14443A_READER_MOD (4<<0) //options for Felica. -#define FPGA_MAJOR_MODE_ISO18092 (5<<5) // 01010 0000 +#define FPGA_MAJOR_MODE_ISO18092 (5<<5) // 01010 0000 #define FPGA_HF_ISO18092_FLAG_NOMOD (1<<0) // 0001 disable modulation module #define FPGA_HF_ISO18092_FLAG_424K (2<<0) // 0010 should enable 414k mode (untested). No autodetect -#define FPGA_HF_ISO18092_FLAG_READER (4<<0) // 0100 enables antenna power, to act as a reader instead of tag +#define FPGA_HF_ISO18092_FLAG_READER (4<<0) // 0100 enables antenna power, to act as a reader instead of tag -#endif \ No newline at end of file +#endif diff --git a/armsrc/hfsnoop.c b/armsrc/hfsnoop.c index d66f88276..117e064e8 100644 --- a/armsrc/hfsnoop.c +++ b/armsrc/hfsnoop.c @@ -2,79 +2,79 @@ #include "apps.h" #include "BigBuf.h" #include "util.h" -#include "usb_cdc.h" // for usb_poll_validate_length +#include "usb_cdc.h" // for usb_poll_validate_length static void RAMFUNC optimizedSnoop(void); static void RAMFUNC optimizedSnoop(void) { - int n = BigBuf_max_traceLen() / sizeof(uint16_t); // take all memory + int n = BigBuf_max_traceLen() / sizeof(uint16_t); // take all memory - uint16_t *dest = (uint16_t *)BigBuf_get_addr(); + uint16_t *dest = (uint16_t *)BigBuf_get_addr(); uint16_t *destend = dest + n-1; - // Reading data loop - while(dest <= destend) { - if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - *dest = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); - dest++; - } - } + // Reading data loop + while(dest <= destend) { + if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + *dest = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); + dest++; + } + } //setting tracelen - important! it was set by buffer overflow before set_tracelen( BigBuf_max_traceLen()); } void HfSnoop(int samplesToSkip, int triggersToSkip) { - BigBuf_free(); BigBuf_Clear(); + BigBuf_free(); BigBuf_Clear(); - Dbprintf("Skipping first %d sample pairs, Skipping %d triggers.\n", samplesToSkip, triggersToSkip); - int trigger_cnt = 0; + Dbprintf("Skipping first %d sample pairs, Skipping %d triggers.\n", samplesToSkip, triggersToSkip); + int trigger_cnt = 0; - LED_D_ON(); + LED_D_ON(); - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - // Set up the synchronous serial port - FpgaSetupSsc(); + // Set up the synchronous serial port + FpgaSetupSsc(); - // Setting Frame Mode For better performance on high speed data transfer. - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16); + // Setting Frame Mode For better performance on high speed data transfer. + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SNOOP); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SNOOP); SpinDelay(100); - uint16_t r = 0; - while (!BUTTON_PRESS() && !usb_poll_validate_length() ) { - WDT_HIT(); + uint16_t r = 0; + while (!BUTTON_PRESS() && !usb_poll_validate_length() ) { + WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - r = (uint16_t)AT91C_BASE_SSC->SSC_RHR; - r = MAX(r & 0xff, r >> 8); + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + r = (uint16_t)AT91C_BASE_SSC->SSC_RHR; + r = MAX(r & 0xff, r >> 8); if (r >= 180) { // 0xB4 ?? if (++trigger_cnt > triggersToSkip) - break; - } - } - } + break; + } + } + } - if (!BUTTON_PRESS()) { - int waitcount = samplesToSkip; // lets wait 40000 ticks of pck0 - while(waitcount != 0) { + if (!BUTTON_PRESS()) { + int waitcount = samplesToSkip; // lets wait 40000 ticks of pck0 + while(waitcount != 0) { - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) - waitcount--; - } - optimizedSnoop(); - Dbprintf("Trigger kicked! Value: %d, Dumping Samples Hispeed now.", r); - } + if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) + waitcount--; + } + optimizedSnoop(); + Dbprintf("Trigger kicked! Value: %d, Dumping Samples Hispeed now.", r); + } - //Resetting Frame mode (First set in fpgaloader.c) - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); + //Resetting Frame mode (First set in fpgaloader.c) + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); - DbpString("HF Snoop end"); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); + DbpString("HF Snoop end"); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); } diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 32db10190..913ea92ab 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -30,17 +30,17 @@ static bool bPwd; static bool bSuccessful; struct hitag2_tag { - uint32_t uid; - enum { - TAG_STATE_RESET = 0x01, // Just powered up, awaiting GetSnr - TAG_STATE_ACTIVATING = 0x02 , // In activation phase (password mode), sent UID, awaiting reader password - TAG_STATE_ACTIVATED = 0x03, // Activation complete, awaiting read/write commands - TAG_STATE_WRITING = 0x04, // In write command, awaiting sector contents to be written - } state; - unsigned int active_sector; - uint8_t crypto_active; - uint64_t cs; - uint8_t sectors[12][4]; + uint32_t uid; + enum { + TAG_STATE_RESET = 0x01, // Just powered up, awaiting GetSnr + TAG_STATE_ACTIVATING = 0x02 , // In activation phase (password mode), sent UID, awaiting reader password + TAG_STATE_ACTIVATED = 0x03, // Activation complete, awaiting read/write commands + TAG_STATE_WRITING = 0x04, // In write command, awaiting sector contents to be written + } state; + unsigned int active_sector; + uint8_t crypto_active; + uint64_t cs; + uint8_t sectors[12][4]; }; static struct hitag2_tag tag = { @@ -62,9 +62,9 @@ static struct hitag2_tag tag = { }; static enum { - WRITE_STATE_START = 0x0, - WRITE_STATE_PAGENUM_WRITTEN, - WRITE_STATE_PROG + WRITE_STATE_START = 0x0, + WRITE_STATE_PAGENUM_WRITTEN, + WRITE_STATE_PROG } writestate; @@ -89,63 +89,63 @@ static uint64_t cipher_state; // Basic macros: -#define u8 uint8_t -#define u32 uint32_t -#define u64 uint64_t -#define rev8(x) ((((x)>>7)&1)+((((x)>>6)&1)<<1)+((((x)>>5)&1)<<2)+((((x)>>4)&1)<<3)+((((x)>>3)&1)<<4)+((((x)>>2)&1)<<5)+((((x)>>1)&1)<<6)+(((x)&1)<<7)) -#define rev16(x) (rev8 (x)+(rev8 (x>> 8)<< 8)) -#define rev32(x) (rev16(x)+(rev16(x>>16)<<16)) -#define rev64(x) (rev32(x)+(rev32(x>>32)<<32)) -#define bit(x,n) (((x)>>(n))&1) -#define bit32(x,n) ((((x)[(n)>>5])>>((n)))&1) -#define inv32(x,i,n) ((x)[(i)>>5]^=((u32)(n))<<((i)&31)) -#define rotl64(x, n) ((((u64)(x))<<((n)&63))+(((u64)(x))>>((0-(n))&63))) +#define u8 uint8_t +#define u32 uint32_t +#define u64 uint64_t +#define rev8(x) ((((x)>>7)&1)+((((x)>>6)&1)<<1)+((((x)>>5)&1)<<2)+((((x)>>4)&1)<<3)+((((x)>>3)&1)<<4)+((((x)>>2)&1)<<5)+((((x)>>1)&1)<<6)+(((x)&1)<<7)) +#define rev16(x) (rev8 (x)+(rev8 (x>> 8)<< 8)) +#define rev32(x) (rev16(x)+(rev16(x>>16)<<16)) +#define rev64(x) (rev32(x)+(rev32(x>>32)<<32)) +#define bit(x,n) (((x)>>(n))&1) +#define bit32(x,n) ((((x)[(n)>>5])>>((n)))&1) +#define inv32(x,i,n) ((x)[(i)>>5]^=((u32)(n))<<((i)&31)) +#define rotl64(x, n) ((((u64)(x))<<((n)&63))+(((u64)(x))>>((0-(n))&63))) // Single bit Hitag2 functions: -#define i4(x,a,b,c,d) ((u32)((((x)>>(a))&1)+(((x)>>(b))&1)*2+(((x)>>(c))&1)*4+(((x)>>(d))&1)*8)) +#define i4(x,a,b,c,d) ((u32)((((x)>>(a))&1)+(((x)>>(b))&1)*2+(((x)>>(c))&1)*4+(((x)>>(d))&1)*8)) -static const u32 ht2_f4a = 0x2C79; // 0010 1100 0111 1001 -static const u32 ht2_f4b = 0x6671; // 0110 0110 0111 0001 -static const u32 ht2_f5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 +static const u32 ht2_f4a = 0x2C79; // 0010 1100 0111 1001 +static const u32 ht2_f4b = 0x6671; // 0110 0110 0111 0001 +static const u32 ht2_f5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 static u32 _f20 (const u64 x) { - u32 i5; + u32 i5; - i5 = ((ht2_f4a >> i4 (x, 1, 2, 4, 5)) & 1)* 1 - + ((ht2_f4b >> i4 (x, 7,11,13,14)) & 1)* 2 - + ((ht2_f4b >> i4 (x,16,20,22,25)) & 1)* 4 - + ((ht2_f4b >> i4 (x,27,28,30,32)) & 1)* 8 - + ((ht2_f4a >> i4 (x,33,42,43,45)) & 1)*16; + i5 = ((ht2_f4a >> i4 (x, 1, 2, 4, 5)) & 1)* 1 + + ((ht2_f4b >> i4 (x, 7,11,13,14)) & 1)* 2 + + ((ht2_f4b >> i4 (x,16,20,22,25)) & 1)* 4 + + ((ht2_f4b >> i4 (x,27,28,30,32)) & 1)* 8 + + ((ht2_f4a >> i4 (x,33,42,43,45)) & 1)*16; - return (ht2_f5c >> i5) & 1; + return (ht2_f5c >> i5) & 1; } static u64 _hitag2_init (const u64 key, const u32 serial, const u32 IV) { - u32 i; - u64 x = ((key & 0xFFFF) << 32) + serial; + u32 i; + u64 x = ((key & 0xFFFF) << 32) + serial; - for (i = 0; i < 32; i++) - { - x >>= 1; - x += (u64) (_f20 (x) ^ (((IV >> i) ^ (key >> (i+16))) & 1)) << 47; - } - return x; + for (i = 0; i < 32; i++) + { + x >>= 1; + x += (u64) (_f20 (x) ^ (((IV >> i) ^ (key >> (i+16))) & 1)) << 47; + } + return x; } static u64 _hitag2_round (u64 *state) { - u64 x = *state; + u64 x = *state; - x = (x >> 1) + - ((((x >> 0) ^ (x >> 2) ^ (x >> 3) ^ (x >> 6) - ^ (x >> 7) ^ (x >> 8) ^ (x >> 16) ^ (x >> 22) - ^ (x >> 23) ^ (x >> 26) ^ (x >> 30) ^ (x >> 41) - ^ (x >> 42) ^ (x >> 43) ^ (x >> 46) ^ (x >> 47)) & 1) << 47); + x = (x >> 1) + + ((((x >> 0) ^ (x >> 2) ^ (x >> 3) ^ (x >> 6) + ^ (x >> 7) ^ (x >> 8) ^ (x >> 16) ^ (x >> 22) + ^ (x >> 23) ^ (x >> 26) ^ (x >> 30) ^ (x >> 41) + ^ (x >> 42) ^ (x >> 43) ^ (x >> 46) ^ (x >> 47)) & 1) << 47); - *state = x; - return _f20 (x); + *state = x; + return _f20 (x); } // "MIKRON" = O N M I K R @@ -160,426 +160,426 @@ static u64 _hitag2_round (u64 *state) static u32 _hitag2_byte (u64 * x) { - u32 i, c; + u32 i, c; - for (i = 0, c = 0; i < 8; i++) c += (u32) _hitag2_round (x) << (i^7); - return c; + for (i = 0, c = 0; i < 8; i++) c += (u32) _hitag2_round (x) << (i^7); + return c; } static int hitag2_reset(void) { - tag.state = TAG_STATE_RESET; - tag.crypto_active = 0; - return 0; + tag.state = TAG_STATE_RESET; + tag.crypto_active = 0; + return 0; } static int hitag2_init(void) { - hitag2_reset(); - return 0; + hitag2_reset(); + return 0; } static void hitag2_cipher_reset(struct hitag2_tag *tag, const uint8_t *iv) { - uint64_t key = ((uint64_t)tag->sectors[2][2]) | + uint64_t key = ((uint64_t)tag->sectors[2][2]) | ((uint64_t)tag->sectors[2][3] << 8) | ((uint64_t)tag->sectors[1][0] << 16) | ((uint64_t)tag->sectors[1][1] << 24) | ((uint64_t)tag->sectors[1][2] << 32) | ((uint64_t)tag->sectors[1][3] << 40); - uint32_t uid = ((uint32_t)tag->sectors[0][0]) | + uint32_t uid = ((uint32_t)tag->sectors[0][0]) | ((uint32_t)tag->sectors[0][1] << 8) | ((uint32_t)tag->sectors[0][2] << 16) | ((uint32_t)tag->sectors[0][3] << 24); - uint32_t iv_ = (((uint32_t)(iv[0]))) | - (((uint32_t)(iv[1])) << 8) | - (((uint32_t)(iv[2])) << 16) | - (((uint32_t)(iv[3])) << 24); - tag->cs = _hitag2_init(rev64(key), rev32(uid), rev32(iv_)); + uint32_t iv_ = (((uint32_t)(iv[0]))) | + (((uint32_t)(iv[1])) << 8) | + (((uint32_t)(iv[2])) << 16) | + (((uint32_t)(iv[3])) << 24); + tag->cs = _hitag2_init(rev64(key), rev32(uid), rev32(iv_)); } static int hitag2_cipher_authenticate(uint64_t* cs, const uint8_t *authenticator_is) { - uint8_t authenticator_should[4]; - authenticator_should[0] = ~_hitag2_byte(cs); - authenticator_should[1] = ~_hitag2_byte(cs); - authenticator_should[2] = ~_hitag2_byte(cs); - authenticator_should[3] = ~_hitag2_byte(cs); - return (memcmp(authenticator_should, authenticator_is, 4) == 0); + uint8_t authenticator_should[4]; + authenticator_should[0] = ~_hitag2_byte(cs); + authenticator_should[1] = ~_hitag2_byte(cs); + authenticator_should[2] = ~_hitag2_byte(cs); + authenticator_should[3] = ~_hitag2_byte(cs); + return (memcmp(authenticator_should, authenticator_is, 4) == 0); } static int hitag2_cipher_transcrypt(uint64_t* cs, uint8_t *data, unsigned int bytes, unsigned int bits) { - int i; - for(i=0; i 36 */ -#define HITAG_T_LOW 8 /* T_LOW should be 4..10 */ -#define HITAG_T_0_MIN 15 /* T[0] should be 18..22 */ -#define HITAG_T_1_MIN 25 /* T[1] should be 26..30 */ -//#define HITAG_T_EOF 40 /* T_EOF should be > 36 */ -#define HITAG_T_EOF 80 /* T_EOF should be > 36 */ -#define HITAG_T_WAIT_1 200 /* T_wresp should be 199..206 */ -#define HITAG_T_WAIT_2 90 /* T_wresp should be 199..206 */ +#define HITAG_FRAME_LEN 20 +#define HITAG_T_STOP 36 /* T_EOF should be > 36 */ +#define HITAG_T_LOW 8 /* T_LOW should be 4..10 */ +#define HITAG_T_0_MIN 15 /* T[0] should be 18..22 */ +#define HITAG_T_1_MIN 25 /* T[1] should be 26..30 */ +//#define HITAG_T_EOF 40 /* T_EOF should be > 36 */ +#define HITAG_T_EOF 80 /* T_EOF should be > 36 */ +#define HITAG_T_WAIT_1 200 /* T_wresp should be 199..206 */ +#define HITAG_T_WAIT_2 90 /* T_wresp should be 199..206 */ #define HITAG_T_WAIT_MAX 300 /* bit more than HITAG_T_WAIT_1 + HITAG_T_WAIT_2 */ -#define HITAG_T_PROG 614 +#define HITAG_T_PROG 614 -#define HITAG_T_TAG_ONE_HALF_PERIOD 10 -#define HITAG_T_TAG_TWO_HALF_PERIOD 25 -#define HITAG_T_TAG_THREE_HALF_PERIOD 41 -#define HITAG_T_TAG_FOUR_HALF_PERIOD 57 +#define HITAG_T_TAG_ONE_HALF_PERIOD 10 +#define HITAG_T_TAG_TWO_HALF_PERIOD 25 +#define HITAG_T_TAG_THREE_HALF_PERIOD 41 +#define HITAG_T_TAG_FOUR_HALF_PERIOD 57 -#define HITAG_T_TAG_HALF_PERIOD 16 -#define HITAG_T_TAG_FULL_PERIOD 32 +#define HITAG_T_TAG_HALF_PERIOD 16 +#define HITAG_T_TAG_FULL_PERIOD 32 -#define HITAG_T_TAG_CAPTURE_ONE_HALF 13 -#define HITAG_T_TAG_CAPTURE_TWO_HALF 25 -#define HITAG_T_TAG_CAPTURE_THREE_HALF 41 +#define HITAG_T_TAG_CAPTURE_ONE_HALF 13 +#define HITAG_T_TAG_CAPTURE_TWO_HALF 25 +#define HITAG_T_TAG_CAPTURE_THREE_HALF 41 #define HITAG_T_TAG_CAPTURE_FOUR_HALF 57 static void hitag_send_bit(int bit) { - LED_A_ON(); - // Reset clock for the next bit - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + LED_A_ON(); + // Reset clock for the next bit + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - // Fixed modulation, earlier proxmark version used inverted signal - if(bit == 0) { - // Manchester: Unloaded, then loaded |__--| - LOW(GPIO_SSC_DOUT); - while(AT91C_BASE_TC0->TC_CV < T0*HITAG_T_TAG_HALF_PERIOD); - HIGH(GPIO_SSC_DOUT); - while(AT91C_BASE_TC0->TC_CV < T0*HITAG_T_TAG_FULL_PERIOD); - } else { - // Manchester: Loaded, then unloaded |--__| - HIGH(GPIO_SSC_DOUT); - while(AT91C_BASE_TC0->TC_CV < T0*HITAG_T_TAG_HALF_PERIOD); - LOW(GPIO_SSC_DOUT); - while(AT91C_BASE_TC0->TC_CV < T0*HITAG_T_TAG_FULL_PERIOD); - } - LED_A_OFF(); + // Fixed modulation, earlier proxmark version used inverted signal + if(bit == 0) { + // Manchester: Unloaded, then loaded |__--| + LOW(GPIO_SSC_DOUT); + while(AT91C_BASE_TC0->TC_CV < T0*HITAG_T_TAG_HALF_PERIOD); + HIGH(GPIO_SSC_DOUT); + while(AT91C_BASE_TC0->TC_CV < T0*HITAG_T_TAG_FULL_PERIOD); + } else { + // Manchester: Loaded, then unloaded |--__| + HIGH(GPIO_SSC_DOUT); + while(AT91C_BASE_TC0->TC_CV < T0*HITAG_T_TAG_HALF_PERIOD); + LOW(GPIO_SSC_DOUT); + while(AT91C_BASE_TC0->TC_CV < T0*HITAG_T_TAG_FULL_PERIOD); + } + LED_A_OFF(); } static void hitag_send_frame(const uint8_t* frame, size_t frame_len) { - // Send start of frame - for(size_t i=0; i<5; i++) { - hitag_send_bit(1); - } + // Send start of frame + for(size_t i=0; i<5; i++) { + hitag_send_bit(1); + } - // Send the content of the frame - for(size_t i=0; i> (7-(i%8)))&1); - } + // Send the content of the frame + for(size_t i=0; i> (7-(i%8)))&1); + } - // Drop the modulation - LOW(GPIO_SSC_DOUT); + // Drop the modulation + LOW(GPIO_SSC_DOUT); } static void hitag2_handle_reader_command(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen) { - uint8_t rx_air[HITAG_FRAME_LEN]; + uint8_t rx_air[HITAG_FRAME_LEN]; - // Copy the (original) received frame how it is send over the air - memcpy(rx_air,rx,nbytes(rxlen)); + // Copy the (original) received frame how it is send over the air + memcpy(rx_air,rx,nbytes(rxlen)); - if(tag.crypto_active) { - hitag2_cipher_transcrypt(&(tag.cs),rx,rxlen/8,rxlen%8); - } + if(tag.crypto_active) { + hitag2_cipher_transcrypt(&(tag.cs),rx,rxlen/8,rxlen%8); + } - // Reset the transmission frame length - *txlen = 0; + // Reset the transmission frame length + *txlen = 0; - // Try to find out which command was send by selecting on length (in bits) - switch (rxlen) { - // Received 11000 from the reader, request for UID, send UID - case 05: { - // Always send over the air in the clear plaintext mode - if(rx_air[0] != 0xC0) { - // Unknown frame ? - return; - } - *txlen = 32; - memcpy(tx,tag.sectors[0],4); - tag.crypto_active = 0; - } - break; + // Try to find out which command was send by selecting on length (in bits) + switch (rxlen) { + // Received 11000 from the reader, request for UID, send UID + case 05: { + // Always send over the air in the clear plaintext mode + if(rx_air[0] != 0xC0) { + // Unknown frame ? + return; + } + *txlen = 32; + memcpy(tx,tag.sectors[0],4); + tag.crypto_active = 0; + } + break; - // Read/Write command: ..xx x..y yy with yyy == ~xxx, xxx is sector number - case 10: { - unsigned int sector = (~( ((rx[0]<<2)&0x04) | ((rx[1]>>6)&0x03) ) & 0x07); - // Verify complement of sector index - if(sector != ((rx[0]>>3)&0x07)) { - //DbpString("Transmission error (read/write)"); - return; - } + // Read/Write command: ..xx x..y yy with yyy == ~xxx, xxx is sector number + case 10: { + unsigned int sector = (~( ((rx[0]<<2)&0x04) | ((rx[1]>>6)&0x03) ) & 0x07); + // Verify complement of sector index + if(sector != ((rx[0]>>3)&0x07)) { + //DbpString("Transmission error (read/write)"); + return; + } - switch (rx[0] & 0xC6) { - // Read command: 11xx x00y - case 0xC0: - memcpy(tx,tag.sectors[sector],4); - *txlen = 32; - break; + switch (rx[0] & 0xC6) { + // Read command: 11xx x00y + case 0xC0: + memcpy(tx,tag.sectors[sector],4); + *txlen = 32; + break; - // Inverted Read command: 01xx x10y - case 0x44: - for (size_t i=0; i<4; i++) { - tx[i] = tag.sectors[sector][i] ^ 0xff; - } - *txlen = 32; - break; + // Inverted Read command: 01xx x10y + case 0x44: + for (size_t i=0; i<4; i++) { + tx[i] = tag.sectors[sector][i] ^ 0xff; + } + *txlen = 32; + break; - // Write command: 10xx x01y - case 0x82: - // Prepare write, acknowledge by repeating command - memcpy(tx,rx,nbytes(rxlen)); - *txlen = rxlen; - tag.active_sector = sector; - tag.state=TAG_STATE_WRITING; - break; + // Write command: 10xx x01y + case 0x82: + // Prepare write, acknowledge by repeating command + memcpy(tx,rx,nbytes(rxlen)); + *txlen = rxlen; + tag.active_sector = sector; + tag.state=TAG_STATE_WRITING; + break; - // Unknown command - default: - Dbprintf("Unknown command: %02x %02x",rx[0],rx[1]); - return; - break; - } - } - break; + // Unknown command + default: + Dbprintf("Unknown command: %02x %02x",rx[0],rx[1]); + return; + break; + } + } + break; - // Writing data or Reader password - case 32: { - if(tag.state == TAG_STATE_WRITING) { - // These are the sector contents to be written. We don't have to do anything else. - memcpy(tag.sectors[tag.active_sector],rx,nbytes(rxlen)); - tag.state=TAG_STATE_RESET; - return; - } else { - // Received RWD password, respond with configuration and our password - if(memcmp(rx,tag.sectors[1],4) != 0) { - DbpString("Reader password is wrong"); - return; - } - *txlen = 32; - memcpy(tx,tag.sectors[3],4); - } - } - break; + // Writing data or Reader password + case 32: { + if(tag.state == TAG_STATE_WRITING) { + // These are the sector contents to be written. We don't have to do anything else. + memcpy(tag.sectors[tag.active_sector],rx,nbytes(rxlen)); + tag.state=TAG_STATE_RESET; + return; + } else { + // Received RWD password, respond with configuration and our password + if(memcmp(rx,tag.sectors[1],4) != 0) { + DbpString("Reader password is wrong"); + return; + } + *txlen = 32; + memcpy(tx,tag.sectors[3],4); + } + } + break; - // Received RWD authentication challenge and respnse - case 64: { - // Store the authentication attempt - if (auth_table_len < (AUTH_TABLE_LENGTH-8)) { - memcpy(auth_table+auth_table_len,rx,8); - auth_table_len += 8; - } + // Received RWD authentication challenge and respnse + case 64: { + // Store the authentication attempt + if (auth_table_len < (AUTH_TABLE_LENGTH-8)) { + memcpy(auth_table+auth_table_len,rx,8); + auth_table_len += 8; + } - // Reset the cipher state - hitag2_cipher_reset(&tag,rx); - // Check if the authentication was correct - if(!hitag2_cipher_authenticate(&(tag.cs),rx+4)) { - // The reader failed to authenticate, do nothing - Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x Failed!",rx[0],rx[1],rx[2],rx[3],rx[4],rx[5],rx[6],rx[7]); - return; - } - // Succesful, but commented out reporting back to the Host, this may delay to much. - // Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x OK!",rx[0],rx[1],rx[2],rx[3],rx[4],rx[5],rx[6],rx[7]); + // Reset the cipher state + hitag2_cipher_reset(&tag,rx); + // Check if the authentication was correct + if(!hitag2_cipher_authenticate(&(tag.cs),rx+4)) { + // The reader failed to authenticate, do nothing + Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x Failed!",rx[0],rx[1],rx[2],rx[3],rx[4],rx[5],rx[6],rx[7]); + return; + } + // Succesful, but commented out reporting back to the Host, this may delay to much. + // Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x OK!",rx[0],rx[1],rx[2],rx[3],rx[4],rx[5],rx[6],rx[7]); - // Activate encryption algorithm for all further communication - tag.crypto_active = 1; + // Activate encryption algorithm for all further communication + tag.crypto_active = 1; - // Use the tag password as response - memcpy(tx,tag.sectors[3],4); - *txlen = 32; - } - break; - } + // Use the tag password as response + memcpy(tx,tag.sectors[3],4); + *txlen = 32; + } + break; + } -// LogTraceHitag(rx,rxlen,0,0,false); -// LogTraceHitag(tx,*txlen,0,0,true); +// LogTraceHitag(rx,rxlen,0,0,false); +// LogTraceHitag(tx,*txlen,0,0,true); - if(tag.crypto_active) { - hitag2_cipher_transcrypt(&(tag.cs), tx, *txlen/8, *txlen%8); - } + if(tag.crypto_active) { + hitag2_cipher_transcrypt(&(tag.cs), tx, *txlen/8, *txlen%8); + } } static void hitag_reader_send_bit(int bit) { - LED_A_ON(); - // Reset clock for the next bit - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + LED_A_ON(); + // Reset clock for the next bit + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - // Binary puls length modulation (BPLM) is used to encode the data stream - // This means that a transmission of a one takes longer than that of a zero + // Binary puls length modulation (BPLM) is used to encode the data stream + // This means that a transmission of a one takes longer than that of a zero - // Enable modulation, which means, drop the field - HIGH(GPIO_SSC_DOUT); + // Enable modulation, which means, drop the field + HIGH(GPIO_SSC_DOUT); - // Wait for 4-10 times the carrier period - while(AT91C_BASE_TC0->TC_CV < T0*6); - // SpinDelayUs(8*8); + // Wait for 4-10 times the carrier period + while(AT91C_BASE_TC0->TC_CV < T0*6); + // SpinDelayUs(8*8); - // Disable modulation, just activates the field again - LOW(GPIO_SSC_DOUT); + // Disable modulation, just activates the field again + LOW(GPIO_SSC_DOUT); - if(bit == 0) { - // Zero bit: |_-| - while (AT91C_BASE_TC0->TC_CV < T0*22) {}; + if(bit == 0) { + // Zero bit: |_-| + while (AT91C_BASE_TC0->TC_CV < T0*22) {}; - } else { - // One bit: |_--| - while (AT91C_BASE_TC0->TC_CV < T0*28) {}; - } - LED_A_OFF(); + } else { + // One bit: |_--| + while (AT91C_BASE_TC0->TC_CV < T0*28) {}; + } + LED_A_OFF(); } static void hitag_reader_send_frame(const uint8_t* frame, size_t frame_len) { - // Send the content of the frame - for(size_t i=0; i> (7-(i%8)))&1); - } - // Send EOF - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - // Enable modulation, which means, drop the field - HIGH(GPIO_SSC_DOUT); - // Wait for 4-10 times the carrier period - while(AT91C_BASE_TC0->TC_CV < T0*6); - // Disable modulation, just activates the field again - LOW(GPIO_SSC_DOUT); + // Send the content of the frame + for(size_t i=0; i> (7-(i%8)))&1); + } + // Send EOF + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + // Enable modulation, which means, drop the field + HIGH(GPIO_SSC_DOUT); + // Wait for 4-10 times the carrier period + while(AT91C_BASE_TC0->TC_CV < T0*6); + // Disable modulation, just activates the field again + LOW(GPIO_SSC_DOUT); } size_t blocknr; static bool hitag2_password(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen) { - // Reset the transmission frame length - *txlen = 0; + // Reset the transmission frame length + *txlen = 0; - // Try to find out which command was send by selecting on length (in bits) - switch (rxlen) { - // No answer, try to resurrect - case 0: { - // Stop if there is no answer (after sending password) - if (bPwd) { - DbpString("Password failed!"); - return false; - } - *txlen = 5; - memcpy(tx,"\xc0",nbytes(*txlen)); - } break; + // Try to find out which command was send by selecting on length (in bits) + switch (rxlen) { + // No answer, try to resurrect + case 0: { + // Stop if there is no answer (after sending password) + if (bPwd) { + DbpString("Password failed!"); + return false; + } + *txlen = 5; + memcpy(tx,"\xc0",nbytes(*txlen)); + } break; - // Received UID, tag password - case 32: { - if (!bPwd) { - *txlen = 32; - memcpy(tx,password,4); - bPwd = true; - memcpy(tag.sectors[blocknr],rx,4); - blocknr++; - } else { + // Received UID, tag password + case 32: { + if (!bPwd) { + *txlen = 32; + memcpy(tx,password,4); + bPwd = true; + memcpy(tag.sectors[blocknr],rx,4); + blocknr++; + } else { - if(blocknr == 1){ - //store password in block1, the TAG answers with Block3, but we need the password in memory - memcpy(tag.sectors[blocknr],tx,4); - } else { - memcpy(tag.sectors[blocknr],rx,4); - } + if(blocknr == 1){ + //store password in block1, the TAG answers with Block3, but we need the password in memory + memcpy(tag.sectors[blocknr],tx,4); + } else { + memcpy(tag.sectors[blocknr],rx,4); + } - blocknr++; - if (blocknr > 7) { - DbpString("Read succesful!"); - bSuccessful = true; - return false; - } - *txlen = 10; - tx[0] = 0xc0 | (blocknr << 3) | ((blocknr^7) >> 2); - tx[1] = ((blocknr^7) << 6); - } - } break; + blocknr++; + if (blocknr > 7) { + DbpString("Read succesful!"); + bSuccessful = true; + return false; + } + *txlen = 10; + tx[0] = 0xc0 | (blocknr << 3) | ((blocknr^7) >> 2); + tx[1] = ((blocknr^7) << 6); + } + } break; - // Unexpected response + // Unexpected response default: { - Dbprintf("Uknown frame length: %d",rxlen); - return false; - } break; - } - return true; + Dbprintf("Uknown frame length: %d",rxlen); + return false; + } break; + } + return true; } static bool hitag2_write_page(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen) { - switch (writestate) { - case WRITE_STATE_START: - *txlen = 10; - tx[0] = 0x82 | (blocknr << 3) | ((blocknr^7) >> 2); - tx[1] = ((blocknr^7) << 6); - writestate = WRITE_STATE_PAGENUM_WRITTEN; - break; - case WRITE_STATE_PAGENUM_WRITTEN: - // Check if page number was received correctly - if ((rxlen == 10) && - (rx[0] == (0x82 | (blocknr << 3) | ((blocknr^7) >> 2))) && - (rx[1] == (((blocknr & 0x3) ^ 0x3) << 6))) { - *txlen = 32; - memset(tx, 0, HITAG_FRAME_LEN); - memcpy(tx, writedata, 4); - writestate = WRITE_STATE_PROG; - } else { - Dbprintf("hitag2_write_page: Page number was not received correctly: rxlen=%d rx=%02x%02x%02x%02x", - rxlen, rx[0], rx[1], rx[2], rx[3]); - bSuccessful = false; - return false; - } - break; - case WRITE_STATE_PROG: - if (rxlen == 0) { - bSuccessful = true; - } else { - bSuccessful = false; - Dbprintf("hitag2_write_page: unexpected rx data (%d) after page write", rxlen); - } - return false; - default: - DbpString("hitag2_write_page: Unknown state %d"); - bSuccessful = false; - return false; - } + switch (writestate) { + case WRITE_STATE_START: + *txlen = 10; + tx[0] = 0x82 | (blocknr << 3) | ((blocknr^7) >> 2); + tx[1] = ((blocknr^7) << 6); + writestate = WRITE_STATE_PAGENUM_WRITTEN; + break; + case WRITE_STATE_PAGENUM_WRITTEN: + // Check if page number was received correctly + if ((rxlen == 10) && + (rx[0] == (0x82 | (blocknr << 3) | ((blocknr^7) >> 2))) && + (rx[1] == (((blocknr & 0x3) ^ 0x3) << 6))) { + *txlen = 32; + memset(tx, 0, HITAG_FRAME_LEN); + memcpy(tx, writedata, 4); + writestate = WRITE_STATE_PROG; + } else { + Dbprintf("hitag2_write_page: Page number was not received correctly: rxlen=%d rx=%02x%02x%02x%02x", + rxlen, rx[0], rx[1], rx[2], rx[3]); + bSuccessful = false; + return false; + } + break; + case WRITE_STATE_PROG: + if (rxlen == 0) { + bSuccessful = true; + } else { + bSuccessful = false; + Dbprintf("hitag2_write_page: unexpected rx data (%d) after page write", rxlen); + } + return false; + default: + DbpString("hitag2_write_page: Unknown state %d"); + bSuccessful = false; + return false; + } - return true; + return true; } static bool hitag2_crypto(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen, bool write) { - // Reset the transmission frame length - *txlen = 0; + // Reset the transmission frame length + *txlen = 0; if(bCrypto) { - hitag2_cipher_transcrypt(&cipher_state,rx,rxlen/8,rxlen%8); - } + hitag2_cipher_transcrypt(&cipher_state,rx,rxlen/8,rxlen%8); + } - if (bCrypto && !bAuthenticating && write) { - if (!hitag2_write_page(rx, rxlen, tx, txlen)) { - return false; - } - } else { + if (bCrypto && !bAuthenticating && write) { + if (!hitag2_write_page(rx, rxlen, tx, txlen)) { + return false; + } + } else { - // Try to find out which command was send by selecting on length (in bits) - switch (rxlen) { + // Try to find out which command was send by selecting on length (in bits) + switch (rxlen) { // No answer, try to resurrect - case 0: { - // Stop if there is no answer while we are in crypto mode (after sending NrAr) - if (bCrypto) { + case 0: { + // Stop if there is no answer while we are in crypto mode (after sending NrAr) + if (bCrypto) { // Failed during authentication if (bAuthenticating) { DbpString("Authentication failed!"); @@ -602,1190 +602,1190 @@ static bool hitag2_crypto(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* blocknr++; bCrypto = false; } - } else { - *txlen = 5; - memcpy(tx,"\xc0",nbytes(*txlen)); - } - break; - } + } else { + *txlen = 5; + memcpy(tx,"\xc0",nbytes(*txlen)); + } + break; + } // Received UID, crypto tag answer - case 32: { - if (!bCrypto) { + case 32: { + if (!bCrypto) { uint64_t ui64key = key[0] | ((uint64_t)key[1]) << 8 | ((uint64_t)key[2]) << 16 | ((uint64_t)key[3]) << 24 | ((uint64_t)key[4]) << 32 | ((uint64_t)key[5]) << 40; uint32_t ui32uid = rx[0] | ((uint32_t)rx[1]) << 8 | ((uint32_t)rx[2]) << 16 | ((uint32_t)rx[3]) << 24; - Dbprintf("hitag2_crypto: key=0x%x%x uid=0x%x", (uint32_t) ((rev64(ui64key)) >> 32), (uint32_t) ((rev64(ui64key)) & 0xffffffff), rev32(ui32uid)); + Dbprintf("hitag2_crypto: key=0x%x%x uid=0x%x", (uint32_t) ((rev64(ui64key)) >> 32), (uint32_t) ((rev64(ui64key)) & 0xffffffff), rev32(ui32uid)); cipher_state = _hitag2_init(rev64(ui64key), rev32(ui32uid), 0); memset(tx,0x00,4); memset(tx+4,0xff,4); hitag2_cipher_transcrypt(&cipher_state,tx+4,4,0); - *txlen = 64; - bCrypto = true; - bAuthenticating = true; - } else { + *txlen = 64; + bCrypto = true; + bAuthenticating = true; + } else { // Check if we received answer tag (at) if (bAuthenticating) { - bAuthenticating = false; - if (write) { - if (!hitag2_write_page(rx, rxlen, tx, txlen)) { - return false; - } - break; - } + bAuthenticating = false; + if (write) { + if (!hitag2_write_page(rx, rxlen, tx, txlen)) { + return false; + } + break; + } } else { - // Store the received block - memcpy(tag.sectors[blocknr],rx,4); - blocknr++; + // Store the received block + memcpy(tag.sectors[blocknr],rx,4); + blocknr++; } if (blocknr > 7) { - DbpString("Read succesful!"); - bSuccessful = true; - return false; - } else { + DbpString("Read succesful!"); + bSuccessful = true; + return false; + } else { *txlen = 10; tx[0] = 0xc0 | (blocknr << 3) | ((blocknr^7) >> 2); tx[1] = ((blocknr^7) << 6); - } - } - } break; + } + } + } break; // Unexpected response - default: { - Dbprintf("Uknown frame length: %d",rxlen); - return false; - } break; - } - } + default: { + Dbprintf("Uknown frame length: %d",rxlen); + return false; + } break; + } + } - if(bCrypto) { - // We have to return now to avoid double encryption - if (!bAuthenticating) { - hitag2_cipher_transcrypt(&cipher_state, tx, *txlen/8, *txlen%8); - } - } + if(bCrypto) { + // We have to return now to avoid double encryption + if (!bAuthenticating) { + hitag2_cipher_transcrypt(&cipher_state, tx, *txlen/8, *txlen%8); + } + } - return true; + return true; } static bool hitag2_authenticate(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen) { - // Reset the transmission frame length - *txlen = 0; + // Reset the transmission frame length + *txlen = 0; - // Try to find out which command was send by selecting on length (in bits) - switch (rxlen) { - // No answer, try to resurrect - case 0: { - // Stop if there is no answer while we are in crypto mode (after sending NrAr) - if (bCrypto) { - DbpString("Authentication failed!"); - return false; - } - *txlen = 5; - memcpy(tx,"\xc0", nbytes(*txlen)); - } break; + // Try to find out which command was send by selecting on length (in bits) + switch (rxlen) { + // No answer, try to resurrect + case 0: { + // Stop if there is no answer while we are in crypto mode (after sending NrAr) + if (bCrypto) { + DbpString("Authentication failed!"); + return false; + } + *txlen = 5; + memcpy(tx,"\xc0", nbytes(*txlen)); + } break; - // Received UID, crypto tag answer - case 32: { - if (!bCrypto) { - *txlen = 64; - memcpy(tx, NrAr, 8); - bCrypto = true; - } else { - DbpString("Authentication succesful!"); - return true; - } - } break; + // Received UID, crypto tag answer + case 32: { + if (!bCrypto) { + *txlen = 64; + memcpy(tx, NrAr, 8); + bCrypto = true; + } else { + DbpString("Authentication succesful!"); + return true; + } + } break; - // Unexpected response - default: { - Dbprintf("Uknown frame length: %d", rxlen); - return false; - } break; - } + // Unexpected response + default: { + Dbprintf("Uknown frame length: %d", rxlen); + return false; + } break; + } - return true; + return true; } static bool hitag2_test_auth_attempts(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen) { - // Reset the transmission frame length - *txlen = 0; + // Reset the transmission frame length + *txlen = 0; - // Try to find out which command was send by selecting on length (in bits) - switch (rxlen) { - // No answer, try to resurrect - case 0: { - // Stop if there is no answer while we are in crypto mode (after sending NrAr) - if (bCrypto) { - Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x Failed, removed entry!",NrAr[0],NrAr[1],NrAr[2],NrAr[3],NrAr[4],NrAr[5],NrAr[6],NrAr[7]); + // Try to find out which command was send by selecting on length (in bits) + switch (rxlen) { + // No answer, try to resurrect + case 0: { + // Stop if there is no answer while we are in crypto mode (after sending NrAr) + if (bCrypto) { + Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x Failed, removed entry!",NrAr[0],NrAr[1],NrAr[2],NrAr[3],NrAr[4],NrAr[5],NrAr[6],NrAr[7]); - // Removing failed entry from authentiations table - memcpy(auth_table+auth_table_pos,auth_table+auth_table_pos+8,8); - auth_table_len -= 8; + // Removing failed entry from authentiations table + memcpy(auth_table+auth_table_pos,auth_table+auth_table_pos+8,8); + auth_table_len -= 8; - // Return if we reached the end of the authentications table - bCrypto = false; - if (auth_table_pos == auth_table_len) { - return false; - } + // Return if we reached the end of the authentications table + bCrypto = false; + if (auth_table_pos == auth_table_len) { + return false; + } - // Copy the next authentication attempt in row (at the same position, b/c we removed last failed entry) - memcpy(NrAr,auth_table+auth_table_pos,8); - } - *txlen = 5; - memcpy(tx,"\xc0",nbytes(*txlen)); - } break; + // Copy the next authentication attempt in row (at the same position, b/c we removed last failed entry) + memcpy(NrAr,auth_table+auth_table_pos,8); + } + *txlen = 5; + memcpy(tx,"\xc0",nbytes(*txlen)); + } break; - // Received UID, crypto tag answer, or read block response - case 32: { - if (!bCrypto) { - *txlen = 64; - memcpy(tx,NrAr,8); - bCrypto = true; - } else { - Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x OK",NrAr[0],NrAr[1],NrAr[2],NrAr[3],NrAr[4],NrAr[5],NrAr[6],NrAr[7]); - bCrypto = false; - if ((auth_table_pos+8) == auth_table_len) { - return false; - } - auth_table_pos += 8; - memcpy(NrAr,auth_table+auth_table_pos,8); - } - } break; + // Received UID, crypto tag answer, or read block response + case 32: { + if (!bCrypto) { + *txlen = 64; + memcpy(tx,NrAr,8); + bCrypto = true; + } else { + Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x OK",NrAr[0],NrAr[1],NrAr[2],NrAr[3],NrAr[4],NrAr[5],NrAr[6],NrAr[7]); + bCrypto = false; + if ((auth_table_pos+8) == auth_table_len) { + return false; + } + auth_table_pos += 8; + memcpy(NrAr,auth_table+auth_table_pos,8); + } + } break; - default: { - Dbprintf("Uknown frame length: %d",rxlen); - return false; - } break; - } + default: { + Dbprintf("Uknown frame length: %d",rxlen); + return false; + } break; + } - return true; + return true; } static bool hitag2_read_uid(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen) { - // Reset the transmission frame length - *txlen = 0; + // Reset the transmission frame length + *txlen = 0; - // Try to find out which command was send by selecting on length (in bits) - switch (rxlen) { - // No answer, try to resurrect - case 0: { - // Just starting or if there is no answer - *txlen = 5; - memcpy(tx, "\xC0", nbytes(*txlen) ); - } break; - // Received UID - case 32: { - // Check if we received answer tag (at) - if (bAuthenticating) { - bAuthenticating = false; - } else { - // Store the received block - memcpy(tag.sectors[blocknr], rx, 4); - blocknr++; - } - if (blocknr > 0) { - // DbpString("Read successful!"); - bSuccessful = true; - return false; - } - } break; - // Unexpected response - default: { - Dbprintf("Uknown frame length: %d", rxlen); - return false; - } break; - } - return true; + // Try to find out which command was send by selecting on length (in bits) + switch (rxlen) { + // No answer, try to resurrect + case 0: { + // Just starting or if there is no answer + *txlen = 5; + memcpy(tx, "\xC0", nbytes(*txlen) ); + } break; + // Received UID + case 32: { + // Check if we received answer tag (at) + if (bAuthenticating) { + bAuthenticating = false; + } else { + // Store the received block + memcpy(tag.sectors[blocknr], rx, 4); + blocknr++; + } + if (blocknr > 0) { + // DbpString("Read successful!"); + bSuccessful = true; + return false; + } + } break; + // Unexpected response + default: { + Dbprintf("Uknown frame length: %d", rxlen); + return false; + } break; + } + return true; } void SnoopHitag(uint32_t type) { - int frame_count; - int response; - int overflow; - bool rising_edge; - bool reader_frame; - int lastbit; - bool bSkip; - int tag_sof; - uint8_t rx[HITAG_FRAME_LEN]; - size_t rxlen=0; + int frame_count; + int response; + int overflow; + bool rising_edge; + bool reader_frame; + int lastbit; + bool bSkip; + int tag_sof; + uint8_t rx[HITAG_FRAME_LEN]; + size_t rxlen=0; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - // free eventually allocated BigBuf memory - BigBuf_free(); BigBuf_Clear_ext(false); + // free eventually allocated BigBuf memory + BigBuf_free(); BigBuf_Clear_ext(false); - // Clean up trace and prepare it for storing frames - clear_trace(); - set_tracing(true); + // Clean up trace and prepare it for storing frames + clear_trace(); + set_tracing(true); - auth_table_len = 0; - auth_table_pos = 0; + auth_table_len = 0; + auth_table_pos = 0; auth_table = (uint8_t *)BigBuf_malloc(AUTH_TABLE_LENGTH); - memset(auth_table, 0x00, AUTH_TABLE_LENGTH); + memset(auth_table, 0x00, AUTH_TABLE_LENGTH); - DbpString("Starting Hitag2 snoop"); - LED_D_ON(); + DbpString("Starting Hitag2 snoop"); + LED_D_ON(); - // Set up eavesdropping mode, frequency divisor which will drive the FPGA - // and analog mux selection. - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - RELAY_OFF(); + // Set up eavesdropping mode, frequency divisor which will drive the FPGA + // and analog mux selection. + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + RELAY_OFF(); - // Configure output pin that is connected to the FPGA (for modulating) - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + // Configure output pin that is connected to the FPGA (for modulating) + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - // Disable modulation, we are going to eavesdrop, not modulate ;) - LOW(GPIO_SSC_DOUT); + // Disable modulation, we are going to eavesdrop, not modulate ;) + LOW(GPIO_SSC_DOUT); - // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the reader frames - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); - AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; + // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the reader frames + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); + AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; - // Disable timer during configuration - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + // Disable timer during configuration + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - // Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, - // external trigger rising edge, load RA on rising edge of TIOA. - uint32_t t1_channel_mode = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_BOTH | AT91C_TC_ABETRG | AT91C_TC_LDRA_BOTH; - AT91C_BASE_TC1->TC_CMR = t1_channel_mode; + // Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, + // external trigger rising edge, load RA on rising edge of TIOA. + uint32_t t1_channel_mode = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_BOTH | AT91C_TC_ABETRG | AT91C_TC_LDRA_BOTH; + AT91C_BASE_TC1->TC_CMR = t1_channel_mode; - // Enable and reset counter - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + // Enable and reset counter + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - // Reset the received frame, frame count and timing info - memset(rx, 0x00, sizeof(rx)); - frame_count = 0; - response = 0; - overflow = 0; - reader_frame = false; - lastbit = 1; - bSkip = true; - tag_sof = 4; + // Reset the received frame, frame count and timing info + memset(rx, 0x00, sizeof(rx)); + frame_count = 0; + response = 0; + overflow = 0; + reader_frame = false; + lastbit = 1; + bSkip = true; + tag_sof = 4; - while(!BUTTON_PRESS() && !usb_poll_validate_length()) { - // Watchdog hit - WDT_HIT(); + while(!BUTTON_PRESS() && !usb_poll_validate_length()) { + // Watchdog hit + WDT_HIT(); - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0*HITAG_T_EOF) { - // Check if rising edge in modulation is detected - if(AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA/T0); + // Receive frame, watch for at most T0*EOF periods + while (AT91C_BASE_TC1->TC_CV < T0*HITAG_T_EOF) { + // Check if rising edge in modulation is detected + if(AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { + // Retrieve the new timing values + int ra = (AT91C_BASE_TC1->TC_RA/T0); - // Find out if we are dealing with a rising or falling edge - rising_edge = (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_FRAME) > 0; + // Find out if we are dealing with a rising or falling edge + rising_edge = (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_FRAME) > 0; - // Shorter periods will only happen with reader frames - if (!reader_frame && rising_edge && ra < HITAG_T_TAG_CAPTURE_ONE_HALF) { - // Switch from tag to reader capture - LED_C_OFF(); - reader_frame = true; - memset(rx,0x00,sizeof(rx)); - rxlen = 0; - } + // Shorter periods will only happen with reader frames + if (!reader_frame && rising_edge && ra < HITAG_T_TAG_CAPTURE_ONE_HALF) { + // Switch from tag to reader capture + LED_C_OFF(); + reader_frame = true; + memset(rx,0x00,sizeof(rx)); + rxlen = 0; + } - // Only handle if reader frame and rising edge, or tag frame and falling edge - if (reader_frame != rising_edge) { - overflow += ra; - continue; - } + // Only handle if reader frame and rising edge, or tag frame and falling edge + if (reader_frame != rising_edge) { + overflow += ra; + continue; + } - // Add the buffered timing values of earlier captured edges which were skipped - ra += overflow; - overflow = 0; + // Add the buffered timing values of earlier captured edges which were skipped + ra += overflow; + overflow = 0; - if (reader_frame) { - LED_B_ON(); - // Capture reader frame - if(ra >= HITAG_T_STOP) { - if (rxlen != 0) { - //DbpString("wierd0?"); - } - // Capture the T0 periods that have passed since last communication or field drop (reset) - response = (ra - HITAG_T_LOW); - } else if(ra >= HITAG_T_1_MIN ) { - // '1' bit - rx[rxlen / 8] |= 1 << (7-(rxlen%8)); - rxlen++; - } else if(ra >= HITAG_T_0_MIN) { - // '0' bit - rx[rxlen / 8] |= 0 << (7-(rxlen%8)); - rxlen++; - } else { - // Ignore wierd value, is to small to mean anything - } - } else { - LED_C_ON(); - // Capture tag frame (manchester decoding using only falling edges) - if(ra >= HITAG_T_EOF) { - if (rxlen != 0) { - //DbpString("wierd1?"); - } - // Capture the T0 periods that have passed since last communication or field drop (reset) - // We always recieve a 'one' first, which has the falling edge after a half period |-_| - response = ra-HITAG_T_TAG_HALF_PERIOD; - } else if(ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { - // Manchester coding example |-_|_-|-_| (101) - rx[rxlen / 8] |= 0 << (7-(rxlen%8)); - rxlen++; - rx[rxlen / 8] |= 1 << (7-(rxlen%8)); - rxlen++; - } else if(ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { - // Manchester coding example |_-|...|_-|-_| (0...01) - rx[rxlen / 8] |= 0 << (7-(rxlen%8)); - rxlen++; - // We have to skip this half period at start and add the 'one' the second time - if (!bSkip) { - rx[rxlen / 8] |= 1 << (7-(rxlen%8)); - rxlen++; - } - lastbit = !lastbit; - bSkip = !bSkip; - } else if(ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { - // Manchester coding example |_-|_-| (00) or |-_|-_| (11) - if (tag_sof) { - // Ignore bits that are transmitted during SOF - tag_sof--; - } else { - // bit is same as last bit - rx[rxlen / 8] |= lastbit << (7-(rxlen%8)); - rxlen++; - } - } else { - // Ignore wierd value, is to small to mean anything - } - } - } - } + if (reader_frame) { + LED_B_ON(); + // Capture reader frame + if(ra >= HITAG_T_STOP) { + if (rxlen != 0) { + //DbpString("wierd0?"); + } + // Capture the T0 periods that have passed since last communication or field drop (reset) + response = (ra - HITAG_T_LOW); + } else if(ra >= HITAG_T_1_MIN ) { + // '1' bit + rx[rxlen / 8] |= 1 << (7-(rxlen%8)); + rxlen++; + } else if(ra >= HITAG_T_0_MIN) { + // '0' bit + rx[rxlen / 8] |= 0 << (7-(rxlen%8)); + rxlen++; + } else { + // Ignore wierd value, is to small to mean anything + } + } else { + LED_C_ON(); + // Capture tag frame (manchester decoding using only falling edges) + if(ra >= HITAG_T_EOF) { + if (rxlen != 0) { + //DbpString("wierd1?"); + } + // Capture the T0 periods that have passed since last communication or field drop (reset) + // We always recieve a 'one' first, which has the falling edge after a half period |-_| + response = ra-HITAG_T_TAG_HALF_PERIOD; + } else if(ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { + // Manchester coding example |-_|_-|-_| (101) + rx[rxlen / 8] |= 0 << (7-(rxlen%8)); + rxlen++; + rx[rxlen / 8] |= 1 << (7-(rxlen%8)); + rxlen++; + } else if(ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { + // Manchester coding example |_-|...|_-|-_| (0...01) + rx[rxlen / 8] |= 0 << (7-(rxlen%8)); + rxlen++; + // We have to skip this half period at start and add the 'one' the second time + if (!bSkip) { + rx[rxlen / 8] |= 1 << (7-(rxlen%8)); + rxlen++; + } + lastbit = !lastbit; + bSkip = !bSkip; + } else if(ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { + // Manchester coding example |_-|_-| (00) or |-_|-_| (11) + if (tag_sof) { + // Ignore bits that are transmitted during SOF + tag_sof--; + } else { + // bit is same as last bit + rx[rxlen / 8] |= lastbit << (7-(rxlen%8)); + rxlen++; + } + } else { + // Ignore wierd value, is to small to mean anything + } + } + } + } - // Check if frame was captured - if(rxlen > 0) { - frame_count++; - if (!LogTraceHitag(rx,rxlen,response,0,reader_frame)) { - DbpString("Trace full"); - break; - } + // Check if frame was captured + if(rxlen > 0) { + frame_count++; + if (!LogTraceHitag(rx,rxlen,response,0,reader_frame)) { + DbpString("Trace full"); + break; + } - // Check if we recognize a valid authentication attempt - if (nbytes(rxlen) == 8) { - // Store the authentication attempt - if (auth_table_len < (AUTH_TABLE_LENGTH-8)) { - memcpy(auth_table+auth_table_len,rx,8); - auth_table_len += 8; - } - } + // Check if we recognize a valid authentication attempt + if (nbytes(rxlen) == 8) { + // Store the authentication attempt + if (auth_table_len < (AUTH_TABLE_LENGTH-8)) { + memcpy(auth_table+auth_table_len,rx,8); + auth_table_len += 8; + } + } - // Reset the received frame and response timing info - memset(rx,0x00,sizeof(rx)); - response = 0; - reader_frame = false; - lastbit = 1; - bSkip = true; - tag_sof = 4; - overflow = 0; + // Reset the received frame and response timing info + memset(rx,0x00,sizeof(rx)); + response = 0; + reader_frame = false; + lastbit = 1; + bSkip = true; + tag_sof = 4; + overflow = 0; - LED_B_OFF(); - LED_C_OFF(); - } else { - // Save the timer overflow, will be 0 when frame was received - overflow += (AT91C_BASE_TC1->TC_CV/T0); - } - // Reset the frame length - rxlen = 0; - // Reset the timer to restart while-loop that receives frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; - } + LED_B_OFF(); + LED_C_OFF(); + } else { + // Save the timer overflow, will be 0 when frame was received + overflow += (AT91C_BASE_TC1->TC_CV/T0); + } + // Reset the frame length + rxlen = 0; + // Reset the timer to restart while-loop that receives frames + AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; + } LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); - LED_D_OFF(); - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + LED_B_OFF(); + LED_C_OFF(); + LED_D_OFF(); + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_A_OFF(); - set_tracing(false); -// Dbprintf("frame received: %d",frame_count); -// Dbprintf("Authentication Attempts: %d",(auth_table_len/8)); -// DbpString("All done"); + set_tracing(false); +// Dbprintf("frame received: %d",frame_count); +// Dbprintf("Authentication Attempts: %d",(auth_table_len/8)); +// DbpString("All done"); } void SimulateHitagTag(bool tag_mem_supplied, uint8_t* data) { - int frame_count; - int response; - int overflow; - uint8_t rx[HITAG_FRAME_LEN]; - size_t rxlen=0; - uint8_t tx[HITAG_FRAME_LEN]; - size_t txlen=0; - bool bQuitTraceFull = false; - bQuiet = false; + int frame_count; + int response; + int overflow; + uint8_t rx[HITAG_FRAME_LEN]; + size_t rxlen=0; + uint8_t tx[HITAG_FRAME_LEN]; + size_t txlen=0; + bool bQuitTraceFull = false; + bQuiet = false; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - // free eventually allocated BigBuf memory - BigBuf_free(); BigBuf_Clear_ext(false); + // free eventually allocated BigBuf memory + BigBuf_free(); BigBuf_Clear_ext(false); - // Clean up trace and prepare it for storing frames - clear_trace(); - set_tracing(true); + // Clean up trace and prepare it for storing frames + clear_trace(); + set_tracing(true); - auth_table_len = 0; - auth_table_pos = 0; + auth_table_len = 0; + auth_table_pos = 0; uint8_t* auth_table; auth_table = (uint8_t *)BigBuf_malloc(AUTH_TABLE_LENGTH); - memset(auth_table, 0x00, AUTH_TABLE_LENGTH); + memset(auth_table, 0x00, AUTH_TABLE_LENGTH); - DbpString("Starting Hitag2 simulation"); - LED_D_ON(); - hitag2_init(); + DbpString("Starting Hitag2 simulation"); + LED_D_ON(); + hitag2_init(); - if (tag_mem_supplied) { - DbpString("Loading hitag2 memory..."); - memcpy((uint8_t*)tag.sectors,data,48); - } + if (tag_mem_supplied) { + DbpString("Loading hitag2 memory..."); + memcpy((uint8_t*)tag.sectors,data,48); + } - uint32_t block = 0; - for (size_t i=0; i<12; i++) { - for (size_t j=0; j<4; j++) { - block <<= 8; - block |= tag.sectors[i][j]; - } - Dbprintf("| %d | %08x |",i,block); - } + uint32_t block = 0; + for (size_t i=0; i<12; i++) { + for (size_t j=0; j<4; j++) { + block <<= 8; + block |= tag.sectors[i][j]; + } + Dbprintf("| %d | %08x |",i,block); + } - // Set up simulator mode, frequency divisor which will drive the FPGA - // and analog mux selection. - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); - SpinDelay(50); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - RELAY_OFF(); + // Set up simulator mode, frequency divisor which will drive the FPGA + // and analog mux selection. + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); + SpinDelay(50); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + RELAY_OFF(); - // Configure output pin that is connected to the FPGA (for modulating) - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + // Configure output pin that is connected to the FPGA (for modulating) + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - // Disable modulation at default, which means release resistance - LOW(GPIO_SSC_DOUT); + // Disable modulation at default, which means release resistance + LOW(GPIO_SSC_DOUT); - // Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); + // Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); - // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the reader frames - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); - AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; + // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the reader frames + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); + AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; // Disable timer during configuration - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - // Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, - // external trigger rising edge, load RA on rising edge of TIOA. - AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_RISING | AT91C_TC_ABETRG | AT91C_TC_LDRA_RISING; + // Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, + // external trigger rising edge, load RA on rising edge of TIOA. + AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_RISING | AT91C_TC_ABETRG | AT91C_TC_LDRA_RISING; - // Reset the received frame, frame count and timing info - memset(rx,0x00,sizeof(rx)); - frame_count = 0; - response = 0; - overflow = 0; + // Reset the received frame, frame count and timing info + memset(rx,0x00,sizeof(rx)); + frame_count = 0; + response = 0; + overflow = 0; - // Enable and reset counter - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + // Enable and reset counter + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - while(!BUTTON_PRESS() && !usb_poll_validate_length()) { - // Watchdog hit - WDT_HIT(); + while(!BUTTON_PRESS() && !usb_poll_validate_length()) { + // Watchdog hit + WDT_HIT(); - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0*HITAG_T_EOF) { - // Check if rising edge in modulation is detected - if(AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA/T0) + overflow; - overflow = 0; + // Receive frame, watch for at most T0*EOF periods + while (AT91C_BASE_TC1->TC_CV < T0*HITAG_T_EOF) { + // Check if rising edge in modulation is detected + if(AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { + // Retrieve the new timing values + int ra = (AT91C_BASE_TC1->TC_RA/T0) + overflow; + overflow = 0; - // Reset timer every frame, we have to capture the last edge for timing - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + // Reset timer every frame, we have to capture the last edge for timing + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - LED_B_ON(); + LED_B_ON(); - // Capture reader frame - if(ra >= HITAG_T_STOP) { - if (rxlen != 0) { - //DbpString("wierd0?"); - } - // Capture the T0 periods that have passed since last communication or field drop (reset) - response = (ra - HITAG_T_LOW); - } else if(ra >= HITAG_T_1_MIN ) { - // '1' bit - rx[rxlen / 8] |= 1 << (7-(rxlen%8)); - rxlen++; - } else if(ra >= HITAG_T_0_MIN) { - // '0' bit - rx[rxlen / 8] |= 0 << (7-(rxlen%8)); - rxlen++; - } else { - // Ignore wierd value, is to small to mean anything - } - } - } + // Capture reader frame + if(ra >= HITAG_T_STOP) { + if (rxlen != 0) { + //DbpString("wierd0?"); + } + // Capture the T0 periods that have passed since last communication or field drop (reset) + response = (ra - HITAG_T_LOW); + } else if(ra >= HITAG_T_1_MIN ) { + // '1' bit + rx[rxlen / 8] |= 1 << (7-(rxlen%8)); + rxlen++; + } else if(ra >= HITAG_T_0_MIN) { + // '0' bit + rx[rxlen / 8] |= 0 << (7-(rxlen%8)); + rxlen++; + } else { + // Ignore wierd value, is to small to mean anything + } + } + } - // Check if frame was captured - if(rxlen > 4) { - frame_count++; - if (!bQuiet) { - if (!LogTraceHitag(rx,rxlen,response,0,true)) { - DbpString("Trace full"); - if (bQuitTraceFull) { - break; - } else { - bQuiet = true; - } - } - } + // Check if frame was captured + if(rxlen > 4) { + frame_count++; + if (!bQuiet) { + if (!LogTraceHitag(rx,rxlen,response,0,true)) { + DbpString("Trace full"); + if (bQuitTraceFull) { + break; + } else { + bQuiet = true; + } + } + } - // Disable timer 1 with external trigger to avoid triggers during our own modulation - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + // Disable timer 1 with external trigger to avoid triggers during our own modulation + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - // Process the incoming frame (rx) and prepare the outgoing frame (tx) - hitag2_handle_reader_command(rx,rxlen,tx,&txlen); + // Process the incoming frame (rx) and prepare the outgoing frame (tx) + hitag2_handle_reader_command(rx,rxlen,tx,&txlen); - // Wait for HITAG_T_WAIT_1 carrier periods after the last reader bit, - // not that since the clock counts since the rising edge, but T_Wait1 is - // with respect to the falling edge, we need to wait actually (T_Wait1 - T_Low) - // periods. The gap time T_Low varies (4..10). All timer values are in - // terms of T0 units - while(AT91C_BASE_TC0->TC_CV < T0*(HITAG_T_WAIT_1-HITAG_T_LOW)); + // Wait for HITAG_T_WAIT_1 carrier periods after the last reader bit, + // not that since the clock counts since the rising edge, but T_Wait1 is + // with respect to the falling edge, we need to wait actually (T_Wait1 - T_Low) + // periods. The gap time T_Low varies (4..10). All timer values are in + // terms of T0 units + while(AT91C_BASE_TC0->TC_CV < T0*(HITAG_T_WAIT_1-HITAG_T_LOW)); - // Send and store the tag answer (if there is any) - if (txlen) { - // Transmit the tag frame - hitag_send_frame(tx,txlen); - // Store the frame in the trace - if (!bQuiet) { - if (!LogTraceHitag(tx,txlen,0,0,false)) { - DbpString("Trace full"); - if (bQuitTraceFull) { - break; - } else { - bQuiet = true; - } - } - } - } + // Send and store the tag answer (if there is any) + if (txlen) { + // Transmit the tag frame + hitag_send_frame(tx,txlen); + // Store the frame in the trace + if (!bQuiet) { + if (!LogTraceHitag(tx,txlen,0,0,false)) { + DbpString("Trace full"); + if (bQuitTraceFull) { + break; + } else { + bQuiet = true; + } + } + } + } - // Reset the received frame and response timing info - memset(rx,0x00,sizeof(rx)); - response = 0; + // Reset the received frame and response timing info + memset(rx,0x00,sizeof(rx)); + response = 0; - // Enable and reset external trigger in timer for capturing future frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - LED_B_OFF(); - } - // Reset the frame length - rxlen = 0; - // Save the timer overflow, will be 0 when frame was received - overflow += (AT91C_BASE_TC1->TC_CV/T0); - // Reset the timer to restart while-loop that receives frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; - } - LED_B_OFF(); - LED_D_OFF(); - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // Enable and reset external trigger in timer for capturing future frames + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + LED_B_OFF(); + } + // Reset the frame length + rxlen = 0; + // Save the timer overflow, will be 0 when frame was received + overflow += (AT91C_BASE_TC1->TC_CV/T0); + // Reset the timer to restart while-loop that receives frames + AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; + } + LED_B_OFF(); + LED_D_OFF(); + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("Sim Stopped"); - set_tracing(false); + DbpString("Sim Stopped"); + set_tracing(false); } void ReaderHitag(hitag_function htf, hitag_data* htd) { - int frame_count = 0; - int response = 0; - uint8_t rx[HITAG_FRAME_LEN]; - size_t rxlen = 0; - uint8_t txbuf[HITAG_FRAME_LEN]; - uint8_t* tx = txbuf; - size_t txlen = 0; - int lastbit = 1; - bool bSkip; - int reset_sof; - int tag_sof; - int t_wait = HITAG_T_WAIT_MAX; - bool bStop = false; - bool bQuitTraceFull = false; + int frame_count = 0; + int response = 0; + uint8_t rx[HITAG_FRAME_LEN]; + size_t rxlen = 0; + uint8_t txbuf[HITAG_FRAME_LEN]; + uint8_t* tx = txbuf; + size_t txlen = 0; + int lastbit = 1; + bool bSkip; + int reset_sof; + int tag_sof; + int t_wait = HITAG_T_WAIT_MAX; + bool bStop = false; + bool bQuitTraceFull = false; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - // Reset the return status - bSuccessful = false; + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + // Reset the return status + bSuccessful = false; - // Clean up trace and prepare it for storing frames - clear_trace(); - set_tracing(true); + // Clean up trace and prepare it for storing frames + clear_trace(); + set_tracing(true); - //DbpString("Starting Hitag reader family"); + //DbpString("Starting Hitag reader family"); - // Check configuration - switch (htf) { - case RHT2F_PASSWORD: { - Dbprintf("List identifier in password mode"); - memcpy(password,htd->pwd.password, 4); - blocknr = 0; - bQuitTraceFull = false; - bQuiet = false; - bPwd = false; - } break; + // Check configuration + switch (htf) { + case RHT2F_PASSWORD: { + Dbprintf("List identifier in password mode"); + memcpy(password,htd->pwd.password, 4); + blocknr = 0; + bQuitTraceFull = false; + bQuiet = false; + bPwd = false; + } break; - case RHT2F_AUTHENTICATE: { - DbpString("Authenticating using nr,ar pair:"); - memcpy(NrAr,htd->auth.NrAr, 8); - Dbhexdump(8,NrAr,false); - bQuiet = false; - bCrypto = false; - bAuthenticating = false; - bQuitTraceFull = true; - } break; + case RHT2F_AUTHENTICATE: { + DbpString("Authenticating using nr,ar pair:"); + memcpy(NrAr,htd->auth.NrAr, 8); + Dbhexdump(8,NrAr,false); + bQuiet = false; + bCrypto = false; + bAuthenticating = false; + bQuitTraceFull = true; + } break; - case RHT2F_CRYPTO: { - DbpString("Authenticating using key:"); - memcpy(key,htd->crypto.key, 6); //HACK; 4 or 6?? I read both in the code. - Dbhexdump(6,key,false); - blocknr = 0; - bQuiet = false; - bCrypto = false; - bAuthenticating = false; - bQuitTraceFull = true; - } break; + case RHT2F_CRYPTO: { + DbpString("Authenticating using key:"); + memcpy(key,htd->crypto.key, 6); //HACK; 4 or 6?? I read both in the code. + Dbhexdump(6,key,false); + blocknr = 0; + bQuiet = false; + bCrypto = false; + bAuthenticating = false; + bQuitTraceFull = true; + } break; - case RHT2F_TEST_AUTH_ATTEMPTS: { - Dbprintf("Testing %d authentication attempts",(auth_table_len/8)); - auth_table_pos = 0; - memcpy(NrAr, auth_table, 8); - bQuitTraceFull = false; - bQuiet = false; - bCrypto = false; - } break; - case RHT2F_UID_ONLY: { - blocknr = 0; - bQuiet = false; - bCrypto = false; - bAuthenticating = false; - bQuitTraceFull = true; - } break; - default: { - Dbprintf("Error, unknown function: %d",htf); - set_tracing(false); - return; - } break; - } + case RHT2F_TEST_AUTH_ATTEMPTS: { + Dbprintf("Testing %d authentication attempts",(auth_table_len/8)); + auth_table_pos = 0; + memcpy(NrAr, auth_table, 8); + bQuitTraceFull = false; + bQuiet = false; + bCrypto = false; + } break; + case RHT2F_UID_ONLY: { + blocknr = 0; + bQuiet = false; + bCrypto = false; + bAuthenticating = false; + bQuitTraceFull = true; + } break; + default: { + Dbprintf("Error, unknown function: %d",htf); + set_tracing(false); + return; + } break; + } - LED_D_ON(); - hitag2_init(); + LED_D_ON(); + hitag2_init(); - // Configure output and enable pin that is connected to the FPGA (for modulating) - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + // Configure output and enable pin that is connected to the FPGA (for modulating) + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - // Set fpga in edge detect with reader field, we can modulate as reader now - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); - SpinDelay(20); + // Set fpga in edge detect with reader field, we can modulate as reader now + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); + SpinDelay(20); - // Set Frequency divisor which will drive the FPGA and analog mux selection - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - RELAY_OFF(); + // Set Frequency divisor which will drive the FPGA and analog mux selection + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + RELAY_OFF(); - // Disable modulation at default, which means enable the field - LOW(GPIO_SSC_DOUT); + // Disable modulation at default, which means enable the field + LOW(GPIO_SSC_DOUT); - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(30); + // Give it a bit of time for the resonant antenna to settle. + SpinDelay(30); - // Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); + // Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); - // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the tag frames - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); - AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; + // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the tag frames + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); + AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; // Disable timer during configuration - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - // Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, - // external trigger rising edge, load RA on falling edge of TIOA. - AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_FALLING | AT91C_TC_ABETRG | AT91C_TC_LDRA_FALLING; + // Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, + // external trigger rising edge, load RA on falling edge of TIOA. + AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_FALLING | AT91C_TC_ABETRG | AT91C_TC_LDRA_FALLING; - // Enable and reset counters - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + // Enable and reset counters + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - // Tag specific configuration settings (sof, timings, etc.) - if (htf < 10){ - // hitagS settings - reset_sof = 1; - t_wait = 200; + // Tag specific configuration settings (sof, timings, etc.) + if (htf < 10){ + // hitagS settings + reset_sof = 1; + t_wait = 200; // DbpString("Configured for hitagS reader"); - } else if (htf < 20) { - // hitag1 settings - reset_sof = 1; - t_wait = 200; + } else if (htf < 20) { + // hitag1 settings + reset_sof = 1; + t_wait = 200; // DbpString("Configured for hitag1 reader"); - } else if (htf < 30) { - // hitag2 settings - reset_sof = 4; - t_wait = HITAG_T_WAIT_2; + } else if (htf < 30) { + // hitag2 settings + reset_sof = 4; + t_wait = HITAG_T_WAIT_2; // DbpString("Configured for hitag2 reader"); - } else { - Dbprintf("Error, unknown hitag reader type: %d",htf); - set_tracing(false); - LED_D_OFF(); - return; - } - uint8_t attempt_count=0; - while (!bStop && !BUTTON_PRESS()) { - // Watchdog hit - WDT_HIT(); + } else { + Dbprintf("Error, unknown hitag reader type: %d",htf); + set_tracing(false); + LED_D_OFF(); + return; + } + uint8_t attempt_count=0; + while (!bStop && !BUTTON_PRESS()) { + // Watchdog hit + WDT_HIT(); - // Check if frame was captured and store it - if (rxlen > 0) { - frame_count++; - if (!bQuiet) { - if (!LogTraceHitag(rx,rxlen, response, 0, false)) { - DbpString("Trace full"); - if (bQuitTraceFull) - break; - else - bQuiet = true; - } - } - } + // Check if frame was captured and store it + if (rxlen > 0) { + frame_count++; + if (!bQuiet) { + if (!LogTraceHitag(rx,rxlen, response, 0, false)) { + DbpString("Trace full"); + if (bQuitTraceFull) + break; + else + bQuiet = true; + } + } + } - // By default reset the transmission buffer - tx = txbuf; - switch (htf) { - case RHT2F_PASSWORD: { - bStop = !hitag2_password(rx,rxlen,tx,&txlen); - } break; - case RHT2F_AUTHENTICATE: { - bStop = !hitag2_authenticate(rx,rxlen,tx,&txlen); - } break; - case RHT2F_CRYPTO: { - bStop = !hitag2_crypto(rx,rxlen,tx,&txlen, false); - } break; - case RHT2F_TEST_AUTH_ATTEMPTS: { - bStop = !hitag2_test_auth_attempts(rx,rxlen,tx,&txlen); - } break; - case RHT2F_UID_ONLY: { - bStop = !hitag2_read_uid(rx, rxlen, tx, &txlen); - attempt_count++; //attempt 3 times to get uid then quit - if (!bStop && attempt_count == 3) - bStop = true; - } break; - default: { - Dbprintf("Error, unknown function: %d",htf); - set_tracing(false); - LED_D_OFF(); - return; - } break; - } + // By default reset the transmission buffer + tx = txbuf; + switch (htf) { + case RHT2F_PASSWORD: { + bStop = !hitag2_password(rx,rxlen,tx,&txlen); + } break; + case RHT2F_AUTHENTICATE: { + bStop = !hitag2_authenticate(rx,rxlen,tx,&txlen); + } break; + case RHT2F_CRYPTO: { + bStop = !hitag2_crypto(rx,rxlen,tx,&txlen, false); + } break; + case RHT2F_TEST_AUTH_ATTEMPTS: { + bStop = !hitag2_test_auth_attempts(rx,rxlen,tx,&txlen); + } break; + case RHT2F_UID_ONLY: { + bStop = !hitag2_read_uid(rx, rxlen, tx, &txlen); + attempt_count++; //attempt 3 times to get uid then quit + if (!bStop && attempt_count == 3) + bStop = true; + } break; + default: { + Dbprintf("Error, unknown function: %d",htf); + set_tracing(false); + LED_D_OFF(); + return; + } break; + } - // Send and store the reader command - // Disable timer 1 with external trigger to avoid triggers during our own modulation - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + // Send and store the reader command + // Disable timer 1 with external trigger to avoid triggers during our own modulation + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting, - // Since the clock counts since the last falling edge, a 'one' means that the - // falling edge occured halfway the period. with respect to this falling edge, - // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. - // All timer values are in terms of T0 units - while (AT91C_BASE_TC0->TC_CV < T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit))); + // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting, + // Since the clock counts since the last falling edge, a 'one' means that the + // falling edge occured halfway the period. with respect to this falling edge, + // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. + // All timer values are in terms of T0 units + while (AT91C_BASE_TC0->TC_CV < T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit))); - // Transmit the reader frame - hitag_reader_send_frame(tx, txlen); + // Transmit the reader frame + hitag_reader_send_frame(tx, txlen); - // Enable and reset external trigger in timer for capturing future frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + // Enable and reset external trigger in timer for capturing future frames + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - // Add transmitted frame to total count - if (txlen > 0) { - frame_count++; - if (!bQuiet) { - // Store the frame in the trace - if (!LogTraceHitag(tx, txlen, HITAG_T_WAIT_2, 0, true)) { - if (bQuitTraceFull) { - break; - } else { - bQuiet = true; - } - } - } - } + // Add transmitted frame to total count + if (txlen > 0) { + frame_count++; + if (!bQuiet) { + // Store the frame in the trace + if (!LogTraceHitag(tx, txlen, HITAG_T_WAIT_2, 0, true)) { + if (bQuitTraceFull) { + break; + } else { + bQuiet = true; + } + } + } + } - // Reset values for receiving frames - memset(rx, 0x00, sizeof(rx)); - rxlen = 0; - lastbit = 1; - bSkip = true; - tag_sof = reset_sof; - response = 0; - uint32_t errorCount = 0; + // Reset values for receiving frames + memset(rx, 0x00, sizeof(rx)); + rxlen = 0; + lastbit = 1; + bSkip = true; + tag_sof = reset_sof; + response = 0; + uint32_t errorCount = 0; - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_WAIT_MAX) { - // Check if falling edge in tag modulation is detected - if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA/T0); + // Receive frame, watch for at most T0*EOF periods + while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_WAIT_MAX) { + // Check if falling edge in tag modulation is detected + if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { + // Retrieve the new timing values + int ra = (AT91C_BASE_TC1->TC_RA/T0); - // Reset timer every frame, we have to capture the last edge for timing - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + // Reset timer every frame, we have to capture the last edge for timing + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - LED_B_ON(); + LED_B_ON(); - // Capture tag frame (manchester decoding using only falling edges) - if (ra >= HITAG_T_EOF) { - // Capture the T0 periods that have passed since last communication or field drop (reset) - // We always recieve a 'one' first, which has the falling edge after a half period |-_| - response = ra-HITAG_T_TAG_HALF_PERIOD; - } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { - // Manchester coding example |-_|_-|-_| (101) - rx[rxlen / 8] |= 0 << (7-(rxlen%8)); - rxlen++; - rx[rxlen / 8] |= 1 << (7-(rxlen%8)); - rxlen++; - } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { - // Manchester coding example |_-|...|_-|-_| (0...01) - rx[rxlen / 8] |= 0 << (7-(rxlen%8)); - rxlen++; - // We have to skip this half period at start and add the 'one' the second time - if (!bSkip) { - rx[rxlen / 8] |= 1 << (7-(rxlen%8)); - rxlen++; - } - lastbit = !lastbit; - bSkip = !bSkip; - } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { - // Manchester coding example |_-|_-| (00) or |-_|-_| (11) - if (tag_sof) { - // Ignore bits that are transmitted during SOF - tag_sof--; - } else { - // bit is same as last bit - rx[rxlen / 8] |= lastbit << (7-(rxlen%8)); - rxlen++; - } - } else { - //Dbprintf("DEBUG: Wierd2"); - errorCount++; - // Ignore wierd value, is to small to mean anything - } - } - //if we saw over 100 wierd values break it probably isn't hitag... - if (errorCount > 100) break; - // We can break this loop if we received the last bit from a frame - if (AT91C_BASE_TC1->TC_CV > T0*HITAG_T_EOF) { - if (rxlen > 0) break; - } - } - } - LED_B_OFF(); - LED_D_OFF(); - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - set_tracing(false); + // Capture tag frame (manchester decoding using only falling edges) + if (ra >= HITAG_T_EOF) { + // Capture the T0 periods that have passed since last communication or field drop (reset) + // We always recieve a 'one' first, which has the falling edge after a half period |-_| + response = ra-HITAG_T_TAG_HALF_PERIOD; + } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { + // Manchester coding example |-_|_-|-_| (101) + rx[rxlen / 8] |= 0 << (7-(rxlen%8)); + rxlen++; + rx[rxlen / 8] |= 1 << (7-(rxlen%8)); + rxlen++; + } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { + // Manchester coding example |_-|...|_-|-_| (0...01) + rx[rxlen / 8] |= 0 << (7-(rxlen%8)); + rxlen++; + // We have to skip this half period at start and add the 'one' the second time + if (!bSkip) { + rx[rxlen / 8] |= 1 << (7-(rxlen%8)); + rxlen++; + } + lastbit = !lastbit; + bSkip = !bSkip; + } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { + // Manchester coding example |_-|_-| (00) or |-_|-_| (11) + if (tag_sof) { + // Ignore bits that are transmitted during SOF + tag_sof--; + } else { + // bit is same as last bit + rx[rxlen / 8] |= lastbit << (7-(rxlen%8)); + rxlen++; + } + } else { + //Dbprintf("DEBUG: Wierd2"); + errorCount++; + // Ignore wierd value, is to small to mean anything + } + } + //if we saw over 100 wierd values break it probably isn't hitag... + if (errorCount > 100) break; + // We can break this loop if we received the last bit from a frame + if (AT91C_BASE_TC1->TC_CV > T0*HITAG_T_EOF) { + if (rxlen > 0) break; + } + } + } + LED_B_OFF(); + LED_D_OFF(); + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + set_tracing(false); - if ( bSuccessful ) - cmd_send(CMD_ACK, bSuccessful, 0, 0, (uint8_t*)tag.sectors, 48); - else - cmd_send(CMD_ACK, bSuccessful, 0, 0, 0, 0); + if ( bSuccessful ) + cmd_send(CMD_ACK, bSuccessful, 0, 0, (uint8_t*)tag.sectors, 48); + else + cmd_send(CMD_ACK, bSuccessful, 0, 0, 0, 0); } void WriterHitag(hitag_function htf, hitag_data* htd, int page) { - int frame_count; - int response; - uint8_t rx[HITAG_FRAME_LEN]; - size_t rxlen=0; - uint8_t txbuf[HITAG_FRAME_LEN]; - uint8_t* tx = txbuf; - size_t txlen=0; - int lastbit; - bool bSkip; - int reset_sof; - int tag_sof; - int t_wait = HITAG_T_WAIT_MAX; - bool bStop; - bool bQuitTraceFull = false; + int frame_count; + int response; + uint8_t rx[HITAG_FRAME_LEN]; + size_t rxlen=0; + uint8_t txbuf[HITAG_FRAME_LEN]; + uint8_t* tx = txbuf; + size_t txlen=0; + int lastbit; + bool bSkip; + int reset_sof; + int tag_sof; + int t_wait = HITAG_T_WAIT_MAX; + bool bStop; + bool bQuitTraceFull = false; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - // Reset the return status - bSuccessful = false; + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + // Reset the return status + bSuccessful = false; - // Clean up trace and prepare it for storing frames - set_tracing(true); - clear_trace(); + // Clean up trace and prepare it for storing frames + set_tracing(true); + clear_trace(); - // DbpString("Starting Hitag reader family"); + // DbpString("Starting Hitag reader family"); - // Check configuration - switch(htf) { - case WHT2F_CRYPTO: { - DbpString("Authenticating using key:"); - memcpy(key,htd->crypto.key,6); //HACK; 4 or 6?? I read both in the code. - memcpy(writedata, htd->crypto.data, 4); - Dbhexdump(6,key,false); - blocknr = page; - bQuiet = false; - bCrypto = false; - bAuthenticating = false; - bQuitTraceFull = true; - writestate = WRITE_STATE_START; - } break; - default: { - Dbprintf("Error, unknown function: %d",htf); - return; - } break; - } + // Check configuration + switch(htf) { + case WHT2F_CRYPTO: { + DbpString("Authenticating using key:"); + memcpy(key,htd->crypto.key,6); //HACK; 4 or 6?? I read both in the code. + memcpy(writedata, htd->crypto.data, 4); + Dbhexdump(6,key,false); + blocknr = page; + bQuiet = false; + bCrypto = false; + bAuthenticating = false; + bQuitTraceFull = true; + writestate = WRITE_STATE_START; + } break; + default: { + Dbprintf("Error, unknown function: %d",htf); + return; + } break; + } - LED_D_ON(); - hitag2_init(); + LED_D_ON(); + hitag2_init(); - // Configure output and enable pin that is connected to the FPGA (for modulating) - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + // Configure output and enable pin that is connected to the FPGA (for modulating) + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - // Set fpga in edge detect with reader field, we can modulate as reader now - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); + // Set fpga in edge detect with reader field, we can modulate as reader now + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); - // Set Frequency divisor which will drive the FPGA and analog mux selection - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - RELAY_OFF(); + // Set Frequency divisor which will drive the FPGA and analog mux selection + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + RELAY_OFF(); - // Disable modulation at default, which means enable the field - LOW(GPIO_SSC_DOUT); + // Disable modulation at default, which means enable the field + LOW(GPIO_SSC_DOUT); - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(30); + // Give it a bit of time for the resonant antenna to settle. + SpinDelay(30); - // Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); + // Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); - // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the tag frames - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); - AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; + // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the tag frames + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); + AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; - // Disable timer during configuration - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + // Disable timer during configuration + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - // Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, - // external trigger rising edge, load RA on falling edge of TIOA. - AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_FALLING | AT91C_TC_ABETRG | AT91C_TC_LDRA_FALLING; + // Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, + // external trigger rising edge, load RA on falling edge of TIOA. + AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_FALLING | AT91C_TC_ABETRG | AT91C_TC_LDRA_FALLING; - // Enable and reset counters - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + // Enable and reset counters + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - // Reset the received frame, frame count and timing info - frame_count = 0; - response = 0; - lastbit = 1; - bStop = false; + // Reset the received frame, frame count and timing info + frame_count = 0; + response = 0; + lastbit = 1; + bStop = false; - // Tag specific configuration settings (sof, timings, etc.) - if (htf < 10){ - // hitagS settings - reset_sof = 1; - t_wait = 200; - // DbpString("Configured for hitagS reader"); - } else if (htf < 20) { - // hitag1 settings - reset_sof = 1; - t_wait = 200; - // DbpString("Configured for hitag1 reader"); - } else if (htf < 30) { - // hitag2 settings - reset_sof = 4; - t_wait = HITAG_T_WAIT_2; - // DbpString("Configured for hitag2 reader"); - } else { - Dbprintf("Error, unknown hitag reader type: %d",htf); - return; - } - while(!bStop && !BUTTON_PRESS()) { - // Watchdog hit - WDT_HIT(); + // Tag specific configuration settings (sof, timings, etc.) + if (htf < 10){ + // hitagS settings + reset_sof = 1; + t_wait = 200; + // DbpString("Configured for hitagS reader"); + } else if (htf < 20) { + // hitag1 settings + reset_sof = 1; + t_wait = 200; + // DbpString("Configured for hitag1 reader"); + } else if (htf < 30) { + // hitag2 settings + reset_sof = 4; + t_wait = HITAG_T_WAIT_2; + // DbpString("Configured for hitag2 reader"); + } else { + Dbprintf("Error, unknown hitag reader type: %d",htf); + return; + } + while(!bStop && !BUTTON_PRESS()) { + // Watchdog hit + WDT_HIT(); - // Check if frame was captured and store it - if(rxlen > 0) { - frame_count++; - if (!bQuiet) { - if (!LogTraceHitag(rx,rxlen,response,0,false)) { - DbpString("Trace full"); - if (bQuitTraceFull) { - break; - } else { - bQuiet = true; - } - } - } - } + // Check if frame was captured and store it + if(rxlen > 0) { + frame_count++; + if (!bQuiet) { + if (!LogTraceHitag(rx,rxlen,response,0,false)) { + DbpString("Trace full"); + if (bQuitTraceFull) { + break; + } else { + bQuiet = true; + } + } + } + } - // By default reset the transmission buffer - tx = txbuf; - switch(htf) { - case WHT2F_CRYPTO: { - bStop = !hitag2_crypto(rx,rxlen,tx,&txlen, true); - } break; - default: { - Dbprintf("Error, unknown function: %d",htf); - return; - } break; - } + // By default reset the transmission buffer + tx = txbuf; + switch(htf) { + case WHT2F_CRYPTO: { + bStop = !hitag2_crypto(rx,rxlen,tx,&txlen, true); + } break; + default: { + Dbprintf("Error, unknown function: %d",htf); + return; + } break; + } - // Send and store the reader command - // Disable timer 1 with external trigger to avoid triggers during our own modulation - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + // Send and store the reader command + // Disable timer 1 with external trigger to avoid triggers during our own modulation + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting, - // Since the clock counts since the last falling edge, a 'one' means that the - // falling edge occured halfway the period. with respect to this falling edge, - // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. - // All timer values are in terms of T0 units - while(AT91C_BASE_TC0->TC_CV < T0*(t_wait+(HITAG_T_TAG_HALF_PERIOD*lastbit))); + // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting, + // Since the clock counts since the last falling edge, a 'one' means that the + // falling edge occured halfway the period. with respect to this falling edge, + // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. + // All timer values are in terms of T0 units + while(AT91C_BASE_TC0->TC_CV < T0*(t_wait+(HITAG_T_TAG_HALF_PERIOD*lastbit))); - // Dbprintf("DEBUG: Sending reader frame"); + // Dbprintf("DEBUG: Sending reader frame"); - // Transmit the reader frame - hitag_reader_send_frame(tx,txlen); + // Transmit the reader frame + hitag_reader_send_frame(tx,txlen); - // Enable and reset external trigger in timer for capturing future frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + // Enable and reset external trigger in timer for capturing future frames + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - // Add transmitted frame to total count - if(txlen > 0) { - frame_count++; - if (!bQuiet) { - // Store the frame in the trace - if (!LogTraceHitag(tx,txlen,HITAG_T_WAIT_2,0,true)) { - if (bQuitTraceFull) { - break; - } else { - bQuiet = true; - } - } - } - } + // Add transmitted frame to total count + if(txlen > 0) { + frame_count++; + if (!bQuiet) { + // Store the frame in the trace + if (!LogTraceHitag(tx,txlen,HITAG_T_WAIT_2,0,true)) { + if (bQuitTraceFull) { + break; + } else { + bQuiet = true; + } + } + } + } - // Reset values for receiving frames - memset(rx,0x00,sizeof(rx)); - rxlen = 0; - lastbit = 1; - bSkip = true; - tag_sof = reset_sof; - response = 0; - // Dbprintf("DEBUG: Waiting to receive frame"); - uint32_t errorCount = 0; + // Reset values for receiving frames + memset(rx,0x00,sizeof(rx)); + rxlen = 0; + lastbit = 1; + bSkip = true; + tag_sof = reset_sof; + response = 0; + // Dbprintf("DEBUG: Waiting to receive frame"); + uint32_t errorCount = 0; - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0*HITAG_T_WAIT_MAX) { - // Check if falling edge in tag modulation is detected - if(AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA/T0); + // Receive frame, watch for at most T0*EOF periods + while (AT91C_BASE_TC1->TC_CV < T0*HITAG_T_WAIT_MAX) { + // Check if falling edge in tag modulation is detected + if(AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { + // Retrieve the new timing values + int ra = (AT91C_BASE_TC1->TC_RA/T0); - // Reset timer every frame, we have to capture the last edge for timing - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + // Reset timer every frame, we have to capture the last edge for timing + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - LED_B_ON(); + LED_B_ON(); - // Capture tag frame (manchester decoding using only falling edges) - if(ra >= HITAG_T_EOF) { - if (rxlen != 0) { - //Dbprintf("DEBUG: Wierd1"); - } - // Capture the T0 periods that have passed since last communication or field drop (reset) - // We always recieve a 'one' first, which has the falling edge after a half period |-_| - response = ra-HITAG_T_TAG_HALF_PERIOD; - } else if(ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { - // Manchester coding example |-_|_-|-_| (101) + // Capture tag frame (manchester decoding using only falling edges) + if(ra >= HITAG_T_EOF) { + if (rxlen != 0) { + //Dbprintf("DEBUG: Wierd1"); + } + // Capture the T0 periods that have passed since last communication or field drop (reset) + // We always recieve a 'one' first, which has the falling edge after a half period |-_| + response = ra-HITAG_T_TAG_HALF_PERIOD; + } else if(ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { + // Manchester coding example |-_|_-|-_| (101) - // need to test to verify we don't exceed memory... - // if ( ((rxlen+2) / 8) > HITAG_FRAME_LEN) { - // break; - // } - rx[rxlen / 8] |= 0 << (7-(rxlen%8)); - rxlen++; - rx[rxlen / 8] |= 1 << (7-(rxlen%8)); - rxlen++; - } else if(ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { - // Manchester coding example |_-|...|_-|-_| (0...01) + // need to test to verify we don't exceed memory... + // if ( ((rxlen+2) / 8) > HITAG_FRAME_LEN) { + // break; + // } + rx[rxlen / 8] |= 0 << (7-(rxlen%8)); + rxlen++; + rx[rxlen / 8] |= 1 << (7-(rxlen%8)); + rxlen++; + } else if(ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { + // Manchester coding example |_-|...|_-|-_| (0...01) - // need to test to verify we don't exceed memory... - // if ( ((rxlen+2) / 8) > HITAG_FRAME_LEN) { - // break; - // } - rx[rxlen / 8] |= 0 << (7-(rxlen%8)); - rxlen++; - // We have to skip this half period at start and add the 'one' the second time - if (!bSkip) { - rx[rxlen / 8] |= 1 << (7-(rxlen%8)); - rxlen++; - } - lastbit = !lastbit; - bSkip = !bSkip; - } else if(ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { - // Manchester coding example |_-|_-| (00) or |-_|-_| (11) + // need to test to verify we don't exceed memory... + // if ( ((rxlen+2) / 8) > HITAG_FRAME_LEN) { + // break; + // } + rx[rxlen / 8] |= 0 << (7-(rxlen%8)); + rxlen++; + // We have to skip this half period at start and add the 'one' the second time + if (!bSkip) { + rx[rxlen / 8] |= 1 << (7-(rxlen%8)); + rxlen++; + } + lastbit = !lastbit; + bSkip = !bSkip; + } else if(ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { + // Manchester coding example |_-|_-| (00) or |-_|-_| (11) - // need to test to verify we don't exceed memory... - // if ( ((rxlen+2) / 8) > HITAG_FRAME_LEN) { - // break; - // } - if (tag_sof) { - // Ignore bits that are transmitted during SOF - tag_sof--; - } else { - // bit is same as last bit - rx[rxlen / 8] |= lastbit << (7-(rxlen%8)); - rxlen++; - } - } else { - // Dbprintf("DEBUG: Wierd2"); - errorCount++; - // Ignore wierd value, is to small to mean anything - } - } - // if we saw over 100 wierd values break it probably isn't hitag... - if (errorCount >100) break; - // We can break this loop if we received the last bit from a frame - if (AT91C_BASE_TC1->TC_CV > T0*HITAG_T_EOF) { - if (rxlen>0) break; - } - } + // need to test to verify we don't exceed memory... + // if ( ((rxlen+2) / 8) > HITAG_FRAME_LEN) { + // break; + // } + if (tag_sof) { + // Ignore bits that are transmitted during SOF + tag_sof--; + } else { + // bit is same as last bit + rx[rxlen / 8] |= lastbit << (7-(rxlen%8)); + rxlen++; + } + } else { + // Dbprintf("DEBUG: Wierd2"); + errorCount++; + // Ignore wierd value, is to small to mean anything + } + } + // if we saw over 100 wierd values break it probably isn't hitag... + if (errorCount >100) break; + // We can break this loop if we received the last bit from a frame + if (AT91C_BASE_TC1->TC_CV > T0*HITAG_T_EOF) { + if (rxlen>0) break; + } + } - // Wait some extra time for flash to be programmed - if ((rxlen == 0) && (writestate == WRITE_STATE_PROG)) - { - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - while(AT91C_BASE_TC0->TC_CV < T0*(HITAG_T_PROG - HITAG_T_WAIT_MAX)); - } - } - // Dbprintf("DEBUG: Done waiting for frame"); + // Wait some extra time for flash to be programmed + if ((rxlen == 0) && (writestate == WRITE_STATE_PROG)) + { + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + while(AT91C_BASE_TC0->TC_CV < T0*(HITAG_T_PROG - HITAG_T_WAIT_MAX)); + } + } + // Dbprintf("DEBUG: Done waiting for frame"); - LED_B_OFF(); - LED_D_OFF(); - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - // Dbprintf("frame received: %d",frame_count); - // DbpString("All done"); - cmd_send(CMD_ACK,bSuccessful,0,0,(uint8_t*)tag.sectors,48); + LED_B_OFF(); + LED_D_OFF(); + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // Dbprintf("frame received: %d",frame_count); + // DbpString("All done"); + cmd_send(CMD_ACK,bSuccessful,0,0,(uint8_t*)tag.sectors,48); } diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index 489cf9f7e..544dbf086 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -22,17 +22,17 @@ #define CRC_PRESET 0xFF #define CRC_POLYNOM 0x1D -#define u8 uint8_t -#define u32 uint32_t -#define u64 uint64_t -#define rev8(x) ((((x)>>7)&1)+((((x)>>6)&1)<<1)+((((x)>>5)&1)<<2)+((((x)>>4)&1)<<3)+((((x)>>3)&1)<<4)+((((x)>>2)&1)<<5)+((((x)>>1)&1)<<6)+(((x)&1)<<7)) -#define rev16(x) (rev8 (x)+(rev8 (x>> 8)<< 8)) -#define rev32(x) (rev16(x)+(rev16(x>>16)<<16)) -#define rev64(x) (rev32(x)+(rev32(x>>32)<<32)) -#define bit(x,n) (((x)>>(n))&1) -#define bit32(x,n) ((((x)[(n)>>5])>>((n)))&1) -#define inv32(x,i,n) ((x)[(i)>>5]^=((u32)(n))<<((i)&31)) -#define rotl64(x, n) ((((u64)(x))<<((n)&63))+(((u64)(x))>>((0-(n))&63))) +#define u8 uint8_t +#define u32 uint32_t +#define u64 uint64_t +#define rev8(x) ((((x)>>7)&1)+((((x)>>6)&1)<<1)+((((x)>>5)&1)<<2)+((((x)>>4)&1)<<3)+((((x)>>3)&1)<<4)+((((x)>>2)&1)<<5)+((((x)>>1)&1)<<6)+(((x)&1)<<7)) +#define rev16(x) (rev8 (x)+(rev8 (x>> 8)<< 8)) +#define rev32(x) (rev16(x)+(rev16(x>>16)<<16)) +#define rev64(x) (rev32(x)+(rev32(x>>32)<<32)) +#define bit(x,n) (((x)>>(n))&1) +#define bit32(x,n) ((((x)[(n)>>5])>>((n)))&1) +#define inv32(x,i,n) ((x)[(i)>>5]^=((u32)(n))<<((i)&31)) +#define rotl64(x, n) ((((u64)(x))<<((n)&63))+(((u64)(x))>>((0-(n))&63))) static bool bQuiet; static bool bSuccessful; @@ -40,103 +40,103 @@ static struct hitagS_tag tag; static byte_t page_to_be_written = 0; static int block_data_left = 0; typedef enum modulation { - AC2K = 0, - AC4K, - MC4K, - MC8K + AC2K = 0, + AC4K, + MC4K, + MC8K } MOD; -static MOD m = AC2K; //used modulation +static MOD m = AC2K; //used modulation static uint32_t temp_uid; static int temp2 = 0; -static int sof_bits; //number of start-of-frame bits -static byte_t pwdh0, pwdl0, pwdl1; //password bytes -static uint32_t rnd = 0x74124485; //randomnumber +static int sof_bits; //number of start-of-frame bits +static byte_t pwdh0, pwdl0, pwdl1; //password bytes +static uint32_t rnd = 0x74124485; //randomnumber static int test = 0; size_t blocknr; bool end=false; // Single bit Hitag2 functions: -#define i4(x,a,b,c,d) ((u32)((((x)>>(a))&1)+(((x)>>(b))&1)*2+(((x)>>(c))&1)*4+(((x)>>(d))&1)*8)) -static const u32 ht2_f4a = 0x2C79; // 0010 1100 0111 1001 -static const u32 ht2_f4b = 0x6671; // 0110 0110 0111 0001 -static const u32 ht2_f5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 -#define ht2bs_4a(a,b,c,d) (~(((a|b)&c)^(a|d)^b)) -#define ht2bs_4b(a,b,c,d) (~(((d|c)&(a^b))^(d|a|b))) -#define ht2bs_5c(a,b,c,d,e) (~((((((c^e)|d)&a)^b)&(c^b))^(((d^e)|a)&((d^b)|c)))) -#define uf20bs u32 +#define i4(x,a,b,c,d) ((u32)((((x)>>(a))&1)+(((x)>>(b))&1)*2+(((x)>>(c))&1)*4+(((x)>>(d))&1)*8)) +static const u32 ht2_f4a = 0x2C79; // 0010 1100 0111 1001 +static const u32 ht2_f4b = 0x6671; // 0110 0110 0111 0001 +static const u32 ht2_f5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011 +#define ht2bs_4a(a,b,c,d) (~(((a|b)&c)^(a|d)^b)) +#define ht2bs_4b(a,b,c,d) (~(((d|c)&(a^b))^(d|a|b))) +#define ht2bs_5c(a,b,c,d,e) (~((((((c^e)|d)&a)^b)&(c^b))^(((d^e)|a)&((d^b)|c)))) +#define uf20bs u32 static u32 f20(const u64 x) { - u32 i5; + u32 i5; - i5 = ((ht2_f4a >> i4(x, 1, 2, 4, 5)) & 1) * 1 - + ((ht2_f4b >> i4(x, 7, 11, 13, 14)) & 1) * 2 - + ((ht2_f4b >> i4(x, 16, 20, 22, 25)) & 1) * 4 - + ((ht2_f4b >> i4(x, 27, 28, 30, 32)) & 1) * 8 - + ((ht2_f4a >> i4(x, 33, 42, 43, 45)) & 1) * 16; + i5 = ((ht2_f4a >> i4(x, 1, 2, 4, 5)) & 1) * 1 + + ((ht2_f4b >> i4(x, 7, 11, 13, 14)) & 1) * 2 + + ((ht2_f4b >> i4(x, 16, 20, 22, 25)) & 1) * 4 + + ((ht2_f4b >> i4(x, 27, 28, 30, 32)) & 1) * 8 + + ((ht2_f4a >> i4(x, 33, 42, 43, 45)) & 1) * 16; - return (ht2_f5c >> i5) & 1; + return (ht2_f5c >> i5) & 1; } static u64 hitag2_round(u64 *state) { - u64 x = *state; + u64 x = *state; - x = (x >> 1) - + ((((x >> 0) ^ (x >> 2) ^ (x >> 3) ^ (x >> 6) ^ (x >> 7) ^ (x >> 8) - ^ (x >> 16) ^ (x >> 22) ^ (x >> 23) ^ (x >> 26) ^ (x >> 30) - ^ (x >> 41) ^ (x >> 42) ^ (x >> 43) ^ (x >> 46) ^ (x >> 47)) - & 1) << 47); + x = (x >> 1) + + ((((x >> 0) ^ (x >> 2) ^ (x >> 3) ^ (x >> 6) ^ (x >> 7) ^ (x >> 8) + ^ (x >> 16) ^ (x >> 22) ^ (x >> 23) ^ (x >> 26) ^ (x >> 30) + ^ (x >> 41) ^ (x >> 42) ^ (x >> 43) ^ (x >> 46) ^ (x >> 47)) + & 1) << 47); - *state = x; - return f20(x); + *state = x; + return f20(x); } static u64 hitag2_init(const u64 key, const u32 serial, const u32 IV) { - u32 i; - u64 x = ((key & 0xFFFF) << 32) + serial; - for (i = 0; i < 32; i++) { - x >>= 1; - x += (u64) (f20(x) ^ (((IV >> i) ^ (key >> (i + 16))) & 1)) << 47; - } - return x; + u32 i; + u64 x = ((key & 0xFFFF) << 32) + serial; + for (i = 0; i < 32; i++) { + x >>= 1; + x += (u64) (f20(x) ^ (((IV >> i) ^ (key >> (i + 16))) & 1)) << 47; + } + return x; } static u32 hitag2_byte(u64 *x) { - u32 i, c; + u32 i, c; - for (i = 0, c = 0; i < 8; i++) - c += (u32) hitag2_round(x) << (i ^ 7); - return c; + for (i = 0, c = 0; i < 8; i++) + c += (u32) hitag2_round(x) << (i ^ 7); + return c; } // Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK) // TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz // Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier) // T0 = TIMER_CLOCK1 / 125000 = 192 -#define T0 192 +#define T0 192 -#define SHORT_COIL() LOW(GPIO_SSC_DOUT) -#define OPEN_COIL() HIGH(GPIO_SSC_DOUT) +#define SHORT_COIL() LOW(GPIO_SSC_DOUT) +#define OPEN_COIL() HIGH(GPIO_SSC_DOUT) -#define HITAG_FRAME_LEN 20 -#define HITAG_T_STOP 36 /* T_EOF should be > 36 */ -#define HITAG_T_LOW 8 /* T_LOW should be 4..10 */ -#define HITAG_T_0_MIN 15 /* T[0] should be 18..22 */ -#define HITAG_T_1_MIN 25 /* T[1] should be 26..30 */ +#define HITAG_FRAME_LEN 20 +#define HITAG_T_STOP 36 /* T_EOF should be > 36 */ +#define HITAG_T_LOW 8 /* T_LOW should be 4..10 */ +#define HITAG_T_0_MIN 15 /* T[0] should be 18..22 */ +#define HITAG_T_1_MIN 25 /* T[1] should be 26..30 */ //#define HITAG_T_EOF 40 /* T_EOF should be > 36 */ -#define HITAG_T_EOF 80 /* T_EOF should be > 36 */ -#define HITAG_T_WAIT_1 200 /* T_wresp should be 199..206 */ -#define HITAG_T_WAIT_2 90 /* T_wresp should be 199..206 */ -#define HITAG_T_WAIT_MAX 300 /* bit more than HITAG_T_WAIT_1 + HITAG_T_WAIT_2 */ +#define HITAG_T_EOF 80 /* T_EOF should be > 36 */ +#define HITAG_T_WAIT_1 200 /* T_wresp should be 199..206 */ +#define HITAG_T_WAIT_2 90 /* T_wresp should be 199..206 */ +#define HITAG_T_WAIT_MAX 300 /* bit more than HITAG_T_WAIT_1 + HITAG_T_WAIT_2 */ -#define HITAG_T_TAG_ONE_HALF_PERIOD 10 -#define HITAG_T_TAG_TWO_HALF_PERIOD 25 -#define HITAG_T_TAG_THREE_HALF_PERIOD 41 -#define HITAG_T_TAG_FOUR_HALF_PERIOD 57 +#define HITAG_T_TAG_ONE_HALF_PERIOD 10 +#define HITAG_T_TAG_TWO_HALF_PERIOD 25 +#define HITAG_T_TAG_THREE_HALF_PERIOD 41 +#define HITAG_T_TAG_FOUR_HALF_PERIOD 57 -#define HITAG_T_TAG_HALF_PERIOD 16 -#define HITAG_T_TAG_FULL_PERIOD 32 +#define HITAG_T_TAG_HALF_PERIOD 16 +#define HITAG_T_TAG_FULL_PERIOD 32 -#define HITAG_T_TAG_CAPTURE_ONE_HALF 13 -#define HITAG_T_TAG_CAPTURE_TWO_HALF 25 -#define HITAG_T_TAG_CAPTURE_THREE_HALF 41 -#define HITAG_T_TAG_CAPTURE_FOUR_HALF 57 +#define HITAG_T_TAG_CAPTURE_ONE_HALF 13 +#define HITAG_T_TAG_CAPTURE_TWO_HALF 25 +#define HITAG_T_TAG_CAPTURE_THREE_HALF 41 +#define HITAG_T_TAG_CAPTURE_FOUR_HALF 57 #define DEBUG 0 @@ -145,793 +145,793 @@ static u32 hitag2_byte(u64 *x) { * from http://www.proxmark.org/files/Documents/125%20kHz%20-%20Hitag/HitagS.V11.pdf */ void calc_crc(unsigned char * crc, unsigned char data, unsigned char Bitcount) { - *crc ^= data; // crc = crc (exor) data - do { - if (*crc & 0x80) // if (MSB-CRC == 1) - { - *crc <<= 1; // CRC = CRC Bit-shift left - *crc ^= CRC_POLYNOM; // CRC = CRC (exor) CRC_POLYNOM - } else { - *crc <<= 1; // CRC = CRC Bit-shift left - } - } while (--Bitcount); + *crc ^= data; // crc = crc (exor) data + do { + if (*crc & 0x80) // if (MSB-CRC == 1) + { + *crc <<= 1; // CRC = CRC Bit-shift left + *crc ^= CRC_POLYNOM; // CRC = CRC (exor) CRC_POLYNOM + } else { + *crc <<= 1; // CRC = CRC Bit-shift left + } + } while (--Bitcount); } static void hitag_send_bit(int bit) { - LED_A_ON(); - // Reset clock for the next bit - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + LED_A_ON(); + // Reset clock for the next bit + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - switch (m) { - case AC2K: - if (bit == 0) { - // AC Coding --__ - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 32) {}; + switch (m) { + case AC2K: + if (bit == 0) { + // AC Coding --__ + HIGH(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * 32) {}; - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 64) {}; + LOW(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * 64) {}; - } else { - // AC coding -_-_ - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 16) {}; + } else { + // AC coding -_-_ + HIGH(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * 16) {}; - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 32) {}; + LOW(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * 32) {}; - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 48) {}; + HIGH(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * 48) {}; - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 64) {}; + LOW(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * 64) {}; - } - LED_A_OFF(); - break; - case AC4K: - if (bit == 0) { - // AC Coding --__ - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_TAG_HALF_PERIOD) {}; + } + LED_A_OFF(); + break; + case AC4K: + if (bit == 0) { + // AC Coding --__ + HIGH(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_TAG_HALF_PERIOD) {}; - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_TAG_FULL_PERIOD) {}; + LOW(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_TAG_FULL_PERIOD) {}; - } else { - // AC coding -_-_ - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 8) {}; + } else { + // AC coding -_-_ + HIGH(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * 8) {}; - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 16) {}; + LOW(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * 16) {}; - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 24) {}; + HIGH(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * 24) {}; - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 32) {}; - } - LED_A_OFF(); - break; - case MC4K: - if (bit == 0) { - // Manchester: Unloaded, then loaded |__--| - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 16) {}; + LOW(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * 32) {}; + } + LED_A_OFF(); + break; + case MC4K: + if (bit == 0) { + // Manchester: Unloaded, then loaded |__--| + LOW(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * 16) {}; - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 32) {}; + HIGH(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * 32) {}; - } else { - // Manchester: Loaded, then unloaded |--__| - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 16) {}; + } else { + // Manchester: Loaded, then unloaded |--__| + HIGH(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * 16) {}; - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 32) {}; + LOW(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * 32) {}; - } - LED_A_OFF(); - break; - case MC8K: - if (bit == 0) { - // Manchester: Unloaded, then loaded |__--| - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 8) {}; + } + LED_A_OFF(); + break; + case MC8K: + if (bit == 0) { + // Manchester: Unloaded, then loaded |__--| + LOW(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * 8) {}; - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 16) {}; + HIGH(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * 16) {}; - } else { - // Manchester: Loaded, then unloaded |--__| - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 8) {}; + } else { + // Manchester: Loaded, then unloaded |--__| + HIGH(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * 8) {}; - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 16) {}; + LOW(GPIO_SSC_DOUT); + while (AT91C_BASE_TC0->TC_CV < T0 * 16) {}; - } - LED_A_OFF(); - break; - default: - break; - } + } + LED_A_OFF(); + break; + default: + break; + } } static void hitag_send_frame(const byte_t* frame, size_t frame_len) { // Send start of frame - for (size_t i = 0; i < sof_bits; i++) { - hitag_send_bit(1); - } + for (size_t i = 0; i < sof_bits; i++) { + hitag_send_bit(1); + } // Send the content of the frame - for (size_t i = 0; i < frame_len; i++) { - hitag_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1); - } + for (size_t i = 0; i < frame_len; i++) { + hitag_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1); + } // Drop the modulation - LOW(GPIO_SSC_DOUT); + LOW(GPIO_SSC_DOUT); } static void hitag_reader_send_bit(int bit) { //Dbprintf("BIT: %d",bit); - LED_A_ON(); + LED_A_ON(); // Reset clock for the next bit - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; // Binary puls length modulation (BPLM) is used to encode the data stream // This means that a transmission of a one takes longer than that of a zero // Enable modulation, which means, drop the the field - HIGH(GPIO_SSC_DOUT); - if (test == 1) { - // Wait for 4-10 times the carrier period - while (AT91C_BASE_TC0->TC_CV < T0 * 6) {}; + HIGH(GPIO_SSC_DOUT); + if (test == 1) { + // Wait for 4-10 times the carrier period + while (AT91C_BASE_TC0->TC_CV < T0 * 6) {}; - // SpinDelayUs(8*8); + // SpinDelayUs(8*8); - // Disable modulation, just activates the field again - LOW(GPIO_SSC_DOUT); + // Disable modulation, just activates the field again + LOW(GPIO_SSC_DOUT); - if (bit == 0) { - // Zero bit: |_-| - while (AT91C_BASE_TC0->TC_CV < T0 * 11) {}; + if (bit == 0) { + // Zero bit: |_-| + while (AT91C_BASE_TC0->TC_CV < T0 * 11) {}; - // SpinDelayUs(16*8); - } else { - // One bit: |_--| - while (AT91C_BASE_TC0->TC_CV < T0 * 14) {}; + // SpinDelayUs(16*8); + } else { + // One bit: |_--| + while (AT91C_BASE_TC0->TC_CV < T0 * 14) {}; - // SpinDelayUs(22*8); - } - } else { - // Wait for 4-10 times the carrier period - while (AT91C_BASE_TC0->TC_CV < T0 * 6) {}; + // SpinDelayUs(22*8); + } + } else { + // Wait for 4-10 times the carrier period + while (AT91C_BASE_TC0->TC_CV < T0 * 6) {}; - // SpinDelayUs(8*8); + // SpinDelayUs(8*8); - // Disable modulation, just activates the field again - LOW(GPIO_SSC_DOUT); + // Disable modulation, just activates the field again + LOW(GPIO_SSC_DOUT); - if (bit == 0) { - // Zero bit: |_-| - while (AT91C_BASE_TC0->TC_CV < T0 * 22) {}; + if (bit == 0) { + // Zero bit: |_-| + while (AT91C_BASE_TC0->TC_CV < T0 * 22) {}; - // SpinDelayUs(16*8); - } else { - // One bit: |_--| - while (AT91C_BASE_TC0->TC_CV < T0 * 28) {}; + // SpinDelayUs(16*8); + } else { + // One bit: |_--| + while (AT91C_BASE_TC0->TC_CV < T0 * 28) {}; - // SpinDelayUs(22*8); - } - } + // SpinDelayUs(22*8); + } + } - LED_A_OFF(); + LED_A_OFF(); } static void hitag_reader_send_frame(const byte_t* frame, size_t frame_len) { // Send the content of the frame - for (size_t i = 0; i < frame_len; i++) { - if (frame[0] == 0xf8) { - //Dbprintf("BIT: %d",(frame[i / 8] >> (7 - (i % 8))) & 1); - } - hitag_reader_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1); - } + for (size_t i = 0; i < frame_len; i++) { + if (frame[0] == 0xf8) { + //Dbprintf("BIT: %d",(frame[i / 8] >> (7 - (i % 8))) & 1); + } + hitag_reader_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1); + } // Send EOF - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; // Enable modulation, which means, drop the the field - HIGH(GPIO_SSC_DOUT); + HIGH(GPIO_SSC_DOUT); // Wait for 4-10 times the carrier period - while (AT91C_BASE_TC0->TC_CV < T0 * 6) {}; + while (AT91C_BASE_TC0->TC_CV < T0 * 6) {}; // Disable modulation, just activates the field again - LOW(GPIO_SSC_DOUT); + LOW(GPIO_SSC_DOUT); } /* * to check if the right uid was selected */ static int check_select(byte_t* rx, uint32_t uid) { - unsigned char resp[48]; - int i; - uint32_t ans = 0x0; - for (i = 0; i < 48; i++) - resp[i] = (rx[i / 8] >> (7 - (i % 8))) & 0x1; - for (i = 0; i < 32; i++) - ans += resp[5 + i] << (31 - i); - /*if (rx[0] == 0x01 && rx[1] == 0x15 && rx[2] == 0xc1 && rx[3] == 0x14 - && rx[4] == 0x65 && rx[5] == 0x38) - Dbprintf("got uid %X", ans);*/ - temp_uid = ans; - if (ans == tag.uid) - return 1; - return 0; + unsigned char resp[48]; + int i; + uint32_t ans = 0x0; + for (i = 0; i < 48; i++) + resp[i] = (rx[i / 8] >> (7 - (i % 8))) & 0x1; + for (i = 0; i < 32; i++) + ans += resp[5 + i] << (31 - i); + /*if (rx[0] == 0x01 && rx[1] == 0x15 && rx[2] == 0xc1 && rx[3] == 0x14 + && rx[4] == 0x65 && rx[5] == 0x38) + Dbprintf("got uid %X", ans);*/ + temp_uid = ans; + if (ans == tag.uid) + return 1; + return 0; } /* * handles all commands from a reader */ static void hitagS_handle_reader_command(byte_t* rx, const size_t rxlen, - byte_t* tx, size_t* txlen) { - byte_t rx_air[HITAG_FRAME_LEN]; - byte_t page; - int i; - u64 state; - unsigned char crc; + byte_t* tx, size_t* txlen) { + byte_t rx_air[HITAG_FRAME_LEN]; + byte_t page; + int i; + u64 state; + unsigned char crc; // Copy the (original) received frame how it is send over the air - memcpy(rx_air, rx, nbytes(rxlen)); + memcpy(rx_air, rx, nbytes(rxlen)); // Reset the transmission frame length - *txlen = 0; + *txlen = 0; // Try to find out which command was send by selecting on length (in bits) - switch (rxlen) { - case 5: { - //UID request with a selected response protocol mode - tag.pstate = HT_READY; - tag.tstate = HT_NO_OP; - if ((rx[0] & 0xf0) == 0x30) { - tag.mode = HT_STANDARD; - sof_bits = 1; - m = AC2K; - } - if ((rx[0] & 0xf0) == 0xc0) { - tag.mode = HT_ADVANCED; - sof_bits = 3; - m = AC2K; - } + switch (rxlen) { + case 5: { + //UID request with a selected response protocol mode + tag.pstate = HT_READY; + tag.tstate = HT_NO_OP; + if ((rx[0] & 0xf0) == 0x30) { + tag.mode = HT_STANDARD; + sof_bits = 1; + m = AC2K; + } + if ((rx[0] & 0xf0) == 0xc0) { + tag.mode = HT_ADVANCED; + sof_bits = 3; + m = AC2K; + } - if ((rx[0] & 0xf0) == 0xd0) { - tag.mode = HT_FAST_ADVANCED; - sof_bits = 3; - m = AC4K; - } - //send uid as a response - *txlen = 32; - for (i = 0; i < 4; i++) - tx[i] = (tag.uid >> (24 - (i * 8))) & 0xff; - } - break; - case 45: { - //select command from reader received - if (check_select(rx, tag.uid) == 1) { - //if the right tag was selected - *txlen = 32; - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + if ((rx[0] & 0xf0) == 0xd0) { + tag.mode = HT_FAST_ADVANCED; + sof_bits = 3; + m = AC4K; + } + //send uid as a response + *txlen = 32; + for (i = 0; i < 4; i++) + tx[i] = (tag.uid >> (24 - (i * 8))) & 0xff; + } + break; + case 45: { + //select command from reader received + if (check_select(rx, tag.uid) == 1) { + //if the right tag was selected + *txlen = 32; + switch (tag.mode) { + case HT_STANDARD: + sof_bits = 1; + m = MC4K; + break; + case HT_ADVANCED: + sof_bits = 6; + m = MC4K; + break; + case HT_FAST_ADVANCED: + sof_bits = 6; + m = MC8K; + break; + default: + break; + } - //send configuration - for (i = 0; i < 4; i++) - tx[i] = (tag.pages[0][1] >> (i * 8)) & 0xff; - tx[3] = 0xff; - if (tag.mode != HT_STANDARD) { - *txlen = 40; - crc = CRC_PRESET; - for (i = 0; i < 4; i++) - calc_crc(&crc, tx[i], 8); - tx[4] = crc; - } - } - } - break; - case 64: { - //challenge message received - Dbprintf("Challenge for UID: %X", temp_uid); - temp2++; - *txlen = 32; - state = hitag2_init(rev64(tag.key), rev32(tag.pages[0][0]), - rev32(((rx[3] << 24) + (rx[2] << 16) + (rx[1] << 8) + rx[0]))); - Dbprintf( - ",{0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X}", - rx[0], rx[1], rx[2], rx[3], rx[4], rx[5], rx[6], rx[7]); - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + //send configuration + for (i = 0; i < 4; i++) + tx[i] = (tag.pages[0][1] >> (i * 8)) & 0xff; + tx[3] = 0xff; + if (tag.mode != HT_STANDARD) { + *txlen = 40; + crc = CRC_PRESET; + for (i = 0; i < 4; i++) + calc_crc(&crc, tx[i], 8); + tx[4] = crc; + } + } + } + break; + case 64: { + //challenge message received + Dbprintf("Challenge for UID: %X", temp_uid); + temp2++; + *txlen = 32; + state = hitag2_init(rev64(tag.key), rev32(tag.pages[0][0]), + rev32(((rx[3] << 24) + (rx[2] << 16) + (rx[1] << 8) + rx[0]))); + Dbprintf( + ",{0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X}", + rx[0], rx[1], rx[2], rx[3], rx[4], rx[5], rx[6], rx[7]); + switch (tag.mode) { + case HT_STANDARD: + sof_bits = 1; + m = MC4K; + break; + case HT_ADVANCED: + sof_bits = 6; + m = MC4K; + break; + case HT_FAST_ADVANCED: + sof_bits = 6; + m = MC8K; + break; + default: + break; + } - for (i = 0; i < 4; i++) - hitag2_byte(&state); - //send con2,pwdh0,pwdl0,pwdl1 encrypted as a response - tx[0] = hitag2_byte(&state) ^ ((tag.pages[0][1] >> 16) & 0xff); - tx[1] = hitag2_byte(&state) ^ tag.pwdh0; - tx[2] = hitag2_byte(&state) ^ tag.pwdl0; - tx[3] = hitag2_byte(&state) ^ tag.pwdl1; - if (tag.mode != HT_STANDARD) { - //add crc8 - *txlen = 40; - crc = CRC_PRESET; - calc_crc(&crc, ((tag.pages[0][1] >> 16) & 0xff), 8); - calc_crc(&crc, tag.pwdh0, 8); - calc_crc(&crc, tag.pwdl0, 8); - calc_crc(&crc, tag.pwdl1, 8); - tx[4] = (crc ^ hitag2_byte(&state)); - } - /* - * some readers do not allow to authenticate multiple times in a row with the same tag. - * use this to change the uid between authentications. - */ + for (i = 0; i < 4; i++) + hitag2_byte(&state); + //send con2,pwdh0,pwdl0,pwdl1 encrypted as a response + tx[0] = hitag2_byte(&state) ^ ((tag.pages[0][1] >> 16) & 0xff); + tx[1] = hitag2_byte(&state) ^ tag.pwdh0; + tx[2] = hitag2_byte(&state) ^ tag.pwdl0; + tx[3] = hitag2_byte(&state) ^ tag.pwdl1; + if (tag.mode != HT_STANDARD) { + //add crc8 + *txlen = 40; + crc = CRC_PRESET; + calc_crc(&crc, ((tag.pages[0][1] >> 16) & 0xff), 8); + calc_crc(&crc, tag.pwdh0, 8); + calc_crc(&crc, tag.pwdl0, 8); + calc_crc(&crc, tag.pwdl1, 8); + tx[4] = (crc ^ hitag2_byte(&state)); + } + /* + * some readers do not allow to authenticate multiple times in a row with the same tag. + * use this to change the uid between authentications. + */ - /* - if (temp2 % 2 == 0) { - tag.uid = 0x11223344; - tag.pages[0][0] = 0x44332211; - } else { - tag.uid = 0x55667788; - tag.pages[0][0] = 0x88776655; - } - */ - } - case 40: - //data received to be written - if (tag.tstate == HT_WRITING_PAGE_DATA) { - tag.tstate = HT_NO_OP; - tag.pages[page_to_be_written / 4][page_to_be_written % 4] = (rx[0] - << 0) + (rx[1] << 8) + (rx[2] << 16) + (rx[3] << 24); - //send ack - *txlen = 2; - tx[0] = 0x40; - page_to_be_written = 0; - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } - } else if (tag.tstate == HT_WRITING_BLOCK_DATA) { - tag.pages[page_to_be_written / 4][page_to_be_written % 4] = (rx[0] - << 24) + (rx[1] << 16) + (rx[2] << 8) + rx[3]; - //send ack - *txlen = 2; - tx[0] = 0x40; - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } - page_to_be_written++; - block_data_left--; - if (block_data_left == 0) { - tag.tstate = HT_NO_OP; - page_to_be_written = 0; - } - } - break; - case 20: { - //write page, write block, read page or read block command received - if ((rx[0] & 0xf0) == 0xc0) //read page - { - //send page data - page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16); - *txlen = 32; - tx[0] = (tag.pages[page / 4][page % 4]) & 0xff; - tx[1] = (tag.pages[page / 4][page % 4] >> 8) & 0xff; - tx[2] = (tag.pages[page / 4][page % 4] >> 16) & 0xff; - tx[3] = (tag.pages[page / 4][page % 4] >> 24) & 0xff; - if (tag.LKP && page == 1) - tx[3] = 0xff; + /* + if (temp2 % 2 == 0) { + tag.uid = 0x11223344; + tag.pages[0][0] = 0x44332211; + } else { + tag.uid = 0x55667788; + tag.pages[0][0] = 0x88776655; + } + */ + } + case 40: + //data received to be written + if (tag.tstate == HT_WRITING_PAGE_DATA) { + tag.tstate = HT_NO_OP; + tag.pages[page_to_be_written / 4][page_to_be_written % 4] = (rx[0] + << 0) + (rx[1] << 8) + (rx[2] << 16) + (rx[3] << 24); + //send ack + *txlen = 2; + tx[0] = 0x40; + page_to_be_written = 0; + switch (tag.mode) { + case HT_STANDARD: + sof_bits = 1; + m = MC4K; + break; + case HT_ADVANCED: + sof_bits = 6; + m = MC4K; + break; + case HT_FAST_ADVANCED: + sof_bits = 6; + m = MC8K; + break; + default: + break; + } + } else if (tag.tstate == HT_WRITING_BLOCK_DATA) { + tag.pages[page_to_be_written / 4][page_to_be_written % 4] = (rx[0] + << 24) + (rx[1] << 16) + (rx[2] << 8) + rx[3]; + //send ack + *txlen = 2; + tx[0] = 0x40; + switch (tag.mode) { + case HT_STANDARD: + sof_bits = 1; + m = MC4K; + break; + case HT_ADVANCED: + sof_bits = 6; + m = MC4K; + break; + case HT_FAST_ADVANCED: + sof_bits = 6; + m = MC8K; + break; + default: + break; + } + page_to_be_written++; + block_data_left--; + if (block_data_left == 0) { + tag.tstate = HT_NO_OP; + page_to_be_written = 0; + } + } + break; + case 20: { + //write page, write block, read page or read block command received + if ((rx[0] & 0xf0) == 0xc0) //read page + { + //send page data + page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16); + *txlen = 32; + tx[0] = (tag.pages[page / 4][page % 4]) & 0xff; + tx[1] = (tag.pages[page / 4][page % 4] >> 8) & 0xff; + tx[2] = (tag.pages[page / 4][page % 4] >> 16) & 0xff; + tx[3] = (tag.pages[page / 4][page % 4] >> 24) & 0xff; + if (tag.LKP && page == 1) + tx[3] = 0xff; - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + switch (tag.mode) { + case HT_STANDARD: + sof_bits = 1; + m = MC4K; + break; + case HT_ADVANCED: + sof_bits = 6; + m = MC4K; + break; + case HT_FAST_ADVANCED: + sof_bits = 6; + m = MC8K; + break; + default: + break; + } - if (tag.mode != HT_STANDARD) { - //add crc8 - *txlen = 40; - crc = CRC_PRESET; - for (i = 0; i < 4; i++) - calc_crc(&crc, tx[i], 8); - tx[4] = crc; - } + if (tag.mode != HT_STANDARD) { + //add crc8 + *txlen = 40; + crc = CRC_PRESET; + for (i = 0; i < 4; i++) + calc_crc(&crc, tx[i], 8); + tx[4] = crc; + } - if (tag.LKP && (page == 2 || page == 3)) { - //if reader asks for key or password and the LKP-mark is set do not respond - sof_bits = 0; - *txlen = 0; - } - } else if ((rx[0] & 0xf0) == 0xd0) //read block - { - page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16); - *txlen = 32 * 4; - //send page,...,page+3 data - for (i = 0; i < 4; i++) { - tx[0 + i * 4] = (tag.pages[page / 4][page % 4]) & 0xff; - tx[1 + i * 4] = (tag.pages[page / 4][page % 4] >> 8) & 0xff; - tx[2 + i * 4] = (tag.pages[page / 4][page % 4] >> 16) & 0xff; - tx[3 + i * 4] = (tag.pages[page / 4][page % 4] >> 24) & 0xff; - page++; - } + if (tag.LKP && (page == 2 || page == 3)) { + //if reader asks for key or password and the LKP-mark is set do not respond + sof_bits = 0; + *txlen = 0; + } + } else if ((rx[0] & 0xf0) == 0xd0) //read block + { + page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16); + *txlen = 32 * 4; + //send page,...,page+3 data + for (i = 0; i < 4; i++) { + tx[0 + i * 4] = (tag.pages[page / 4][page % 4]) & 0xff; + tx[1 + i * 4] = (tag.pages[page / 4][page % 4] >> 8) & 0xff; + tx[2 + i * 4] = (tag.pages[page / 4][page % 4] >> 16) & 0xff; + tx[3 + i * 4] = (tag.pages[page / 4][page % 4] >> 24) & 0xff; + page++; + } - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + switch (tag.mode) { + case HT_STANDARD: + sof_bits = 1; + m = MC4K; + break; + case HT_ADVANCED: + sof_bits = 6; + m = MC4K; + break; + case HT_FAST_ADVANCED: + sof_bits = 6; + m = MC8K; + break; + default: + break; + } - if (tag.mode != HT_STANDARD) { - //add crc8 - *txlen = 32 * 4 + 8; - crc = CRC_PRESET; - for (i = 0; i < 16; i++) - calc_crc(&crc, tx[i], 8); - tx[16] = crc; - } + if (tag.mode != HT_STANDARD) { + //add crc8 + *txlen = 32 * 4 + 8; + crc = CRC_PRESET; + for (i = 0; i < 16; i++) + calc_crc(&crc, tx[i], 8); + tx[16] = crc; + } - if ((page - 4) % 4 != 0 || (tag.LKP && (page - 4) == 0)) { - sof_bits = 0; - *txlen = 0; - } - } else if ((rx[0] & 0xf0) == 0x80) //write page - { - page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16); + if ((page - 4) % 4 != 0 || (tag.LKP && (page - 4) == 0)) { + sof_bits = 0; + *txlen = 0; + } + } else if ((rx[0] & 0xf0) == 0x80) //write page + { + page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16); - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } - if ((tag.LCON && page == 1) - || (tag.LKP && (page == 2 || page == 3))) { - //deny - *txlen = 0; - } else { - //allow - *txlen = 2; - tx[0] = 0x40; - page_to_be_written = page; - tag.tstate = HT_WRITING_PAGE_DATA; - } + switch (tag.mode) { + case HT_STANDARD: + sof_bits = 1; + m = MC4K; + break; + case HT_ADVANCED: + sof_bits = 6; + m = MC4K; + break; + case HT_FAST_ADVANCED: + sof_bits = 6; + m = MC8K; + break; + default: + break; + } + if ((tag.LCON && page == 1) + || (tag.LKP && (page == 2 || page == 3))) { + //deny + *txlen = 0; + } else { + //allow + *txlen = 2; + tx[0] = 0x40; + page_to_be_written = page; + tag.tstate = HT_WRITING_PAGE_DATA; + } - } else if ((rx[0] & 0xf0) == 0x90) //write block - { - page = ((rx[0] & 0x0f) * 6) + ((rx[1] & 0xf0) / 16); - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } - if (page % 4 != 0 || page == 0) { - //deny - *txlen = 0; - } else { - //allow - *txlen = 2; - tx[0] = 0x40; - page_to_be_written = page; - block_data_left = 4; - tag.tstate = HT_WRITING_BLOCK_DATA; - } - } - } - break; - default: + } else if ((rx[0] & 0xf0) == 0x90) //write block + { + page = ((rx[0] & 0x0f) * 6) + ((rx[1] & 0xf0) / 16); + switch (tag.mode) { + case HT_STANDARD: + sof_bits = 1; + m = MC4K; + break; + case HT_ADVANCED: + sof_bits = 6; + m = MC4K; + break; + case HT_FAST_ADVANCED: + sof_bits = 6; + m = MC8K; + break; + default: + break; + } + if (page % 4 != 0 || page == 0) { + //deny + *txlen = 0; + } else { + //allow + *txlen = 2; + tx[0] = 0x40; + page_to_be_written = page; + block_data_left = 4; + tag.tstate = HT_WRITING_BLOCK_DATA; + } + } + } + break; + default: - break; - } + break; + } } /* * to autenticate to a tag with the given key or challenge */ static int hitagS_handle_tag_auth(hitag_function htf,uint64_t key, uint64_t NrAr, byte_t* rx, const size_t rxlen, byte_t* tx, - size_t* txlen) { - byte_t rx_air[HITAG_FRAME_LEN]; - int response_bit[200]; - int i, j, z, k; - unsigned char mask = 1; - unsigned char uid[32]; - byte_t uid1 = 0x00, uid2 = 0x00, uid3 = 0x00, uid4 = 0x00; - unsigned char crc; - u64 state; - byte_t auth_ks[4]; - byte_t conf_pages[3]; - memcpy(rx_air, rx, nbytes(rxlen)); - *txlen = 0; + size_t* txlen) { + byte_t rx_air[HITAG_FRAME_LEN]; + int response_bit[200]; + int i, j, z, k; + unsigned char mask = 1; + unsigned char uid[32]; + byte_t uid1 = 0x00, uid2 = 0x00, uid3 = 0x00, uid4 = 0x00; + unsigned char crc; + u64 state; + byte_t auth_ks[4]; + byte_t conf_pages[3]; + memcpy(rx_air, rx, nbytes(rxlen)); + *txlen = 0; - if (tag.pstate == HT_READY && rxlen >= 67) { - //received uid - if(end==true) { - Dbprintf("authentication failed!"); - return -1; - } - z = 0; - for (i = 0; i < 10; i++) { - for (j = 0; j < 8; j++) { - response_bit[z] = 0; - if ((rx[i] & ((mask << 7) >> j)) != 0) - response_bit[z] = 1; - z++; - } - } - k = 0; - for (i = 5; i < z; i += 2) { - uid[k] = response_bit[i]; - k++; - if (k > 31) - break; - } - uid1 = (uid[0] << 7) | (uid[1] << 6) | (uid[2] << 5) | (uid[3] << 4) - | (uid[4] << 3) | (uid[5] << 2) | (uid[6] << 1) | uid[7]; - uid2 = (uid[8] << 7) | (uid[9] << 6) | (uid[10] << 5) | (uid[11] << 4) - | (uid[12] << 3) | (uid[13] << 2) | (uid[14] << 1) | uid[15]; - uid3 = (uid[16] << 7) | (uid[17] << 6) | (uid[18] << 5) | (uid[19] << 4) - | (uid[20] << 3) | (uid[21] << 2) | (uid[22] << 1) | uid[23]; - uid4 = (uid[24] << 7) | (uid[25] << 6) | (uid[26] << 5) | (uid[27] << 4) - | (uid[28] << 3) | (uid[29] << 2) | (uid[30] << 1) | uid[31]; - if (DEBUG) - Dbprintf("UID: %02X %02X %02X %02X", uid1, uid2, uid3, uid4); - tag.uid = (uid4 << 24 | uid3 << 16 | uid2 << 8 | uid1); + if (tag.pstate == HT_READY && rxlen >= 67) { + //received uid + if(end==true) { + Dbprintf("authentication failed!"); + return -1; + } + z = 0; + for (i = 0; i < 10; i++) { + for (j = 0; j < 8; j++) { + response_bit[z] = 0; + if ((rx[i] & ((mask << 7) >> j)) != 0) + response_bit[z] = 1; + z++; + } + } + k = 0; + for (i = 5; i < z; i += 2) { + uid[k] = response_bit[i]; + k++; + if (k > 31) + break; + } + uid1 = (uid[0] << 7) | (uid[1] << 6) | (uid[2] << 5) | (uid[3] << 4) + | (uid[4] << 3) | (uid[5] << 2) | (uid[6] << 1) | uid[7]; + uid2 = (uid[8] << 7) | (uid[9] << 6) | (uid[10] << 5) | (uid[11] << 4) + | (uid[12] << 3) | (uid[13] << 2) | (uid[14] << 1) | uid[15]; + uid3 = (uid[16] << 7) | (uid[17] << 6) | (uid[18] << 5) | (uid[19] << 4) + | (uid[20] << 3) | (uid[21] << 2) | (uid[22] << 1) | uid[23]; + uid4 = (uid[24] << 7) | (uid[25] << 6) | (uid[26] << 5) | (uid[27] << 4) + | (uid[28] << 3) | (uid[29] << 2) | (uid[30] << 1) | uid[31]; + if (DEBUG) + Dbprintf("UID: %02X %02X %02X %02X", uid1, uid2, uid3, uid4); + tag.uid = (uid4 << 24 | uid3 << 16 | uid2 << 8 | uid1); - //select uid - *txlen = 45; - crc = CRC_PRESET; - calc_crc(&crc, 0x00, 5); - calc_crc(&crc, uid1, 8); - calc_crc(&crc, uid2, 8); - calc_crc(&crc, uid3, 8); - calc_crc(&crc, uid4, 8); - for (i = 0; i < 100; i++) { - response_bit[i] = 0; - } - for (i = 0; i < 5; i++) { - response_bit[i] = 0; - } - for (i = 5; i < 37; i++) { - response_bit[i] = uid[i - 5]; - } - for (j = 0; j < 8; j++) { - response_bit[i] = 0; - if ((crc & ((mask << 7) >> j)) != 0) - response_bit[i] = 1; - i++; - } - k = 0; - for (i = 0; i < 6; i++) { - tx[i] = (response_bit[k] << 7) | (response_bit[k + 1] << 6) - | (response_bit[k + 2] << 5) | (response_bit[k + 3] << 4) - | (response_bit[k + 4] << 3) | (response_bit[k + 5] << 2) - | (response_bit[k + 6] << 1) | response_bit[k + 7]; - k += 8; - } - tag.pstate = HT_INIT; - } else if (tag.pstate == HT_INIT && rxlen == 44) { - // received configuration after select command - z = 0; - for (i = 0; i < 6; i++) { - for (j = 0; j < 8; j++) { - response_bit[z] = 0; - if ((rx[i] & ((mask << 7) >> j)) != 0) - response_bit[z] = 1; - z++; - } - } - conf_pages[0] = ((response_bit[4] << 7) | (response_bit[5] << 6) - | (response_bit[6] << 5) | (response_bit[7] << 4) - | (response_bit[8] << 3) | (response_bit[9] << 2) - | (response_bit[10] << 1) | response_bit[11]); - //check wich memorysize this tag has - if (response_bit[10] == 0 && response_bit[11] == 0) - tag.max_page = 32 / 32; - if (response_bit[10] == 0 && response_bit[11] == 1) - tag.max_page = 256 / 32; - if (response_bit[10] == 1 && response_bit[11] == 0) - tag.max_page = 2048 / 32; - conf_pages[1] = ((response_bit[12] << 7) | (response_bit[13] << 6) - | (response_bit[14] << 5) | (response_bit[15] << 4) - | (response_bit[16] << 3) | (response_bit[17] << 2) - | (response_bit[18] << 1) | response_bit[19]); - tag.auth = response_bit[12]; - tag.TTFC = response_bit[13]; - //tag.TTFDR in response_bit[14] and response_bit[15] - //tag.TTFM in response_bit[16] and response_bit[17] - tag.LCON = response_bit[18]; - tag.LKP = response_bit[19]; - conf_pages[2] = ((response_bit[20] << 7) | (response_bit[21] << 6) - | (response_bit[22] << 5) | (response_bit[23] << 4) - | (response_bit[24] << 3) | (response_bit[25] << 2) - | (response_bit[26] << 1) | response_bit[27]); - tag.LCK7 = response_bit[20]; - tag.LCK6 = response_bit[21]; - tag.LCK5 = response_bit[22]; - tag.LCK4 = response_bit[23]; - tag.LCK3 = response_bit[24]; - tag.LCK2 = response_bit[25]; - tag.LCK1 = response_bit[26]; - tag.LCK0 = response_bit[27]; + //select uid + *txlen = 45; + crc = CRC_PRESET; + calc_crc(&crc, 0x00, 5); + calc_crc(&crc, uid1, 8); + calc_crc(&crc, uid2, 8); + calc_crc(&crc, uid3, 8); + calc_crc(&crc, uid4, 8); + for (i = 0; i < 100; i++) { + response_bit[i] = 0; + } + for (i = 0; i < 5; i++) { + response_bit[i] = 0; + } + for (i = 5; i < 37; i++) { + response_bit[i] = uid[i - 5]; + } + for (j = 0; j < 8; j++) { + response_bit[i] = 0; + if ((crc & ((mask << 7) >> j)) != 0) + response_bit[i] = 1; + i++; + } + k = 0; + for (i = 0; i < 6; i++) { + tx[i] = (response_bit[k] << 7) | (response_bit[k + 1] << 6) + | (response_bit[k + 2] << 5) | (response_bit[k + 3] << 4) + | (response_bit[k + 4] << 3) | (response_bit[k + 5] << 2) + | (response_bit[k + 6] << 1) | response_bit[k + 7]; + k += 8; + } + tag.pstate = HT_INIT; + } else if (tag.pstate == HT_INIT && rxlen == 44) { + // received configuration after select command + z = 0; + for (i = 0; i < 6; i++) { + for (j = 0; j < 8; j++) { + response_bit[z] = 0; + if ((rx[i] & ((mask << 7) >> j)) != 0) + response_bit[z] = 1; + z++; + } + } + conf_pages[0] = ((response_bit[4] << 7) | (response_bit[5] << 6) + | (response_bit[6] << 5) | (response_bit[7] << 4) + | (response_bit[8] << 3) | (response_bit[9] << 2) + | (response_bit[10] << 1) | response_bit[11]); + //check wich memorysize this tag has + if (response_bit[10] == 0 && response_bit[11] == 0) + tag.max_page = 32 / 32; + if (response_bit[10] == 0 && response_bit[11] == 1) + tag.max_page = 256 / 32; + if (response_bit[10] == 1 && response_bit[11] == 0) + tag.max_page = 2048 / 32; + conf_pages[1] = ((response_bit[12] << 7) | (response_bit[13] << 6) + | (response_bit[14] << 5) | (response_bit[15] << 4) + | (response_bit[16] << 3) | (response_bit[17] << 2) + | (response_bit[18] << 1) | response_bit[19]); + tag.auth = response_bit[12]; + tag.TTFC = response_bit[13]; + //tag.TTFDR in response_bit[14] and response_bit[15] + //tag.TTFM in response_bit[16] and response_bit[17] + tag.LCON = response_bit[18]; + tag.LKP = response_bit[19]; + conf_pages[2] = ((response_bit[20] << 7) | (response_bit[21] << 6) + | (response_bit[22] << 5) | (response_bit[23] << 4) + | (response_bit[24] << 3) | (response_bit[25] << 2) + | (response_bit[26] << 1) | response_bit[27]); + tag.LCK7 = response_bit[20]; + tag.LCK6 = response_bit[21]; + tag.LCK5 = response_bit[22]; + tag.LCK4 = response_bit[23]; + tag.LCK3 = response_bit[24]; + tag.LCK2 = response_bit[25]; + tag.LCK1 = response_bit[26]; + tag.LCK0 = response_bit[27]; - if (DEBUG) - Dbprintf("conf0: %02X conf1: %02X conf2: %02X", conf_pages[0], - conf_pages[1], conf_pages[2]); - if (tag.auth == 1) { - //if the tag is in authentication mode try the key or challenge - *txlen = 64; - if(end!=true){ - if(htf==02||htf==04){ //RHTS_KEY //WHTS_KEY - state = hitag2_init(rev64(key), rev32(tag.uid), - rev32(rnd)); + if (DEBUG) + Dbprintf("conf0: %02X conf1: %02X conf2: %02X", conf_pages[0], + conf_pages[1], conf_pages[2]); + if (tag.auth == 1) { + //if the tag is in authentication mode try the key or challenge + *txlen = 64; + if(end!=true){ + if(htf==02||htf==04){ //RHTS_KEY //WHTS_KEY + state = hitag2_init(rev64(key), rev32(tag.uid), + rev32(rnd)); - for (i = 0; i < 4; i++) { - auth_ks[i] = hitag2_byte(&state) ^ 0xff; - } - *txlen = 64; - tx[0] = rnd & 0xff; - tx[1] = (rnd >> 8) & 0xff; - tx[2] = (rnd >> 16) & 0xff; - tx[3] = (rnd >> 24) & 0xff; + for (i = 0; i < 4; i++) { + auth_ks[i] = hitag2_byte(&state) ^ 0xff; + } + *txlen = 64; + tx[0] = rnd & 0xff; + tx[1] = (rnd >> 8) & 0xff; + tx[2] = (rnd >> 16) & 0xff; + tx[3] = (rnd >> 24) & 0xff; - tx[4] = auth_ks[0]; - tx[5] = auth_ks[1]; - tx[6] = auth_ks[2]; - tx[7] = auth_ks[3]; - if (DEBUG) - Dbprintf("%02X %02X %02X %02X %02X %02X %02X %02X", tx[0], - tx[1], tx[2], tx[3], tx[4], tx[5], tx[6], tx[7]); - } else if(htf==01 || htf==03) { //RHTS_CHALLENGE //WHTS_CHALLENGE - for (i = 0; i < 8; i++) - tx[i]=((NrAr>>(56-(i*8)))&0xff); - } - end=true; - tag.pstate = HT_AUTHENTICATE; - } else { - Dbprintf("authentication failed!"); - return -1; - } - } else if (tag.auth == 0) { - tag.pstate = HT_SELECTED; - } + tx[4] = auth_ks[0]; + tx[5] = auth_ks[1]; + tx[6] = auth_ks[2]; + tx[7] = auth_ks[3]; + if (DEBUG) + Dbprintf("%02X %02X %02X %02X %02X %02X %02X %02X", tx[0], + tx[1], tx[2], tx[3], tx[4], tx[5], tx[6], tx[7]); + } else if(htf==01 || htf==03) { //RHTS_CHALLENGE //WHTS_CHALLENGE + for (i = 0; i < 8; i++) + tx[i]=((NrAr>>(56-(i*8)))&0xff); + } + end=true; + tag.pstate = HT_AUTHENTICATE; + } else { + Dbprintf("authentication failed!"); + return -1; + } + } else if (tag.auth == 0) { + tag.pstate = HT_SELECTED; + } - } else if (tag.pstate == HT_AUTHENTICATE && rxlen == 44) { - //encrypted con2,password received. - crc = CRC_PRESET; - calc_crc(&crc, 0x80, 1); - calc_crc(&crc, ((rx[0] & 0x0f) * 16 + ((rx[1] & 0xf0) / 16)), 8); - calc_crc(&crc, ((rx[1] & 0x0f) * 16 + ((rx[2] & 0xf0) / 16)), 8); - calc_crc(&crc, ((rx[2] & 0x0f) * 16 + ((rx[3] & 0xf0) / 16)), 8); - calc_crc(&crc, ((rx[3] & 0x0f) * 16 + ((rx[4] & 0xf0) / 16)), 8); - if (DEBUG) { - Dbprintf("UID:::%X", tag.uid); - Dbprintf("RND:::%X", rnd); - } + } else if (tag.pstate == HT_AUTHENTICATE && rxlen == 44) { + //encrypted con2,password received. + crc = CRC_PRESET; + calc_crc(&crc, 0x80, 1); + calc_crc(&crc, ((rx[0] & 0x0f) * 16 + ((rx[1] & 0xf0) / 16)), 8); + calc_crc(&crc, ((rx[1] & 0x0f) * 16 + ((rx[2] & 0xf0) / 16)), 8); + calc_crc(&crc, ((rx[2] & 0x0f) * 16 + ((rx[3] & 0xf0) / 16)), 8); + calc_crc(&crc, ((rx[3] & 0x0f) * 16 + ((rx[4] & 0xf0) / 16)), 8); + if (DEBUG) { + Dbprintf("UID:::%X", tag.uid); + Dbprintf("RND:::%X", rnd); + } - //decrypt password - pwdh0=0; - pwdl0=0; - pwdl1=0; - if(htf==02 || htf==04){ //RHTS_KEY //WHTS_KEY - { - state = hitag2_init(rev64(key), rev32(tag.uid), rev32(rnd)); - for (i = 0; i < 5; i++) - hitag2_byte(&state); - pwdh0 = ((rx[1] & 0x0f) * 16 + ((rx[2] & 0xf0) / 16)) - ^ hitag2_byte(&state); - pwdl0 = ((rx[2] & 0x0f) * 16 + ((rx[3] & 0xf0) / 16)) - ^ hitag2_byte(&state); - pwdl1 = ((rx[3] & 0x0f) * 16 + ((rx[4] & 0xf0) / 16)) - ^ hitag2_byte(&state); - } + //decrypt password + pwdh0=0; + pwdl0=0; + pwdl1=0; + if(htf==02 || htf==04){ //RHTS_KEY //WHTS_KEY + { + state = hitag2_init(rev64(key), rev32(tag.uid), rev32(rnd)); + for (i = 0; i < 5; i++) + hitag2_byte(&state); + pwdh0 = ((rx[1] & 0x0f) * 16 + ((rx[2] & 0xf0) / 16)) + ^ hitag2_byte(&state); + pwdl0 = ((rx[2] & 0x0f) * 16 + ((rx[3] & 0xf0) / 16)) + ^ hitag2_byte(&state); + pwdl1 = ((rx[3] & 0x0f) * 16 + ((rx[4] & 0xf0) / 16)) + ^ hitag2_byte(&state); + } - if (DEBUG) - Dbprintf("pwdh0 %02X pwdl0 %02X pwdl1 %02X", pwdh0, pwdl0, pwdl1); + if (DEBUG) + Dbprintf("pwdh0 %02X pwdl0 %02X pwdl1 %02X", pwdh0, pwdl0, pwdl1); - //Dbprintf("%X %02X", rnd, ((rx[4] & 0x0f) * 16) + ((rx[5] & 0xf0) / 16)); - //rnd += 1; - } - tag.pstate = HT_SELECTED; //tag is now ready for read/write commands - } - return 0; + //Dbprintf("%X %02X", rnd, ((rx[4] & 0x0f) * 16) + ((rx[5] & 0xf0) / 16)); + //rnd += 1; + } + tag.pstate = HT_SELECTED; //tag is now ready for read/write commands + } + return 0; } @@ -939,223 +939,223 @@ static int hitagS_handle_tag_auth(hitag_function htf,uint64_t key, uint64_t NrAr * Emulates a Hitag S Tag with the given data from the .hts file */ void SimulateHitagSTag(bool tag_mem_supplied, byte_t* data) { - int frame_count; - int response; - int overflow; - int i, j; - byte_t rx[HITAG_FRAME_LEN]; - size_t rxlen = 0; - //bool bQuitTraceFull = false; - bQuiet = false; - byte_t txbuf[HITAG_FRAME_LEN]; - byte_t* tx = txbuf; - size_t txlen = 0; - // free eventually allocated BigBuf memory - BigBuf_free(); BigBuf_Clear_ext(false); + int frame_count; + int response; + int overflow; + int i, j; + byte_t rx[HITAG_FRAME_LEN]; + size_t rxlen = 0; + //bool bQuitTraceFull = false; + bQuiet = false; + byte_t txbuf[HITAG_FRAME_LEN]; + byte_t* tx = txbuf; + size_t txlen = 0; + // free eventually allocated BigBuf memory + BigBuf_free(); BigBuf_Clear_ext(false); - // Clean up trace and prepare it for storing frames - set_tracing(true); - clear_trace(); + // Clean up trace and prepare it for storing frames + set_tracing(true); + clear_trace(); - DbpString("Starting HitagS simulation"); - LED_D_ON(); + DbpString("Starting HitagS simulation"); + LED_D_ON(); - tag.pstate = HT_READY; - tag.tstate = HT_NO_OP; - for (i = 0; i < 16; i++) - for (j = 0; j < 4; j++) - tag.pages[i][j] = 0x0; - //read tag data into memory - if (tag_mem_supplied) { - DbpString("Loading hitagS memory..."); - memcpy((byte_t*)tag.pages,data,4*64); - } - tag.uid=(uint32_t)tag.pages[0]; - Dbprintf("Hitag S simulation started"); - tag.key=(intptr_t)tag.pages[3]; - tag.key<<=16; - tag.key+=((tag.pages[2][0])<<8)+tag.pages[2][1]; - tag.pwdl0=tag.pages[2][3]; - tag.pwdl1=tag.pages[2][2]; - tag.pwdh0=tag.pages[1][0]; - //con0 - tag.max_page=64; - if((tag.pages[1][3]&0x2)==0 && (tag.pages[1][3]&0x1)==1) - tag.max_page=8; - if((tag.pages[1][3]&0x2)==0 && (tag.pages[1][3]&0x1)==0) - tag.max_page=0; - //con1 - tag.auth=0; - if((tag.pages[1][2]&0x80) == 0x80) - tag.auth=1; - tag.LCON=0; - if((tag.pages[1][2]&0x2) == 0x02) - tag.LCON=1; - tag.LKP=0; - if((tag.pages[1][2]&0x1) == 0x01) - tag.LKP=1; - //con2 - //0=read write 1=read only - tag.LCK7=0; - if((tag.pages[1][1]&0x80) == 0x80) - tag.LCK7=1; - tag.LCK6=0; - if((tag.pages[1][1]&0x40) == 0x040) - tag.LCK6=1; - tag.LCK5=0; - if((tag.pages[1][1]&0x20) == 0x20) - tag.LCK5=1; - tag.LCK4=0; - if((tag.pages[1][1]&0x10) == 0x10) - tag.LCK4=1; - tag.LCK3=0; - if((tag.pages[1][1]&0x8) == 0x08) - tag.LCK3=1; - tag.LCK2=0; - if((tag.pages[1][1]&0x4) == 0x04) - tag.LCK2=1; - tag.LCK1=0; - if((tag.pages[1][1]&0x2) == 0x02) - tag.LCK1=1; - tag.LCK0=0; - if((tag.pages[1][1]&0x1) == 0x01) - tag.LCK0=1; + tag.pstate = HT_READY; + tag.tstate = HT_NO_OP; + for (i = 0; i < 16; i++) + for (j = 0; j < 4; j++) + tag.pages[i][j] = 0x0; + //read tag data into memory + if (tag_mem_supplied) { + DbpString("Loading hitagS memory..."); + memcpy((byte_t*)tag.pages,data,4*64); + } + tag.uid=(uint32_t)tag.pages[0]; + Dbprintf("Hitag S simulation started"); + tag.key=(intptr_t)tag.pages[3]; + tag.key<<=16; + tag.key+=((tag.pages[2][0])<<8)+tag.pages[2][1]; + tag.pwdl0=tag.pages[2][3]; + tag.pwdl1=tag.pages[2][2]; + tag.pwdh0=tag.pages[1][0]; + //con0 + tag.max_page=64; + if((tag.pages[1][3]&0x2)==0 && (tag.pages[1][3]&0x1)==1) + tag.max_page=8; + if((tag.pages[1][3]&0x2)==0 && (tag.pages[1][3]&0x1)==0) + tag.max_page=0; + //con1 + tag.auth=0; + if((tag.pages[1][2]&0x80) == 0x80) + tag.auth=1; + tag.LCON=0; + if((tag.pages[1][2]&0x2) == 0x02) + tag.LCON=1; + tag.LKP=0; + if((tag.pages[1][2]&0x1) == 0x01) + tag.LKP=1; + //con2 + //0=read write 1=read only + tag.LCK7=0; + if((tag.pages[1][1]&0x80) == 0x80) + tag.LCK7=1; + tag.LCK6=0; + if((tag.pages[1][1]&0x40) == 0x040) + tag.LCK6=1; + tag.LCK5=0; + if((tag.pages[1][1]&0x20) == 0x20) + tag.LCK5=1; + tag.LCK4=0; + if((tag.pages[1][1]&0x10) == 0x10) + tag.LCK4=1; + tag.LCK3=0; + if((tag.pages[1][1]&0x8) == 0x08) + tag.LCK3=1; + tag.LCK2=0; + if((tag.pages[1][1]&0x4) == 0x04) + tag.LCK2=1; + tag.LCK1=0; + if((tag.pages[1][1]&0x2) == 0x02) + tag.LCK1=1; + tag.LCK0=0; + if((tag.pages[1][1]&0x1) == 0x01) + tag.LCK0=1; // 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); - SpinDelay(20); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - RELAY_OFF(); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); + SpinDelay(20); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + RELAY_OFF(); // Configure output pin that is connected to the FPGA (for modulating) - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; // Disable modulation at default, which means release resistance - LOW(GPIO_SSC_DOUT); + LOW(GPIO_SSC_DOUT); // Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the reader frames - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); - AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); + AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; // Disable timer during configuration - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, // external trigger rising edge, load RA on rising edge of TIOA. - AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK - | AT91C_TC_ETRGEDG_RISING | AT91C_TC_ABETRG | AT91C_TC_LDRA_RISING; + AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK + | AT91C_TC_ETRGEDG_RISING | AT91C_TC_ABETRG | AT91C_TC_LDRA_RISING; // Reset the received frame, frame count and timing info - memset(rx, 0x00, sizeof(rx)); - frame_count = 0; - response = 0; - overflow = 0; + memset(rx, 0x00, sizeof(rx)); + frame_count = 0; + response = 0; + overflow = 0; // Enable and reset counter - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - while (!BUTTON_PRESS()) { - // Watchdog hit - WDT_HIT(); + while (!BUTTON_PRESS()) { + // Watchdog hit + WDT_HIT(); - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_EOF) { - // Check if rising edge in modulation is detected - if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA / T0) + overflow; - overflow = 0; + // Receive frame, watch for at most T0*EOF periods + while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_EOF) { + // Check if rising edge in modulation is detected + if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { + // Retrieve the new timing values + int ra = (AT91C_BASE_TC1->TC_RA / T0) + overflow; + overflow = 0; - // Reset timer every frame, we have to capture the last edge for timing - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + // Reset timer every frame, we have to capture the last edge for timing + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - LED_B_ON(); + LED_B_ON(); - // Capture reader frame - if (ra >= HITAG_T_STOP) { - if (rxlen != 0) { - //DbpString("wierd0?"); - } - // Capture the T0 periods that have passed since last communication or field drop (reset) - response = (ra - HITAG_T_LOW); - } else if (ra >= HITAG_T_1_MIN) { - // '1' bit - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } else if (ra >= HITAG_T_0_MIN) { - // '0' bit - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - } else { - // Ignore wierd value, is to small to mean anything - } - } - } + // Capture reader frame + if (ra >= HITAG_T_STOP) { + if (rxlen != 0) { + //DbpString("wierd0?"); + } + // Capture the T0 periods that have passed since last communication or field drop (reset) + response = (ra - HITAG_T_LOW); + } else if (ra >= HITAG_T_1_MIN) { + // '1' bit + rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); + rxlen++; + } else if (ra >= HITAG_T_0_MIN) { + // '0' bit + rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); + rxlen++; + } else { + // Ignore wierd value, is to small to mean anything + } + } + } - // Check if frame was captured - if (rxlen > 0) { - frame_count++; - if (!bQuiet) { - if (!LogTraceHitag(rx, rxlen, response, 0, true)) { - DbpString("Trace full"); - clear_trace(); - } - } + // Check if frame was captured + if (rxlen > 0) { + frame_count++; + if (!bQuiet) { + if (!LogTraceHitag(rx, rxlen, response, 0, true)) { + DbpString("Trace full"); + clear_trace(); + } + } - // Disable timer 1 with external trigger to avoid triggers during our own modulation - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + // Disable timer 1 with external trigger to avoid triggers during our own modulation + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - // Process the incoming frame (rx) and prepare the outgoing frame (tx) - hitagS_handle_reader_command(rx, rxlen, tx, &txlen); + // Process the incoming frame (rx) and prepare the outgoing frame (tx) + hitagS_handle_reader_command(rx, rxlen, tx, &txlen); - // Wait for HITAG_T_WAIT_1 carrier periods after the last reader bit, - // not that since the clock counts since the rising edge, but T_Wait1 is - // with respect to the falling edge, we need to wait actually (T_Wait1 - T_Low) - // periods. The gap time T_Low varies (4..10). All timer values are in - // terms of T0 units - while (AT91C_BASE_TC0->TC_CV < T0 * (HITAG_T_WAIT_1 - HITAG_T_LOW)) - ; + // Wait for HITAG_T_WAIT_1 carrier periods after the last reader bit, + // not that since the clock counts since the rising edge, but T_Wait1 is + // with respect to the falling edge, we need to wait actually (T_Wait1 - T_Low) + // periods. The gap time T_Low varies (4..10). All timer values are in + // terms of T0 units + while (AT91C_BASE_TC0->TC_CV < T0 * (HITAG_T_WAIT_1 - HITAG_T_LOW)) + ; - // Send and store the tag answer (if there is any) - if (txlen > 0) { - // Transmit the tag frame - hitag_send_frame(tx, txlen); - // Store the frame in the trace - if (!bQuiet) { - if (!LogTraceHitag(tx, txlen, 0, 0, false)) { - DbpString("Trace full"); - clear_trace(); - } - } - } + // Send and store the tag answer (if there is any) + if (txlen > 0) { + // Transmit the tag frame + hitag_send_frame(tx, txlen); + // Store the frame in the trace + if (!bQuiet) { + if (!LogTraceHitag(tx, txlen, 0, 0, false)) { + DbpString("Trace full"); + clear_trace(); + } + } + } - // Reset the received frame and response timing info - memset(rx, 0x00, sizeof(rx)); - response = 0; + // Reset the received frame and response timing info + memset(rx, 0x00, sizeof(rx)); + response = 0; - // Enable and reset external trigger in timer for capturing future frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - LED_B_OFF(); - } - // Reset the frame length - rxlen = 0; - // Save the timer overflow, will be 0 when frame was received - overflow += (AT91C_BASE_TC1->TC_CV / T0); - // Reset the timer to restart while-loop that receives frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; - } - LED_B_OFF(); - LED_D_OFF(); - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // Enable and reset external trigger in timer for capturing future frames + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + LED_B_OFF(); + } + // Reset the frame length + rxlen = 0; + // Save the timer overflow, will be 0 when frame was received + overflow += (AT91C_BASE_TC1->TC_CV / T0); + // Reset the timer to restart while-loop that receives frames + AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; + } + LED_B_OFF(); + LED_D_OFF(); + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); } /* @@ -1164,341 +1164,341 @@ void SimulateHitagSTag(bool tag_mem_supplied, byte_t* data) { * Reads every page of a hitag S transpoder. */ void ReadHitagS(hitag_function htf, hitag_data* htd) { - int i, j, z, k; - int frame_count; - int response_bit[200]; - int response; - byte_t rx[HITAG_FRAME_LEN]; - size_t rxlen = 0; - byte_t txbuf[HITAG_FRAME_LEN]; - byte_t* tx = txbuf; - size_t txlen = 0; - int lastbit; - bool bSkip; - int reset_sof; - int tag_sof; - int t_wait = HITAG_T_WAIT_MAX; - bool bStop = false; - bool bQuitTraceFull = false; - int sendNum = 0; - unsigned char mask = 1; - unsigned char crc; - unsigned char pageData[32]; - page_to_be_written = 0; + int i, j, z, k; + int frame_count; + int response_bit[200]; + int response; + byte_t rx[HITAG_FRAME_LEN]; + size_t rxlen = 0; + byte_t txbuf[HITAG_FRAME_LEN]; + byte_t* tx = txbuf; + size_t txlen = 0; + int lastbit; + bool bSkip; + int reset_sof; + int tag_sof; + int t_wait = HITAG_T_WAIT_MAX; + bool bStop = false; + bool bQuitTraceFull = false; + int sendNum = 0; + unsigned char mask = 1; + unsigned char crc; + unsigned char pageData[32]; + page_to_be_written = 0; - //read given key/challenge - byte_t NrAr_[8]; - uint64_t key = 0; - uint64_t NrAr = 0; - byte_t key_[6]; - switch (htf) { - case 01: { //RHTS_CHALLENGE - DbpString("Authenticating using nr,ar pair:"); - memcpy(NrAr_, htd->auth.NrAr, 8); - Dbhexdump(8, NrAr_, false); - NrAr = NrAr_[7] | ((uint64_t)NrAr_[6]) << 8 | ((uint64_t)NrAr_[5]) << 16 | ((uint64_t)NrAr_[4]) << 24 | ((uint64_t)NrAr_[3]) << 32 | - ((uint64_t)NrAr_[2]) << 40| ((uint64_t)NrAr_[1]) << 48 | ((uint64_t)NrAr_[0]) << 56; - } break; - case 02: { //RHTS_KEY - DbpString("Authenticating using key:"); - memcpy(key_, htd->crypto.key, 6); - Dbhexdump(6, key_, false); - key = key_[5] | ((uint64_t)key_[4]) << 8 | ((uint64_t)key_[3]) << 16 | ((uint64_t)key_[2]) << 24 | ((uint64_t)key_[1]) << 32 | ((uint64_t)key_[0]) << 40; - } break; - default: { - Dbprintf("Error , unknown function: %d",htf); - return; - } break; - } + //read given key/challenge + byte_t NrAr_[8]; + uint64_t key = 0; + uint64_t NrAr = 0; + byte_t key_[6]; + switch (htf) { + case 01: { //RHTS_CHALLENGE + DbpString("Authenticating using nr,ar pair:"); + memcpy(NrAr_, htd->auth.NrAr, 8); + Dbhexdump(8, NrAr_, false); + NrAr = NrAr_[7] | ((uint64_t)NrAr_[6]) << 8 | ((uint64_t)NrAr_[5]) << 16 | ((uint64_t)NrAr_[4]) << 24 | ((uint64_t)NrAr_[3]) << 32 | + ((uint64_t)NrAr_[2]) << 40| ((uint64_t)NrAr_[1]) << 48 | ((uint64_t)NrAr_[0]) << 56; + } break; + case 02: { //RHTS_KEY + DbpString("Authenticating using key:"); + memcpy(key_, htd->crypto.key, 6); + Dbhexdump(6, key_, false); + key = key_[5] | ((uint64_t)key_[4]) << 8 | ((uint64_t)key_[3]) << 16 | ((uint64_t)key_[2]) << 24 | ((uint64_t)key_[1]) << 32 | ((uint64_t)key_[0]) << 40; + } break; + default: { + Dbprintf("Error , unknown function: %d",htf); + return; + } break; + } - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - // Reset the return status - bSuccessful = false; + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + // Reset the return status + bSuccessful = false; - // Clean up trace and prepare it for storing frames - set_tracing(true); - clear_trace(); + // Clean up trace and prepare it for storing frames + set_tracing(true); + clear_trace(); - bQuiet = false; - bQuitTraceFull = true; + bQuiet = false; + bQuitTraceFull = true; - LED_D_ON(); + LED_D_ON(); - // Configure output and enable pin that is connected to the FPGA (for modulating) - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + // Configure output and enable pin that is connected to the FPGA (for modulating) + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - // Set fpga in edge detect with reader field, we can modulate as reader now - FpgaWriteConfWord( - FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); + // Set fpga in edge detect with reader field, we can modulate as reader now + FpgaWriteConfWord( + FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); - // Set Frequency divisor which will drive the FPGA and analog mux selection - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - RELAY_OFF(); + // Set Frequency divisor which will drive the FPGA and analog mux selection + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + RELAY_OFF(); - // Disable modulation at default, which means enable the field - LOW(GPIO_SSC_DOUT); + // Disable modulation at default, which means enable the field + LOW(GPIO_SSC_DOUT); - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(30); + // Give it a bit of time for the resonant antenna to settle. + SpinDelay(30); - // Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); + // Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); - // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the tag frames - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); - AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; + // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the tag frames + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); + AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; - // Disable timer during configuration - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + // Disable timer during configuration + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - // Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, - // external trigger rising edge, load RA on falling edge of TIOA. - AT91C_BASE_TC1->TC_CMR = - AT91C_TC_CLKS_TIMER_DIV1_CLOCK | - AT91C_TC_ETRGEDG_FALLING | - AT91C_TC_ABETRG | - AT91C_TC_LDRA_FALLING; + // Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, + // external trigger rising edge, load RA on falling edge of TIOA. + AT91C_BASE_TC1->TC_CMR = + AT91C_TC_CLKS_TIMER_DIV1_CLOCK | + AT91C_TC_ETRGEDG_FALLING | + AT91C_TC_ABETRG | + AT91C_TC_LDRA_FALLING; - // Enable and reset counters - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + // Enable and reset counters + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - // Reset the received frame, frame count and timing info - frame_count = 0; - response = 0; - lastbit = 1; - bStop = false; + // Reset the received frame, frame count and timing info + frame_count = 0; + response = 0; + lastbit = 1; + bStop = false; - reset_sof = 1; - t_wait = 200; + reset_sof = 1; + t_wait = 200; - while (!bStop && !BUTTON_PRESS()) { - // Watchdog hit - WDT_HIT(); + while (!bStop && !BUTTON_PRESS()) { + // Watchdog hit + WDT_HIT(); - // Check if frame was captured and store it - if (rxlen > 0) { - frame_count++; - if (!bQuiet) { - if (!LogTraceHitag(rx, rxlen, response, 0, false)) { - DbpString("Trace full"); - if (bQuitTraceFull) { - break; - } else { - bQuiet = true; - } - } - } - } + // Check if frame was captured and store it + if (rxlen > 0) { + frame_count++; + if (!bQuiet) { + if (!LogTraceHitag(rx, rxlen, response, 0, false)) { + DbpString("Trace full"); + if (bQuitTraceFull) { + break; + } else { + bQuiet = true; + } + } + } + } - // By default reset the transmission buffer - tx = txbuf; - txlen = 0; + // By default reset the transmission buffer + tx = txbuf; + txlen = 0; - if (rxlen == 0) { - //start authentication - txlen = 5; - memcpy(tx, "\xc0", nbytes(txlen)); - tag.pstate = HT_READY; - tag.tstate = HT_NO_OP; - } else if (tag.pstate != HT_SELECTED) { - if (hitagS_handle_tag_auth(htf, key,NrAr,rx, rxlen, tx, &txlen) == -1) - bStop = !false; - } - if (tag.pstate == HT_SELECTED && tag.tstate == HT_NO_OP && rxlen > 0) { - //send read request - tag.tstate = HT_READING_PAGE; - txlen = 20; - crc = CRC_PRESET; - tx[0] = 0xc0 + (sendNum / 16); - calc_crc(&crc, tx[0], 8); - calc_crc(&crc, 0x00 + ((sendNum % 16) * 16), 4); - tx[1] = 0x00 + ((sendNum % 16) * 16) + (crc / 16); - tx[2] = 0x00 + (crc % 16) * 16; - } else if (tag.pstate == HT_SELECTED && tag.tstate == HT_READING_PAGE - && rxlen > 0) { - //save received data - z = 0; - for (i = 0; i < 5; i++) { - for (j = 0; j < 8; j++) { - response_bit[z] = 0; - if ((rx[i] & ((mask << 7) >> j)) != 0) - response_bit[z] = 1; - z++; - } - } - k = 0; - for (i = 4; i < 36; i++) { - pageData[k] = response_bit[i]; - k++; - } - for (i = 0; i < 4; i++) - tag.pages[sendNum / 4][sendNum % 4] = 0x0; - for (i = 0; i < 4; i++) { - tag.pages[sendNum / 4][sendNum % 4] += ((pageData[i * 8] << 7) - | (pageData[1 + (i * 8)] << 6) - | (pageData[2 + (i * 8)] << 5) - | (pageData[3 + (i * 8)] << 4) - | (pageData[4 + (i * 8)] << 3) - | (pageData[5 + (i * 8)] << 2) - | (pageData[6 + (i * 8)] << 1) | pageData[7 + (i * 8)]) - << (i * 8); - } - if (tag.auth && tag.LKP && sendNum == 1) { - Dbprintf("Page[%2d]: %02X %02X %02X %02X", sendNum, pwdh0, - (tag.pages[sendNum / 4][sendNum % 4] >> 16) & 0xff, - (tag.pages[sendNum / 4][sendNum % 4] >> 8) & 0xff, - tag.pages[sendNum / 4][sendNum % 4] & 0xff); - } else { - Dbprintf("Page[%2d]: %02X %02X %02X %02X", sendNum, - (tag.pages[sendNum / 4][sendNum % 4] >> 24) & 0xff, - (tag.pages[sendNum / 4][sendNum % 4] >> 16) & 0xff, - (tag.pages[sendNum / 4][sendNum % 4] >> 8) & 0xff, - tag.pages[sendNum / 4][sendNum % 4] & 0xff); - } + if (rxlen == 0) { + //start authentication + txlen = 5; + memcpy(tx, "\xc0", nbytes(txlen)); + tag.pstate = HT_READY; + tag.tstate = HT_NO_OP; + } else if (tag.pstate != HT_SELECTED) { + if (hitagS_handle_tag_auth(htf, key,NrAr,rx, rxlen, tx, &txlen) == -1) + bStop = !false; + } + if (tag.pstate == HT_SELECTED && tag.tstate == HT_NO_OP && rxlen > 0) { + //send read request + tag.tstate = HT_READING_PAGE; + txlen = 20; + crc = CRC_PRESET; + tx[0] = 0xc0 + (sendNum / 16); + calc_crc(&crc, tx[0], 8); + calc_crc(&crc, 0x00 + ((sendNum % 16) * 16), 4); + tx[1] = 0x00 + ((sendNum % 16) * 16) + (crc / 16); + tx[2] = 0x00 + (crc % 16) * 16; + } else if (tag.pstate == HT_SELECTED && tag.tstate == HT_READING_PAGE + && rxlen > 0) { + //save received data + z = 0; + for (i = 0; i < 5; i++) { + for (j = 0; j < 8; j++) { + response_bit[z] = 0; + if ((rx[i] & ((mask << 7) >> j)) != 0) + response_bit[z] = 1; + z++; + } + } + k = 0; + for (i = 4; i < 36; i++) { + pageData[k] = response_bit[i]; + k++; + } + for (i = 0; i < 4; i++) + tag.pages[sendNum / 4][sendNum % 4] = 0x0; + for (i = 0; i < 4; i++) { + tag.pages[sendNum / 4][sendNum % 4] += ((pageData[i * 8] << 7) + | (pageData[1 + (i * 8)] << 6) + | (pageData[2 + (i * 8)] << 5) + | (pageData[3 + (i * 8)] << 4) + | (pageData[4 + (i * 8)] << 3) + | (pageData[5 + (i * 8)] << 2) + | (pageData[6 + (i * 8)] << 1) | pageData[7 + (i * 8)]) + << (i * 8); + } + if (tag.auth && tag.LKP && sendNum == 1) { + Dbprintf("Page[%2d]: %02X %02X %02X %02X", sendNum, pwdh0, + (tag.pages[sendNum / 4][sendNum % 4] >> 16) & 0xff, + (tag.pages[sendNum / 4][sendNum % 4] >> 8) & 0xff, + tag.pages[sendNum / 4][sendNum % 4] & 0xff); + } else { + Dbprintf("Page[%2d]: %02X %02X %02X %02X", sendNum, + (tag.pages[sendNum / 4][sendNum % 4] >> 24) & 0xff, + (tag.pages[sendNum / 4][sendNum % 4] >> 16) & 0xff, + (tag.pages[sendNum / 4][sendNum % 4] >> 8) & 0xff, + tag.pages[sendNum / 4][sendNum % 4] & 0xff); + } - sendNum++; - //display key and password if possible - if (sendNum == 2 && tag.auth == 1 && tag.LKP) { - if (htf == 02) { //RHTS_KEY - Dbprintf("Page[ 2]: %02X %02X %02X %02X", - (byte_t)(key >> 8) & 0xff, - (byte_t) key & 0xff, pwdl1, pwdl0); - Dbprintf("Page[ 3]: %02X %02X %02X %02X", - (byte_t)(key >> 40) & 0xff, - (byte_t)(key >> 32) & 0xff, - (byte_t)(key >> 24) & 0xff, - (byte_t)(key >> 16) & 0xff); - } else { - //if the authentication is done with a challenge the key and password are unknown - Dbprintf("Page[ 2]: __ __ __ __"); - Dbprintf("Page[ 3]: __ __ __ __"); - } - } + sendNum++; + //display key and password if possible + if (sendNum == 2 && tag.auth == 1 && tag.LKP) { + if (htf == 02) { //RHTS_KEY + Dbprintf("Page[ 2]: %02X %02X %02X %02X", + (byte_t)(key >> 8) & 0xff, + (byte_t) key & 0xff, pwdl1, pwdl0); + Dbprintf("Page[ 3]: %02X %02X %02X %02X", + (byte_t)(key >> 40) & 0xff, + (byte_t)(key >> 32) & 0xff, + (byte_t)(key >> 24) & 0xff, + (byte_t)(key >> 16) & 0xff); + } else { + //if the authentication is done with a challenge the key and password are unknown + Dbprintf("Page[ 2]: __ __ __ __"); + Dbprintf("Page[ 3]: __ __ __ __"); + } + } - txlen = 20; - crc = CRC_PRESET; - tx[0] = 0xc0 + (sendNum / 16); - calc_crc(&crc, tx[0], 8); - calc_crc(&crc, 0x00 + ((sendNum % 16) * 16), 4); - tx[1] = 0x00 + ((sendNum % 16) * 16) + (crc / 16); - tx[2] = 0x00 + (crc % 16) * 16; - if (sendNum >= tag.max_page) { - bStop = !false; - } - } + txlen = 20; + crc = CRC_PRESET; + tx[0] = 0xc0 + (sendNum / 16); + calc_crc(&crc, tx[0], 8); + calc_crc(&crc, 0x00 + ((sendNum % 16) * 16), 4); + tx[1] = 0x00 + ((sendNum % 16) * 16) + (crc / 16); + tx[2] = 0x00 + (crc % 16) * 16; + if (sendNum >= tag.max_page) { + bStop = !false; + } + } - // Send and store the reader command - // Disable timer 1 with external trigger to avoid triggers during our own modulation - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + // Send and store the reader command + // Disable timer 1 with external trigger to avoid triggers during our own modulation + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting, - // Since the clock counts since the last falling edge, a 'one' means that the - // falling edge occured halfway the period. with respect to this falling edge, - // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. - // All timer values are in terms of T0 units + // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting, + // Since the clock counts since the last falling edge, a 'one' means that the + // falling edge occured halfway the period. with respect to this falling edge, + // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. + // All timer values are in terms of T0 units - while (AT91C_BASE_TC0->TC_CV < T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit))) {}; + while (AT91C_BASE_TC0->TC_CV < T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit))) {}; - // Transmit the reader frame - hitag_reader_send_frame(tx, txlen); + // Transmit the reader frame + hitag_reader_send_frame(tx, txlen); - // Enable and reset external trigger in timer for capturing future frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + // Enable and reset external trigger in timer for capturing future frames + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - // Add transmitted frame to total count - if (txlen > 0) { - frame_count++; - if (!bQuiet) { - // Store the frame in the trace - if (!LogTraceHitag(tx, txlen, HITAG_T_WAIT_2, 0, true)) { - if (bQuitTraceFull) { - DbpString("Trace full"); - break; - } else { - bQuiet = true; - } - } - } - } + // Add transmitted frame to total count + if (txlen > 0) { + frame_count++; + if (!bQuiet) { + // Store the frame in the trace + if (!LogTraceHitag(tx, txlen, HITAG_T_WAIT_2, 0, true)) { + if (bQuitTraceFull) { + DbpString("Trace full"); + break; + } else { + bQuiet = true; + } + } + } + } - // Reset values for receiving frames - memset(rx, 0x00, sizeof(rx)); - rxlen = 0; - lastbit = 1; - bSkip = true; - tag_sof = reset_sof; - response = 0; + // Reset values for receiving frames + memset(rx, 0x00, sizeof(rx)); + rxlen = 0; + lastbit = 1; + bSkip = true; + tag_sof = reset_sof; + response = 0; - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_WAIT_MAX) { - // Check if falling edge in tag modulation is detected - if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA / T0); + // Receive frame, watch for at most T0*EOF periods + while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_WAIT_MAX) { + // Check if falling edge in tag modulation is detected + if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { + // Retrieve the new timing values + int ra = (AT91C_BASE_TC1->TC_RA / T0); - // Reset timer every frame, we have to capture the last edge for timing - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + // Reset timer every frame, we have to capture the last edge for timing + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - LED_B_ON(); + LED_B_ON(); - // Capture tag frame (manchester decoding using only falling edges) - if (ra >= HITAG_T_EOF) { - if (rxlen != 0) { - //DbpString("wierd1?"); - } - // Capture the T0 periods that have passed since last communication or field drop (reset) - // We always recieve a 'one' first, which has the falling edge after a half period |-_| - response = ra - HITAG_T_TAG_HALF_PERIOD; - } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { - // Manchester coding example |-_|_-|-_| (101) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { - // Manchester coding example |_-|...|_-|-_| (0...01) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - // We have to skip this half period at start and add the 'one' the second time - if (!bSkip) { - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } - lastbit = !lastbit; - bSkip = !bSkip; - } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { - // Manchester coding example |_-|_-| (00) or |-_|-_| (11) - if (tag_sof) { - // Ignore bits that are transmitted during SOF - tag_sof--; - } else { - // bit is same as last bit - rx[rxlen / 8] |= lastbit << (7 - (rxlen % 8)); - rxlen++; - } - } else { - // Ignore wierd value, is to small to mean anything - } - } + // Capture tag frame (manchester decoding using only falling edges) + if (ra >= HITAG_T_EOF) { + if (rxlen != 0) { + //DbpString("wierd1?"); + } + // Capture the T0 periods that have passed since last communication or field drop (reset) + // We always recieve a 'one' first, which has the falling edge after a half period |-_| + response = ra - HITAG_T_TAG_HALF_PERIOD; + } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { + // Manchester coding example |-_|_-|-_| (101) + rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); + rxlen++; + rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); + rxlen++; + } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { + // Manchester coding example |_-|...|_-|-_| (0...01) + rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); + rxlen++; + // We have to skip this half period at start and add the 'one' the second time + if (!bSkip) { + rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); + rxlen++; + } + lastbit = !lastbit; + bSkip = !bSkip; + } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { + // Manchester coding example |_-|_-| (00) or |-_|-_| (11) + if (tag_sof) { + // Ignore bits that are transmitted during SOF + tag_sof--; + } else { + // bit is same as last bit + rx[rxlen / 8] |= lastbit << (7 - (rxlen % 8)); + rxlen++; + } + } else { + // Ignore wierd value, is to small to mean anything + } + } - // We can break this loop if we received the last bit from a frame - if (AT91C_BASE_TC1->TC_CV > T0 * HITAG_T_EOF) { - if (rxlen > 0) - break; - } - } - } - end = false; - LED_B_OFF(); - LED_D_OFF(); - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // We can break this loop if we received the last bit from a frame + if (AT91C_BASE_TC1->TC_CV > T0 * HITAG_T_EOF) { + if (rxlen > 0) + break; + } + } + } + end = false; + LED_B_OFF(); + LED_D_OFF(); + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - cmd_send(CMD_ACK, bSuccessful, 0, 0, 0, 0); + cmd_send(CMD_ACK, bSuccessful, 0, 0, 0, 0); } /* @@ -1506,309 +1506,309 @@ void ReadHitagS(hitag_function htf, hitag_data* htd) { * Writes the given 32Bit data into page_ */ void WritePageHitagS(hitag_function htf, hitag_data* htd,int page_) { - int frame_count; - int response; - byte_t rx[HITAG_FRAME_LEN]; - size_t rxlen = 0; - byte_t txbuf[HITAG_FRAME_LEN]; - byte_t* tx = txbuf; - size_t txlen = 0; - int lastbit; - bool bSkip; - int reset_sof; - int tag_sof; - int t_wait = HITAG_T_WAIT_MAX; - bool bStop; - bool bQuitTraceFull = false; - int page = page_; - unsigned char crc; - byte_t data[4]= {0,0,0,0}; + int frame_count; + int response; + byte_t rx[HITAG_FRAME_LEN]; + size_t rxlen = 0; + byte_t txbuf[HITAG_FRAME_LEN]; + byte_t* tx = txbuf; + size_t txlen = 0; + int lastbit; + bool bSkip; + int reset_sof; + int tag_sof; + int t_wait = HITAG_T_WAIT_MAX; + bool bStop; + bool bQuitTraceFull = false; + int page = page_; + unsigned char crc; + byte_t data[4]= {0,0,0,0}; - //read given key/challenge, the page and the data - byte_t NrAr_[8]; - uint64_t key=0; - uint64_t NrAr=0; - byte_t key_[6]; - switch(htf) { - case 03: { //WHTS_CHALLENGE - memcpy(data,htd->auth.data,4); - DbpString("Authenticating using nr,ar pair:"); - memcpy(NrAr_,htd->auth.NrAr,8); - Dbhexdump(8,NrAr_,false); - NrAr=NrAr_[7] | ((uint64_t)NrAr_[6]) << 8 | ((uint64_t)NrAr_[5]) << 16 | ((uint64_t)NrAr_[4]) << 24 | ((uint64_t)NrAr_[3]) << 32 | - ((uint64_t)NrAr_[2]) << 40| ((uint64_t)NrAr_[1]) << 48 | ((uint64_t)NrAr_[0]) << 56; - } break; - case 04: { //WHTS_KEY - memcpy(data,htd->crypto.data,4); - DbpString("Authenticating using key:"); - memcpy(key_,htd->crypto.key,6); - Dbhexdump(6,key_,false); - key=key_[5] | ((uint64_t)key_[4]) << 8 | ((uint64_t)key_[3]) << 16 | ((uint64_t)key_[2]) << 24 | ((uint64_t)key_[1]) << 32 | ((uint64_t)key_[0]) << 40; - } break; - default: { - Dbprintf("Error , unknown function: %d",htf); - return; - } break; - } + //read given key/challenge, the page and the data + byte_t NrAr_[8]; + uint64_t key=0; + uint64_t NrAr=0; + byte_t key_[6]; + switch(htf) { + case 03: { //WHTS_CHALLENGE + memcpy(data,htd->auth.data,4); + DbpString("Authenticating using nr,ar pair:"); + memcpy(NrAr_,htd->auth.NrAr,8); + Dbhexdump(8,NrAr_,false); + NrAr=NrAr_[7] | ((uint64_t)NrAr_[6]) << 8 | ((uint64_t)NrAr_[5]) << 16 | ((uint64_t)NrAr_[4]) << 24 | ((uint64_t)NrAr_[3]) << 32 | + ((uint64_t)NrAr_[2]) << 40| ((uint64_t)NrAr_[1]) << 48 | ((uint64_t)NrAr_[0]) << 56; + } break; + case 04: { //WHTS_KEY + memcpy(data,htd->crypto.data,4); + DbpString("Authenticating using key:"); + memcpy(key_,htd->crypto.key,6); + Dbhexdump(6,key_,false); + key=key_[5] | ((uint64_t)key_[4]) << 8 | ((uint64_t)key_[3]) << 16 | ((uint64_t)key_[2]) << 24 | ((uint64_t)key_[1]) << 32 | ((uint64_t)key_[0]) << 40; + } break; + default: { + Dbprintf("Error , unknown function: %d",htf); + return; + } break; + } - Dbprintf("Page: %d",page_); - Dbprintf("DATA: %02X %02X %02X %02X", data[0], data[1], data[2], data[3]); - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + Dbprintf("Page: %d",page_); + Dbprintf("DATA: %02X %02X %02X %02X", data[0], data[1], data[2], data[3]); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); // Reset the return status - bSuccessful = false; + bSuccessful = false; - tag.pstate = HT_READY; - tag.tstate = HT_NO_OP; + tag.pstate = HT_READY; + tag.tstate = HT_NO_OP; // Clean up trace and prepare it for storing frames - set_tracing(true); - clear_trace(); + set_tracing(true); + clear_trace(); - bQuiet = false; - bQuitTraceFull = true; + bQuiet = false; + bQuitTraceFull = true; - LED_D_ON(); + LED_D_ON(); // Configure output and enable pin that is connected to the FPGA (for modulating) - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; // Set fpga in edge detect with reader field, we can modulate as reader now - FpgaWriteConfWord( - FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); + FpgaWriteConfWord( + FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); // Set Frequency divisor which will drive the FPGA and analog mux selection - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - RELAY_OFF(); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + RELAY_OFF(); // Disable modulation at default, which means enable the field - LOW(GPIO_SSC_DOUT); + LOW(GPIO_SSC_DOUT); // Give it a bit of time for the resonant antenna to settle. - SpinDelay(30); + SpinDelay(30); // Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the tag frames - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); - AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); + AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; // Disable timer during configuration - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, // external trigger rising edge, load RA on falling edge of TIOA. - AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK - | AT91C_TC_ETRGEDG_FALLING | AT91C_TC_ABETRG - | AT91C_TC_LDRA_FALLING; + AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK + | AT91C_TC_ETRGEDG_FALLING | AT91C_TC_ABETRG + | AT91C_TC_LDRA_FALLING; // Enable and reset counters - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // Reset the received frame, frame count and timing info - frame_count = 0; - response = 0; - lastbit = 1; - bStop = false; + frame_count = 0; + response = 0; + lastbit = 1; + bStop = false; - reset_sof = 1; - t_wait = 200; + reset_sof = 1; + t_wait = 200; - while (!bStop && !BUTTON_PRESS()) { - // Watchdog hit - WDT_HIT(); + while (!bStop && !BUTTON_PRESS()) { + // Watchdog hit + WDT_HIT(); - // Check if frame was captured and store it - if (rxlen > 0) { - frame_count++; - if (!bQuiet) { - if (!LogTraceHitag(rx, rxlen, response, 0, false)) { - DbpString("Trace full"); - if (bQuitTraceFull) { - break; - } else { - bQuiet = true; - } - } - } - } + // Check if frame was captured and store it + if (rxlen > 0) { + frame_count++; + if (!bQuiet) { + if (!LogTraceHitag(rx, rxlen, response, 0, false)) { + DbpString("Trace full"); + if (bQuitTraceFull) { + break; + } else { + bQuiet = true; + } + } + } + } - //check for valid input - if (page == 0) { - Dbprintf( - "usage: lf hitag writer [03 | 04] [CHALLENGE | KEY] [page] [byte0] [byte1] [byte2] [byte3]"); - bStop = !false; - } + //check for valid input + if (page == 0) { + Dbprintf( + "usage: lf hitag writer [03 | 04] [CHALLENGE | KEY] [page] [byte0] [byte1] [byte2] [byte3]"); + bStop = !false; + } - // By default reset the transmission buffer - tx = txbuf; - txlen = 0; + // By default reset the transmission buffer + tx = txbuf; + txlen = 0; - if (rxlen == 0 && tag.tstate == HT_WRITING_PAGE_ACK) { - //no write access on this page - Dbprintf("no write access on page %d", page_); - bStop = !false; - } else if (rxlen == 0 && tag.tstate != HT_WRITING_PAGE_DATA) { - //start the authetication - txlen = 5; - memcpy(tx, "\xc0", nbytes(txlen)); - tag.pstate = HT_READY; - tag.tstate = HT_NO_OP; - } else if (tag.pstate != HT_SELECTED) { - //try to authenticate with the given key or challenge - if (hitagS_handle_tag_auth(htf,key,NrAr,rx, rxlen, tx, &txlen) == -1) - bStop = !false; - } - if (tag.pstate == HT_SELECTED && tag.tstate == HT_NO_OP && rxlen > 0) { - //check if the given page exists - if (page > tag.max_page) { - Dbprintf("page number too big"); - bStop = !false; - } - //ask Tag for write permission - tag.tstate = HT_WRITING_PAGE_ACK; - txlen = 20; - crc = CRC_PRESET; - tx[0] = 0x90 + (page / 16); - calc_crc(&crc, tx[0], 8); - calc_crc(&crc, 0x00 + ((page % 16) * 16), 4); - tx[1] = 0x00 + ((page % 16) * 16) + (crc / 16); - tx[2] = 0x00 + (crc % 16) * 16; - } else if (tag.pstate == HT_SELECTED && tag.tstate == HT_WRITING_PAGE_ACK - && rxlen == 6 && rx[0] == 0xf4) { - //ACK recieved to write the page. send data - tag.tstate = HT_WRITING_PAGE_DATA; - txlen = 40; - crc = CRC_PRESET; - calc_crc(&crc, data[3], 8); - calc_crc(&crc, data[2], 8); - calc_crc(&crc, data[1], 8); - calc_crc(&crc, data[0], 8); - tx[0] = data[3]; - tx[1] = data[2]; - tx[2] = data[1]; - tx[3] = data[0]; - tx[4] = crc; - } else if (tag.pstate == HT_SELECTED && tag.tstate == HT_WRITING_PAGE_DATA - && rxlen == 6 && rx[0] == 0xf4) { - //received ACK - Dbprintf("Successful!"); - bStop = !false; - } + if (rxlen == 0 && tag.tstate == HT_WRITING_PAGE_ACK) { + //no write access on this page + Dbprintf("no write access on page %d", page_); + bStop = !false; + } else if (rxlen == 0 && tag.tstate != HT_WRITING_PAGE_DATA) { + //start the authetication + txlen = 5; + memcpy(tx, "\xc0", nbytes(txlen)); + tag.pstate = HT_READY; + tag.tstate = HT_NO_OP; + } else if (tag.pstate != HT_SELECTED) { + //try to authenticate with the given key or challenge + if (hitagS_handle_tag_auth(htf,key,NrAr,rx, rxlen, tx, &txlen) == -1) + bStop = !false; + } + if (tag.pstate == HT_SELECTED && tag.tstate == HT_NO_OP && rxlen > 0) { + //check if the given page exists + if (page > tag.max_page) { + Dbprintf("page number too big"); + bStop = !false; + } + //ask Tag for write permission + tag.tstate = HT_WRITING_PAGE_ACK; + txlen = 20; + crc = CRC_PRESET; + tx[0] = 0x90 + (page / 16); + calc_crc(&crc, tx[0], 8); + calc_crc(&crc, 0x00 + ((page % 16) * 16), 4); + tx[1] = 0x00 + ((page % 16) * 16) + (crc / 16); + tx[2] = 0x00 + (crc % 16) * 16; + } else if (tag.pstate == HT_SELECTED && tag.tstate == HT_WRITING_PAGE_ACK + && rxlen == 6 && rx[0] == 0xf4) { + //ACK recieved to write the page. send data + tag.tstate = HT_WRITING_PAGE_DATA; + txlen = 40; + crc = CRC_PRESET; + calc_crc(&crc, data[3], 8); + calc_crc(&crc, data[2], 8); + calc_crc(&crc, data[1], 8); + calc_crc(&crc, data[0], 8); + tx[0] = data[3]; + tx[1] = data[2]; + tx[2] = data[1]; + tx[3] = data[0]; + tx[4] = crc; + } else if (tag.pstate == HT_SELECTED && tag.tstate == HT_WRITING_PAGE_DATA + && rxlen == 6 && rx[0] == 0xf4) { + //received ACK + Dbprintf("Successful!"); + bStop = !false; + } - // Send and store the reader command - // Disable timer 1 with external trigger to avoid triggers during our own modulation - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + // Send and store the reader command + // Disable timer 1 with external trigger to avoid triggers during our own modulation + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting, - // Since the clock counts since the last falling edge, a 'one' means that the - // falling edge occured halfway the period. with respect to this falling edge, - // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. - // All timer values are in terms of T0 units + // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting, + // Since the clock counts since the last falling edge, a 'one' means that the + // falling edge occured halfway the period. with respect to this falling edge, + // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. + // All timer values are in terms of T0 units - while (AT91C_BASE_TC0->TC_CV - < T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit))) - ; + while (AT91C_BASE_TC0->TC_CV + < T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit))) + ; - // Transmit the reader frame - hitag_reader_send_frame(tx, txlen); + // Transmit the reader frame + hitag_reader_send_frame(tx, txlen); - // Enable and reset external trigger in timer for capturing future frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + // Enable and reset external trigger in timer for capturing future frames + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - // Add transmitted frame to total count - if (txlen > 0) { - frame_count++; - if (!bQuiet) { - // Store the frame in the trace - if (!LogTraceHitag(tx, txlen, HITAG_T_WAIT_2, 0, true)) { - if (bQuitTraceFull) { - DbpString("Trace full"); - break; - } else { - bQuiet = true; - } - } - } - } + // Add transmitted frame to total count + if (txlen > 0) { + frame_count++; + if (!bQuiet) { + // Store the frame in the trace + if (!LogTraceHitag(tx, txlen, HITAG_T_WAIT_2, 0, true)) { + if (bQuitTraceFull) { + DbpString("Trace full"); + break; + } else { + bQuiet = true; + } + } + } + } - // Reset values for receiving frames - memset(rx, 0x00, sizeof(rx)); - rxlen = 0; - lastbit = 1; - bSkip = true; - tag_sof = reset_sof; - response = 0; + // Reset values for receiving frames + memset(rx, 0x00, sizeof(rx)); + rxlen = 0; + lastbit = 1; + bSkip = true; + tag_sof = reset_sof; + response = 0; - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_WAIT_MAX) { - // Check if falling edge in tag modulation is detected - if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA / T0); + // Receive frame, watch for at most T0*EOF periods + while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_WAIT_MAX) { + // Check if falling edge in tag modulation is detected + if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { + // Retrieve the new timing values + int ra = (AT91C_BASE_TC1->TC_RA / T0); - // Reset timer every frame, we have to capture the last edge for timing - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + // Reset timer every frame, we have to capture the last edge for timing + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - LED_B_ON(); + LED_B_ON(); - // Capture tag frame (manchester decoding using only falling edges) - if (ra >= HITAG_T_EOF) { - if (rxlen != 0) { - //DbpString("wierd1?"); - } - // Capture the T0 periods that have passed since last communication or field drop (reset) - // We always recieve a 'one' first, which has the falling edge after a half period |-_| - response = ra - HITAG_T_TAG_HALF_PERIOD; - } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { - // Manchester coding example |-_|_-|-_| (101) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { - // Manchester coding example |_-|...|_-|-_| (0...01) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - // We have to skip this half period at start and add the 'one' the second time - if (!bSkip) { - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } - lastbit = !lastbit; - bSkip = !bSkip; - } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { - // Manchester coding example |_-|_-| (00) or |-_|-_| (11) - if (tag_sof) { - // Ignore bits that are transmitted during SOF - tag_sof--; - } else { - // bit is same as last bit - rx[rxlen / 8] |= lastbit << (7 - (rxlen % 8)); - rxlen++; - } - } else { - // Ignore wierd value, is to small to mean anything - } - } + // Capture tag frame (manchester decoding using only falling edges) + if (ra >= HITAG_T_EOF) { + if (rxlen != 0) { + //DbpString("wierd1?"); + } + // Capture the T0 periods that have passed since last communication or field drop (reset) + // We always recieve a 'one' first, which has the falling edge after a half period |-_| + response = ra - HITAG_T_TAG_HALF_PERIOD; + } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { + // Manchester coding example |-_|_-|-_| (101) + rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); + rxlen++; + rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); + rxlen++; + } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { + // Manchester coding example |_-|...|_-|-_| (0...01) + rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); + rxlen++; + // We have to skip this half period at start and add the 'one' the second time + if (!bSkip) { + rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); + rxlen++; + } + lastbit = !lastbit; + bSkip = !bSkip; + } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { + // Manchester coding example |_-|_-| (00) or |-_|-_| (11) + if (tag_sof) { + // Ignore bits that are transmitted during SOF + tag_sof--; + } else { + // bit is same as last bit + rx[rxlen / 8] |= lastbit << (7 - (rxlen % 8)); + rxlen++; + } + } else { + // Ignore wierd value, is to small to mean anything + } + } - // We can break this loop if we received the last bit from a frame - if (AT91C_BASE_TC1->TC_CV > T0 * HITAG_T_EOF) { - if (rxlen > 0) - break; - } - } - } - end=false; - LED_B_OFF(); - LED_D_OFF(); - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - cmd_send(CMD_ACK, bSuccessful, 0, 0, 0, 0); + // We can break this loop if we received the last bit from a frame + if (AT91C_BASE_TC1->TC_CV > T0 * HITAG_T_EOF) { + if (rxlen > 0) + break; + } + } + } + end=false; + LED_B_OFF(); + LED_D_OFF(); + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + cmd_send(CMD_ACK, bSuccessful, 0, 0, 0, 0); } /* @@ -1819,327 +1819,327 @@ void WritePageHitagS(hitag_function htf, hitag_data* htd,int page_) { * detects these challenges. */ void check_challenges(bool file_given, byte_t* data) { - int i, j, z, k; - byte_t uid_byte[4]; - int frame_count; - int response; - byte_t rx[HITAG_FRAME_LEN]; - byte_t unlocker[60][8]; - int u1 = 0; - size_t rxlen = 0; - byte_t txbuf[HITAG_FRAME_LEN]; - byte_t* tx = txbuf; - size_t txlen = 0; - int lastbit; - bool bSkip; - int reset_sof; - int tag_sof; - int t_wait = HITAG_T_WAIT_MAX; - int STATE = 0; - bool bStop; - bool bQuitTraceFull = false; - int response_bit[200]; - unsigned char mask = 1; - unsigned char uid[32]; - unsigned char crc; + int i, j, z, k; + byte_t uid_byte[4]; + int frame_count; + int response; + byte_t rx[HITAG_FRAME_LEN]; + byte_t unlocker[60][8]; + int u1 = 0; + size_t rxlen = 0; + byte_t txbuf[HITAG_FRAME_LEN]; + byte_t* tx = txbuf; + size_t txlen = 0; + int lastbit; + bool bSkip; + int reset_sof; + int tag_sof; + int t_wait = HITAG_T_WAIT_MAX; + int STATE = 0; + bool bStop; + bool bQuitTraceFull = false; + int response_bit[200]; + unsigned char mask = 1; + unsigned char uid[32]; + unsigned char crc; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); // Reset the return status - bSuccessful = false; + bSuccessful = false; // Clean up trace and prepare it for storing frames - set_tracing(true); - clear_trace(); + set_tracing(true); + clear_trace(); - bQuiet = false; - bQuitTraceFull = true; + bQuiet = false; + bQuitTraceFull = true; - LED_D_ON(); + LED_D_ON(); // Configure output and enable pin that is connected to the FPGA (for modulating) - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; // Set fpga in edge detect with reader field, we can modulate as reader now - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); - SpinDelay(50); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD); + SpinDelay(50); // Set Frequency divisor which will drive the FPGA and analog mux selection - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - RELAY_OFF(); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + RELAY_OFF(); // Disable modulation at default, which means enable the field - LOW(GPIO_SSC_DOUT); + LOW(GPIO_SSC_DOUT); // Give it a bit of time for the resonant antenna to settle. - SpinDelay(30); + SpinDelay(30); // Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the tag frames - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); - AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); + AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; // Disable timer during configuration - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, // external trigger rising edge, load RA on falling edge of TIOA. - AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK + AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK - | AT91C_TC_ETRGEDG_FALLING | AT91C_TC_ABETRG | AT91C_TC_LDRA_FALLING; + | AT91C_TC_ETRGEDG_FALLING | AT91C_TC_ABETRG | AT91C_TC_LDRA_FALLING; // Enable and reset counters - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // Reset the received frame, frame count and timing info - frame_count = 0; - response = 0; - lastbit = 1; - bStop = false; + frame_count = 0; + response = 0; + lastbit = 1; + bStop = false; - reset_sof = 1; - t_wait = 200; + reset_sof = 1; + t_wait = 200; - if (file_given) { - DbpString("Loading challenges..."); - memcpy((byte_t*)unlocker,data,60*8); - } + if (file_given) { + DbpString("Loading challenges..."); + memcpy((byte_t*)unlocker,data,60*8); + } - while (file_given && !bStop && !BUTTON_PRESS()) { - // Watchdog hit - WDT_HIT(); + while (file_given && !bStop && !BUTTON_PRESS()) { + // Watchdog hit + WDT_HIT(); - // Check if frame was captured and store it - if (rxlen > 0) { - frame_count++; - if (!bQuiet) { - if (!LogTraceHitag(rx, rxlen, response, 0, false)) { - DbpString("Trace full"); - if (bQuitTraceFull) { - break; - } else { - bQuiet = true; - } - } - } - } + // Check if frame was captured and store it + if (rxlen > 0) { + frame_count++; + if (!bQuiet) { + if (!LogTraceHitag(rx, rxlen, response, 0, false)) { + DbpString("Trace full"); + if (bQuitTraceFull) { + break; + } else { + bQuiet = true; + } + } + } + } - tx = txbuf; - txlen = 0; - if (rxlen == 0) { - if (STATE == 2) - // challenge failed - Dbprintf("Challenge failed: %02X %02X %02X %02X %02X %02X %02X %02X", - unlocker[u1 - 1][0], unlocker[u1 - 1][1], - unlocker[u1 - 1][2], unlocker[u1 - 1][3], - unlocker[u1 - 1][4], unlocker[u1 - 1][5], - unlocker[u1 - 1][6], unlocker[u1 - 1][7]); - STATE = 0; - txlen = 5; - //start new authentication - memcpy(tx, "\xc0", nbytes(txlen)); - } else if (rxlen >= 67 && STATE == 0) { - //received uid - z = 0; - for (i = 0; i < 10; i++) { - for (j = 0; j < 8; j++) { - response_bit[z] = 0; - if ((rx[i] & ((mask << 7) >> j)) != 0) - response_bit[z] = 1; - z++; - } - } - k = 0; - for (i = 5; i < z; i += 2) { - uid[k] = response_bit[i]; - k++; - if (k > 31) - break; - } - uid_byte[0] = (uid[0] << 7) | (uid[1] << 6) | (uid[2] << 5) - | (uid[3] << 4) | (uid[4] << 3) | (uid[5] << 2) - | (uid[6] << 1) | uid[7]; - uid_byte[1] = (uid[8] << 7) | (uid[9] << 6) | (uid[10] << 5) - | (uid[11] << 4) | (uid[12] << 3) | (uid[13] << 2) - | (uid[14] << 1) | uid[15]; - uid_byte[2] = (uid[16] << 7) | (uid[17] << 6) | (uid[18] << 5) - | (uid[19] << 4) | (uid[20] << 3) | (uid[21] << 2) - | (uid[22] << 1) | uid[23]; - uid_byte[3] = (uid[24] << 7) | (uid[25] << 6) | (uid[26] << 5) - | (uid[27] << 4) | (uid[28] << 3) | (uid[29] << 2) - | (uid[30] << 1) | uid[31]; - //Dbhexdump(10, rx, rxlen); - STATE = 1; - txlen = 45; - crc = CRC_PRESET; - calc_crc(&crc, 0x00, 5); - calc_crc(&crc, uid_byte[0], 8); - calc_crc(&crc, uid_byte[1], 8); - calc_crc(&crc, uid_byte[2], 8); - calc_crc(&crc, uid_byte[3], 8); - for (i = 0; i < 100; i++) { - response_bit[i] = 0; - } - for (i = 0; i < 5; i++) { - response_bit[i] = 0; - } - for (i = 5; i < 37; i++) { - response_bit[i] = uid[i - 5]; - } - for (j = 0; j < 8; j++) { - response_bit[i] = 0; - if ((crc & ((mask << 7) >> j)) != 0) - response_bit[i] = 1; - i++; - } - k = 0; - for (i = 0; i < 6; i++) { - tx[i] = (response_bit[k] << 7) | (response_bit[k + 1] << 6) - | (response_bit[k + 2] << 5) - | (response_bit[k + 3] << 4) - | (response_bit[k + 4] << 3) - | (response_bit[k + 5] << 2) - | (response_bit[k + 6] << 1) | response_bit[k + 7]; - k += 8; - } + tx = txbuf; + txlen = 0; + if (rxlen == 0) { + if (STATE == 2) + // challenge failed + Dbprintf("Challenge failed: %02X %02X %02X %02X %02X %02X %02X %02X", + unlocker[u1 - 1][0], unlocker[u1 - 1][1], + unlocker[u1 - 1][2], unlocker[u1 - 1][3], + unlocker[u1 - 1][4], unlocker[u1 - 1][5], + unlocker[u1 - 1][6], unlocker[u1 - 1][7]); + STATE = 0; + txlen = 5; + //start new authentication + memcpy(tx, "\xc0", nbytes(txlen)); + } else if (rxlen >= 67 && STATE == 0) { + //received uid + z = 0; + for (i = 0; i < 10; i++) { + for (j = 0; j < 8; j++) { + response_bit[z] = 0; + if ((rx[i] & ((mask << 7) >> j)) != 0) + response_bit[z] = 1; + z++; + } + } + k = 0; + for (i = 5; i < z; i += 2) { + uid[k] = response_bit[i]; + k++; + if (k > 31) + break; + } + uid_byte[0] = (uid[0] << 7) | (uid[1] << 6) | (uid[2] << 5) + | (uid[3] << 4) | (uid[4] << 3) | (uid[5] << 2) + | (uid[6] << 1) | uid[7]; + uid_byte[1] = (uid[8] << 7) | (uid[9] << 6) | (uid[10] << 5) + | (uid[11] << 4) | (uid[12] << 3) | (uid[13] << 2) + | (uid[14] << 1) | uid[15]; + uid_byte[2] = (uid[16] << 7) | (uid[17] << 6) | (uid[18] << 5) + | (uid[19] << 4) | (uid[20] << 3) | (uid[21] << 2) + | (uid[22] << 1) | uid[23]; + uid_byte[3] = (uid[24] << 7) | (uid[25] << 6) | (uid[26] << 5) + | (uid[27] << 4) | (uid[28] << 3) | (uid[29] << 2) + | (uid[30] << 1) | uid[31]; + //Dbhexdump(10, rx, rxlen); + STATE = 1; + txlen = 45; + crc = CRC_PRESET; + calc_crc(&crc, 0x00, 5); + calc_crc(&crc, uid_byte[0], 8); + calc_crc(&crc, uid_byte[1], 8); + calc_crc(&crc, uid_byte[2], 8); + calc_crc(&crc, uid_byte[3], 8); + for (i = 0; i < 100; i++) { + response_bit[i] = 0; + } + for (i = 0; i < 5; i++) { + response_bit[i] = 0; + } + for (i = 5; i < 37; i++) { + response_bit[i] = uid[i - 5]; + } + for (j = 0; j < 8; j++) { + response_bit[i] = 0; + if ((crc & ((mask << 7) >> j)) != 0) + response_bit[i] = 1; + i++; + } + k = 0; + for (i = 0; i < 6; i++) { + tx[i] = (response_bit[k] << 7) | (response_bit[k + 1] << 6) + | (response_bit[k + 2] << 5) + | (response_bit[k + 3] << 4) + | (response_bit[k + 4] << 3) + | (response_bit[k + 5] << 2) + | (response_bit[k + 6] << 1) | response_bit[k + 7]; + k += 8; + } - } else if (STATE == 1 && rxlen == 44) { - //received configuration - STATE = 2; - z = 0; - for (i = 0; i < 6; i++) { - for (j = 0; j < 8; j++) { - response_bit[z] = 0; - if ((rx[i] & ((mask << 7) >> j)) != 0) - response_bit[z] = 1; - z++; - } - } - txlen = 64; + } else if (STATE == 1 && rxlen == 44) { + //received configuration + STATE = 2; + z = 0; + for (i = 0; i < 6; i++) { + for (j = 0; j < 8; j++) { + response_bit[z] = 0; + if ((rx[i] & ((mask << 7) >> j)) != 0) + response_bit[z] = 1; + z++; + } + } + txlen = 64; - if (u1 >= (sizeof(unlocker) / sizeof(unlocker[0]))) - bStop = !false; - for (i = 0; i < 8; i++) - tx[i] = unlocker[u1][i]; - u1++; + if (u1 >= (sizeof(unlocker) / sizeof(unlocker[0]))) + bStop = !false; + for (i = 0; i < 8; i++) + tx[i] = unlocker[u1][i]; + u1++; - } else if (STATE == 2 && rxlen >= 44) { - STATE = 0; - } + } else if (STATE == 2 && rxlen >= 44) { + STATE = 0; + } - // Send and store the reader command - // Disable timer 1 with external trigger to avoid triggers during our own modulation - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + // Send and store the reader command + // Disable timer 1 with external trigger to avoid triggers during our own modulation + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting, - // Since the clock counts since the last falling edge, a 'one' means that the - // falling edge occured halfway the period. with respect to this falling edge, - // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. - // All timer values are in terms of T0 units + // Wait for HITAG_T_WAIT_2 carrier periods after the last tag bit before transmitting, + // Since the clock counts since the last falling edge, a 'one' means that the + // falling edge occured halfway the period. with respect to this falling edge, + // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. + // All timer values are in terms of T0 units - while (AT91C_BASE_TC0->TC_CV - < T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit))) - ; + while (AT91C_BASE_TC0->TC_CV + < T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit))) + ; - // Transmit the reader frame - hitag_reader_send_frame(tx, txlen); + // Transmit the reader frame + hitag_reader_send_frame(tx, txlen); - // Enable and reset external trigger in timer for capturing future frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + // Enable and reset external trigger in timer for capturing future frames + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - // Add transmitted frame to total count - if (txlen > 0) { - frame_count++; - if (!bQuiet) { - // Store the frame in the trace - if (!LogTraceHitag(tx, txlen, HITAG_T_WAIT_2, 0, true)) { - if (bQuitTraceFull) { - DbpString("Trace full"); - break; - } else { - bQuiet = true; - } - } - } - } + // Add transmitted frame to total count + if (txlen > 0) { + frame_count++; + if (!bQuiet) { + // Store the frame in the trace + if (!LogTraceHitag(tx, txlen, HITAG_T_WAIT_2, 0, true)) { + if (bQuitTraceFull) { + DbpString("Trace full"); + break; + } else { + bQuiet = true; + } + } + } + } - // Reset values for receiving frames - memset(rx, 0x00, sizeof(rx)); - rxlen = 0; - lastbit = 1; - bSkip = true; - tag_sof = reset_sof; - response = 0; + // Reset values for receiving frames + memset(rx, 0x00, sizeof(rx)); + rxlen = 0; + lastbit = 1; + bSkip = true; + tag_sof = reset_sof; + response = 0; - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_WAIT_MAX) { - // Check if falling edge in tag modulation is detected - if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA / T0); + // Receive frame, watch for at most T0*EOF periods + while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_WAIT_MAX) { + // Check if falling edge in tag modulation is detected + if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { + // Retrieve the new timing values + int ra = (AT91C_BASE_TC1->TC_RA / T0); - // Reset timer every frame, we have to capture the last edge for timing - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + // Reset timer every frame, we have to capture the last edge for timing + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - LED_B_ON(); + LED_B_ON(); - // Capture tag frame (manchester decoding using only falling edges) - if (ra >= HITAG_T_EOF) { - if (rxlen != 0) { - //DbpString("wierd1?"); - } - // Capture the T0 periods that have passed since last communication or field drop (reset) - // We always recieve a 'one' first, which has the falling edge after a half period |-_| - response = ra - HITAG_T_TAG_HALF_PERIOD; - } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { - // Manchester coding example |-_|_-|-_| (101) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { - // Manchester coding example |_-|...|_-|-_| (0...01) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - // We have to skip this half period at start and add the 'one' the second time - if (!bSkip) { - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } - lastbit = !lastbit; - bSkip = !bSkip; - } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { - // Manchester coding example |_-|_-| (00) or |-_|-_| (11) - if (tag_sof) { - // Ignore bits that are transmitted during SOF - tag_sof--; - } else { - // bit is same as last bit - rx[rxlen / 8] |= lastbit << (7 - (rxlen % 8)); - rxlen++; - } - } else { - // Ignore wierd value, is to small to mean anything - } - } + // Capture tag frame (manchester decoding using only falling edges) + if (ra >= HITAG_T_EOF) { + if (rxlen != 0) { + //DbpString("wierd1?"); + } + // Capture the T0 periods that have passed since last communication or field drop (reset) + // We always recieve a 'one' first, which has the falling edge after a half period |-_| + response = ra - HITAG_T_TAG_HALF_PERIOD; + } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { + // Manchester coding example |-_|_-|-_| (101) + rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); + rxlen++; + rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); + rxlen++; + } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { + // Manchester coding example |_-|...|_-|-_| (0...01) + rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); + rxlen++; + // We have to skip this half period at start and add the 'one' the second time + if (!bSkip) { + rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); + rxlen++; + } + lastbit = !lastbit; + bSkip = !bSkip; + } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { + // Manchester coding example |_-|_-| (00) or |-_|-_| (11) + if (tag_sof) { + // Ignore bits that are transmitted during SOF + tag_sof--; + } else { + // bit is same as last bit + rx[rxlen / 8] |= lastbit << (7 - (rxlen % 8)); + rxlen++; + } + } else { + // Ignore wierd value, is to small to mean anything + } + } - // We can break this loop if we received the last bit from a frame - if (AT91C_BASE_TC1->TC_CV > T0 * HITAG_T_EOF) { - if (rxlen > 0) - break; - } - } - } - LED_B_OFF(); - LED_D_OFF(); - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - cmd_send(CMD_ACK, bSuccessful, 0, 0, 0, 0); + // We can break this loop if we received the last bit from a frame + if (AT91C_BASE_TC1->TC_CV > T0 * HITAG_T_EOF) { + if (rxlen > 0) + break; + } + } + } + LED_B_OFF(); + LED_D_OFF(); + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + cmd_send(CMD_ACK, bSuccessful, 0, 0, 0, 0); } diff --git a/armsrc/iclass.c b/armsrc/iclass.c index af85c18fc..7b529a999 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -61,10 +61,10 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf); // The length of a received command will in most cases be no more than 18 bytes. // 32 should be enough! #ifndef ICLASS_BUFFER_SIZE - #define ICLASS_BUFFER_SIZE 32 + #define ICLASS_BUFFER_SIZE 32 #endif -#define AddCrc(data, len) compute_crc(CRC_ICLASS, (data), (len), (data)+(len), (data)+(len)+1) +#define AddCrc(data, len) compute_crc(CRC_ICLASS, (data), (len), (data)+(len), (data)+(len)+1) //----------------------------------------------------------------------------- // The software UART that receives commands from the reader, and its state @@ -75,7 +75,7 @@ typedef struct { enum { STATE_UNSYNCD, STATE_START_OF_COMMUNICATION, - STATE_RECEIVING + STATE_RECEIVING } state; uint16_t shiftReg; int bitCnt; @@ -97,33 +97,33 @@ typedef struct { typedef struct { enum { DEMOD_UNSYNCD, - DEMOD_START_OF_COMMUNICATION, - DEMOD_START_OF_COMMUNICATION2, - DEMOD_START_OF_COMMUNICATION3, - DEMOD_SOF_COMPLETE, - DEMOD_MANCHESTER_D, - DEMOD_MANCHESTER_E, - DEMOD_END_OF_COMMUNICATION, - DEMOD_END_OF_COMMUNICATION2, - DEMOD_MANCHESTER_F, + DEMOD_START_OF_COMMUNICATION, + DEMOD_START_OF_COMMUNICATION2, + DEMOD_START_OF_COMMUNICATION3, + DEMOD_SOF_COMPLETE, + DEMOD_MANCHESTER_D, + DEMOD_MANCHESTER_E, + DEMOD_END_OF_COMMUNICATION, + DEMOD_END_OF_COMMUNICATION2, + DEMOD_MANCHESTER_F, DEMOD_ERROR_WAIT } state; int bitCount; int posCount; - int syncBit; + int syncBit; uint16_t shiftReg; - uint32_t buffer; - uint32_t buffer2; - uint32_t buffer3; - int buff; - int samples; + uint32_t buffer; + uint32_t buffer2; + uint32_t buffer3; + int buff; + int samples; int len; - enum { - SUB_NONE, - SUB_FIRST_HALF, - SUB_SECOND_HALF, - SUB_BOTH - } sub; + enum { + SUB_NONE, + SUB_FIRST_HALF, + SUB_SECOND_HALF, + SUB_BOTH + } sub; uint8_t *output; } tDemod; @@ -133,22 +133,22 @@ typedef struct { */ // Static vars for UART typedef struct { - bool synced; - bool frame; - bool frame_done; - uint8_t *buf; - int len; + bool synced; + bool frame; + bool frame_done; + uint8_t *buf; + int len; } tUart; static tUart Uart; static void uart_reset(void){ - Uart.frame_done = false; - Uart.synced = false; - Uart.frame = false; + Uart.frame_done = false; + Uart.synced = false; + Uart.frame = false; } static void uart_init(uint8_t *data){ - Uart.buf = data; - uart_reset(); + Uart.buf = data; + uart_reset(); } static void uart_bit(uint8_t bit) { static uint8_t buf = 0xff; @@ -159,7 +159,7 @@ static void uart_bit(uint8_t bit) { buf |= bit ? 1 : 0; if (!Uart.frame) { - if (buf == 0x7b) { // 0b0111 1011 + if (buf == 0x7b) { // 0b0111 1011 Uart.frame = true; n_buf = 0; Uart.len = 0; @@ -188,7 +188,7 @@ static void uart_bit(uint8_t bit) { break; default: Uart.frame = false; - Uart.synced = false; + Uart.synced = false; Dbprintf("[-] bad %02X at %d:%d", buf, Uart.len, nmsg_byte); } @@ -255,8 +255,8 @@ again: /* static void UartReset(){ - Uart.state = STATE_UNSYNCD; - Uart.shiftReg = 0; + Uart.state = STATE_UNSYNCD; + Uart.shiftReg = 0; Uart.bitCnt = 0; Uart.byteCnt = 0; Uart.posCnt = 0; @@ -279,220 +279,220 @@ static void UartReset(){ */ /* static RAMFUNC int OutOfNDecoding(int bit) { - //int error = 0; - int bitright; + //int error = 0; + int bitright; - if (!Uart.bitBuffer) { - Uart.bitBuffer = bit ^ 0xFF0; - return false; - } else { - Uart.bitBuffer <<= 4; - Uart.bitBuffer ^= bit; - } + if (!Uart.bitBuffer) { + Uart.bitBuffer = bit ^ 0xFF0; + return false; + } else { + Uart.bitBuffer <<= 4; + Uart.bitBuffer ^= bit; + } - // if (Uart.swapper) { - // Uart.output[Uart.byteCnt] = Uart.bitBuffer & 0xFF; - // Uart.byteCnt++; - // Uart.swapper = 0; - // if (Uart.byteCnt > 15) return true; - //} - //else { - // Uart.swapper = 1; - //} + // if (Uart.swapper) { + // Uart.output[Uart.byteCnt] = Uart.bitBuffer & 0xFF; + // Uart.byteCnt++; + // Uart.swapper = 0; + // if (Uart.byteCnt > 15) return true; + // } + // else { + // Uart.swapper = 1; + // } - if (Uart.state != STATE_UNSYNCD) { - Uart.posCnt++; + if (Uart.state != STATE_UNSYNCD) { + Uart.posCnt++; - if ((Uart.bitBuffer & Uart.syncBit) ^ Uart.syncBit) - bit = 0; - else - bit = 1; + if ((Uart.bitBuffer & Uart.syncBit) ^ Uart.syncBit) + bit = 0; + else + bit = 1; - if (((Uart.bitBuffer << 1) & Uart.syncBit) ^ Uart.syncBit) - bitright = 0; - else - bitright = 1; + if (((Uart.bitBuffer << 1) & Uart.syncBit) ^ Uart.syncBit) + bitright = 0; + else + bitright = 1; - if(bit != bitright) - bit = bitright; + if(bit != bitright) + bit = bitright; - // So, now we only have to deal with *bit*, lets see... - if (Uart.posCnt == 1) { - // measurement first half bitperiod - if (!bit) { - // Drop in first half means that we are either seeing - // an SOF or an EOF. + // So, now we only have to deal with *bit*, lets see... + if (Uart.posCnt == 1) { + // measurement first half bitperiod + if (!bit) { + // Drop in first half means that we are either seeing + // an SOF or an EOF. - if (Uart.nOutOfCnt == 1) { - // End of Communication - Uart.state = STATE_UNSYNCD; - Uart.highCnt = 0; - if (Uart.byteCnt == 0) { - // Its not straightforward to show single EOFs - // So just leave it and do not return TRUE - Uart.output[0] = 0xf0; - Uart.byteCnt++; - } else { - return true; - } - } else if (Uart.state != STATE_START_OF_COMMUNICATION) { - // When not part of SOF or EOF, it is an error - Uart.state = STATE_UNSYNCD; - Uart.highCnt = 0; - //error = 4; - } - } - } else { - // measurement second half bitperiod - // Count the bitslot we are in... (ISO 15693) - Uart.nOutOfCnt++; + if (Uart.nOutOfCnt == 1) { + // End of Communication + Uart.state = STATE_UNSYNCD; + Uart.highCnt = 0; + if (Uart.byteCnt == 0) { + // Its not straightforward to show single EOFs + // So just leave it and do not return TRUE + Uart.output[0] = 0xf0; + Uart.byteCnt++; + } else { + return true; + } + } else if (Uart.state != STATE_START_OF_COMMUNICATION) { + // When not part of SOF or EOF, it is an error + Uart.state = STATE_UNSYNCD; + Uart.highCnt = 0; + //error = 4; + } + } + } else { + // measurement second half bitperiod + // Count the bitslot we are in... (ISO 15693) + Uart.nOutOfCnt++; - if (!bit) { - if (Uart.dropPosition) { - if (Uart.state == STATE_START_OF_COMMUNICATION) { - //error = 1; - } else { - //error = 7; - } - // It is an error if we already have seen a drop in current frame - Uart.state = STATE_UNSYNCD; - Uart.highCnt = 0; - } else { - Uart.dropPosition = Uart.nOutOfCnt; - } - } - Uart.posCnt = 0; + if (!bit) { + if (Uart.dropPosition) { + if (Uart.state == STATE_START_OF_COMMUNICATION) { + //error = 1; + } else { + //error = 7; + } + // It is an error if we already have seen a drop in current frame + Uart.state = STATE_UNSYNCD; + Uart.highCnt = 0; + } else { + Uart.dropPosition = Uart.nOutOfCnt; + } + } + Uart.posCnt = 0; - if (Uart.nOutOfCnt == Uart.OutOfCnt && Uart.OutOfCnt == 4) { - Uart.nOutOfCnt = 0; + if (Uart.nOutOfCnt == Uart.OutOfCnt && Uart.OutOfCnt == 4) { + Uart.nOutOfCnt = 0; - if (Uart.state == STATE_START_OF_COMMUNICATION) { - if (Uart.dropPosition == 4) { - Uart.state = STATE_RECEIVING; - Uart.OutOfCnt = 256; - } else if (Uart.dropPosition == 3) { - Uart.state = STATE_RECEIVING; - Uart.OutOfCnt = 4; - //Uart.output[Uart.byteCnt] = 0xdd; - //Uart.byteCnt++; - } else { - Uart.state = STATE_UNSYNCD; - Uart.highCnt = 0; - } - Uart.dropPosition = 0; - } else { - // RECEIVING DATA - // 1 out of 4 - if (!Uart.dropPosition) { - Uart.state = STATE_UNSYNCD; - Uart.highCnt = 0; - //error = 9; - } else { - Uart.shiftReg >>= 2; + if (Uart.state == STATE_START_OF_COMMUNICATION) { + if (Uart.dropPosition == 4) { + Uart.state = STATE_RECEIVING; + Uart.OutOfCnt = 256; + } else if (Uart.dropPosition == 3) { + Uart.state = STATE_RECEIVING; + Uart.OutOfCnt = 4; + //Uart.output[Uart.byteCnt] = 0xdd; + //Uart.byteCnt++; + } else { + Uart.state = STATE_UNSYNCD; + Uart.highCnt = 0; + } + Uart.dropPosition = 0; + } else { + // RECEIVING DATA + // 1 out of 4 + if (!Uart.dropPosition) { + Uart.state = STATE_UNSYNCD; + Uart.highCnt = 0; + //error = 9; + } else { + Uart.shiftReg >>= 2; - // Swap bit order - Uart.dropPosition--; - //if(Uart.dropPosition == 1) { Uart.dropPosition = 2; } - //else if(Uart.dropPosition == 2) { Uart.dropPosition = 1; } + // Swap bit order + Uart.dropPosition--; + //if(Uart.dropPosition == 1) { Uart.dropPosition = 2; } + //else if(Uart.dropPosition == 2) { Uart.dropPosition = 1; } - Uart.shiftReg ^= ((Uart.dropPosition & 0x03) << 6); - Uart.bitCnt += 2; - Uart.dropPosition = 0; + Uart.shiftReg ^= ((Uart.dropPosition & 0x03) << 6); + Uart.bitCnt += 2; + Uart.dropPosition = 0; - if (Uart.bitCnt == 8) { - Uart.output[Uart.byteCnt] = (Uart.shiftReg & 0xff); - Uart.byteCnt++; - Uart.bitCnt = 0; - Uart.shiftReg = 0; - } - } - } - } else if (Uart.nOutOfCnt == Uart.OutOfCnt) { - // RECEIVING DATA - // 1 out of 256 - if (!Uart.dropPosition) { - Uart.state = STATE_UNSYNCD; - Uart.highCnt = 0; - //error = 3; - } else { - Uart.dropPosition--; - Uart.output[Uart.byteCnt] = (Uart.dropPosition & 0xff); - Uart.byteCnt++; - Uart.bitCnt = 0; - Uart.shiftReg = 0; - Uart.nOutOfCnt = 0; - Uart.dropPosition = 0; - } - } + if (Uart.bitCnt == 8) { + Uart.output[Uart.byteCnt] = (Uart.shiftReg & 0xff); + Uart.byteCnt++; + Uart.bitCnt = 0; + Uart.shiftReg = 0; + } + } + } + } else if (Uart.nOutOfCnt == Uart.OutOfCnt) { + // RECEIVING DATA + // 1 out of 256 + if (!Uart.dropPosition) { + Uart.state = STATE_UNSYNCD; + Uart.highCnt = 0; + //error = 3; + } else { + Uart.dropPosition--; + Uart.output[Uart.byteCnt] = (Uart.dropPosition & 0xff); + Uart.byteCnt++; + Uart.bitCnt = 0; + Uart.shiftReg = 0; + Uart.nOutOfCnt = 0; + Uart.dropPosition = 0; + } + } */ - /*if (error) { - Uart.output[Uart.byteCnt] = 0xAA; - Uart.byteCnt++; - Uart.output[Uart.byteCnt] = error & 0xFF; - Uart.byteCnt++; - Uart.output[Uart.byteCnt] = 0xAA; - Uart.byteCnt++; - Uart.output[Uart.byteCnt] = (Uart.bitBuffer >> 8) & 0xFF; - Uart.byteCnt++; - Uart.output[Uart.byteCnt] = Uart.bitBuffer & 0xFF; - Uart.byteCnt++; - Uart.output[Uart.byteCnt] = (Uart.syncBit >> 3) & 0xFF; - Uart.byteCnt++; - Uart.output[Uart.byteCnt] = 0xAA; - Uart.byteCnt++; - return true; - }*/ + /*if (error) { + Uart.output[Uart.byteCnt] = 0xAA; + Uart.byteCnt++; + Uart.output[Uart.byteCnt] = error & 0xFF; + Uart.byteCnt++; + Uart.output[Uart.byteCnt] = 0xAA; + Uart.byteCnt++; + Uart.output[Uart.byteCnt] = (Uart.bitBuffer >> 8) & 0xFF; + Uart.byteCnt++; + Uart.output[Uart.byteCnt] = Uart.bitBuffer & 0xFF; + Uart.byteCnt++; + Uart.output[Uart.byteCnt] = (Uart.syncBit >> 3) & 0xFF; + Uart.byteCnt++; + Uart.output[Uart.byteCnt] = 0xAA; + Uart.byteCnt++; + return true; + }*/ /* - } - } else { - bit = Uart.bitBuffer & 0xf0; - bit >>= 4; - bit ^= 0x0F; // drops become 1s ;-) - if (bit) { - // should have been high or at least (4 * 128) / fc - // according to ISO this should be at least (9 * 128 + 20) / fc - if (Uart.highCnt == 8) { - // we went low, so this could be start of communication - // it turns out to be safer to choose a less significant - // syncbit... so we check whether the neighbour also represents the drop - Uart.posCnt = 1; // apparently we are busy with our first half bit period - Uart.syncBit = bit & 8; - Uart.samples = 3; + } + } else { + bit = Uart.bitBuffer & 0xf0; + bit >>= 4; + bit ^= 0x0F; // drops become 1s ;-) + if (bit) { + // should have been high or at least (4 * 128) / fc + // according to ISO this should be at least (9 * 128 + 20) / fc + if (Uart.highCnt == 8) { + // we went low, so this could be start of communication + // it turns out to be safer to choose a less significant + // syncbit... so we check whether the neighbour also represents the drop + Uart.posCnt = 1; // apparently we are busy with our first half bit period + Uart.syncBit = bit & 8; + Uart.samples = 3; - if (!Uart.syncBit) { Uart.syncBit = bit & 4; Uart.samples = 2; } - else if (bit & 4) { Uart.syncBit = bit & 4; Uart.samples = 2; bit <<= 2; } + if (!Uart.syncBit) { Uart.syncBit = bit & 4; Uart.samples = 2; } + else if (bit & 4) { Uart.syncBit = bit & 4; Uart.samples = 2; bit <<= 2; } - if (!Uart.syncBit) { Uart.syncBit = bit & 2; Uart.samples = 1; } - else if (bit & 2) { Uart.syncBit = bit & 2; Uart.samples = 1; bit <<= 1; } + if (!Uart.syncBit) { Uart.syncBit = bit & 2; Uart.samples = 1; } + else if (bit & 2) { Uart.syncBit = bit & 2; Uart.samples = 1; bit <<= 1; } - if (!Uart.syncBit) { Uart.syncBit = bit & 1; Uart.samples = 0; - if (Uart.syncBit && (Uart.bitBuffer & 8)) { - Uart.syncBit = 8; + if (!Uart.syncBit) { Uart.syncBit = bit & 1; Uart.samples = 0; + if (Uart.syncBit && (Uart.bitBuffer & 8)) { + Uart.syncBit = 8; - // the first half bit period is expected in next sample - Uart.posCnt = 0; - Uart.samples = 3; - } - } else if (bit & 1) { Uart.syncBit = bit & 1; Uart.samples = 0; } + // the first half bit period is expected in next sample + Uart.posCnt = 0; + Uart.samples = 3; + } + } else if (bit & 1) { Uart.syncBit = bit & 1; Uart.samples = 0; } - Uart.syncBit <<= 4; - Uart.state = STATE_START_OF_COMMUNICATION; - Uart.bitCnt = 0; - Uart.byteCnt = 0; - Uart.nOutOfCnt = 0; - Uart.OutOfCnt = 4; // Start at 1/4, could switch to 1/256 - Uart.dropPosition = 0; - Uart.shiftReg = 0; - //error = 0; - } else { - Uart.highCnt = 0; - } - } else { - if (Uart.highCnt < 8) - Uart.highCnt++; - } - } + Uart.syncBit <<= 4; + Uart.state = STATE_START_OF_COMMUNICATION; + Uart.bitCnt = 0; + Uart.byteCnt = 0; + Uart.nOutOfCnt = 0; + Uart.OutOfCnt = 4; // Start at 1/4, could switch to 1/256 + Uart.dropPosition = 0; + Uart.shiftReg = 0; + //error = 0; + } else { + Uart.highCnt = 0; + } + } else { + if (Uart.highCnt < 8) + Uart.highCnt++; + } + } return false; } */ @@ -501,22 +501,22 @@ static RAMFUNC int OutOfNDecoding(int bit) { //============================================================================= static tDemod Demod; static void DemodReset() { - Demod.bitCount = 0; - Demod.posCount = 0; - Demod.syncBit = 0; - Demod.shiftReg = 0; - Demod.buffer = 0; - Demod.buffer2 = 0; - Demod.buffer3 = 0; - Demod.buff = 0; - Demod.samples = 0; - Demod.len = 0; - Demod.sub = SUB_NONE; - Demod.state = DEMOD_UNSYNCD; + Demod.bitCount = 0; + Demod.posCount = 0; + Demod.syncBit = 0; + Demod.shiftReg = 0; + Demod.buffer = 0; + Demod.buffer2 = 0; + Demod.buffer3 = 0; + Demod.buff = 0; + Demod.samples = 0; + Demod.len = 0; + Demod.sub = SUB_NONE; + Demod.state = DEMOD_UNSYNCD; } static void DemodInit(uint8_t *data) { - Demod.output = data; - DemodReset(); + Demod.output = data; + DemodReset(); } // UART debug @@ -541,23 +541,23 @@ Recorded Activity (TraceLen = 162 bytes) 3232 | 3232 | Tag |bb! d4! bb! 02 02 08 04 bb! | ok | */ static void uart_debug(int error, int bit) { - Demod.output[Demod.len] = 0xBB; - Demod.len++; - Demod.output[Demod.len] = error & 0xFF; - Demod.len++; - Demod.output[Demod.len] = 0xBB; - Demod.len++; - Demod.output[Demod.len] = bit & 0xFF; - Demod.len++; - Demod.output[Demod.len] = Demod.buffer & 0xFF; - Demod.len++; - // Look harder ;-) - Demod.output[Demod.len] = Demod.buffer2 & 0xFF; - Demod.len++; - Demod.output[Demod.len] = Demod.syncBit & 0xFF; - Demod.len++; - Demod.output[Demod.len] = 0xBB; - Demod.len++; + Demod.output[Demod.len] = 0xBB; + Demod.len++; + Demod.output[Demod.len] = error & 0xFF; + Demod.len++; + Demod.output[Demod.len] = 0xBB; + Demod.len++; + Demod.output[Demod.len] = bit & 0xFF; + Demod.len++; + Demod.output[Demod.len] = Demod.buffer & 0xFF; + Demod.len++; + // Look harder ;-) + Demod.output[Demod.len] = Demod.buffer2 & 0xFF; + Demod.len++; + Demod.output[Demod.len] = Demod.syncBit & 0xFF; + Demod.len++; + Demod.output[Demod.len] = 0xBB; + Demod.len++; } /* @@ -569,219 +569,219 @@ static void uart_debug(int error, int bit) { * ISO 15693-2 * Tout = 330 µs, Tprog 1 = 4 to 15 ms, Tslot = 330 µs + (number of slots x 160 µs) * ISO 14443a -* Tout = 100 µs, Tprog = 4 to 15 ms, Tslot = 100 µs+ (number of slots x 80 µs) +* Tout = 100 µs, Tprog = 4 to 15 ms, Tslot = 100 µs+ (number of slots x 80 µs) * ISO 14443b - Tout = 76 µs, Tprog = 4 to 15 ms, Tslot = 119 µs+ (number of slots x 150 µs) + Tout = 76 µs, Tprog = 4 to 15 ms, Tslot = 119 µs+ (number of slots x 150 µs) * * * So for current implementation in ISO15693, its 330 µs from end of reader, to start of card. */ static RAMFUNC int ManchesterDecoding_iclass( uint32_t v) { - int bit; - int modulation; - int error = 0; + int bit; + int modulation; + int error = 0; - bit = Demod.buffer; - Demod.buffer = Demod.buffer2; - Demod.buffer2 = Demod.buffer3; - Demod.buffer3 = v; + bit = Demod.buffer; + Demod.buffer = Demod.buffer2; + Demod.buffer2 = Demod.buffer3; + Demod.buffer3 = v; - // too few bits? - if (Demod.buff < 3) { - Demod.buff++; - return false; - } + // too few bits? + if (Demod.buff < 3) { + Demod.buff++; + return false; + } - if (Demod.state == DEMOD_UNSYNCD) { - Demod.output[Demod.len] = 0xfa; - Demod.syncBit = 0; - //Demod.samples = 0; - Demod.posCount = 1; // This is the first half bit period, so after syncing handle the second part + if (Demod.state == DEMOD_UNSYNCD) { + Demod.output[Demod.len] = 0xfa; + Demod.syncBit = 0; + //Demod.samples = 0; + Demod.posCount = 1; // This is the first half bit period, so after syncing handle the second part - if (bit & 0x08) - Demod.syncBit = 0x08; + if (bit & 0x08) + Demod.syncBit = 0x08; - if (bit & 0x04) { - if (Demod.syncBit) - bit <<= 4; + if (bit & 0x04) { + if (Demod.syncBit) + bit <<= 4; - Demod.syncBit = 0x04; - } + Demod.syncBit = 0x04; + } - if (bit & 0x02) { - if (Demod.syncBit) - bit <<= 2; + if (bit & 0x02) { + if (Demod.syncBit) + bit <<= 2; - Demod.syncBit = 0x02; - } + Demod.syncBit = 0x02; + } - if (bit & 0x01 && Demod.syncBit) - Demod.syncBit = 0x01; + if (bit & 0x01 && Demod.syncBit) + Demod.syncBit = 0x01; - if (Demod.syncBit) { - Demod.len = 0; - Demod.state = DEMOD_START_OF_COMMUNICATION; - Demod.sub = SUB_FIRST_HALF; - Demod.bitCount = 0; - Demod.shiftReg = 0; - Demod.samples = 0; + if (Demod.syncBit) { + Demod.len = 0; + Demod.state = DEMOD_START_OF_COMMUNICATION; + Demod.sub = SUB_FIRST_HALF; + Demod.bitCount = 0; + Demod.shiftReg = 0; + Demod.samples = 0; - if (Demod.posCount) { + if (Demod.posCount) { - switch (Demod.syncBit) { - case 0x08: Demod.samples = 3; break; - case 0x04: Demod.samples = 2; break; - case 0x02: Demod.samples = 1; break; - case 0x01: Demod.samples = 0; break; - } - // SOF must be long burst... otherwise stay unsynced!!! - if (!(Demod.buffer & Demod.syncBit) || !(Demod.buffer2 & Demod.syncBit)) - Demod.state = DEMOD_UNSYNCD; + switch (Demod.syncBit) { + case 0x08: Demod.samples = 3; break; + case 0x04: Demod.samples = 2; break; + case 0x02: Demod.samples = 1; break; + case 0x01: Demod.samples = 0; break; + } + // SOF must be long burst... otherwise stay unsynced!!! + if (!(Demod.buffer & Demod.syncBit) || !(Demod.buffer2 & Demod.syncBit)) + Demod.state = DEMOD_UNSYNCD; - } else { - // SOF must be long burst... otherwise stay unsynced!!! - if (!(Demod.buffer2 & Demod.syncBit) || !(Demod.buffer3 & Demod.syncBit)) { - Demod.state = DEMOD_UNSYNCD; - error = 0x88; - uart_debug(error, bit); - return false; - } - } - error = 0; - } - return false; - } + } else { + // SOF must be long burst... otherwise stay unsynced!!! + if (!(Demod.buffer2 & Demod.syncBit) || !(Demod.buffer3 & Demod.syncBit)) { + Demod.state = DEMOD_UNSYNCD; + error = 0x88; + uart_debug(error, bit); + return false; + } + } + error = 0; + } + return false; + } - // state is DEMOD is in SYNC from here on. + // state is DEMOD is in SYNC from here on. - modulation = bit & Demod.syncBit; - modulation |= ((bit << 1) ^ ((Demod.buffer & 0x08) >> 3)) & Demod.syncBit; - Demod.samples += 4; + modulation = bit & Demod.syncBit; + modulation |= ((bit << 1) ^ ((Demod.buffer & 0x08) >> 3)) & Demod.syncBit; + Demod.samples += 4; - if (Demod.posCount == 0) { - Demod.posCount = 1; - Demod.sub = (modulation) ? SUB_FIRST_HALF : SUB_NONE; - return false; - } + if (Demod.posCount == 0) { + Demod.posCount = 1; + Demod.sub = (modulation) ? SUB_FIRST_HALF : SUB_NONE; + return false; + } - Demod.posCount = 0; + Demod.posCount = 0; - if (modulation) { + if (modulation) { - if (Demod.sub == SUB_FIRST_HALF) - Demod.sub = SUB_BOTH; - else - Demod.sub = SUB_SECOND_HALF; - } + if (Demod.sub == SUB_FIRST_HALF) + Demod.sub = SUB_BOTH; + else + Demod.sub = SUB_SECOND_HALF; + } - if (Demod.sub == SUB_NONE) { - if (Demod.state == DEMOD_SOF_COMPLETE) { - Demod.output[Demod.len] = 0x0f; - Demod.len++; - Demod.state = DEMOD_UNSYNCD; - return true; - } else { - Demod.state = DEMOD_ERROR_WAIT; - error = 0x33; - } - } + if (Demod.sub == SUB_NONE) { + if (Demod.state == DEMOD_SOF_COMPLETE) { + Demod.output[Demod.len] = 0x0f; + Demod.len++; + Demod.state = DEMOD_UNSYNCD; + return true; + } else { + Demod.state = DEMOD_ERROR_WAIT; + error = 0x33; + } + } - switch (Demod.state) { + switch (Demod.state) { - case DEMOD_START_OF_COMMUNICATION: - if (Demod.sub == SUB_BOTH) { + case DEMOD_START_OF_COMMUNICATION: + if (Demod.sub == SUB_BOTH) { - Demod.state = DEMOD_START_OF_COMMUNICATION2; - Demod.posCount = 1; - Demod.sub = SUB_NONE; - } else { - Demod.output[Demod.len] = 0xab; - Demod.state = DEMOD_ERROR_WAIT; - error = 0xd2; - } - break; + Demod.state = DEMOD_START_OF_COMMUNICATION2; + Demod.posCount = 1; + Demod.sub = SUB_NONE; + } else { + Demod.output[Demod.len] = 0xab; + Demod.state = DEMOD_ERROR_WAIT; + error = 0xd2; + } + break; - case DEMOD_START_OF_COMMUNICATION2: - if (Demod.sub == SUB_SECOND_HALF) { - Demod.state = DEMOD_START_OF_COMMUNICATION3; - } else { - Demod.output[Demod.len] = 0xab; - Demod.state = DEMOD_ERROR_WAIT; - error = 0xd3; - } - break; + case DEMOD_START_OF_COMMUNICATION2: + if (Demod.sub == SUB_SECOND_HALF) { + Demod.state = DEMOD_START_OF_COMMUNICATION3; + } else { + Demod.output[Demod.len] = 0xab; + Demod.state = DEMOD_ERROR_WAIT; + error = 0xd3; + } + break; - case DEMOD_START_OF_COMMUNICATION3: - if (Demod.sub == SUB_SECOND_HALF) { - Demod.state = DEMOD_SOF_COMPLETE; - } else { - Demod.output[Demod.len] = 0xab; - Demod.state = DEMOD_ERROR_WAIT; - error = 0xd4; - } - break; + case DEMOD_START_OF_COMMUNICATION3: + if (Demod.sub == SUB_SECOND_HALF) { + Demod.state = DEMOD_SOF_COMPLETE; + } else { + Demod.output[Demod.len] = 0xab; + Demod.state = DEMOD_ERROR_WAIT; + error = 0xd4; + } + break; - case DEMOD_SOF_COMPLETE: - case DEMOD_MANCHESTER_D: - case DEMOD_MANCHESTER_E: - // OPPOSITE FROM ISO14443 - 11110000 = 0 (1 in 14443) - // 00001111 = 1 (0 in 14443) - if (Demod.sub == SUB_SECOND_HALF) { // SUB_FIRST_HALF - Demod.bitCount++; - Demod.shiftReg = (Demod.shiftReg >> 1) ^ 0x100; - Demod.state = DEMOD_MANCHESTER_D; - } else if (Demod.sub == SUB_FIRST_HALF) { // SUB_SECOND_HALF - Demod.bitCount++; - Demod.shiftReg >>= 1; - Demod.state = DEMOD_MANCHESTER_E; - } else if (Demod.sub == SUB_BOTH) { - Demod.state = DEMOD_MANCHESTER_F; - } else { - Demod.state = DEMOD_ERROR_WAIT; - error = 0x55; - } - break; + case DEMOD_SOF_COMPLETE: + case DEMOD_MANCHESTER_D: + case DEMOD_MANCHESTER_E: + // OPPOSITE FROM ISO14443 - 11110000 = 0 (1 in 14443) + // 00001111 = 1 (0 in 14443) + if (Demod.sub == SUB_SECOND_HALF) { // SUB_FIRST_HALF + Demod.bitCount++; + Demod.shiftReg = (Demod.shiftReg >> 1) ^ 0x100; + Demod.state = DEMOD_MANCHESTER_D; + } else if (Demod.sub == SUB_FIRST_HALF) { // SUB_SECOND_HALF + Demod.bitCount++; + Demod.shiftReg >>= 1; + Demod.state = DEMOD_MANCHESTER_E; + } else if (Demod.sub == SUB_BOTH) { + Demod.state = DEMOD_MANCHESTER_F; + } else { + Demod.state = DEMOD_ERROR_WAIT; + error = 0x55; + } + break; - case DEMOD_MANCHESTER_F: - // Tag response does not need to be a complete byte! - if (Demod.len > 0 || Demod.bitCount > 0) { - if (Demod.bitCount > 1) { // was > 0, do not interpret last closing bit, is part of EOF - Demod.shiftReg >>= (9 - Demod.bitCount); // right align data - Demod.output[Demod.len] = Demod.shiftReg & 0xff; - Demod.len++; - } + case DEMOD_MANCHESTER_F: + // Tag response does not need to be a complete byte! + if (Demod.len > 0 || Demod.bitCount > 0) { + if (Demod.bitCount > 1) { // was > 0, do not interpret last closing bit, is part of EOF + Demod.shiftReg >>= (9 - Demod.bitCount); // right align data + Demod.output[Demod.len] = Demod.shiftReg & 0xff; + Demod.len++; + } - Demod.state = DEMOD_UNSYNCD; - return true; - } else { - Demod.output[Demod.len] = 0xad; - Demod.state = DEMOD_ERROR_WAIT; - error = 0x03; - } - break; + Demod.state = DEMOD_UNSYNCD; + return true; + } else { + Demod.output[Demod.len] = 0xad; + Demod.state = DEMOD_ERROR_WAIT; + error = 0x03; + } + break; - case DEMOD_ERROR_WAIT: - Demod.state = DEMOD_UNSYNCD; - break; + case DEMOD_ERROR_WAIT: + Demod.state = DEMOD_UNSYNCD; + break; - default: - Demod.output[Demod.len] = 0xdd; - Demod.state = DEMOD_UNSYNCD; - break; - } + default: + Demod.output[Demod.len] = 0xdd; + Demod.state = DEMOD_UNSYNCD; + break; + } - if (Demod.bitCount >= 8) { - Demod.shiftReg >>= 1; - Demod.output[Demod.len] = (Demod.shiftReg & 0xff); - Demod.len++; - Demod.bitCount = 0; - Demod.shiftReg = 0; - } + if (Demod.bitCount >= 8) { + Demod.shiftReg >>= 1; + Demod.output[Demod.len] = (Demod.shiftReg & 0xff); + Demod.len++; + Demod.bitCount = 0; + Demod.shiftReg = 0; + } - if (error) { - uart_debug(error, bit); - return true; - } + if (error) { + uart_debug(error, bit); + return true; + } return false; } @@ -791,49 +791,49 @@ static RAMFUNC int ManchesterDecoding_iclass( uint32_t v) { // Both sides of communication! //============================================================================= static void iclass_setup_sniff(void){ - if (MF_DBGLEVEL > 3) Dbprintf("iclass_setup_sniff Enter"); + if (MF_DBGLEVEL > 3) Dbprintf("iclass_setup_sniff Enter"); - LEDsoff(); + LEDsoff(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - // connect Demodulated Signal to ADC: - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + // connect Demodulated Signal to ADC: + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - // Set up the synchronous serial port - FpgaSetupSsc(); + // Set up the synchronous serial port + FpgaSetupSsc(); - BigBuf_free(); BigBuf_Clear_ext(false); - clear_trace(); - set_tracing(true); + BigBuf_free(); BigBuf_Clear_ext(false); + clear_trace(); + set_tracing(true); - // Initialize Demod and Uart structs - DemodInit(BigBuf_malloc(ICLASS_BUFFER_SIZE)); + // Initialize Demod and Uart structs + DemodInit(BigBuf_malloc(ICLASS_BUFFER_SIZE)); - uart_init(BigBuf_malloc(ICLASS_BUFFER_SIZE)); - //UartInit(BigBuf_malloc(ICLASS_BUFFER_SIZE)); + uart_init(BigBuf_malloc(ICLASS_BUFFER_SIZE)); + //UartInit(BigBuf_malloc(ICLASS_BUFFER_SIZE)); - if (MF_DBGLEVEL > 1) { - // Print debug information about the buffer sizes - Dbprintf("[+] Sniffing buffers initialized:"); - Dbprintf(" Trace: %i bytes", BigBuf_max_traceLen()); - Dbprintf(" Reader -> tag: %i bytes", ICLASS_BUFFER_SIZE); - Dbprintf(" tag -> Reader: %i bytes", ICLASS_BUFFER_SIZE); - Dbprintf(" DMA: %i bytes", ICLASS_DMA_BUFFER_SIZE); - } + if (MF_DBGLEVEL > 1) { + // Print debug information about the buffer sizes + Dbprintf("[+] Sniffing buffers initialized:"); + Dbprintf(" Trace: %i bytes", BigBuf_max_traceLen()); + Dbprintf(" Reader -> tag: %i bytes", ICLASS_BUFFER_SIZE); + Dbprintf(" tag -> Reader: %i bytes", ICLASS_BUFFER_SIZE); + Dbprintf(" DMA: %i bytes", ICLASS_DMA_BUFFER_SIZE); + } - // Set FPGA in the appropriate mode + // Set FPGA in the appropriate mode // put the FPGA in the appropriate mode FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER); - SpinDelay(200); + SpinDelay(200); - // Start the SSP timer - StartCountSspClk(); + // Start the SSP timer + StartCountSspClk(); - LED_A_ON(); - if (MF_DBGLEVEL > 3) Dbprintf("[+] iclass_setup_sniff Exit"); + LED_A_ON(); + if (MF_DBGLEVEL > 3) Dbprintf("[+] iclass_setup_sniff Exit"); } //----------------------------------------------------------------------------- @@ -844,130 +844,130 @@ static void iclass_setup_sniff(void){ // turn off afterwards void RAMFUNC SniffIClass(void) { - //int datalen = 0; - uint32_t previous_data = 0; - uint32_t time_0 = 0, time_start = 0, time_stop = 0; + //int datalen = 0; + uint32_t previous_data = 0; + uint32_t time_0 = 0, time_start = 0, time_stop = 0; uint32_t sniffCounter = 0; - bool TagIsActive = false; - bool ReaderIsActive = false; + bool TagIsActive = false; + bool ReaderIsActive = false; - iclass_setup_sniff(); + iclass_setup_sniff(); // The DMA buffer, used to stream samples from the FPGA - // *dmaBuf is the start reference. + // *dmaBuf is the start reference. uint8_t *dmaBuf = BigBuf_malloc(ICLASS_DMA_BUFFER_SIZE); - // pointer to samples from fpga + // pointer to samples from fpga uint8_t *data = dmaBuf; - // Setup and start DMA. - if ( !FpgaSetupSscDma(dmaBuf, ICLASS_DMA_BUFFER_SIZE) ){ - if (MF_DBGLEVEL > 1) DbpString("[-] FpgaSetupSscDma failed. Exiting"); - return; - } + // Setup and start DMA. + if ( !FpgaSetupSscDma(dmaBuf, ICLASS_DMA_BUFFER_SIZE) ){ + if (MF_DBGLEVEL > 1) DbpString("[-] FpgaSetupSscDma failed. Exiting"); + return; + } - // time ZERO, the point from which it all is calculated. - time_0 = GetCountSspClk(); + // time ZERO, the point from which it all is calculated. + time_0 = GetCountSspClk(); - int div = 0; - uint8_t tag_byte = 0, foo = 0; + int div = 0; + uint8_t tag_byte = 0, foo = 0; // loop and listen - // every sample (1byte in data), - // contains HIGH nibble = reader data - // contains LOW nibble = tag data - // so two bytes are needed in order to get 1byte of either reader or tag data. (ie 2 sample bytes) - // since reader data is manchester encoded, we need 2bytes of data in order to get one demoded byte. (ie: 4 sample bytes) - while (!BUTTON_PRESS()) { + // every sample (1byte in data), + // contains HIGH nibble = reader data + // contains LOW nibble = tag data + // so two bytes are needed in order to get 1byte of either reader or tag data. (ie 2 sample bytes) + // since reader data is manchester encoded, we need 2bytes of data in order to get one demoded byte. (ie: 4 sample bytes) + while (!BUTTON_PRESS()) { WDT_HIT(); - previous_data <<= 8; - previous_data |= *data; + previous_data <<= 8; + previous_data |= *data; - sniffCounter++; - data++; + sniffCounter++; + data++; - if (data == dmaBuf + ICLASS_DMA_BUFFER_SIZE) { - data = dmaBuf; - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; - AT91C_BASE_PDC_SSC->PDC_RNCR = ICLASS_DMA_BUFFER_SIZE; - } + if (data == dmaBuf + ICLASS_DMA_BUFFER_SIZE) { + data = dmaBuf; + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; + AT91C_BASE_PDC_SSC->PDC_RNCR = ICLASS_DMA_BUFFER_SIZE; + } - if ( *data & 0xF) { - //tag_byte <<= 1; - tag_byte ^= (1 << 4); - foo ^= (1 << (3 - div)); - Dbprintf(" %d|%x == %d|%x", tag_byte, tag_byte, foo, foo); - } - div++; + if ( *data & 0xF) { + //tag_byte <<= 1; + tag_byte ^= (1 << 4); + foo ^= (1 << (3 - div)); + Dbprintf(" %d|%x == %d|%x", tag_byte, tag_byte, foo, foo); + } + div++; - // every odd sample - if (sniffCounter & 0x01) { - // no need to try decoding reader data if the tag is sending - // READER TO CARD - if (!TagIsActive) { - LED_C_INV(); - // HIGH nibble is always reader data. - uint8_t reader_byte = (previous_data & 0xF0) | (*data >> 4); - uart_samples(reader_byte); - if (Uart.frame_done) { - time_stop = GetCountSspClk() - time_0; - LogTrace( Uart.buf, Uart.len, time_start, time_stop, NULL, true); - DemodReset(); - uart_reset(); - } else { - time_start = GetCountSspClk() - time_0; - } - ReaderIsActive = Uart.frame_done; - } - } - // every four sample - if ( (sniffCounter % 4) == 0) { - // need two samples to feed Manchester - // no need to try decoding tag data if the reader is sending - and we cannot afford the time - // CARD TO READER - if (!ReaderIsActive) { - LED_C_INV(); - // LOW nibble is always tag data. - /* + // every odd sample + if (sniffCounter & 0x01) { + // no need to try decoding reader data if the tag is sending + // READER TO CARD + if (!TagIsActive) { + LED_C_INV(); + // HIGH nibble is always reader data. + uint8_t reader_byte = (previous_data & 0xF0) | (*data >> 4); + uart_samples(reader_byte); + if (Uart.frame_done) { + time_stop = GetCountSspClk() - time_0; + LogTrace( Uart.buf, Uart.len, time_start, time_stop, NULL, true); + DemodReset(); + uart_reset(); + } else { + time_start = GetCountSspClk() - time_0; + } + ReaderIsActive = Uart.frame_done; + } + } + // every four sample + if ( (sniffCounter % 4) == 0) { + // need two samples to feed Manchester + // no need to try decoding tag data if the reader is sending - and we cannot afford the time + // CARD TO READER + if (!ReaderIsActive) { + LED_C_INV(); + // LOW nibble is always tag data. + /* - uint32_t tag_byte = - ((previous_data & 0x0F000000) >> 8 ) | - ((previous_data & 0x000F0000) >> 4 ) | - ((previous_data & 0x00000F00) ) | - ((previous_data & 0x0000000F) << 4 ) | - (*data & 0xF); - */ + uint32_t tag_byte = + ((previous_data & 0x0F000000) >> 8 ) | + ((previous_data & 0x000F0000) >> 4 ) | + ((previous_data & 0x00000F00) ) | + ((previous_data & 0x0000000F) << 4 ) | + (*data & 0xF); + */ - //uint8_t tag_byte = ((previous_data & 0xF) << 4 ) | (*data & 0xF); - if (ManchesterDecoding_iclass(foo)) { - time_stop = GetCountSspClk() - time_0; - LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false); - DemodReset(); - uart_reset(); - } else { - time_start = GetCountSspClk() - time_0; - } - TagIsActive = (Demod.state != DEMOD_UNSYNCD); - } - tag_byte = 0; - foo = 0; - div = 0; - } - } // end main loop + //uint8_t tag_byte = ((previous_data & 0xF) << 4 ) | (*data & 0xF); + if (ManchesterDecoding_iclass(foo)) { + time_stop = GetCountSspClk() - time_0; + LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false); + DemodReset(); + uart_reset(); + } else { + time_start = GetCountSspClk() - time_0; + } + TagIsActive = (Demod.state != DEMOD_UNSYNCD); + } + tag_byte = 0; + foo = 0; + div = 0; + } + } // end main loop - if (MF_DBGLEVEL >= 1) { - DbpString("[+] Sniff statistics:"); - Dbhexdump(ICLASS_DMA_BUFFER_SIZE, data, false); - } + if (MF_DBGLEVEL >= 1) { + DbpString("[+] Sniff statistics:"); + Dbhexdump(ICLASS_DMA_BUFFER_SIZE, data, false); + } - switch_off(); + switch_off(); } void rotateCSN(uint8_t* originalCSN, uint8_t* rotatedCSN) { - int i; - for(i = 0; i < 8; i++) - rotatedCSN[i] = (originalCSN[i] >> 3) | (originalCSN[(i+1)%8] << 5); + int i; + for(i = 0; i < 8; i++) + rotatedCSN[i] = (originalCSN[i] >> 3) | (originalCSN[(i+1)%8] << 5); } //----------------------------------------------------------------------------- @@ -981,142 +981,142 @@ static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen) // only, since we are receiving, not transmitting). // Signal field is off with the appropriate LED LED_D_OFF(); - uart_init(received); + uart_init(received); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN); - // clear RXRDY: + // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - while (!BUTTON_PRESS()) { + while (!BUTTON_PRESS()) { WDT_HIT(); - // keep tx buffer in a defined state anyway. + // keep tx buffer in a defined state anyway. if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) AT91C_BASE_SSC->SSC_THR = 0x00; - // wait for byte to become available in rx holding register + // wait for byte to become available in rx holding register if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; uart_samples(b); if (Uart.frame_done) { *len = Uart.len; - return true; - } + return true; + } } } - return false; + return false; } static uint8_t encode4Bits(const uint8_t b) { - // OTA, the least significant bits first - // Manchester encoding added - // The columns are - // 1 - Bit value to send - // 2 - Reversed (big-endian) - // 3 - Machester Encoded - // 4 - Hex values + // OTA, the least significant bits first + // Manchester encoding added + // The columns are + // 1 - Bit value to send + // 2 - Reversed (big-endian) + // 3 - Machester Encoded + // 4 - Hex values - uint8_t c = b & 0xF; - switch (c) { - // 1 2 3 4 - case 15: return 0x55; // 1111 -> 1111 -> 01010101 -> 0x55 - case 14: return 0x95; // 1110 -> 0111 -> 10010101 -> 0x95 - case 13: return 0x65; // 1101 -> 1011 -> 01100101 -> 0x65 - case 12: return 0xa5; // 1100 -> 0011 -> 10100101 -> 0xa5 - case 11: return 0x59; // 1011 -> 1101 -> 01011001 -> 0x59 - case 10: return 0x99; // 1010 -> 0101 -> 10011001 -> 0x99 - case 9: return 0x69; // 1001 -> 1001 -> 01101001 -> 0x69 - case 8: return 0xa9; // 1000 -> 0001 -> 10101001 -> 0xa9 - case 7: return 0x56; // 0111 -> 1110 -> 01010110 -> 0x56 - case 6: return 0x96; // 0110 -> 0110 -> 10010110 -> 0x96 - case 5: return 0x66; // 0101 -> 1010 -> 01100110 -> 0x66 - case 4: return 0xa6; // 0100 -> 0010 -> 10100110 -> 0xa6 - case 3: return 0x5a; // 0011 -> 1100 -> 01011010 -> 0x5a - case 2: return 0x9a; // 0010 -> 0100 -> 10011010 -> 0x9a - case 1: return 0x6a; // 0001 -> 1000 -> 01101010 -> 0x6a - default: return 0xaa; // 0000 -> 0000 -> 10101010 -> 0xaa - } + uint8_t c = b & 0xF; + switch (c) { + // 1 2 3 4 + case 15: return 0x55; // 1111 -> 1111 -> 01010101 -> 0x55 + case 14: return 0x95; // 1110 -> 0111 -> 10010101 -> 0x95 + case 13: return 0x65; // 1101 -> 1011 -> 01100101 -> 0x65 + case 12: return 0xa5; // 1100 -> 0011 -> 10100101 -> 0xa5 + case 11: return 0x59; // 1011 -> 1101 -> 01011001 -> 0x59 + case 10: return 0x99; // 1010 -> 0101 -> 10011001 -> 0x99 + case 9: return 0x69; // 1001 -> 1001 -> 01101001 -> 0x69 + case 8: return 0xa9; // 1000 -> 0001 -> 10101001 -> 0xa9 + case 7: return 0x56; // 0111 -> 1110 -> 01010110 -> 0x56 + case 6: return 0x96; // 0110 -> 0110 -> 10010110 -> 0x96 + case 5: return 0x66; // 0101 -> 1010 -> 01100110 -> 0x66 + case 4: return 0xa6; // 0100 -> 0010 -> 10100110 -> 0xa6 + case 3: return 0x5a; // 0011 -> 1100 -> 01011010 -> 0x5a + case 2: return 0x9a; // 0010 -> 0100 -> 10011010 -> 0x9a + case 1: return 0x6a; // 0001 -> 1000 -> 01101010 -> 0x6a + default: return 0xaa; // 0000 -> 0000 -> 10101010 -> 0xaa + } } //----------------------------------------------------------------------------- // Prepare tag messages //----------------------------------------------------------------------------- static void CodeIClassTagAnswer(const uint8_t *cmd, int len) { - /* - * SOF comprises 3 parts; - * * An unmodulated time of 56.64 us - * * 24 pulses of 423.75 KHz (fc/32) - * * A logic 1, which starts with an unmodulated time of 18.88us - * followed by 8 pulses of 423.75kHz (fc/32) - * - * - * EOF comprises 3 parts: - * - A logic 0 (which starts with 8 pulses of fc/32 followed by an unmodulated - * time of 18.88us. - * - 24 pulses of fc/32 - * - An unmodulated time of 56.64 us - * - * - * A logic 0 starts with 8 pulses of fc/32 - * followed by an unmodulated time of 256/fc (~18,88us). - * - * A logic 0 starts with unmodulated time of 256/fc (~18,88us) followed by - * 8 pulses of fc/32 (also 18.88us) - * - * The mode FPGA_HF_SIMULATOR_MODULATE_424K_8BIT which we use to simulate tag, - * works like this. - * - A 1-bit input to the FPGA becomes 8 pulses on 423.5kHz (fc/32) (18.88us). - * - A 0-bit input to the FPGA becomes an unmodulated time of 18.88us - * - * In this mode - * SOF can be written as 00011101 = 0x1D - * EOF can be written as 10111000 = 0xb8 - * logic 1 be written as 01 = 0x1 - * logic 0 be written as 10 = 0x2 - * - * */ - ToSendReset(); + /* + * SOF comprises 3 parts; + * * An unmodulated time of 56.64 us + * * 24 pulses of 423.75 KHz (fc/32) + * * A logic 1, which starts with an unmodulated time of 18.88us + * followed by 8 pulses of 423.75kHz (fc/32) + * + * + * EOF comprises 3 parts: + * - A logic 0 (which starts with 8 pulses of fc/32 followed by an unmodulated + * time of 18.88us. + * - 24 pulses of fc/32 + * - An unmodulated time of 56.64 us + * + * + * A logic 0 starts with 8 pulses of fc/32 + * followed by an unmodulated time of 256/fc (~18,88us). + * + * A logic 0 starts with unmodulated time of 256/fc (~18,88us) followed by + * 8 pulses of fc/32 (also 18.88us) + * + * The mode FPGA_HF_SIMULATOR_MODULATE_424K_8BIT which we use to simulate tag, + * works like this. + * - A 1-bit input to the FPGA becomes 8 pulses on 423.5kHz (fc/32) (18.88us). + * - A 0-bit input to the FPGA becomes an unmodulated time of 18.88us + * + * In this mode + * SOF can be written as 00011101 = 0x1D + * EOF can be written as 10111000 = 0xb8 + * logic 1 be written as 01 = 0x1 + * logic 0 be written as 10 = 0x2 + * + * */ + ToSendReset(); - // Send SOF - ToSend[++ToSendMax] = 0x1D; + // Send SOF + ToSend[++ToSendMax] = 0x1D; - int i; - for(i = 0; i < len; i++) { - uint8_t b = cmd[i]; - ToSend[++ToSendMax] = encode4Bits(b & 0xF); // least significant half - ToSend[++ToSendMax] = encode4Bits((b >> 4) & 0xF); // most significant half - } + int i; + for(i = 0; i < len; i++) { + uint8_t b = cmd[i]; + ToSend[++ToSendMax] = encode4Bits(b & 0xF); // least significant half + ToSend[++ToSendMax] = encode4Bits((b >> 4) & 0xF); // most significant half + } - // Send EOF - ToSend[++ToSendMax] = 0xB8; - //lastProxToAirDuration = 8*ToSendMax - 3*8 - 3*8;//Not counting zeroes in the beginning or end - // Convert from last byte pos to length - ToSendMax++; + // Send EOF + ToSend[++ToSendMax] = 0xB8; + //lastProxToAirDuration = 8*ToSendMax - 3*8 - 3*8;//Not counting zeroes in the beginning or end + // Convert from last byte pos to length + ToSendMax++; } // Only SOF static void CodeIClassTagSOF() { - //So far a dummy implementation, not used - //int lastProxToAirDuration =0; + //So far a dummy implementation, not used + //int lastProxToAirDuration =0; - ToSendReset(); - // Send SOF - ToSend[++ToSendMax] = 0x1D; - // lastProxToAirDuration = 8*ToSendMax - 3*8;//Not counting zeroes in the beginning + ToSendReset(); + // Send SOF + ToSend[++ToSendMax] = 0x1D; + // lastProxToAirDuration = 8*ToSendMax - 3*8;//Not counting zeroes in the beginning - // Convert from last byte pos to length - ToSendMax++; + // Convert from last byte pos to length + ToSendMax++; } /** * @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) + * - 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 @@ -1124,107 +1124,107 @@ static void CodeIClassTagSOF() { // turn off afterwards void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) { - if (MF_DBGLEVEL > 3) Dbprintf("[+] iClass_simulate Enter"); + if (MF_DBGLEVEL > 3) Dbprintf("[+] iClass_simulate Enter"); - LEDsoff(); + LEDsoff(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - // this will clear out bigbuf memory, the eload command must select this before! - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - FpgaSetupSsc(); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // this will clear out bigbuf memory, the eload command must select this before! + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + FpgaSetupSsc(); + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - // Enable and clear the trace - clear_trace(); - set_tracing(true); + // Enable and clear the trace + clear_trace(); + set_tracing(true); - uint32_t simType = arg0; - uint32_t numberOfCSNS = arg1; + uint32_t simType = arg0; + uint32_t numberOfCSNS = arg1; - //Use the emulator memory for SIM - uint8_t *emulator = BigBuf_get_EM_addr(); - uint8_t mac_responses[USB_CMD_DATA_SIZE] = { 0 }; + //Use the emulator memory for SIM + uint8_t *emulator = BigBuf_get_EM_addr(); + uint8_t mac_responses[USB_CMD_DATA_SIZE] = { 0 }; - if (simType == 0) { - // Use the CSN from commandline - memcpy(emulator, datain, 8); - doIClassSimulation(MODE_SIM_CSN, NULL); - } else if (simType == 1) { - //Default CSN - uint8_t csn_crc[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 }; - // Use the CSN from commandline - memcpy(emulator, csn_crc, 8); - doIClassSimulation(MODE_SIM_CSN, NULL); - } else if (simType == 2) { + if (simType == 0) { + // Use the CSN from commandline + memcpy(emulator, datain, 8); + doIClassSimulation(MODE_SIM_CSN, NULL); + } else if (simType == 1) { + //Default CSN + uint8_t csn_crc[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 }; + // Use the CSN from commandline + memcpy(emulator, csn_crc, 8); + doIClassSimulation(MODE_SIM_CSN, NULL); + } else if (simType == 2) { - Dbprintf("[+] going into attack mode, %d CSNS sent", numberOfCSNS); - // 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. - #define EPURSE_MAC_SIZE 16 - int i = 0; - for (; i < numberOfCSNS && i * EPURSE_MAC_SIZE + 8 < USB_CMD_DATA_SIZE; i++) { - // The usb data is 512 bytes, fitting 65 8-byte CSNs in there. + Dbprintf("[+] going into attack mode, %d CSNS sent", numberOfCSNS); + // 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. + #define EPURSE_MAC_SIZE 16 + int i = 0; + for (; i < numberOfCSNS && i * EPURSE_MAC_SIZE + 8 < USB_CMD_DATA_SIZE; i++) { + // The usb data is 512 bytes, fitting 65 8-byte CSNs in there. - memcpy(emulator, datain + (i*8), 8); + memcpy(emulator, datain + (i*8), 8); - if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses+i * EPURSE_MAC_SIZE)) { - // Button pressed - cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i, 0, mac_responses, i * EPURSE_MAC_SIZE); - goto out; - } - } - cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i, 0, mac_responses, i * EPURSE_MAC_SIZE); + if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses+i * EPURSE_MAC_SIZE)) { + // Button pressed + cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i, 0, mac_responses, i * EPURSE_MAC_SIZE); + goto out; + } + } + cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i, 0, mac_responses, i * EPURSE_MAC_SIZE); - } else if (simType == 3){ - //This is 'full sim' mode, where we use the emulator storage for data. - //ie: BigBuf_get_EM_addr should be previously filled with data from the "eload" command - doIClassSimulation(MODE_FULLSIM, NULL); - } else if (simType == 4){ + } else if (simType == 3){ + //This is 'full sim' mode, where we use the emulator storage for data. + //ie: BigBuf_get_EM_addr should be previously filled with data from the "eload" command + doIClassSimulation(MODE_FULLSIM, NULL); + } else if (simType == 4){ - // This is the KEYROLL version of sim 2. - // the collected data (mac_response) is doubled out since we are trying to collect both keys in the keyroll process. - // Keyroll iceman 9 csns * 8 * 2 = 144 - // keyroll CARL55 15csns * 8 * 2 = 15 * 8 * 2 = 240 - Dbprintf("[+] going into attack keyroll mode, %d CSNS sent", numberOfCSNS); - // 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. + // This is the KEYROLL version of sim 2. + // the collected data (mac_response) is doubled out since we are trying to collect both keys in the keyroll process. + // Keyroll iceman 9 csns * 8 * 2 = 144 + // keyroll CARL55 15csns * 8 * 2 = 15 * 8 * 2 = 240 + Dbprintf("[+] going into attack keyroll mode, %d CSNS sent", numberOfCSNS); + // 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. - // keyroll mode, reader swaps between old key and new key alternatively when fail a authentication. - // attack below is same as SIM 2, but we run the CSN twice to collected the mac for both keys. - int i = 0; - // The usb data is 512 bytes, fitting 65 8-byte CSNs in there. iceman fork uses 9 CSNS - for (; i < numberOfCSNS && i * EPURSE_MAC_SIZE + 8 < USB_CMD_DATA_SIZE; i++) { + // keyroll mode, reader swaps between old key and new key alternatively when fail a authentication. + // attack below is same as SIM 2, but we run the CSN twice to collected the mac for both keys. + int i = 0; + // The usb data is 512 bytes, fitting 65 8-byte CSNs in there. iceman fork uses 9 CSNS + for (; i < numberOfCSNS && i * EPURSE_MAC_SIZE + 8 < USB_CMD_DATA_SIZE; i++) { - memcpy(emulator, datain + (i*8), 8); + memcpy(emulator, datain + (i*8), 8); - // keyroll 1 - if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses + i * EPURSE_MAC_SIZE )) { - cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i*2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2); - // Button pressed - goto out; - } + // keyroll 1 + if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses + i * EPURSE_MAC_SIZE )) { + cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i*2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2); + // Button pressed + goto out; + } - // keyroll 2 - if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses + (i + numberOfCSNS) * EPURSE_MAC_SIZE )) { - cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i*2, 0, mac_responses, i * EPURSE_MAC_SIZE* 2); - // Button pressed - goto out; - } - } - // double the amount of collected data. - cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i*2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2 ); + // keyroll 2 + if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses + (i + numberOfCSNS) * EPURSE_MAC_SIZE )) { + cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i*2, 0, mac_responses, i * EPURSE_MAC_SIZE* 2); + // Button pressed + goto out; + } + } + // double the amount of collected data. + cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i*2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2 ); - } 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. - DbpString("[-] the mode is not implemented, reserved for future use"); - } + } 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. + DbpString("[-] the mode is not implemented, reserved for future use"); + } out: - switch_off(); - BigBuf_free_keep_EM(); + switch_off(); + BigBuf_free_keep_EM(); } /** @@ -1234,344 +1234,344 @@ out: */ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) { - // free eventually allocated BigBuf memory - BigBuf_free_keep_EM(); + // free eventually allocated BigBuf memory + BigBuf_free_keep_EM(); - State cipher_state; + State cipher_state; - uint8_t *csn = BigBuf_get_EM_addr(); - uint8_t *emulator = csn; - uint8_t sof_data[] = { 0x0F} ; + uint8_t *csn = BigBuf_get_EM_addr(); + uint8_t *emulator = csn; + uint8_t sof_data[] = { 0x0F} ; - // CSN followed by two CRC bytes - uint8_t anticoll_data[10] = { 0 }; - uint8_t csn_data[10] = { 0 }; - memcpy(csn_data, csn, sizeof(csn_data)); + // CSN followed by two CRC bytes + uint8_t anticoll_data[10] = { 0 }; + uint8_t csn_data[10] = { 0 }; + memcpy(csn_data, csn, sizeof(csn_data)); - // Construct anticollision-CSN - rotateCSN(csn_data, anticoll_data); + // Construct anticollision-CSN + rotateCSN(csn_data, anticoll_data); - // Compute CRC on both CSNs - AddCrc(anticoll_data, 8); - AddCrc(csn_data, 8); + // Compute CRC on both CSNs + AddCrc(anticoll_data, 8); + AddCrc(csn_data, 8); - uint8_t diversified_key[8] = { 0 }; - // e-Purse - uint8_t card_challenge_data[8] = { 0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; - //uint8_t card_challenge_data[8] = { 0 }; - if (simulationMode == MODE_FULLSIM) { - //The diversified key should be stored on block 3 - //Get the diversified key from emulator memory - memcpy(diversified_key, emulator+(8*3),8); + uint8_t diversified_key[8] = { 0 }; + // e-Purse + uint8_t card_challenge_data[8] = { 0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; + //uint8_t card_challenge_data[8] = { 0 }; + if (simulationMode == MODE_FULLSIM) { + //The diversified key should be stored on block 3 + //Get the diversified key from emulator memory + memcpy(diversified_key, emulator+(8*3),8); - //Card challenge, a.k.a e-purse is on block 2 - memcpy(card_challenge_data, emulator + (8 * 2) ,8); - //Precalculate the cipher state, feeding it the CC - cipher_state = opt_doTagMAC_1(card_challenge_data, diversified_key); - } - // set epurse of sim2,4 attack - if (reader_mac_buf != NULL) { - memcpy(reader_mac_buf, card_challenge_data, 8); - } + //Card challenge, a.k.a e-purse is on block 2 + memcpy(card_challenge_data, emulator + (8 * 2) ,8); + //Precalculate the cipher state, feeding it the CC + cipher_state = opt_doTagMAC_1(card_challenge_data, diversified_key); + } + // set epurse of sim2,4 attack + if (reader_mac_buf != NULL) { + memcpy(reader_mac_buf, card_challenge_data, 8); + } - int exitLoop = 0; - // Reader 0a - // Tag 0f - // Reader 0c - // Tag anticoll. CSN - // Reader 81 anticoll. CSN - // Tag CSN + int exitLoop = 0; + // Reader 0a + // Tag 0f + // Reader 0c + // Tag anticoll. CSN + // Reader 81 anticoll. CSN + // Tag CSN - uint8_t *modulated_response; - int modulated_response_size = 0; - uint8_t* trace_data = NULL; - int trace_data_size = 0; + uint8_t *modulated_response; + int modulated_response_size = 0; + uint8_t* trace_data = NULL; + int trace_data_size = 0; - // Respond SOF -- takes 1 bytes - uint8_t *resp_sof = BigBuf_malloc(2); - int resp_sof_Len; + // Respond SOF -- takes 1 bytes + uint8_t *resp_sof = BigBuf_malloc(2); + int resp_sof_Len; - // Anticollision CSN (rotated CSN) - // 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte) - uint8_t *resp_anticoll = BigBuf_malloc(28); - int resp_anticoll_len; + // Anticollision CSN (rotated CSN) + // 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte) + uint8_t *resp_anticoll = BigBuf_malloc(28); + int resp_anticoll_len; - // CSN - // 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte) - uint8_t *resp_csn = BigBuf_malloc(28); - int resp_csn_len; + // CSN + // 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte) + uint8_t *resp_csn = BigBuf_malloc(28); + int resp_csn_len; - // configuration picopass 2ks - uint8_t *resp_conf = BigBuf_malloc(28); - int resp_conf_len; - uint8_t conf_data[10] = {0x12,0xFF,0xFF,0xFF,0x7F,0x1F,0xFF,0x3C,0x00,0x00}; - AddCrc(conf_data, 8); + // configuration picopass 2ks + uint8_t *resp_conf = BigBuf_malloc(28); + int resp_conf_len; + uint8_t conf_data[10] = {0x12,0xFF,0xFF,0xFF,0x7F,0x1F,0xFF,0x3C,0x00,0x00}; + AddCrc(conf_data, 8); - // e-Purse - // 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/bit) - uint8_t *resp_cc = BigBuf_malloc(28); - int resp_cc_len; + // e-Purse + // 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/bit) + uint8_t *resp_cc = BigBuf_malloc(28); + int resp_cc_len; - // Application Issuer Area - uint8_t *resp_aia = BigBuf_malloc(28); - int resp_aia_len; - uint8_t aia_data[10] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00}; - AddCrc(aia_data, 8); + // Application Issuer Area + uint8_t *resp_aia = BigBuf_malloc(28); + int resp_aia_len; + uint8_t aia_data[10] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00}; + AddCrc(aia_data, 8); - // receive command - uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); - int len = 0; + // receive command + uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); + int len = 0; - // Prepare card messages - ToSendMax = 0; + // Prepare card messages + ToSendMax = 0; - // First card answer: SOF - CodeIClassTagSOF(); - memcpy(resp_sof, ToSend, ToSendMax); resp_sof_Len = ToSendMax; + // First card answer: SOF + CodeIClassTagSOF(); + memcpy(resp_sof, ToSend, ToSendMax); resp_sof_Len = ToSendMax; - // Anticollision CSN - CodeIClassTagAnswer(anticoll_data, sizeof(anticoll_data)); - memcpy(resp_anticoll, ToSend, ToSendMax); resp_anticoll_len = ToSendMax; + // Anticollision CSN + CodeIClassTagAnswer(anticoll_data, sizeof(anticoll_data)); + memcpy(resp_anticoll, ToSend, ToSendMax); resp_anticoll_len = ToSendMax; - // CSN - CodeIClassTagAnswer(csn_data, sizeof(csn_data)); - memcpy(resp_csn, ToSend, ToSendMax); resp_csn_len = ToSendMax; + // CSN + CodeIClassTagAnswer(csn_data, sizeof(csn_data)); + memcpy(resp_csn, ToSend, ToSendMax); resp_csn_len = ToSendMax; - // Configuration - CodeIClassTagAnswer(conf_data, sizeof(conf_data)); - memcpy(resp_conf, ToSend, ToSendMax); resp_conf_len = ToSendMax; + // Configuration + CodeIClassTagAnswer(conf_data, sizeof(conf_data)); + memcpy(resp_conf, ToSend, ToSendMax); resp_conf_len = ToSendMax; - // e-Purse - CodeIClassTagAnswer(card_challenge_data, sizeof(card_challenge_data)); - memcpy(resp_cc, ToSend, ToSendMax); resp_cc_len = ToSendMax; + // e-Purse + CodeIClassTagAnswer(card_challenge_data, sizeof(card_challenge_data)); + memcpy(resp_cc, ToSend, ToSendMax); resp_cc_len = ToSendMax; - // Application Issuer Area - CodeIClassTagAnswer(aia_data, sizeof(aia_data)); - memcpy(resp_aia, ToSend, ToSendMax); resp_aia_len = ToSendMax; + // Application Issuer Area + CodeIClassTagAnswer(aia_data, sizeof(aia_data)); + memcpy(resp_aia, ToSend, ToSendMax); resp_aia_len = ToSendMax; - //This is used for responding to READ-block commands or other data which is dynamically generated - //First the 'trace'-data, not encoded for FPGA - uint8_t *data_generic_trace = BigBuf_malloc(8 + 2);//8 bytes data + 2byte CRC is max tag answer + //This is used for responding to READ-block commands or other data which is dynamically generated + //First the 'trace'-data, not encoded for FPGA + uint8_t *data_generic_trace = BigBuf_malloc(8 + 2);//8 bytes data + 2byte CRC is max tag answer - //Then storage for the modulated data - //Each bit is doubled when modulated for FPGA, and we also have SOF and EOF (2 bytes) - uint8_t *data_response = BigBuf_malloc( (8+2) * 2 + 2); + //Then storage for the modulated data + //Each bit is doubled when modulated for FPGA, and we also have SOF and EOF (2 bytes) + uint8_t *data_response = BigBuf_malloc( (8+2) * 2 + 2); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN); - SpinDelay(100); - StartCountSspClk(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN); + SpinDelay(100); + StartCountSspClk(); - // To control where we are in the protocol - uint32_t time_0 = GetCountSspClk(); - uint32_t t2r_stime = 0, t2r_etime = 0; - uint32_t r2t_stime = 0, r2t_etime = 0; + // To control where we are in the protocol + uint32_t time_0 = GetCountSspClk(); + uint32_t t2r_stime = 0, t2r_etime = 0; + uint32_t r2t_stime = 0, r2t_etime = 0; - LED_A_ON(); - bool buttonPressed = false; + LED_A_ON(); + bool buttonPressed = false; - while (!exitLoop) { - WDT_HIT(); + while (!exitLoop) { + WDT_HIT(); - //Signal tracer, can be used to get a trigger for an oscilloscope.. - LED_B_OFF(); LED_C_OFF(); + //Signal tracer, can be used to get a trigger for an oscilloscope.. + LED_B_OFF(); LED_C_OFF(); - r2t_stime = (GetCountSspClk() - time_0) << 4; - if (!GetIClassCommandFromReader(receivedCmd, &len, 0)) { - buttonPressed = true; - exitLoop = true; - continue; - } - r2t_etime = ((GetCountSspClk() - time_0) << 4 ) - r2t_stime; + r2t_stime = (GetCountSspClk() - time_0) << 4; + if (!GetIClassCommandFromReader(receivedCmd, &len, 0)) { + buttonPressed = true; + exitLoop = true; + continue; + } + r2t_etime = ((GetCountSspClk() - time_0) << 4 ) - r2t_stime; - // 330us normal wait, adjusted for our execution + // 330us normal wait, adjusted for our execution - LED_C_ON(); //Signal tracer + LED_C_ON(); //Signal tracer - if (receivedCmd[0] == ICLASS_CMD_ACTALL ) { // 0x0A - // Reader in anticollission phase - modulated_response = resp_sof; modulated_response_size = resp_sof_Len; //order = 1; - trace_data = sof_data; - trace_data_size = sizeof(sof_data); - // adjusted for 330 + (160*num of slot) - goto send; - } else if (receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY) { // 0x0C - if (len == 1) { - // Reader asks for anticollission CSN - modulated_response = resp_anticoll; modulated_response_size = resp_anticoll_len; //order = 2; - trace_data = anticoll_data; - trace_data_size = sizeof(anticoll_data); - goto send; - } - if (len == 4){ - // block0,1,2,5 is always readable. - switch (receivedCmd[1]){ - case 0: // csn (0c 00) - modulated_response = resp_csn; modulated_response_size = resp_csn_len; - trace_data = csn_data; - trace_data_size = sizeof(csn_data); - break; - case 1: // configuration (0c 01) - modulated_response = resp_conf; modulated_response_size = resp_conf_len; - trace_data = conf_data; - trace_data_size = sizeof(conf_data); - break; - case 2: // e-purse (0c 02) - modulated_response = resp_cc; modulated_response_size = resp_cc_len; - trace_data = card_challenge_data; - trace_data_size = sizeof(card_challenge_data); - // set epurse of sim2,4 attack - if (reader_mac_buf != NULL) { - memcpy(reader_mac_buf, card_challenge_data, 8); - } - break; - case 5:// Application Issuer Area (0c 05) - modulated_response = resp_aia; modulated_response_size = resp_aia_len; - trace_data = aia_data; - trace_data_size = sizeof(aia_data); - break; - default: break; - } - goto send; - } + if (receivedCmd[0] == ICLASS_CMD_ACTALL ) { // 0x0A + // Reader in anticollission phase + modulated_response = resp_sof; modulated_response_size = resp_sof_Len; //order = 1; + trace_data = sof_data; + trace_data_size = sizeof(sof_data); + // adjusted for 330 + (160*num of slot) + goto send; + } else if (receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY) { // 0x0C + if (len == 1) { + // Reader asks for anticollission CSN + modulated_response = resp_anticoll; modulated_response_size = resp_anticoll_len; //order = 2; + trace_data = anticoll_data; + trace_data_size = sizeof(anticoll_data); + goto send; + } + if (len == 4){ + // block0,1,2,5 is always readable. + switch (receivedCmd[1]){ + case 0: // csn (0c 00) + modulated_response = resp_csn; modulated_response_size = resp_csn_len; + trace_data = csn_data; + trace_data_size = sizeof(csn_data); + break; + case 1: // configuration (0c 01) + modulated_response = resp_conf; modulated_response_size = resp_conf_len; + trace_data = conf_data; + trace_data_size = sizeof(conf_data); + break; + case 2: // e-purse (0c 02) + modulated_response = resp_cc; modulated_response_size = resp_cc_len; + trace_data = card_challenge_data; + trace_data_size = sizeof(card_challenge_data); + // set epurse of sim2,4 attack + if (reader_mac_buf != NULL) { + memcpy(reader_mac_buf, card_challenge_data, 8); + } + break; + case 5:// Application Issuer Area (0c 05) + modulated_response = resp_aia; modulated_response_size = resp_aia_len; + trace_data = aia_data; + trace_data_size = sizeof(aia_data); + break; + default: break; + } + goto send; + } - } else if (receivedCmd[0] == ICLASS_CMD_SELECT) { // 0x81 - // Reader selects anticollission CSN. - // Tag sends the corresponding real CSN - modulated_response = resp_csn; modulated_response_size = resp_csn_len; //order = 3; - trace_data = csn_data; - trace_data_size = sizeof(csn_data); - goto send; - } else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KD) { // 0x88 - // Read e-purse (88 02) - modulated_response = resp_cc; modulated_response_size = resp_cc_len; //order = 4; - trace_data = card_challenge_data; - trace_data_size = sizeof(card_challenge_data); - LED_B_ON(); - goto send; - } else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KC) { // 0x18 - // Read e-purse (18 02) - modulated_response = resp_cc; modulated_response_size = resp_cc_len; //order = 4; - trace_data = card_challenge_data; - trace_data_size = sizeof(card_challenge_data); - LED_B_ON(); - goto send; - } else if (receivedCmd[0] == ICLASS_CMD_CHECK) { // 0x05 - // Reader random and reader MAC!!! - if (simulationMode == MODE_FULLSIM) { - // NR, from reader, is in receivedCmd +1 - opt_doTagMAC_2(cipher_state, receivedCmd+1, data_generic_trace, diversified_key); + } else if (receivedCmd[0] == ICLASS_CMD_SELECT) { // 0x81 + // Reader selects anticollission CSN. + // Tag sends the corresponding real CSN + modulated_response = resp_csn; modulated_response_size = resp_csn_len; //order = 3; + trace_data = csn_data; + trace_data_size = sizeof(csn_data); + goto send; + } else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KD) { // 0x88 + // Read e-purse (88 02) + modulated_response = resp_cc; modulated_response_size = resp_cc_len; //order = 4; + trace_data = card_challenge_data; + trace_data_size = sizeof(card_challenge_data); + LED_B_ON(); + goto send; + } else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KC) { // 0x18 + // Read e-purse (18 02) + modulated_response = resp_cc; modulated_response_size = resp_cc_len; //order = 4; + trace_data = card_challenge_data; + trace_data_size = sizeof(card_challenge_data); + LED_B_ON(); + goto send; + } else if (receivedCmd[0] == ICLASS_CMD_CHECK) { // 0x05 + // Reader random and reader MAC!!! + if (simulationMode == MODE_FULLSIM) { + // NR, from reader, is in receivedCmd +1 + opt_doTagMAC_2(cipher_state, receivedCmd+1, data_generic_trace, diversified_key); - trace_data = data_generic_trace; - trace_data_size = 4; - CodeIClassTagAnswer(trace_data , trace_data_size); - memcpy(data_response, ToSend, ToSendMax); - modulated_response = data_response; - modulated_response_size = ToSendMax; - } else { - // Not fullsim, we don't respond - // We do not know what to answer, so lets keep quiet - modulated_response = resp_sof; modulated_response_size = 0; - trace_data = NULL; - trace_data_size = 0; + trace_data = data_generic_trace; + trace_data_size = 4; + CodeIClassTagAnswer(trace_data , trace_data_size); + memcpy(data_response, ToSend, ToSendMax); + modulated_response = data_response; + modulated_response_size = ToSendMax; + } else { + // Not fullsim, we don't respond + // We do not know what to answer, so lets keep quiet + modulated_response = resp_sof; modulated_response_size = 0; + trace_data = NULL; + trace_data_size = 0; - if (simulationMode == MODE_EXIT_AFTER_MAC) { + if (simulationMode == MODE_EXIT_AFTER_MAC) { - if ( MF_DBGLEVEL == MF_DBG_EXTENDED) { - 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]); - } else { - Dbprintf("[+] CSN: %02x .... %02x OK", csn[0], csn[7]); - } - if (reader_mac_buf != NULL) { - memcpy(reader_mac_buf + 8, receivedCmd+1, 8); - } - exitLoop = true; - } - } - goto send; - } else if (receivedCmd[0] == ICLASS_CMD_HALT && len == 1) { - // Reader ends the session - modulated_response = resp_sof; modulated_response_size = 0; //order = 0; - trace_data = NULL; - trace_data_size = 0; - goto send; - } else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY && len == 4){ // 0x0C - //Read block - uint16_t blk = receivedCmd[1]; - //Take the data... - memcpy(data_generic_trace, emulator+(blk << 3),8); - AddCrc(data_generic_trace, 8); - trace_data = data_generic_trace; - trace_data_size = 10; - CodeIClassTagAnswer(trace_data , trace_data_size); - memcpy(data_response, ToSend, ToSendMax); - modulated_response = data_response; - modulated_response_size = ToSendMax; - goto send; - } else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_UPDATE) { + if ( MF_DBGLEVEL == MF_DBG_EXTENDED) { + 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]); + } else { + Dbprintf("[+] CSN: %02x .... %02x OK", csn[0], csn[7]); + } + if (reader_mac_buf != NULL) { + memcpy(reader_mac_buf + 8, receivedCmd+1, 8); + } + exitLoop = true; + } + } + goto send; + } else if (receivedCmd[0] == ICLASS_CMD_HALT && len == 1) { + // Reader ends the session + modulated_response = resp_sof; modulated_response_size = 0; //order = 0; + trace_data = NULL; + trace_data_size = 0; + goto send; + } else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY && len == 4){ // 0x0C + //Read block + uint16_t blk = receivedCmd[1]; + //Take the data... + memcpy(data_generic_trace, emulator+(blk << 3),8); + AddCrc(data_generic_trace, 8); + trace_data = data_generic_trace; + trace_data_size = 10; + CodeIClassTagAnswer(trace_data , trace_data_size); + memcpy(data_response, ToSend, ToSendMax); + modulated_response = data_response; + modulated_response_size = ToSendMax; + goto send; + } else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_UPDATE) { - //Probably the reader wants to update the nonce. Let's just ignore that for now. - // OBS! If this is implemented, don't forget to regenerate the cipher_state - //We're expected to respond with the data+crc, exactly what's already in the receivedcmd - //receivedcmd is now UPDATE 1b | ADDRESS 1b| DATA 8b| Signature 4b or CRC 2b| + //Probably the reader wants to update the nonce. Let's just ignore that for now. + // OBS! If this is implemented, don't forget to regenerate the cipher_state + //We're expected to respond with the data+crc, exactly what's already in the receivedcmd + //receivedcmd is now UPDATE 1b | ADDRESS 1b| DATA 8b| Signature 4b or CRC 2b| - //Take the data... - memcpy(data_generic_trace, receivedCmd+2, 8); - AddCrc(data_generic_trace, 8); - trace_data = data_generic_trace; - trace_data_size = 10; - CodeIClassTagAnswer(trace_data, trace_data_size); + //Take the data... + memcpy(data_generic_trace, receivedCmd+2, 8); + AddCrc(data_generic_trace, 8); + trace_data = data_generic_trace; + trace_data_size = 10; + CodeIClassTagAnswer(trace_data, trace_data_size); - memcpy(data_response, ToSend, ToSendMax); - modulated_response = data_response; - modulated_response_size = ToSendMax; -// response_delay = 4600 * 1.5; // tPROG 4-15ms - goto send; -// } else if(receivedCmd[0] == ICLASS_CMD_PAGESEL) { // 0x84 - //Pagesel - //Pagesel enables to select a page in the selected chip memory and return its configuration block - //Chips with a single page will not answer to this command - // It appears we're fine ignoring this. - //Otherwise, we should answer 8bytes (block) + 2bytes CRC -// } else if(receivedCmd[0] == ICLASS_CMD_DETECT) { // 0x0F - } else { - //#db# Unknown command received from reader (len=5): 26 1 0 f6 a 44 44 44 44 - // Never seen this command before - if ( MF_DBGLEVEL == MF_DBG_EXTENDED) - print_result("[-] Unhandled command received ", receivedCmd, len); + memcpy(data_response, ToSend, ToSendMax); + modulated_response = data_response; + modulated_response_size = ToSendMax; +// response_delay = 4600 * 1.5; // tPROG 4-15ms + goto send; +// } else if(receivedCmd[0] == ICLASS_CMD_PAGESEL) { // 0x84 + //Pagesel + //Pagesel enables to select a page in the selected chip memory and return its configuration block + //Chips with a single page will not answer to this command + // It appears we're fine ignoring this. + //Otherwise, we should answer 8bytes (block) + 2bytes CRC +// } else if(receivedCmd[0] == ICLASS_CMD_DETECT) { // 0x0F + } else { + //#db# Unknown command received from reader (len=5): 26 1 0 f6 a 44 44 44 44 + // Never seen this command before + if ( MF_DBGLEVEL == MF_DBG_EXTENDED) + print_result("[-] Unhandled command received ", receivedCmd, len); - // Do not respond - modulated_response = resp_sof; - modulated_response_size = 0; //order = 0; - trace_data = NULL; - trace_data_size = 0; - } + // Do not respond + modulated_response = resp_sof; + modulated_response_size = 0; //order = 0; + trace_data = NULL; + trace_data_size = 0; + } send: - /** - A legit tag has about 330us delay between reader EOT and tag SOF. - **/ - if (modulated_response_size > 0) { - t2r_stime = (GetCountSspClk() - time_0) << 4; - SendIClassAnswer(modulated_response, modulated_response_size, 0); - t2r_etime = ((GetCountSspClk() - time_0) << 4 ) - t2r_stime; - } + /** + A legit tag has about 330us delay between reader EOT and tag SOF. + **/ + if (modulated_response_size > 0) { + t2r_stime = (GetCountSspClk() - time_0) << 4; + SendIClassAnswer(modulated_response, modulated_response_size, 0); + t2r_etime = ((GetCountSspClk() - time_0) << 4 ) - t2r_stime; + } - LogTrace(receivedCmd, len, r2t_stime, r2t_etime, NULL, true); + LogTrace(receivedCmd, len, r2t_stime, r2t_etime, NULL, true); - if (trace_data != NULL) - LogTrace(trace_data, trace_data_size, t2r_stime, t2r_etime, NULL, false); - } + if (trace_data != NULL) + LogTrace(trace_data, trace_data_size, t2r_stime, t2r_etime, NULL, false); + } - LEDsoff(); + LEDsoff(); - if (buttonPressed) - DbpString("[+] button pressed"); + if (buttonPressed) + DbpString("[+] button pressed"); - return buttonPressed; + return buttonPressed; } /** @@ -1581,35 +1581,35 @@ send: * @param delay */ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) { - int i = 0; - volatile uint8_t b = 0; + int i = 0; + volatile uint8_t b = 0; - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_424K_8BIT); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_424K_8BIT); - AT91C_BASE_SSC->SSC_THR = 0x00; + AT91C_BASE_SSC->SSC_THR = 0x00; - while (!BUTTON_PRESS()) { + while (!BUTTON_PRESS()) { - // Prevent rx holding register from overflowing - if ( (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)){ - b = AT91C_BASE_SSC->SSC_RHR; (void) b; - } + // Prevent rx holding register from overflowing + if ( (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)){ + b = AT91C_BASE_SSC->SSC_RHR; (void) b; + } - // Put byte into tx holding register as soon as it is ready - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)){ - b = 0x00; - if ( i < respLen){ - b = resp[i]; - //Hack - //b = 0xAC; - } - i++; - AT91C_BASE_SSC->SSC_THR = b; - } -// if (i > respLen + 4) break; - if (i > respLen + 1) break; - } - return 0; + // Put byte into tx holding register as soon as it is ready + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)){ + b = 0x00; + if ( i < respLen){ + b = resp[i]; + //Hack + //b = 0xAC; + } + i++; + AT91C_BASE_SSC->SSC_THR = b; + } +// if (i > respLen + 4) break; + if (i > respLen + 1) break; + } + return 0; } /// THE READER CODE @@ -1619,114 +1619,114 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) { //----------------------------------------------------------------------------- static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int *wait) { - int c = 0; - volatile uint32_t b; - bool firstpart = true; - uint8_t sendbyte; + int c = 0; + volatile uint32_t b; + bool firstpart = true; + uint8_t sendbyte; - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); - AT91C_BASE_SSC->SSC_THR = 0x00; + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); + AT91C_BASE_SSC->SSC_THR = 0x00; - // make sure we timeout previous comms. - if ( *wait ) - SpinDelayUs(*wait); + // make sure we timeout previous comms. + if ( *wait ) + SpinDelayUs(*wait); - for (;;) { + for (;;) { - WDT_HIT(); + WDT_HIT(); - // Put byte into tx holding register as soon as it is ready - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + // Put byte into tx holding register as soon as it is ready + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - // DOUBLE THE SAMPLES! - if (firstpart) { - sendbyte = (cmd[c] & 0xf0) | (cmd[c] >> 4); - } else { - sendbyte = (cmd[c] & 0x0f) | (cmd[c] << 4); - c++; - } + // DOUBLE THE SAMPLES! + if (firstpart) { + sendbyte = (cmd[c] & 0xf0) | (cmd[c] >> 4); + } else { + sendbyte = (cmd[c] & 0x0f) | (cmd[c] << 4); + c++; + } - if (sendbyte == 0xff) - sendbyte = 0xfe; + if (sendbyte == 0xff) + sendbyte = 0xfe; - AT91C_BASE_SSC->SSC_THR = sendbyte; - firstpart = !firstpart; + AT91C_BASE_SSC->SSC_THR = sendbyte; + firstpart = !firstpart; - if (c >= len) break; - } + if (c >= len) break; + } - // Prevent rx holding register from overflowing - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - b = AT91C_BASE_SSC->SSC_RHR; (void)b; - } - } + // Prevent rx holding register from overflowing + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + b = AT91C_BASE_SSC->SSC_RHR; (void)b; + } + } - if (samples) { - if (wait) - *samples = (c + *wait) << 3; - else - *samples = c << 3; - } + if (samples) { + if (wait) + *samples = (c + *wait) << 3; + else + *samples = c << 3; + } } //----------------------------------------------------------------------------- // Prepare iClass reader command to send to FPGA //----------------------------------------------------------------------------- void CodeIClassCommand(const uint8_t* cmd, int len) { - int i, j, k; - uint8_t b; + int i, j, k; + uint8_t b; - ToSendReset(); + ToSendReset(); - // (SOC) Start of Communication: 1 out of 4 - ToSend[++ToSendMax] = 0xf0; - ToSend[++ToSendMax] = 0x00; - ToSend[++ToSendMax] = 0x0f; - ToSend[++ToSendMax] = 0x00; + // (SOC) Start of Communication: 1 out of 4 + ToSend[++ToSendMax] = 0xf0; + ToSend[++ToSendMax] = 0x00; + ToSend[++ToSendMax] = 0x0f; + ToSend[++ToSendMax] = 0x00; - // Modulate the bytes - for (i = 0; i < len; i++) { - b = cmd[i]; - for (j = 0; j < 4; j++) { - for (k = 0; k < 4; k++) { + // Modulate the bytes + for (i = 0; i < len; i++) { + b = cmd[i]; + for (j = 0; j < 4; j++) { + for (k = 0; k < 4; k++) { - if (k == (b & 3)) - ToSend[++ToSendMax] = 0xf0; - else - ToSend[++ToSendMax] = 0x00; - } - b >>= 2; - } - } + if (k == (b & 3)) + ToSend[++ToSendMax] = 0xf0; + else + ToSend[++ToSendMax] = 0x00; + } + b >>= 2; + } + } - // (EOC) End of Communication - ToSend[++ToSendMax] = 0x00; - ToSend[++ToSendMax] = 0x00; - ToSend[++ToSendMax] = 0xf0; - ToSend[++ToSendMax] = 0x00; + // (EOC) End of Communication + ToSend[++ToSendMax] = 0x00; + ToSend[++ToSendMax] = 0x00; + ToSend[++ToSendMax] = 0xf0; + ToSend[++ToSendMax] = 0x00; - // Convert from last character reference to length - ToSendMax++; + // Convert from last character reference to length + ToSendMax++; } void ReaderTransmitIClass_ext(uint8_t* frame, int len, int wait) { - int samples = 0; + int samples = 0; - // This is tied to other size changes - CodeIClassCommand(frame, len); + // This is tied to other size changes + CodeIClassCommand(frame, len); - // Select the card - TransmitIClassCommand(ToSend, ToSendMax, &samples, &wait); - if (trigger) - LED_A_ON(); + // Select the card + TransmitIClassCommand(ToSend, ToSendMax, &samples, &wait); + if (trigger) + LED_A_ON(); - rsamples += samples; + rsamples += samples; - LogTrace(frame, len, rsamples, rsamples, NULL, true); + LogTrace(frame, len, rsamples, rsamples, NULL, true); } void ReaderTransmitIClass(uint8_t* frame, int len) { - ReaderTransmitIClass_ext(frame, len, 330); + ReaderTransmitIClass_ext(frame, len, 330); } //----------------------------------------------------------------------------- @@ -1735,75 +1735,75 @@ void ReaderTransmitIClass(uint8_t* frame, int len) { // If it takes too long return FALSE //----------------------------------------------------------------------------- static int GetIClassAnswer(uint8_t* receivedResponse, int maxLen, int *samples, int *elapsed) { - // buffer needs to be 512 bytes - // maxLen is not used... + // buffer needs to be 512 bytes + // maxLen is not used... - int c = 0; - bool skip = false; + int c = 0; + bool skip = false; - // Setup UART/DEMOD to receive - DemodInit(receivedResponse); + // Setup UART/DEMOD to receive + DemodInit(receivedResponse); - if (elapsed) *elapsed = 0; + if (elapsed) *elapsed = 0; - // Set FPGA mode to "reader listen mode", no modulation (listen - // only, since we are receiving, not transmitting). - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN); - SpinDelayUs(320); //310 Tout= 330us (iso15603-2) (330/21.3) take consideration for clock increments. + // Set FPGA mode to "reader listen mode", no modulation (listen + // only, since we are receiving, not transmitting). + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN); + SpinDelayUs(320); //310 Tout= 330us (iso15603-2) (330/21.3) take consideration for clock increments. - // clear RXRDY: + // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - while (!BUTTON_PRESS()) { - WDT_HIT(); + while (!BUTTON_PRESS()) { + WDT_HIT(); - // keep tx buffer in a defined state anyway. - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0x00; - // To make use of exact timing of next command from reader!! - if (elapsed) (*elapsed)++; - } + // keep tx buffer in a defined state anyway. + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = 0x00; + // To make use of exact timing of next command from reader!! + if (elapsed) (*elapsed)++; + } - // Wait for byte be become available in rx holding register - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - if (c >= timeout) return false; + // Wait for byte be become available in rx holding register + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + if (c >= timeout) return false; - c++; + c++; - b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - skip = !skip; - if (skip) continue; + skip = !skip; + if (skip) continue; - if (ManchesterDecoding_iclass(b & 0x0f)) { - if (samples) - *samples = c << 3; - return true; - } - } - } - return false; + if (ManchesterDecoding_iclass(b & 0x0f)) { + if (samples) + *samples = c << 3; + return true; + } + } + } + return false; } int ReaderReceiveIClass(uint8_t* receivedAnswer) { - int samples = 0; + int samples = 0; - if (!GetIClassAnswer(receivedAnswer, 0, &samples, NULL)) - return false; + if (!GetIClassAnswer(receivedAnswer, 0, &samples, NULL)) + return false; - rsamples += samples; + rsamples += samples; - LogTrace(receivedAnswer, Demod.len, rsamples, rsamples, NULL, false); + LogTrace(receivedAnswer, Demod.len, rsamples, rsamples, NULL, false); - if (samples == 0) - return false; + if (samples == 0) + return false; - return Demod.len; + return Demod.len; } void setupIclassReader() { - LEDsoff(); + LEDsoff(); // Start from off (no field generated) // Signal field is off with the appropriate LED @@ -1815,39 +1815,39 @@ void setupIclassReader() { SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - clear_trace(); - set_tracing(true); + clear_trace(); + set_tracing(true); // 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(300); - StartCountSspClk(); + StartCountSspClk(); LED_A_ON(); } bool sendCmdGetResponseWithRetries(uint8_t* command, size_t cmdsize, uint8_t* resp, uint8_t expected_size, uint8_t retries) { - uint8_t got_n = 0; - while (retries-- > 0) { + uint8_t got_n = 0; + while (retries-- > 0) { - ReaderTransmitIClass(command, cmdsize); + ReaderTransmitIClass(command, cmdsize); - //iceman - if received size is bigger than expected, we smash the stack here - // since its called with fixed sized arrays - got_n = ReaderReceiveIClass(resp); + //iceman - if received size is bigger than expected, we smash the stack here + // since its called with fixed sized arrays + got_n = ReaderReceiveIClass(resp); - // 0xBB is the internal debug separator byte.. - if ( expected_size != got_n|| (resp[0] == 0xBB || resp[7] == 0xBB || resp[2] == 0xBB)) { - //try again - continue; - } + // 0xBB is the internal debug separator byte.. + if ( expected_size != got_n|| (resp[0] == 0xBB || resp[7] == 0xBB || resp[2] == 0xBB)) { + //try again + continue; + } - if (got_n == expected_size) - return true; - } - return false; + if (got_n == expected_size) + return true; + } + return false; } /** @@ -1859,357 +1859,357 @@ bool sendCmdGetResponseWithRetries(uint8_t* command, size_t cmdsize, uint8_t* re */ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) { - // act_all... - static uint8_t act_all[] = { ICLASS_CMD_ACTALL }; - static uint8_t identify[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x00, 0x73, 0x33 }; - static uint8_t select[] = { ICLASS_CMD_SELECT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - uint8_t readcheck_cc[] = { ICLASS_CMD_READCHECK_KD, 0x02 }; + // act_all... + static uint8_t act_all[] = { ICLASS_CMD_ACTALL }; + static uint8_t identify[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x00, 0x73, 0x33 }; + static uint8_t select[] = { ICLASS_CMD_SELECT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + uint8_t readcheck_cc[] = { ICLASS_CMD_READCHECK_KD, 0x02 }; - if (use_credit_key) - readcheck_cc[0] = ICLASS_CMD_READCHECK_KC; + if (use_credit_key) + readcheck_cc[0] = ICLASS_CMD_READCHECK_KC; - uint8_t resp[ICLASS_BUFFER_SIZE] = {0}; - uint8_t read_status = 0; + uint8_t resp[ICLASS_BUFFER_SIZE] = {0}; + uint8_t read_status = 0; - // Send act_all - ReaderTransmitIClass_ext(act_all, 1, 330+160); - // Card present? - if (!ReaderReceiveIClass(resp)) return read_status;//Fail + // Send act_all + ReaderTransmitIClass_ext(act_all, 1, 330+160); + // Card present? + if (!ReaderReceiveIClass(resp)) return read_status;//Fail - //Send Identify - ReaderTransmitIClass(identify, 1); + //Send Identify + ReaderTransmitIClass(identify, 1); - //We expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC - uint8_t len = ReaderReceiveIClass(resp); - if (len != 10) return read_status;//Fail + //We expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC + uint8_t len = ReaderReceiveIClass(resp); + if (len != 10) return read_status;//Fail - //Copy the Anti-collision CSN to our select-packet - memcpy(&select[1], resp, 8); + //Copy the Anti-collision CSN to our select-packet + memcpy(&select[1], resp, 8); - //Select the card - ReaderTransmitIClass(select, sizeof(select)); + //Select the card + ReaderTransmitIClass(select, sizeof(select)); - //We expect a 10-byte response here, 8 byte CSN and 2 byte CRC - len = ReaderReceiveIClass(resp); - if (len != 10) return read_status;//Fail + //We expect a 10-byte response here, 8 byte CSN and 2 byte CRC + len = ReaderReceiveIClass(resp); + if (len != 10) return read_status;//Fail - //Success - level 1, we got CSN - //Save CSN in response data - memcpy(card_data, resp, 8); + //Success - level 1, we got CSN + //Save CSN in response data + memcpy(card_data, resp, 8); - //Flag that we got to at least stage 1, read CSN - read_status = 1; + //Flag that we got to at least stage 1, read CSN + read_status = 1; - // Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC) - // ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc)); - // if (ReaderReceiveIClass(resp) == 8) { - // //Save CC (e-purse) in response data - // memcpy(card_data+8, resp, 8); - // read_status++; - // } + // Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC) + // ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc)); + // if (ReaderReceiveIClass(resp) == 8) { + // //Save CC (e-purse) in response data + // memcpy(card_data+8, resp, 8); + // read_status++; + // } - bool isOK = sendCmdGetResponseWithRetries(readcheck_cc, sizeof(readcheck_cc), resp, 8, 3); - if (!isOK) return read_status; + bool isOK = sendCmdGetResponseWithRetries(readcheck_cc, sizeof(readcheck_cc), resp, 8, 3); + if (!isOK) return read_status; - //Save CC (e-purse) in response data - memcpy(card_data+8, resp, 8); - read_status++; - return read_status; + //Save CC (e-purse) in response data + memcpy(card_data+8, resp, 8); + read_status++; + return read_status; } uint8_t handshakeIclassTag(uint8_t *card_data){ - return handshakeIclassTag_ext(card_data, false); + return handshakeIclassTag_ext(card_data, false); } // Reader iClass Anticollission // turn off afterwards void ReaderIClass(uint8_t arg0) { - uint8_t card_data[6 * 8] = {0}; - uint8_t last_csn[8] = {0,0,0,0,0,0,0,0}; - uint8_t resp[ICLASS_BUFFER_SIZE]; + uint8_t card_data[6 * 8] = {0}; + uint8_t last_csn[8] = {0,0,0,0,0,0,0,0}; + uint8_t resp[ICLASS_BUFFER_SIZE]; - memset(card_data, 0xFF, sizeof(card_data)); - memset(resp, 0xFF, sizeof(resp)); + memset(card_data, 0xFF, sizeof(card_data)); + memset(resp, 0xFF, sizeof(resp)); - //Read conf block CRC(0x01) => 0xfa 0x22 - uint8_t readConf[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x01, 0xfa, 0x22}; + //Read conf block CRC(0x01) => 0xfa 0x22 + uint8_t readConf[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x01, 0xfa, 0x22}; - //Read App Issuer Area block CRC(0x05) => 0xde 0x64 - uint8_t readAA[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x05, 0xde, 0x64}; + //Read App Issuer Area block CRC(0x05) => 0xde 0x64 + uint8_t readAA[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x05, 0xde, 0x64}; int read_status = 0; - uint16_t tryCnt = 0; - uint8_t result_status = 0; + uint16_t tryCnt = 0; + uint8_t result_status = 0; - bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE; // flag to read until one tag is found successfully - bool try_once = arg0 & FLAG_ICLASS_READER_ONE_TRY; // flag to not to loop continuously, looking for tag - bool use_credit_key = arg0 & FLAG_ICLASS_READER_CEDITKEY; // flag to use credit key - bool flagReadConfig = arg0 & FLAG_ICLASS_READER_CONF; // flag to read block1, configuration - bool flagReadCC = arg0 & FLAG_ICLASS_READER_CC; // flag to read block2, e-purse - bool flagReadAIA = arg0 & FLAG_ICLASS_READER_AIA; // flag to read block5, application issuer area + bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE; // flag to read until one tag is found successfully + bool try_once = arg0 & FLAG_ICLASS_READER_ONE_TRY; // flag to not to loop continuously, looking for tag + bool use_credit_key = arg0 & FLAG_ICLASS_READER_CEDITKEY; // flag to use credit key + bool flagReadConfig = arg0 & FLAG_ICLASS_READER_CONF; // flag to read block1, configuration + bool flagReadCC = arg0 & FLAG_ICLASS_READER_CC; // flag to read block2, e-purse + bool flagReadAIA = arg0 & FLAG_ICLASS_READER_AIA; // flag to read block5, application issuer area - setupIclassReader(); + setupIclassReader(); - bool userCancelled = BUTTON_PRESS() || usb_poll_validate_length(); - while (!userCancelled) { + bool userCancelled = BUTTON_PRESS() || usb_poll_validate_length(); + while (!userCancelled) { - WDT_HIT(); + WDT_HIT(); - // if only looking for one card try 2 times if we missed it the first time - if (try_once && tryCnt > 2) { - if (MF_DBGLEVEL > 1) DbpString("Failed to find a tag"); - break; - } + // if only looking for one card try 2 times if we missed it the first time + if (try_once && tryCnt > 2) { + if (MF_DBGLEVEL > 1) DbpString("Failed to find a tag"); + break; + } - tryCnt++; - result_status = 0; + tryCnt++; + result_status = 0; - read_status = handshakeIclassTag_ext(card_data, use_credit_key); + read_status = handshakeIclassTag_ext(card_data, use_credit_key); - if (read_status == 0) continue; - if (read_status == 1) result_status = FLAG_ICLASS_READER_CSN; - if (read_status == 2) result_status = FLAG_ICLASS_READER_CSN | FLAG_ICLASS_READER_CC; + if (read_status == 0) continue; + if (read_status == 1) result_status = FLAG_ICLASS_READER_CSN; + if (read_status == 2) result_status = FLAG_ICLASS_READER_CSN | FLAG_ICLASS_READER_CC; - // handshakeIclass returns CSN|CC, but the actual block - // layout is CSN|CONFIG|CC, so here we reorder the data, - // moving CC forward 8 bytes - memcpy(card_data+16, card_data+8, 8); + // handshakeIclass returns CSN|CC, but the actual block + // layout is CSN|CONFIG|CC, so here we reorder the data, + // moving CC forward 8 bytes + memcpy(card_data+16, card_data+8, 8); - //Read block 1, config - if (flagReadConfig) { - if (sendCmdGetResponseWithRetries(readConf, sizeof(readConf), resp, 10, 5)) { - result_status |= FLAG_ICLASS_READER_CONF; - memcpy(card_data+8, resp, 8); - } else { - if (MF_DBGLEVEL > 1) DbpString("Failed to dump config block"); - } - } + //Read block 1, config + if (flagReadConfig) { + if (sendCmdGetResponseWithRetries(readConf, sizeof(readConf), resp, 10, 5)) { + result_status |= FLAG_ICLASS_READER_CONF; + memcpy(card_data+8, resp, 8); + } else { + if (MF_DBGLEVEL > 1) DbpString("Failed to dump config block"); + } + } - //Read block 5, AIA - if (flagReadAIA) { - if (sendCmdGetResponseWithRetries(readAA, sizeof(readAA), resp, 10, 5)) { - result_status |= FLAG_ICLASS_READER_AIA; - memcpy(card_data+(8*5), resp, 8); - } else { - if (MF_DBGLEVEL > 1) DbpString("Failed to dump AA block"); - } - } + //Read block 5, AIA + if (flagReadAIA) { + if (sendCmdGetResponseWithRetries(readAA, sizeof(readAA), resp, 10, 5)) { + result_status |= FLAG_ICLASS_READER_AIA; + memcpy(card_data+(8*5), resp, 8); + } else { + if (MF_DBGLEVEL > 1) DbpString("Failed to dump AA block"); + } + } - // 0 : CSN - // 1 : Configuration - // 2 : e-purse - // 3 : kd / debit / aa2 (write-only) - // 4 : kc / credit / aa1 (write-only) - // 5 : AIA, Application issuer area - // - //Then we can 'ship' back the 6 * 8 bytes of data, - // with 0xFF:s in block 3 and 4. + // 0 : CSN + // 1 : Configuration + // 2 : e-purse + // 3 : kd / debit / aa2 (write-only) + // 4 : kc / credit / aa1 (write-only) + // 5 : AIA, Application issuer area + // + //Then we can 'ship' back the 6 * 8 bytes of data, + // with 0xFF:s in block 3 and 4. - LED_B_ON(); - //Send back to client, but don't bother if we already sent this - - // only useful if looping in arm (not try_once && not abort_after_read) - if (memcmp(last_csn, card_data, 8) != 0) { - // If caller requires that we get Conf, CC, AA, continue until we got it - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { - Dbprintf("STATUS %02X | CSN %c | CONF %c | CC %c | AIA %c | ONCE %c | 1TRY %c", - result_status, - (result_status & FLAG_ICLASS_READER_CSN) ? 'Y':'N', - (result_status & FLAG_ICLASS_READER_CONF)? 'Y':'N', - (result_status & FLAG_ICLASS_READER_CC) ? 'Y':'N', - (result_status & FLAG_ICLASS_READER_AIA) ? 'Y':'N' - ); - Dbprintf(" aar %c | to %c, | uc %c | frc %c | fra %c | cc %c", - abort_after_read ? 'Y':'N', - try_once ? 'Y':'N', - use_credit_key ? 'Y':'N', - flagReadConfig ? 'Y':'N', - flagReadAIA ? 'Y':'N', - flagReadCC ? 'Y':'N' - ); - } + LED_B_ON(); + //Send back to client, but don't bother if we already sent this - + // only useful if looping in arm (not try_once && not abort_after_read) + if (memcmp(last_csn, card_data, 8) != 0) { + // If caller requires that we get Conf, CC, AA, continue until we got it + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { + Dbprintf("STATUS %02X | CSN %c | CONF %c | CC %c | AIA %c | ONCE %c | 1TRY %c", + result_status, + (result_status & FLAG_ICLASS_READER_CSN) ? 'Y':'N', + (result_status & FLAG_ICLASS_READER_CONF)? 'Y':'N', + (result_status & FLAG_ICLASS_READER_CC) ? 'Y':'N', + (result_status & FLAG_ICLASS_READER_AIA) ? 'Y':'N' + ); + Dbprintf(" aar %c | to %c, | uc %c | frc %c | fra %c | cc %c", + abort_after_read ? 'Y':'N', + try_once ? 'Y':'N', + use_credit_key ? 'Y':'N', + flagReadConfig ? 'Y':'N', + flagReadAIA ? 'Y':'N', + flagReadCC ? 'Y':'N' + ); + } - bool send = (result_status & FLAG_ICLASS_READER_CSN ); - if (flagReadCC) - send |= (result_status & FLAG_ICLASS_READER_CC ); - if (flagReadAIA) - send |= (result_status & FLAG_ICLASS_READER_AIA ); - if (flagReadConfig) - send |= (result_status & FLAG_ICLASS_READER_CONF ); + bool send = (result_status & FLAG_ICLASS_READER_CSN ); + if (flagReadCC) + send |= (result_status & FLAG_ICLASS_READER_CC ); + if (flagReadAIA) + send |= (result_status & FLAG_ICLASS_READER_AIA ); + if (flagReadConfig) + send |= (result_status & FLAG_ICLASS_READER_CONF ); - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("SEND %c", send?'y':'n'); + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("SEND %c", send?'y':'n'); - if ( send ) { - cmd_send(CMD_ACK, result_status, 0, 0, card_data, sizeof(card_data) ); - if (abort_after_read) { - LED_B_OFF(); - return; - } - //Save that we already sent this.... - memcpy(last_csn, card_data, 8); - } - } - LED_B_OFF(); - userCancelled = BUTTON_PRESS() || usb_poll_validate_length(); - } + if ( send ) { + cmd_send(CMD_ACK, result_status, 0, 0, card_data, sizeof(card_data) ); + if (abort_after_read) { + LED_B_OFF(); + return; + } + //Save that we already sent this.... + memcpy(last_csn, card_data, 8); + } + } + LED_B_OFF(); + userCancelled = BUTTON_PRESS() || usb_poll_validate_length(); + } - if (userCancelled) { - cmd_send(CMD_ACK, 0xFF, 0, 0, card_data, 0); - switch_off(); - } else { - cmd_send(CMD_ACK, 0, 0, 0, card_data, 0); - } + if (userCancelled) { + cmd_send(CMD_ACK, 0xFF, 0, 0, card_data, 0); + switch_off(); + } else { + cmd_send(CMD_ACK, 0, 0, 0, card_data, 0); + } } // turn off afterwards void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) { - uint8_t cardsize = 0; - uint8_t mem = 0; - uint8_t check[] = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - uint8_t read[] = { 0x0c, 0x00, 0x00, 0x00 }; - uint8_t card_data[USB_CMD_DATA_SIZE] = {0}; - uint8_t resp[ICLASS_BUFFER_SIZE] = {0}; + uint8_t cardsize = 0; + uint8_t mem = 0; + uint8_t check[] = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + uint8_t read[] = { 0x0c, 0x00, 0x00, 0x00 }; + uint8_t card_data[USB_CMD_DATA_SIZE] = {0}; + uint8_t resp[ICLASS_BUFFER_SIZE] = {0}; - static struct memory_t{ - int k16; - int book; - int k2; - int lockauth; - int keyaccess; - } memory; + static struct memory_t{ + int k16; + int book; + int k2; + int lockauth; + int keyaccess; + } memory; setupIclassReader(); - while (!BUTTON_PRESS()) { + while (!BUTTON_PRESS()) { - WDT_HIT(); + WDT_HIT(); - uint8_t read_status = handshakeIclassTag(card_data); - if (read_status < 2) continue; + uint8_t read_status = handshakeIclassTag(card_data); + if (read_status < 2) continue; - //for now replay captured auth (as cc not updated) - memcpy(check+5, MAC, 4); + //for now replay captured auth (as cc not updated) + memcpy(check+5, MAC, 4); - if (!sendCmdGetResponseWithRetries(check, sizeof(check), resp, 4, 5)) { - DbpString("Error: Authentication Fail!"); - continue; - } + if (!sendCmdGetResponseWithRetries(check, sizeof(check), resp, 4, 5)) { + DbpString("Error: Authentication Fail!"); + continue; + } - //first get configuration block (block 1) - read[1] = 1; - AddCrc( read+1, 1 ); + //first get configuration block (block 1) + read[1] = 1; + AddCrc( read+1, 1 ); - if (!sendCmdGetResponseWithRetries(read, sizeof(read), resp, 10, 5)) { - DbpString("Dump config (block 1) failed"); - continue; - } + if (!sendCmdGetResponseWithRetries(read, sizeof(read), resp, 10, 5)) { + DbpString("Dump config (block 1) failed"); + continue; + } - mem = resp[5]; - memory.k16 = (mem & 0x80); - memory.book = (mem & 0x20); - memory.k2 = (mem & 0x8); - memory.lockauth = (mem & 0x2); - memory.keyaccess = (mem & 0x1); + mem = resp[5]; + memory.k16 = (mem & 0x80); + memory.book = (mem & 0x20); + memory.k2 = (mem & 0x8); + memory.lockauth = (mem & 0x2); + memory.keyaccess = (mem & 0x1); - cardsize = memory.k16 ? 255 : 32; + cardsize = memory.k16 ? 255 : 32; - WDT_HIT(); - //Set card_data to all zeroes, we'll fill it with data - memset(card_data, 0x0, USB_CMD_DATA_SIZE); - uint8_t failedRead = 0; - uint32_t stored_data_length = 0; + WDT_HIT(); + //Set card_data to all zeroes, we'll fill it with data + memset(card_data, 0x0, USB_CMD_DATA_SIZE); + uint8_t failedRead = 0; + uint32_t stored_data_length = 0; - //then loop around remaining blocks - for ( uint16_t block=0; block < cardsize; block++) { + //then loop around remaining blocks + for ( uint16_t block=0; block < cardsize; block++) { - read[1] = block; - AddCrc( read+1, 1 ); + read[1] = block; + AddCrc( read+1, 1 ); - if (sendCmdGetResponseWithRetries(read, sizeof(read), resp, 10, 5)) { - Dbprintf(" %02x: %02x %02x %02x %02x %02x %02x %02x %02x", - block, resp[0], resp[1], resp[2], - resp[3], resp[4], resp[5], - resp[6], resp[7] - ); + if (sendCmdGetResponseWithRetries(read, sizeof(read), resp, 10, 5)) { + Dbprintf(" %02x: %02x %02x %02x %02x %02x %02x %02x %02x", + block, resp[0], resp[1], resp[2], + resp[3], resp[4], resp[5], + resp[6], resp[7] + ); - //Fill up the buffer - memcpy(card_data + stored_data_length, resp, 8); - stored_data_length += 8; - if (stored_data_length + 8 > USB_CMD_DATA_SIZE) { - //Time to send this off and start afresh - cmd_send(CMD_ACK, - stored_data_length,//data length - failedRead,//Failed blocks? - 0,//Not used ATM - card_data, - stored_data_length - ); - //reset - stored_data_length = 0; - failedRead = 0; - } - } else { - failedRead = 1; - stored_data_length += 8;//Otherwise, data becomes misaligned - Dbprintf("Failed to dump block %d", block); - } - } + //Fill up the buffer + memcpy(card_data + stored_data_length, resp, 8); + stored_data_length += 8; + if (stored_data_length + 8 > USB_CMD_DATA_SIZE) { + //Time to send this off and start afresh + cmd_send(CMD_ACK, + stored_data_length,//data length + failedRead,//Failed blocks? + 0,//Not used ATM + card_data, + stored_data_length + ); + //reset + stored_data_length = 0; + failedRead = 0; + } + } else { + failedRead = 1; + stored_data_length += 8;//Otherwise, data becomes misaligned + Dbprintf("Failed to dump block %d", block); + } + } - //Send off any remaining data - if (stored_data_length > 0) { - cmd_send(CMD_ACK, - stored_data_length,//data length - failedRead,//Failed blocks? - 0,//Not used ATM - card_data, - stored_data_length - ); - } - //If we got here, let's break - break; - } - //Signal end of transmission - cmd_send(CMD_ACK, - 0,//data length - 0,//Failed blocks? - 0,//Not used ATM - card_data, - 0 - ); - switch_off(); + //Send off any remaining data + if (stored_data_length > 0) { + cmd_send(CMD_ACK, + stored_data_length,//data length + failedRead,//Failed blocks? + 0,//Not used ATM + card_data, + stored_data_length + ); + } + //If we got here, let's break + break; + } + //Signal end of transmission + cmd_send(CMD_ACK, + 0,//data length + 0,//Failed blocks? + 0,//Not used ATM + card_data, + 0 + ); + switch_off(); } // not used. ?!? ( CMD_ICLASS_READCHECK) // turn off afterwards void iClass_ReadCheck(uint8_t blockNo, uint8_t keyType) { - uint8_t readcheck[] = { keyType, blockNo }; - uint8_t resp[] = {0,0,0,0,0,0,0,0}; - size_t isOK = 0; - isOK = sendCmdGetResponseWithRetries(readcheck, sizeof(readcheck), resp, sizeof(resp), 6); - cmd_send(CMD_ACK,isOK,0,0,0,0); - switch_off(); + uint8_t readcheck[] = { keyType, blockNo }; + uint8_t resp[] = {0,0,0,0,0,0,0,0}; + size_t isOK = 0; + isOK = sendCmdGetResponseWithRetries(readcheck, sizeof(readcheck), resp, sizeof(resp), 6); + cmd_send(CMD_ACK,isOK,0,0,0,0); + switch_off(); } // used with function select_and_auth (cmdhficlass.c) // which needs to authenticate before doing more things like read/write void iClass_Authentication(uint8_t *mac) { - uint8_t check[] = { ICLASS_CMD_CHECK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - uint8_t resp[ICLASS_BUFFER_SIZE]; + uint8_t check[] = { ICLASS_CMD_CHECK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + uint8_t resp[ICLASS_BUFFER_SIZE]; - // copy MAC to check command (readersignature) - check[5] = mac[0]; - check[6] = mac[1]; - check[7] = mac[2]; - check[8] = mac[3]; - //memcpy(check+5, mac, 4); + // copy MAC to check command (readersignature) + check[5] = mac[0]; + check[6] = mac[1]; + check[7] = mac[2]; + check[8] = mac[3]; + //memcpy(check+5, mac, 4); - // 6 retries - bool isOK = sendCmdGetResponseWithRetries(check, sizeof(check), resp, 4, 6); - cmd_send(CMD_ACK,isOK,0,0,0,0); + // 6 retries + bool isOK = sendCmdGetResponseWithRetries(check, sizeof(check), resp, 4, 6); + cmd_send(CMD_ACK,isOK,0,0,0,0); } typedef struct iclass_premac { - uint8_t mac[4]; + uint8_t mac[4]; } iclass_premac_t; /* this function works on the following assumptions. @@ -2220,194 +2220,194 @@ typedef struct iclass_premac { * to cover debit and credit key. (AA1/AA2) */ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { - uint8_t i = 0, isOK = 0; - uint8_t lastChunk = ((arg0 >> 8) & 0xFF); - bool use_credit_key =((arg0 >> 16) & 0xFF); - uint8_t keyCount = arg1 & 0xFF; - uint8_t check[] = { ICLASS_CMD_CHECK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - uint8_t resp[ICLASS_BUFFER_SIZE]; - uint8_t readcheck_cc[] = { ICLASS_CMD_READCHECK_KD, 0x02 }; + uint8_t i = 0, isOK = 0; + uint8_t lastChunk = ((arg0 >> 8) & 0xFF); + bool use_credit_key =((arg0 >> 16) & 0xFF); + uint8_t keyCount = arg1 & 0xFF; + uint8_t check[] = { ICLASS_CMD_CHECK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + uint8_t resp[ICLASS_BUFFER_SIZE]; + uint8_t readcheck_cc[] = { ICLASS_CMD_READCHECK_KD, 0x02 }; - if (use_credit_key) - readcheck_cc[0] = ICLASS_CMD_READCHECK_KC; + if (use_credit_key) + readcheck_cc[0] = ICLASS_CMD_READCHECK_KC; - // select card / e-purse - uint8_t card_data[6 * 8] = {0}; + // select card / e-purse + uint8_t card_data[6 * 8] = {0}; - iclass_premac_t *keys = (iclass_premac_t *)datain; + iclass_premac_t *keys = (iclass_premac_t *)datain; - LED_A_ON(); + LED_A_ON(); - switch_off(); - SpinDelay(20); + switch_off(); + SpinDelay(20); - setupIclassReader(); + setupIclassReader(); - int read_status = 0; - uint8_t startup_limit = 10; - while ( read_status != 2) { + int read_status = 0; + uint8_t startup_limit = 10; + while ( read_status != 2) { - if (BUTTON_PRESS() && !usb_poll_validate_length()) goto out; + if (BUTTON_PRESS() && !usb_poll_validate_length()) goto out; - read_status = handshakeIclassTag_ext(card_data, use_credit_key); - if ( startup_limit-- == 0 ) { - Dbprintf("[-] Handshake status | %d (fail 10)", read_status); - isOK = 99; - goto out; - } - }; - // since handshakeIclassTag_ext call sends s readcheck, we start with sending first response. + read_status = handshakeIclassTag_ext(card_data, use_credit_key); + if ( startup_limit-- == 0 ) { + Dbprintf("[-] Handshake status | %d (fail 10)", read_status); + isOK = 99; + goto out; + } + }; + // since handshakeIclassTag_ext call sends s readcheck, we start with sending first response. - // Keychunk loop - for (i = 0; i < keyCount; i++) { + // Keychunk loop + for (i = 0; i < keyCount; i++) { - // Allow button press / usb cmd to interrupt device - if (BUTTON_PRESS() && !usb_poll_validate_length()) break; + // Allow button press / usb cmd to interrupt device + if (BUTTON_PRESS() && !usb_poll_validate_length()) break; - WDT_HIT(); - LED_B_ON(); + WDT_HIT(); + LED_B_ON(); - // copy MAC to check command (readersignature) - check[5] = keys[i].mac[0]; - check[6] = keys[i].mac[1]; - check[7] = keys[i].mac[2]; - check[8] = keys[i].mac[3]; + // copy MAC to check command (readersignature) + check[5] = keys[i].mac[0]; + check[6] = keys[i].mac[1]; + check[7] = keys[i].mac[2]; + check[8] = keys[i].mac[3]; - // expect 4bytes, 3 retries times.. - isOK = sendCmdGetResponseWithRetries(check, sizeof(check), resp, 4, 3); - if ( isOK ) - goto out; + // expect 4bytes, 3 retries times.. + isOK = sendCmdGetResponseWithRetries(check, sizeof(check), resp, 4, 3); + if ( isOK ) + goto out; - SpinDelayUs(400); //iClass (iso15693-2) should timeout after 330us. + SpinDelayUs(400); //iClass (iso15693-2) should timeout after 330us. - // Auth Sequence MUST begin with reading e-purse. (block2) - // Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC) - ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc)); + // Auth Sequence MUST begin with reading e-purse. (block2) + // Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC) + ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc)); - LED_B_OFF(); - } + LED_B_OFF(); + } out: - // send keyindex. - cmd_send(CMD_ACK, isOK, i, 0, 0, 0); + // send keyindex. + cmd_send(CMD_ACK, isOK, i, 0, 0, 0); - if ( isOK >= 1 || lastChunk ) { - switch_off(); - LED_A_OFF(); - } + if ( isOK >= 1 || lastChunk ) { + switch_off(); + LED_A_OFF(); + } - LED_B_OFF(); - LED_C_OFF(); + LED_B_OFF(); + LED_C_OFF(); } // Tries to read block. // retries 10times. bool iClass_ReadBlock(uint8_t blockNo, uint8_t *data, uint8_t len) { - uint8_t resp[10]; - uint8_t cmd[] = {ICLASS_CMD_READ_OR_IDENTIFY, blockNo, 0x00, 0x00}; - AddCrc( cmd+1, 1 ); - // expect size 10, retry 5times - bool isOK = sendCmdGetResponseWithRetries(cmd, sizeof(cmd), resp, 10, 5); - memcpy(data, resp, len); - return isOK; + uint8_t resp[10]; + uint8_t cmd[] = {ICLASS_CMD_READ_OR_IDENTIFY, blockNo, 0x00, 0x00}; + AddCrc( cmd+1, 1 ); + // expect size 10, retry 5times + bool isOK = sendCmdGetResponseWithRetries(cmd, sizeof(cmd), resp, 10, 5); + memcpy(data, resp, len); + return isOK; } // turn off afterwards // readblock 8 + 2. only want 8. void iClass_ReadBlk(uint8_t blockno) { - uint8_t data[] = {0,0,0,0,0,0,0,0,0,0}; - bool isOK = iClass_ReadBlock(blockno, data, sizeof(data)); - cmd_send(CMD_ACK, isOK, 0, 0, data, sizeof(data)); - switch_off(); + uint8_t data[] = {0,0,0,0,0,0,0,0,0,0}; + bool isOK = iClass_ReadBlock(blockno, data, sizeof(data)); + cmd_send(CMD_ACK, isOK, 0, 0, data, sizeof(data)); + switch_off(); } // turn off afterwards void iClass_Dump(uint8_t blockno, uint8_t numblks) { - uint8_t blockdata[] = {0,0,0,0,0,0,0,0,0,0}; - bool isOK = false; - uint8_t blkCnt = 0; + uint8_t blockdata[] = {0,0,0,0,0,0,0,0,0,0}; + bool isOK = false; + uint8_t blkCnt = 0; - BigBuf_free(); - uint8_t *dataout = BigBuf_malloc(255*8); - if (dataout == NULL){ - DbpString("[!] out of memory"); - OnError(1); - return; - } - // fill mem with 0xFF - memset(dataout, 0xFF, 255*8); + BigBuf_free(); + uint8_t *dataout = BigBuf_malloc(255*8); + if (dataout == NULL){ + DbpString("[!] out of memory"); + OnError(1); + return; + } + // fill mem with 0xFF + memset(dataout, 0xFF, 255*8); - for (;blkCnt < numblks; blkCnt++) { - isOK = iClass_ReadBlock(blockno + blkCnt, blockdata, sizeof(blockdata)); + for (;blkCnt < numblks; blkCnt++) { + isOK = iClass_ReadBlock(blockno + blkCnt, blockdata, sizeof(blockdata)); - // 0xBB is the internal debug separator byte.. - if (!isOK || (blockdata[0] == 0xBB || blockdata[7] == 0xBB || blockdata[2] == 0xBB)) { //try again - isOK = iClass_ReadBlock(blockno + blkCnt, blockdata, sizeof(blockdata)); - if (!isOK) { - Dbprintf("[!] block %02X failed to read", blkCnt + blockno); - break; - } - } - memcpy(dataout + (blkCnt * 8), blockdata, 8); - } - //return pointer to dump memory in arg3 - cmd_send(CMD_ACK, isOK, blkCnt, BigBuf_max_traceLen(), 0, 0); - switch_off(); - BigBuf_free(); + // 0xBB is the internal debug separator byte.. + if (!isOK || (blockdata[0] == 0xBB || blockdata[7] == 0xBB || blockdata[2] == 0xBB)) { //try again + isOK = iClass_ReadBlock(blockno + blkCnt, blockdata, sizeof(blockdata)); + if (!isOK) { + Dbprintf("[!] block %02X failed to read", blkCnt + blockno); + break; + } + } + memcpy(dataout + (blkCnt * 8), blockdata, 8); + } + //return pointer to dump memory in arg3 + cmd_send(CMD_ACK, isOK, blkCnt, BigBuf_max_traceLen(), 0, 0); + switch_off(); + BigBuf_free(); } bool iClass_WriteBlock_ext(uint8_t blockNo, uint8_t *data) { - uint8_t resp[] = {0,0,0,0,0,0,0,0,0,0}; - uint8_t write[] = { ICLASS_CMD_UPDATE, blockNo, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - memcpy(write+2, data, 12); // data + mac - AddCrc(write+1, 13); + uint8_t resp[] = {0,0,0,0,0,0,0,0,0,0}; + uint8_t write[] = { ICLASS_CMD_UPDATE, blockNo, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + memcpy(write+2, data, 12); // data + mac + AddCrc(write+1, 13); - bool isOK = sendCmdGetResponseWithRetries(write, sizeof(write), resp, sizeof(resp), 5); - if (isOK) { //if reader responded correctly + bool isOK = sendCmdGetResponseWithRetries(write, sizeof(write), resp, sizeof(resp), 5); + if (isOK) { //if reader responded correctly - //if response is not equal to write values - if (memcmp(write + 2, resp, 8)) { + //if response is not equal to write values + if (memcmp(write + 2, resp, 8)) { - //if not programming key areas (note key blocks don't get programmed with actual key data it is xor data) - if (blockNo != 3 && blockNo != 4) { - isOK = sendCmdGetResponseWithRetries(write, sizeof(write), resp, sizeof(resp), 5); - } - } - } - return isOK; + //if not programming key areas (note key blocks don't get programmed with actual key data it is xor data) + if (blockNo != 3 && blockNo != 4) { + isOK = sendCmdGetResponseWithRetries(write, sizeof(write), resp, sizeof(resp), 5); + } + } + } + return isOK; } // turn off afterwards void iClass_WriteBlock(uint8_t blockNo, uint8_t *data) { - bool isOK = iClass_WriteBlock_ext(blockNo, data); - cmd_send(CMD_ACK,isOK,0,0,0,0); - switch_off(); + bool isOK = iClass_WriteBlock_ext(blockNo, data); + cmd_send(CMD_ACK,isOK,0,0,0,0); + switch_off(); } // turn off afterwards void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data) { - int i, written = 0; - int total_block = (endblock - startblock) + 1; - for (i = 0; i < total_block; i++){ - // block number - if (iClass_WriteBlock_ext(i + startblock, data + ( i*12 ) )){ - Dbprintf("Write block [%02x] successful", i + startblock); - written++; - } else { - if (iClass_WriteBlock_ext(i + startblock, data + ( i*12 ) )){ - Dbprintf("Write block [%02x] successful", i + startblock); - written++; - } else { - Dbprintf("Write block [%02x] failed", i + startblock); - } - } - } - if (written == total_block) - DbpString("Clone complete"); - else - DbpString("Clone incomplete"); + int i, written = 0; + int total_block = (endblock - startblock) + 1; + for (i = 0; i < total_block; i++){ + // block number + if (iClass_WriteBlock_ext(i + startblock, data + ( i*12 ) )){ + Dbprintf("Write block [%02x] successful", i + startblock); + written++; + } else { + if (iClass_WriteBlock_ext(i + startblock, data + ( i*12 ) )){ + Dbprintf("Write block [%02x] successful", i + startblock); + written++; + } else { + Dbprintf("Write block [%02x] failed", i + startblock); + } + } + } + if (written == total_block) + DbpString("Clone complete"); + else + DbpString("Clone incomplete"); - cmd_send(CMD_ACK,1,0,0,0,0); - switch_off(); + cmd_send(CMD_ACK,1,0,0,0,0); + switch_off(); } \ No newline at end of file diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 9e415fcdb..e44af5fe3 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -112,49 +112,49 @@ static uint32_t LastProxToAirDuration; // Sequence X: 00001100 drop after half a period // Sequence Y: 00000000 no drop // Sequence Z: 11000000 drop at start -#define SEC_D 0xf0 -#define SEC_E 0x0f -#define SEC_F 0x00 +#define SEC_D 0xf0 +#define SEC_E 0x0f +#define SEC_F 0x00 #define SEC_COLL 0xff -#define SEC_X 0x0c -#define SEC_Y 0x00 -#define SEC_Z 0xc0 +#define SEC_X 0x0c +#define SEC_Y 0x00 +#define SEC_Z 0xc0 void iso14a_set_trigger(bool enable) { - trigger = enable; + trigger = enable; } void iso14a_set_timeout(uint32_t timeout) { - iso14a_timeout = timeout + (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/(16*8) + 2; + iso14a_timeout = timeout + (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/(16*8) + 2; } uint32_t iso14a_get_timeout(void) { - return iso14a_timeout - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/(16*8) - 2; + return iso14a_timeout - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/(16*8) - 2; } //----------------------------------------------------------------------------- // Generate the parity value for a byte sequence //----------------------------------------------------------------------------- void GetParity(const uint8_t *pbtCmd, uint16_t iLen, uint8_t *par) { - uint16_t paritybit_cnt = 0; - uint16_t paritybyte_cnt = 0; - uint8_t parityBits = 0; + uint16_t paritybit_cnt = 0; + uint16_t paritybyte_cnt = 0; + uint8_t parityBits = 0; - for (uint16_t i = 0; i < iLen; i++) { - // Generate the parity bits - parityBits |= ((oddparity8(pbtCmd[i])) << (7-paritybit_cnt)); - if (paritybit_cnt == 7) { - par[paritybyte_cnt] = parityBits; // save 8 Bits parity - parityBits = 0; // and advance to next Parity Byte - paritybyte_cnt++; - paritybit_cnt = 0; - } else { - paritybit_cnt++; - } - } + for (uint16_t i = 0; i < iLen; i++) { + // Generate the parity bits + parityBits |= ((oddparity8(pbtCmd[i])) << (7-paritybit_cnt)); + if (paritybit_cnt == 7) { + par[paritybyte_cnt] = parityBits; // save 8 Bits parity + parityBits = 0; // and advance to next Parity Byte + paritybyte_cnt++; + paritybit_cnt = 0; + } else { + paritybit_cnt++; + } + } - // save remaining parity bits - par[paritybyte_cnt] = parityBits; + // save remaining parity bits + par[paritybyte_cnt] = parityBits; } @@ -168,9 +168,9 @@ void GetParity(const uint8_t *pbtCmd, uint16_t iLen, uint8_t *par) { // The FPGA does a comparison with a threshold and would deliver e.g.: // ........ 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 ....... // The Miller decoder needs to identify the following sequences: -// 2 (or 3) ticks pause followed by 6 (or 5) ticks unmodulated: pause at beginning - Sequence Z ("start of communication" or a "0") -// 8 ticks without a modulation: no pause - Sequence Y (a "0" or "end of communication" or "no information") -// 4 ticks unmodulated followed by 2 (or 3) ticks pause: pause in second half - Sequence X (a "1") +// 2 (or 3) ticks pause followed by 6 (or 5) ticks unmodulated: pause at beginning - Sequence Z ("start of communication" or a "0") +// 8 ticks without a modulation: no pause - Sequence Y (a "0" or "end of communication" or "no information") +// 4 ticks unmodulated followed by 2 (or 3) ticks pause: pause in second half - Sequence X (a "1") // Note 1: the bitstream may start at any time. We therefore need to sync. // Note 2: the interpretation of Sequence Y and Z depends on the preceding sequence. //----------------------------------------------------------------------------- @@ -183,155 +183,155 @@ static tUart Uart; // 0111 - a 2 tick wide pause shifted left // 1001 - a 2 tick wide pause shifted right const bool Mod_Miller_LUT[] = { - false, true, false, true, false, false, false, true, - false, true, false, false, false, false, false, false + false, true, false, true, false, false, false, true, + false, true, false, false, false, false, false, false }; #define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4]) #define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)]) tUart* GetUart() { - return &Uart; + return &Uart; } void UartReset(void) { - Uart.state = STATE_UNSYNCD; - Uart.bitCount = 0; - Uart.len = 0; // number of decoded data bytes - Uart.parityLen = 0; // number of decoded parity bytes - Uart.shiftReg = 0; // shiftreg to hold decoded data bits - Uart.parityBits = 0; // holds 8 parity bits - Uart.startTime = 0; - Uart.endTime = 0; - Uart.fourBits = 0x00000000; // clear the buffer for 4 Bits - Uart.posCnt = 0; - Uart.syncBit = 9999; + Uart.state = STATE_UNSYNCD; + Uart.bitCount = 0; + Uart.len = 0; // number of decoded data bytes + Uart.parityLen = 0; // number of decoded parity bytes + Uart.shiftReg = 0; // shiftreg to hold decoded data bits + Uart.parityBits = 0; // holds 8 parity bits + Uart.startTime = 0; + Uart.endTime = 0; + Uart.fourBits = 0x00000000; // clear the buffer for 4 Bits + Uart.posCnt = 0; + Uart.syncBit = 9999; } void UartInit(uint8_t *data, uint8_t *parity) { - Uart.output = data; - Uart.parity = parity; - UartReset(); + Uart.output = data; + Uart.parity = parity; + UartReset(); } // use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) { - Uart.fourBits = (Uart.fourBits << 8) | bit; + Uart.fourBits = (Uart.fourBits << 8) | bit; - if (Uart.state == STATE_UNSYNCD) { // not yet synced - Uart.syncBit = 9999; // not set + if (Uart.state == STATE_UNSYNCD) { // not yet synced + Uart.syncBit = 9999; // not set - // 00x11111 2|3 ticks pause followed by 6|5 ticks unmodulated Sequence Z (a "0" or "start of communication") - // 11111111 8 ticks unmodulation Sequence Y (a "0" or "end of communication" or "no information") - // 111100x1 4 ticks unmodulated followed by 2|3 ticks pause Sequence X (a "1") + // 00x11111 2|3 ticks pause followed by 6|5 ticks unmodulated Sequence Z (a "0" or "start of communication") + // 11111111 8 ticks unmodulation Sequence Y (a "0" or "end of communication" or "no information") + // 111100x1 4 ticks unmodulated followed by 2|3 ticks pause Sequence X (a "1") - // The start bit is one ore more Sequence Y followed by a Sequence Z (... 11111111 00x11111). We need to distinguish from - // Sequence X followed by Sequence Y followed by Sequence Z (111100x1 11111111 00x11111) - // we therefore look for a ...xx1111 11111111 00x11111xxxxxx... pattern - // (12 '1's followed by 2 '0's, eventually followed by another '0', followed by 5 '1's) - #define ISO14443A_STARTBIT_MASK 0x07FFEF80 // mask is 00000111 11111111 11101111 10000000 - #define ISO14443A_STARTBIT_PATTERN 0x07FF8F80 // pattern is 00000111 11111111 10001111 10000000 - if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 0)) == ISO14443A_STARTBIT_PATTERN >> 0) Uart.syncBit = 7; - else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 1)) == ISO14443A_STARTBIT_PATTERN >> 1) Uart.syncBit = 6; - else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 2)) == ISO14443A_STARTBIT_PATTERN >> 2) Uart.syncBit = 5; - else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 3)) == ISO14443A_STARTBIT_PATTERN >> 3) Uart.syncBit = 4; - else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 4)) == ISO14443A_STARTBIT_PATTERN >> 4) Uart.syncBit = 3; - else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 5)) == ISO14443A_STARTBIT_PATTERN >> 5) Uart.syncBit = 2; - else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 6)) == ISO14443A_STARTBIT_PATTERN >> 6) Uart.syncBit = 1; - else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 7)) == ISO14443A_STARTBIT_PATTERN >> 7) Uart.syncBit = 0; + // The start bit is one ore more Sequence Y followed by a Sequence Z (... 11111111 00x11111). We need to distinguish from + // Sequence X followed by Sequence Y followed by Sequence Z (111100x1 11111111 00x11111) + // we therefore look for a ...xx1111 11111111 00x11111xxxxxx... pattern + // (12 '1's followed by 2 '0's, eventually followed by another '0', followed by 5 '1's) + #define ISO14443A_STARTBIT_MASK 0x07FFEF80 // mask is 00000111 11111111 11101111 10000000 + #define ISO14443A_STARTBIT_PATTERN 0x07FF8F80 // pattern is 00000111 11111111 10001111 10000000 + if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 0)) == ISO14443A_STARTBIT_PATTERN >> 0) Uart.syncBit = 7; + else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 1)) == ISO14443A_STARTBIT_PATTERN >> 1) Uart.syncBit = 6; + else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 2)) == ISO14443A_STARTBIT_PATTERN >> 2) Uart.syncBit = 5; + else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 3)) == ISO14443A_STARTBIT_PATTERN >> 3) Uart.syncBit = 4; + else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 4)) == ISO14443A_STARTBIT_PATTERN >> 4) Uart.syncBit = 3; + else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 5)) == ISO14443A_STARTBIT_PATTERN >> 5) Uart.syncBit = 2; + else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 6)) == ISO14443A_STARTBIT_PATTERN >> 6) Uart.syncBit = 1; + else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 7)) == ISO14443A_STARTBIT_PATTERN >> 7) Uart.syncBit = 0; - if (Uart.syncBit != 9999) { // found a sync bit - Uart.startTime = non_real_time ? non_real_time : (GetCountSspClk() & 0xfffffff8); - Uart.startTime -= Uart.syncBit; - Uart.endTime = Uart.startTime; - Uart.state = STATE_START_OF_COMMUNICATION; - } - } else { + if (Uart.syncBit != 9999) { // found a sync bit + Uart.startTime = non_real_time ? non_real_time : (GetCountSspClk() & 0xfffffff8); + Uart.startTime -= Uart.syncBit; + Uart.endTime = Uart.startTime; + Uart.state = STATE_START_OF_COMMUNICATION; + } + } else { - if (IsMillerModulationNibble1(Uart.fourBits >> Uart.syncBit)) { - if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) { // Modulation in both halves - error - UartReset(); - } else { // Modulation in first half = Sequence Z = logic "0" - if (Uart.state == STATE_MILLER_X) { // error - must not follow after X - UartReset(); - } else { - Uart.bitCount++; - Uart.shiftReg = (Uart.shiftReg >> 1); // add a 0 to the shiftreg - Uart.state = STATE_MILLER_Z; - Uart.endTime = Uart.startTime + 8 * (9 * Uart.len + Uart.bitCount + 1) - 6; - if (Uart.bitCount >= 9) { // if we decoded a full byte (including parity) - Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); - Uart.parityBits <<= 1; // make room for the parity bit - Uart.parityBits |= ((Uart.shiftReg >> 8) & 0x01); // store parity bit - Uart.bitCount = 0; - Uart.shiftReg = 0; - if ((Uart.len & 0x0007) == 0) { // every 8 data bytes - Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits - Uart.parityBits = 0; - } - } - } - } - } else { - if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) { // Modulation second half = Sequence X = logic "1" - Uart.bitCount++; - Uart.shiftReg = (Uart.shiftReg >> 1) | 0x100; // add a 1 to the shiftreg - Uart.state = STATE_MILLER_X; - Uart.endTime = Uart.startTime + 8 * (9 * Uart.len + Uart.bitCount + 1) - 2; - if (Uart.bitCount >= 9) { // if we decoded a full byte (including parity) - Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); - Uart.parityBits <<= 1; // make room for the new parity bit - Uart.parityBits |= ((Uart.shiftReg >> 8) & 0x01); // store parity bit - Uart.bitCount = 0; - Uart.shiftReg = 0; - if ((Uart.len & 0x0007) == 0) { // every 8 data bytes - Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits - Uart.parityBits = 0; - } - } - } else { // no modulation in both halves - Sequence Y - if (Uart.state == STATE_MILLER_Z || Uart.state == STATE_MILLER_Y) { // Y after logic "0" - End of Communication - Uart.state = STATE_UNSYNCD; - Uart.bitCount--; // last "0" was part of EOC sequence - Uart.shiftReg <<= 1; // drop it - if (Uart.bitCount > 0) { // if we decoded some bits - Uart.shiftReg >>= (9 - Uart.bitCount); // right align them - Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); // add last byte to the output - Uart.parityBits <<= 1; // add a (void) parity bit - Uart.parityBits <<= (8 - (Uart.len&0x0007)); // left align parity bits - Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store it - return true; - } else if (Uart.len & 0x0007) { // there are some parity bits to store - Uart.parityBits <<= (8 - (Uart.len&0x0007)); // left align remaining parity bits - Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store them - } - if (Uart.len) { - return true; // we are finished with decoding the raw data sequence - } else { - UartReset(); // Nothing received - start over - } - } - if (Uart.state == STATE_START_OF_COMMUNICATION) { // error - must not follow directly after SOC - UartReset(); - } else { // a logic "0" - Uart.bitCount++; - Uart.shiftReg = (Uart.shiftReg >> 1); // add a 0 to the shiftreg - Uart.state = STATE_MILLER_Y; - if (Uart.bitCount >= 9) { // if we decoded a full byte (including parity) - Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); - Uart.parityBits <<= 1; // make room for the parity bit - Uart.parityBits |= ((Uart.shiftReg >> 8) & 0x01); // store parity bit - Uart.bitCount = 0; - Uart.shiftReg = 0; - if ((Uart.len & 0x0007) == 0) { // every 8 data bytes - Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits - Uart.parityBits = 0; - } - } - } - } - } - } - return false; // not finished yet, need more data + if (IsMillerModulationNibble1(Uart.fourBits >> Uart.syncBit)) { + if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) { // Modulation in both halves - error + UartReset(); + } else { // Modulation in first half = Sequence Z = logic "0" + if (Uart.state == STATE_MILLER_X) { // error - must not follow after X + UartReset(); + } else { + Uart.bitCount++; + Uart.shiftReg = (Uart.shiftReg >> 1); // add a 0 to the shiftreg + Uart.state = STATE_MILLER_Z; + Uart.endTime = Uart.startTime + 8 * (9 * Uart.len + Uart.bitCount + 1) - 6; + if (Uart.bitCount >= 9) { // if we decoded a full byte (including parity) + Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); + Uart.parityBits <<= 1; // make room for the parity bit + Uart.parityBits |= ((Uart.shiftReg >> 8) & 0x01); // store parity bit + Uart.bitCount = 0; + Uart.shiftReg = 0; + if ((Uart.len & 0x0007) == 0) { // every 8 data bytes + Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits + Uart.parityBits = 0; + } + } + } + } + } else { + if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) { // Modulation second half = Sequence X = logic "1" + Uart.bitCount++; + Uart.shiftReg = (Uart.shiftReg >> 1) | 0x100; // add a 1 to the shiftreg + Uart.state = STATE_MILLER_X; + Uart.endTime = Uart.startTime + 8 * (9 * Uart.len + Uart.bitCount + 1) - 2; + if (Uart.bitCount >= 9) { // if we decoded a full byte (including parity) + Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); + Uart.parityBits <<= 1; // make room for the new parity bit + Uart.parityBits |= ((Uart.shiftReg >> 8) & 0x01); // store parity bit + Uart.bitCount = 0; + Uart.shiftReg = 0; + if ((Uart.len & 0x0007) == 0) { // every 8 data bytes + Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits + Uart.parityBits = 0; + } + } + } else { // no modulation in both halves - Sequence Y + if (Uart.state == STATE_MILLER_Z || Uart.state == STATE_MILLER_Y) { // Y after logic "0" - End of Communication + Uart.state = STATE_UNSYNCD; + Uart.bitCount--; // last "0" was part of EOC sequence + Uart.shiftReg <<= 1; // drop it + if (Uart.bitCount > 0) { // if we decoded some bits + Uart.shiftReg >>= (9 - Uart.bitCount); // right align them + Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); // add last byte to the output + Uart.parityBits <<= 1; // add a (void) parity bit + Uart.parityBits <<= (8 - (Uart.len&0x0007)); // left align parity bits + Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store it + return true; + } else if (Uart.len & 0x0007) { // there are some parity bits to store + Uart.parityBits <<= (8 - (Uart.len&0x0007)); // left align remaining parity bits + Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store them + } + if (Uart.len) { + return true; // we are finished with decoding the raw data sequence + } else { + UartReset(); // Nothing received - start over + } + } + if (Uart.state == STATE_START_OF_COMMUNICATION) { // error - must not follow directly after SOC + UartReset(); + } else { // a logic "0" + Uart.bitCount++; + Uart.shiftReg = (Uart.shiftReg >> 1); // add a 0 to the shiftreg + Uart.state = STATE_MILLER_Y; + if (Uart.bitCount >= 9) { // if we decoded a full byte (including parity) + Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); + Uart.parityBits <<= 1; // make room for the parity bit + Uart.parityBits |= ((Uart.shiftReg >> 8) & 0x01); // store parity bit + Uart.bitCount = 0; + Uart.shiftReg = 0; + if ((Uart.len & 0x0007) == 0) { // every 8 data bytes + Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits + Uart.parityBits = 0; + } + } + } + } + } + } + return false; // not finished yet, need more data } //============================================================================= @@ -343,10 +343,10 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) { // at the reader antenna will be modulated as well. The FPGA detects the modulation for us and would deliver e.g. the following: // ........ 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ....... // The Manchester decoder needs to identify the following sequences: -// 4 ticks modulated followed by 4 ticks unmodulated: Sequence D = 1 (also used as "start of communication") -// 4 ticks unmodulated followed by 4 ticks modulated: Sequence E = 0 -// 8 ticks unmodulated: Sequence F = end of communication -// 8 ticks modulated: A collision. Save the collision position and treat as Sequence D +// 4 ticks modulated followed by 4 ticks unmodulated: Sequence D = 1 (also used as "start of communication") +// 4 ticks unmodulated followed by 4 ticks modulated: Sequence E = 0 +// 8 ticks unmodulated: Sequence F = end of communication +// 8 ticks modulated: A collision. Save the collision position and treat as Sequence D // Note 1: the bitstream may start at any time. We therefore need to sync. // Note 2: parameter offset is used to determine the position of the parity bits (required for the anticollision command only) tDemod Demod; @@ -354,126 +354,126 @@ tDemod Demod; // Lookup-Table to decide if 4 raw bits are a modulation. // We accept three or four "1" in any position const bool Mod_Manchester_LUT[] = { - false, false, false, false, false, false, false, true, - false, false, false, true, false, true, true, true + false, false, false, false, false, false, false, true, + false, false, false, true, false, true, true, true }; #define IsManchesterModulationNibble1(b) (Mod_Manchester_LUT[(b & 0x00F0) >> 4]) #define IsManchesterModulationNibble2(b) (Mod_Manchester_LUT[(b & 0x000F)]) tDemod* GetDemod() { - return &Demod; + return &Demod; } void DemodReset(void) { - Demod.state = DEMOD_UNSYNCD; - Demod.len = 0; // number of decoded data bytes - Demod.parityLen = 0; - Demod.shiftReg = 0; // shiftreg to hold decoded data bits - Demod.parityBits = 0; // - Demod.collisionPos = 0; // Position of collision bit - Demod.twoBits = 0xFFFF; // buffer for 2 Bits - Demod.highCnt = 0; - Demod.startTime = 0; - Demod.endTime = 0; - Demod.bitCount = 0; - Demod.syncBit = 0xFFFF; - Demod.samples = 0; + Demod.state = DEMOD_UNSYNCD; + Demod.len = 0; // number of decoded data bytes + Demod.parityLen = 0; + Demod.shiftReg = 0; // shiftreg to hold decoded data bits + Demod.parityBits = 0; // + Demod.collisionPos = 0; // Position of collision bit + Demod.twoBits = 0xFFFF; // buffer for 2 Bits + Demod.highCnt = 0; + Demod.startTime = 0; + Demod.endTime = 0; + Demod.bitCount = 0; + Demod.syncBit = 0xFFFF; + Demod.samples = 0; } void DemodInit(uint8_t *data, uint8_t *parity) { - Demod.output = data; - Demod.parity = parity; - DemodReset(); + Demod.output = data; + Demod.parity = parity; + DemodReset(); } // use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time) { - Demod.twoBits = (Demod.twoBits << 8) | bit; + Demod.twoBits = (Demod.twoBits << 8) | bit; - if (Demod.state == DEMOD_UNSYNCD) { + if (Demod.state == DEMOD_UNSYNCD) { - if (Demod.highCnt < 2) { // wait for a stable unmodulated signal - if (Demod.twoBits == 0x0000) { - Demod.highCnt++; - } else { - Demod.highCnt = 0; - } - } else { - Demod.syncBit = 0xFFFF; // not set - if ((Demod.twoBits & 0x7700) == 0x7000) Demod.syncBit = 7; - else if ((Demod.twoBits & 0x3B80) == 0x3800) Demod.syncBit = 6; - else if ((Demod.twoBits & 0x1DC0) == 0x1C00) Demod.syncBit = 5; - else if ((Demod.twoBits & 0x0EE0) == 0x0E00) Demod.syncBit = 4; - else if ((Demod.twoBits & 0x0770) == 0x0700) Demod.syncBit = 3; - else if ((Demod.twoBits & 0x03B8) == 0x0380) Demod.syncBit = 2; - else if ((Demod.twoBits & 0x01DC) == 0x01C0) Demod.syncBit = 1; - else if ((Demod.twoBits & 0x00EE) == 0x00E0) Demod.syncBit = 0; - if (Demod.syncBit != 0xFFFF) { - Demod.startTime = non_real_time ? non_real_time : (GetCountSspClk() & 0xfffffff8); - Demod.startTime -= Demod.syncBit; - Demod.bitCount = offset; // number of decoded data bits - Demod.state = DEMOD_MANCHESTER_DATA; - } - } - } else { + if (Demod.highCnt < 2) { // wait for a stable unmodulated signal + if (Demod.twoBits == 0x0000) { + Demod.highCnt++; + } else { + Demod.highCnt = 0; + } + } else { + Demod.syncBit = 0xFFFF; // not set + if ((Demod.twoBits & 0x7700) == 0x7000) Demod.syncBit = 7; + else if ((Demod.twoBits & 0x3B80) == 0x3800) Demod.syncBit = 6; + else if ((Demod.twoBits & 0x1DC0) == 0x1C00) Demod.syncBit = 5; + else if ((Demod.twoBits & 0x0EE0) == 0x0E00) Demod.syncBit = 4; + else if ((Demod.twoBits & 0x0770) == 0x0700) Demod.syncBit = 3; + else if ((Demod.twoBits & 0x03B8) == 0x0380) Demod.syncBit = 2; + else if ((Demod.twoBits & 0x01DC) == 0x01C0) Demod.syncBit = 1; + else if ((Demod.twoBits & 0x00EE) == 0x00E0) Demod.syncBit = 0; + if (Demod.syncBit != 0xFFFF) { + Demod.startTime = non_real_time ? non_real_time : (GetCountSspClk() & 0xfffffff8); + Demod.startTime -= Demod.syncBit; + Demod.bitCount = offset; // number of decoded data bits + Demod.state = DEMOD_MANCHESTER_DATA; + } + } + } else { - if (IsManchesterModulationNibble1(Demod.twoBits >> Demod.syncBit)) { // modulation in first half - if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // ... and in second half = collision - if (!Demod.collisionPos) { - Demod.collisionPos = (Demod.len << 3) + Demod.bitCount; - } - } // modulation in first half only - Sequence D = 1 - Demod.bitCount++; - Demod.shiftReg = (Demod.shiftReg >> 1) | 0x100; // in both cases, add a 1 to the shiftreg - if (Demod.bitCount == 9) { // if we decoded a full byte (including parity) - Demod.output[Demod.len++] = (Demod.shiftReg & 0xff); - Demod.parityBits <<= 1; // make room for the parity bit - Demod.parityBits |= ((Demod.shiftReg >> 8) & 0x01); // store parity bit - Demod.bitCount = 0; - Demod.shiftReg = 0; - if ((Demod.len & 0x0007) == 0) { // every 8 data bytes - Demod.parity[Demod.parityLen++] = Demod.parityBits; // store 8 parity bits - Demod.parityBits = 0; - } - } - Demod.endTime = Demod.startTime + 8 * (9 * Demod.len + Demod.bitCount + 1) - 4; - } else { // no modulation in first half - if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // and modulation in second half = Sequence E = 0 - Demod.bitCount++; - Demod.shiftReg = (Demod.shiftReg >> 1); // add a 0 to the shiftreg - if (Demod.bitCount >= 9) { // if we decoded a full byte (including parity) - Demod.output[Demod.len++] = (Demod.shiftReg & 0xff); - Demod.parityBits <<= 1; // make room for the new parity bit - Demod.parityBits |= ((Demod.shiftReg >> 8) & 0x01); // store parity bit - Demod.bitCount = 0; - Demod.shiftReg = 0; - if ((Demod.len & 0x0007) == 0) { // every 8 data bytes - Demod.parity[Demod.parityLen++] = Demod.parityBits; // store 8 parity bits1 - Demod.parityBits = 0; - } - } - Demod.endTime = Demod.startTime + 8 * (9 * Demod.len + Demod.bitCount + 1); - } else { // no modulation in both halves - End of communication - if(Demod.bitCount > 0) { // there are some remaining data bits - Demod.shiftReg >>= (9 - Demod.bitCount); // right align the decoded bits - Demod.output[Demod.len++] = Demod.shiftReg & 0xff; // and add them to the output - Demod.parityBits <<= 1; // add a (void) parity bit - Demod.parityBits <<= (8 - (Demod.len&0x0007)); // left align remaining parity bits - Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them - return true; - } else if (Demod.len & 0x0007) { // there are some parity bits to store - Demod.parityBits <<= (8 - (Demod.len&0x0007)); // left align remaining parity bits - Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them - } - if (Demod.len) { - return true; // we are finished with decoding the raw data sequence - } else { // nothing received. Start over - DemodReset(); - } - } - } - } - return false; // not finished yet, need more data + if (IsManchesterModulationNibble1(Demod.twoBits >> Demod.syncBit)) { // modulation in first half + if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // ... and in second half = collision + if (!Demod.collisionPos) { + Demod.collisionPos = (Demod.len << 3) + Demod.bitCount; + } + } // modulation in first half only - Sequence D = 1 + Demod.bitCount++; + Demod.shiftReg = (Demod.shiftReg >> 1) | 0x100; // in both cases, add a 1 to the shiftreg + if (Demod.bitCount == 9) { // if we decoded a full byte (including parity) + Demod.output[Demod.len++] = (Demod.shiftReg & 0xff); + Demod.parityBits <<= 1; // make room for the parity bit + Demod.parityBits |= ((Demod.shiftReg >> 8) & 0x01); // store parity bit + Demod.bitCount = 0; + Demod.shiftReg = 0; + if ((Demod.len & 0x0007) == 0) { // every 8 data bytes + Demod.parity[Demod.parityLen++] = Demod.parityBits; // store 8 parity bits + Demod.parityBits = 0; + } + } + Demod.endTime = Demod.startTime + 8 * (9 * Demod.len + Demod.bitCount + 1) - 4; + } else { // no modulation in first half + if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // and modulation in second half = Sequence E = 0 + Demod.bitCount++; + Demod.shiftReg = (Demod.shiftReg >> 1); // add a 0 to the shiftreg + if (Demod.bitCount >= 9) { // if we decoded a full byte (including parity) + Demod.output[Demod.len++] = (Demod.shiftReg & 0xff); + Demod.parityBits <<= 1; // make room for the new parity bit + Demod.parityBits |= ((Demod.shiftReg >> 8) & 0x01); // store parity bit + Demod.bitCount = 0; + Demod.shiftReg = 0; + if ((Demod.len & 0x0007) == 0) { // every 8 data bytes + Demod.parity[Demod.parityLen++] = Demod.parityBits; // store 8 parity bits1 + Demod.parityBits = 0; + } + } + Demod.endTime = Demod.startTime + 8 * (9 * Demod.len + Demod.bitCount + 1); + } else { // no modulation in both halves - End of communication + if(Demod.bitCount > 0) { // there are some remaining data bits + Demod.shiftReg >>= (9 - Demod.bitCount); // right align the decoded bits + Demod.output[Demod.len++] = Demod.shiftReg & 0xff; // and add them to the output + Demod.parityBits <<= 1; // add a (void) parity bit + Demod.parityBits <<= (8 - (Demod.len&0x0007)); // left align remaining parity bits + Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them + return true; + } else if (Demod.len & 0x0007) { // there are some parity bits to store + Demod.parityBits <<= (8 - (Demod.len&0x0007)); // left align remaining parity bits + Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them + } + if (Demod.len) { + return true; // we are finished with decoding the raw data sequence + } else { // nothing received. Start over + DemodReset(); + } + } + } + } + return false; // not finished yet, need more data } //============================================================================= @@ -488,162 +488,162 @@ RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_t // "hf 14a sniff" //----------------------------------------------------------------------------- void RAMFUNC SniffIso14443a(uint8_t param) { - LEDsoff(); - // param: - // bit 0 - trigger from first card answer - // bit 1 - trigger from first reader 7-bit request - iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER); + LEDsoff(); + // param: + // bit 0 - trigger from first card answer + // bit 1 - trigger from first reader 7-bit request + iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER); - // Allocate memory from BigBuf for some buffers - // free all previous allocations first - BigBuf_free(); BigBuf_Clear_ext(false); - clear_trace(); - set_tracing(true); + // Allocate memory from BigBuf for some buffers + // free all previous allocations first + BigBuf_free(); BigBuf_Clear_ext(false); + clear_trace(); + set_tracing(true); - // The command (reader -> tag) that we're receiving. - uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); - uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE); + // The command (reader -> tag) that we're receiving. + uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); + uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE); - // The response (tag -> reader) that we're receiving. - uint8_t *receivedResp = BigBuf_malloc(MAX_FRAME_SIZE); - uint8_t *receivedRespPar = BigBuf_malloc(MAX_PARITY_SIZE); + // The response (tag -> reader) that we're receiving. + uint8_t *receivedResp = BigBuf_malloc(MAX_FRAME_SIZE); + uint8_t *receivedRespPar = BigBuf_malloc(MAX_PARITY_SIZE); - // The DMA buffer, used to stream samples from the FPGA - uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); - uint8_t *data = dmaBuf; + // The DMA buffer, used to stream samples from the FPGA + uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); + uint8_t *data = dmaBuf; - uint8_t previous_data = 0; - int maxDataLen = 0; - int dataLen = 0; - bool TagIsActive = false; - bool ReaderIsActive = false; + uint8_t previous_data = 0; + int maxDataLen = 0; + int dataLen = 0; + bool TagIsActive = false; + bool ReaderIsActive = false; - // Set up the demodulator for tag -> reader responses. - DemodInit(receivedResp, receivedRespPar); + // Set up the demodulator for tag -> reader responses. + DemodInit(receivedResp, receivedRespPar); - // Set up the demodulator for the reader -> tag commands - UartInit(receivedCmd, receivedCmdPar); + // Set up the demodulator for the reader -> tag commands + UartInit(receivedCmd, receivedCmdPar); - // Setup and start DMA. - if ( !FpgaSetupSscDma((uint8_t*) dmaBuf, DMA_BUFFER_SIZE) ){ - if (MF_DBGLEVEL > 1) Dbprintf("FpgaSetupSscDma failed. Exiting"); - return; - } + // Setup and start DMA. + if ( !FpgaSetupSscDma((uint8_t*) dmaBuf, DMA_BUFFER_SIZE) ){ + if (MF_DBGLEVEL > 1) Dbprintf("FpgaSetupSscDma failed. Exiting"); + return; + } - // 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 - // response from the tag. - // triggered == false -- to wait first for card - bool triggered = !(param & 0x03); + // 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 + // response from the tag. + // triggered == false -- to wait first for card + bool triggered = !(param & 0x03); - uint32_t rsamples = 0; + uint32_t rsamples = 0; - DbpString("Starting to sniff"); + DbpString("Starting to sniff"); - // loop and listen - while (!BUTTON_PRESS()) { + // loop and listen + while (!BUTTON_PRESS()) { WDT_HIT(); LED_A_ON(); - int register readBufDataP = data - dmaBuf; - int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR; - if (readBufDataP <= dmaBufDataP) - dataLen = dmaBufDataP - readBufDataP; - else - dataLen = DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP; + int register readBufDataP = data - dmaBuf; + int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR; + if (readBufDataP <= dmaBufDataP) + dataLen = dmaBufDataP - readBufDataP; + else + dataLen = DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP; - // test for length of buffer - if (dataLen > maxDataLen) { - maxDataLen = dataLen; - if (dataLen > (9 * DMA_BUFFER_SIZE / 10)) { - Dbprintf("[!] blew circular buffer! | datalen %u", dataLen); - break; - } - } - if (dataLen < 1) continue; + // test for length of buffer + if (dataLen > maxDataLen) { + maxDataLen = dataLen; + if (dataLen > (9 * DMA_BUFFER_SIZE / 10)) { + Dbprintf("[!] blew circular buffer! | datalen %u", dataLen); + break; + } + } + if (dataLen < 1) continue; - // primary buffer was stopped( <-- we lost data! - 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 | data length %d", dataLen); // temporary - } - // secondary buffer sets as primary, secondary buffer was stopped - if (!AT91C_BASE_PDC_SSC->PDC_RNCR) { - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; - AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; - } + // primary buffer was stopped( <-- we lost data! + 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 | data length %d", dataLen); // temporary + } + // secondary buffer sets as primary, secondary buffer was stopped + if (!AT91C_BASE_PDC_SSC->PDC_RNCR) { + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; + AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; + } - LED_A_OFF(); + LED_A_OFF(); - // Need two samples to feed Miller and Manchester-Decoder - if (rsamples & 0x01) { + // Need two samples to feed Miller and Manchester-Decoder + if (rsamples & 0x01) { - if (!TagIsActive) { // no need to try decoding reader data if the tag is sending - uint8_t readerdata = (previous_data & 0xF0) | (*data >> 4); - if (MillerDecoding(readerdata, (rsamples-1)*4)) { - LED_C_ON(); + if (!TagIsActive) { // no need to try decoding reader data if the tag is sending + uint8_t readerdata = (previous_data & 0xF0) | (*data >> 4); + if (MillerDecoding(readerdata, (rsamples-1)*4)) { + LED_C_ON(); - // check - if there is a short 7bit request from reader - if ((!triggered) && (param & 0x02) && (Uart.len == 1) && (Uart.bitCount == 7)) triggered = true; + // check - if there is a short 7bit request from reader + if ((!triggered) && (param & 0x02) && (Uart.len == 1) && (Uart.bitCount == 7)) triggered = true; - if (triggered) { - if (!LogTrace(receivedCmd, - Uart.len, - Uart.startTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, - Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, - Uart.parity, - true)) break; - } - /* ready to receive another command. */ - UartReset(); - /* reset the demod code, which might have been */ - /* false-triggered by the commands from the reader. */ - DemodReset(); - LED_B_OFF(); - } - ReaderIsActive = (Uart.state != STATE_UNSYNCD); - } + if (triggered) { + if (!LogTrace(receivedCmd, + Uart.len, + Uart.startTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, + Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, + Uart.parity, + true)) break; + } + /* ready to receive another command. */ + UartReset(); + /* reset the demod code, which might have been */ + /* false-triggered by the commands from the reader. */ + DemodReset(); + LED_B_OFF(); + } + ReaderIsActive = (Uart.state != STATE_UNSYNCD); + } - // no need to try decoding tag data if the reader is sending - and we cannot afford the time - if (!ReaderIsActive) { - uint8_t tagdata = (previous_data << 4) | (*data & 0x0F); - if (ManchesterDecoding(tagdata, 0, (rsamples-1)*4)) { - LED_B_ON(); + // no need to try decoding tag data if the reader is sending - and we cannot afford the time + if (!ReaderIsActive) { + uint8_t tagdata = (previous_data << 4) | (*data & 0x0F); + if (ManchesterDecoding(tagdata, 0, (rsamples-1)*4)) { + LED_B_ON(); - if (!LogTrace(receivedResp, - Demod.len, - Demod.startTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, - Demod.endTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, - Demod.parity, - false)) break; + if (!LogTrace(receivedResp, + Demod.len, + Demod.startTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, + Demod.endTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, + Demod.parity, + false)) break; - if ((!triggered) && (param & 0x01)) triggered = true; + if ((!triggered) && (param & 0x01)) triggered = true; - // ready to receive another response. - DemodReset(); - // reset the Miller decoder including its (now outdated) input buffer - UartReset(); - //UartInit(receivedCmd, receivedCmdPar); - LED_C_OFF(); - } - TagIsActive = (Demod.state != DEMOD_UNSYNCD); - } - } + // ready to receive another response. + DemodReset(); + // reset the Miller decoder including its (now outdated) input buffer + UartReset(); + //UartInit(receivedCmd, receivedCmdPar); + LED_C_OFF(); + } + TagIsActive = (Demod.state != DEMOD_UNSYNCD); + } + } - previous_data = *data; - rsamples++; - data++; - if (data == dmaBuf + DMA_BUFFER_SIZE) { - data = dmaBuf; - } - } // end main loop + previous_data = *data; + rsamples++; + data++; + if (data == dmaBuf + DMA_BUFFER_SIZE) { + data = dmaBuf; + } + } // end main loop - if (MF_DBGLEVEL >= 1) { - Dbprintf("maxDataLen=%d, Uart.state=%x, Uart.len=%d", maxDataLen, Uart.state, Uart.len); - Dbprintf("traceLen=%d, Uart.output[0]=%08x", BigBuf_get_traceLen(), (uint32_t)Uart.output[0]); - } - switch_off(); + if (MF_DBGLEVEL >= 1) { + Dbprintf("maxDataLen=%d, Uart.state=%x, Uart.len=%d", maxDataLen, Uart.state, Uart.len); + Dbprintf("traceLen=%d, Uart.output[0]=%08x", BigBuf_get_traceLen(), (uint32_t)Uart.output[0]); + } + switch_off(); } //----------------------------------------------------------------------------- @@ -651,107 +651,107 @@ void RAMFUNC SniffIso14443a(uint8_t param) { //----------------------------------------------------------------------------- static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *parity, bool collision) { - //uint8_t localCol = 0; - ToSendReset(); + //uint8_t localCol = 0; + ToSendReset(); - // Correction bit, might be removed when not needed - ToSendStuffBit(0); - ToSendStuffBit(0); - ToSendStuffBit(0); - ToSendStuffBit(0); - ToSendStuffBit(1); // <----- - ToSendStuffBit(0); - ToSendStuffBit(0); - ToSendStuffBit(0); + // Correction bit, might be removed when not needed + ToSendStuffBit(0); + ToSendStuffBit(0); + ToSendStuffBit(0); + ToSendStuffBit(0); + ToSendStuffBit(1); // <----- + ToSendStuffBit(0); + ToSendStuffBit(0); + ToSendStuffBit(0); - // Send startbit - ToSend[++ToSendMax] = SEC_D; - LastProxToAirDuration = 8 * ToSendMax - 4; + // Send startbit + ToSend[++ToSendMax] = SEC_D; + LastProxToAirDuration = 8 * ToSendMax - 4; - for(uint16_t i = 0; i < len; i++) { - uint8_t b = cmd[i]; + for(uint16_t i = 0; i < len; i++) { + uint8_t b = cmd[i]; - // Data bits - for(uint16_t j = 0; j < 8; j++) { - //if (collision && (localCol >= colpos)){ - if (collision) { - ToSend[++ToSendMax] = SEC_COLL; - //localCol++; + // Data bits + for(uint16_t j = 0; j < 8; j++) { + //if (collision && (localCol >= colpos)){ + if (collision) { + ToSend[++ToSendMax] = SEC_COLL; + //localCol++; } else { - if (b & 1) { - ToSend[++ToSendMax] = SEC_D; - } else { - ToSend[++ToSendMax] = SEC_E; - } - b >>= 1; - } - } + if (b & 1) { + ToSend[++ToSendMax] = SEC_D; + } else { + ToSend[++ToSendMax] = SEC_E; + } + b >>= 1; + } + } - if (collision) { - ToSend[++ToSendMax] = SEC_COLL; - LastProxToAirDuration = 8 * ToSendMax; - } else { - // Get the parity bit - if (parity[i>>3] & (0x80>>(i&0x0007))) { - ToSend[++ToSendMax] = SEC_D; - LastProxToAirDuration = 8 * ToSendMax - 4; - } else { - ToSend[++ToSendMax] = SEC_E; - LastProxToAirDuration = 8 * ToSendMax; - } - } - } + if (collision) { + ToSend[++ToSendMax] = SEC_COLL; + LastProxToAirDuration = 8 * ToSendMax; + } else { + // Get the parity bit + if (parity[i>>3] & (0x80>>(i&0x0007))) { + ToSend[++ToSendMax] = SEC_D; + LastProxToAirDuration = 8 * ToSendMax - 4; + } else { + ToSend[++ToSendMax] = SEC_E; + LastProxToAirDuration = 8 * ToSendMax; + } + } + } - // Send stopbit - ToSend[++ToSendMax] = SEC_F; + // Send stopbit + ToSend[++ToSendMax] = SEC_F; - // Convert from last byte pos to length - ToSendMax++; + // Convert from last byte pos to length + ToSendMax++; } static void CodeIso14443aAsTagEx(const uint8_t *cmd, uint16_t len, bool collision) { - uint8_t par[MAX_PARITY_SIZE] = {0}; - GetParity(cmd, len, par); - CodeIso14443aAsTagPar(cmd, len, par, collision); + uint8_t par[MAX_PARITY_SIZE] = {0}; + GetParity(cmd, len, par); + CodeIso14443aAsTagPar(cmd, len, par, collision); } static void CodeIso14443aAsTag(const uint8_t *cmd, uint16_t len) { - CodeIso14443aAsTagEx(cmd, len, false); + CodeIso14443aAsTagEx(cmd, len, false); } static void Code4bitAnswerAsTag(uint8_t cmd) { - uint8_t b = cmd; + uint8_t b = cmd; - ToSendReset(); + ToSendReset(); - // Correction bit, might be removed when not needed - ToSendStuffBit(0); - ToSendStuffBit(0); - ToSendStuffBit(0); - ToSendStuffBit(0); - ToSendStuffBit(1); // 1 - ToSendStuffBit(0); - ToSendStuffBit(0); - ToSendStuffBit(0); + // Correction bit, might be removed when not needed + ToSendStuffBit(0); + ToSendStuffBit(0); + ToSendStuffBit(0); + ToSendStuffBit(0); + ToSendStuffBit(1); // 1 + ToSendStuffBit(0); + ToSendStuffBit(0); + ToSendStuffBit(0); - // Send startbit - ToSend[++ToSendMax] = SEC_D; + // Send startbit + ToSend[++ToSendMax] = SEC_D; - for(uint8_t i = 0; i < 4; i++) { - if(b & 1) { - ToSend[++ToSendMax] = SEC_D; - LastProxToAirDuration = 8 * ToSendMax - 4; - } else { - ToSend[++ToSendMax] = SEC_E; - LastProxToAirDuration = 8 * ToSendMax; - } - b >>= 1; - } + for(uint8_t i = 0; i < 4; i++) { + if(b & 1) { + ToSend[++ToSendMax] = SEC_D; + LastProxToAirDuration = 8 * ToSendMax - 4; + } else { + ToSend[++ToSendMax] = SEC_E; + LastProxToAirDuration = 8 * ToSendMax; + } + b >>= 1; + } - // Send stopbit - ToSend[++ToSendMax] = SEC_F; + // Send stopbit + ToSend[++ToSendMax] = SEC_F; - // Convert from last byte pos to length - ToSendMax++; + // Convert from last byte pos to length + ToSendMax++; } //----------------------------------------------------------------------------- @@ -767,9 +767,9 @@ int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len) FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN); // Now run a `software UART` on the stream of incoming samples. - UartInit(received, parity); + UartInit(received, parity); - // clear RXRDY: + // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; while (!BUTTON_PRESS()) { @@ -777,43 +777,43 @@ int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len) if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - if (MillerDecoding(b, 0)) { - *len = Uart.len; - return true; - } - } + if (MillerDecoding(b, 0)) { + *len = Uart.len; + return true; + } + } } - return false; + return false; } bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffer_size) { - // Example response, answer to MIFARE Classic read block will be 16 bytes + 2 CRC = 18 bytes - // This will need the following byte array for a modulation sequence - // 144 data bits (18 * 8) - // 18 parity bits - // 2 Start and stop - // 1 Correction bit (Answer in 1172 or 1236 periods, see FPGA) - // 1 just for the case - // ----------- + - // 166 bytes, since every bit that needs to be send costs us a byte - // - // Prepare the tag modulation bits from the message - CodeIso14443aAsTag(response_info->response,response_info->response_n); + // Example response, answer to MIFARE Classic read block will be 16 bytes + 2 CRC = 18 bytes + // This will need the following byte array for a modulation sequence + // 144 data bits (18 * 8) + // 18 parity bits + // 2 Start and stop + // 1 Correction bit (Answer in 1172 or 1236 periods, see FPGA) + // 1 just for the case + // ----------- + + // 166 bytes, since every bit that needs to be send costs us a byte + // + // Prepare the tag modulation bits from the message + CodeIso14443aAsTag(response_info->response,response_info->response_n); - // Make sure we do not exceed the free buffer space - if (ToSendMax > max_buffer_size) { - Dbprintf("Out of memory, when modulating bits for tag answer:"); - Dbhexdump(response_info->response_n, response_info->response, false); - return false; - } + // Make sure we do not exceed the free buffer space + if (ToSendMax > max_buffer_size) { + Dbprintf("Out of memory, when modulating bits for tag answer:"); + Dbhexdump(response_info->response_n, response_info->response, false); + return false; + } - // Copy the byte array, used for this modulation to the buffer position - memcpy(response_info->modulation, ToSend, ToSendMax); + // Copy the byte array, used for this modulation to the buffer position + memcpy(response_info->modulation, ToSend, ToSendMax); - // Store the number of bytes that were used for encoding/modulation and the time needed to transfer them - response_info->modulation_n = ToSendMax; - response_info->ProxToAirDuration = LastProxToAirDuration; - return true; + // Store the number of bytes that were used for encoding/modulation and the time needed to transfer them + response_info->modulation_n = ToSendMax; + response_info->ProxToAirDuration = LastProxToAirDuration; + return true; } // "precompile" responses. There are 7 predefined responses with a total of 28 bytes data to transmit. @@ -825,20 +825,20 @@ bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffe #define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 453 bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) { - // Retrieve and store the current buffer index - response_info->modulation = free_buffer_pointer; + // Retrieve and store the current buffer index + response_info->modulation = free_buffer_pointer; - // Determine the maximum size we can use from our buffer - size_t max_buffer_size = ALLOCATED_TAG_MODULATION_BUFFER_SIZE; + // Determine the maximum size we can use from our buffer + size_t max_buffer_size = ALLOCATED_TAG_MODULATION_BUFFER_SIZE; - // Forward the prepare tag modulation function to the inner function - if (prepare_tag_modulation(response_info, max_buffer_size)) { - // Update the free buffer offset - free_buffer_pointer += ToSendMax; - return true; - } else { - return false; - } + // Forward the prepare tag modulation function to the inner function + if (prepare_tag_modulation(response_info, max_buffer_size)) { + // Update the free buffer offset + free_buffer_pointer += ToSendMax; + return true; + } else { + return false; + } } //----------------------------------------------------------------------------- @@ -848,699 +848,699 @@ bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) { //----------------------------------------------------------------------------- void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) { - #define ATTACK_KEY_COUNT 8 // keep same as define in cmdhfmf.c -> readerAttack() + #define ATTACK_KEY_COUNT 8 // keep same as define in cmdhfmf.c -> readerAttack() - uint8_t sak = 0; - uint32_t cuid = 0; - uint32_t nonce = 0; + uint8_t sak = 0; + uint32_t cuid = 0; + uint32_t nonce = 0; - // PACK response to PWD AUTH for EV1/NTAG - uint8_t response8[4] = {0,0,0,0}; - // Counter for EV1/NTAG - uint32_t counters[] = {0,0,0}; + // PACK response to PWD AUTH for EV1/NTAG + uint8_t response8[4] = {0,0,0,0}; + // Counter for EV1/NTAG + uint32_t counters[] = {0,0,0}; - // The first response contains the ATQA (note: bytes are transmitted in reverse order). - uint8_t response1[] = {0,0}; + // The first response contains the ATQA (note: bytes are transmitted in reverse order). + uint8_t response1[] = {0,0}; - // Here, we collect CUID, block1, keytype1, NT1, NR1, AR1, CUID, block2, keytyp2, NT2, NR2, AR2 - // it should also collect block, keytype. - uint8_t cardAUTHSC = 0; - uint8_t cardAUTHKEY = 0xff; // no authentication - // allow collecting up to 8 sets of nonces to allow recovery of up to 8 keys + // Here, we collect CUID, block1, keytype1, NT1, NR1, AR1, CUID, block2, keytyp2, NT2, NR2, AR2 + // it should also collect block, keytype. + uint8_t cardAUTHSC = 0; + uint8_t cardAUTHKEY = 0xff; // no authentication + // allow collecting up to 8 sets of nonces to allow recovery of up to 8 keys - nonces_t ar_nr_nonces[ATTACK_KEY_COUNT]; // for attack types moebius - memset(ar_nr_nonces, 0x00, sizeof(ar_nr_nonces)); - uint8_t moebius_count = 0; + nonces_t ar_nr_nonces[ATTACK_KEY_COUNT]; // for attack types moebius + memset(ar_nr_nonces, 0x00, sizeof(ar_nr_nonces)); + uint8_t moebius_count = 0; - switch (tagType) { - case 1: { // MIFARE Classic 1k - response1[0] = 0x04; - sak = 0x08; - } break; - case 2: { // MIFARE Ultralight - response1[0] = 0x44; - sak = 0x00; - } break; - case 3: { // MIFARE DESFire - response1[0] = 0x04; - response1[1] = 0x03; - sak = 0x20; - } break; - case 4: { // ISO/IEC 14443-4 - javacard (JCOP) - response1[0] = 0x04; - sak = 0x28; - } break; - case 5: { // MIFARE TNP3XXX - response1[0] = 0x01; - response1[1] = 0x0f; - sak = 0x01; - } break; - case 6: { // MIFARE Mini 320b - response1[0] = 0x44; - sak = 0x09; - } break; - case 7: { // NTAG - response1[0] = 0x44; - sak = 0x00; - // PACK - response8[0] = 0x80; - response8[1] = 0x80; - compute_crc(CRC_14443_A, response8, 2, &response8[2], &response8[3]); - // uid not supplied then get from emulator memory - if (data[0]==0) { - uint16_t start = 4 * (0+12); - uint8_t emdata[8]; - emlGetMemBt( emdata, start, sizeof(emdata)); - memcpy(data, emdata, 3); // uid bytes 0-2 - memcpy(data+3, emdata+4, 4); // uid bytes 3-7 - flags |= FLAG_7B_UID_IN_DATA; - } - } break; - case 8: { // MIFARE Classic 4k - response1[0] = 0x02; - sak = 0x18; - } break; - case 9 : { // FM11RF005SH (Shanghai Metro) - response1[0] = 0x03; - response1[1] = 0x00; - sak = 0x0A; - } - default: { - Dbprintf("Error: unkown tagtype (%d)",tagType); - return; - } break; - } + switch (tagType) { + case 1: { // MIFARE Classic 1k + response1[0] = 0x04; + sak = 0x08; + } break; + case 2: { // MIFARE Ultralight + response1[0] = 0x44; + sak = 0x00; + } break; + case 3: { // MIFARE DESFire + response1[0] = 0x04; + response1[1] = 0x03; + sak = 0x20; + } break; + case 4: { // ISO/IEC 14443-4 - javacard (JCOP) + response1[0] = 0x04; + sak = 0x28; + } break; + case 5: { // MIFARE TNP3XXX + response1[0] = 0x01; + response1[1] = 0x0f; + sak = 0x01; + } break; + case 6: { // MIFARE Mini 320b + response1[0] = 0x44; + sak = 0x09; + } break; + case 7: { // NTAG + response1[0] = 0x44; + sak = 0x00; + // PACK + response8[0] = 0x80; + response8[1] = 0x80; + compute_crc(CRC_14443_A, response8, 2, &response8[2], &response8[3]); + // uid not supplied then get from emulator memory + if (data[0]==0) { + uint16_t start = 4 * (0+12); + uint8_t emdata[8]; + emlGetMemBt( emdata, start, sizeof(emdata)); + memcpy(data, emdata, 3); // uid bytes 0-2 + memcpy(data+3, emdata+4, 4); // uid bytes 3-7 + flags |= FLAG_7B_UID_IN_DATA; + } + } break; + case 8: { // MIFARE Classic 4k + response1[0] = 0x02; + sak = 0x18; + } break; + case 9 : { // FM11RF005SH (Shanghai Metro) + response1[0] = 0x03; + response1[1] = 0x00; + sak = 0x0A; + } + default: { + Dbprintf("Error: unkown tagtype (%d)",tagType); + return; + } break; + } - // The second response contains the (mandatory) first 24 bits of the UID - uint8_t response2[5] = {0x00}; + // The second response contains the (mandatory) first 24 bits of the UID + uint8_t response2[5] = {0x00}; - // For UID size 7, - uint8_t response2a[5] = {0x00}; + // For UID size 7, + uint8_t response2a[5] = {0x00}; - if ( (flags & FLAG_7B_UID_IN_DATA) == FLAG_7B_UID_IN_DATA ) { - response2[0] = 0x88; // Cascade Tag marker - response2[1] = data[0]; - response2[2] = data[1]; - response2[3] = data[2]; + if ( (flags & FLAG_7B_UID_IN_DATA) == FLAG_7B_UID_IN_DATA ) { + response2[0] = 0x88; // Cascade Tag marker + response2[1] = data[0]; + response2[2] = data[1]; + response2[3] = data[2]; - response2a[0] = data[3]; - response2a[1] = data[4]; - response2a[2] = data[5]; - response2a[3] = data[6]; //?? - response2a[4] = response2a[0] ^ response2a[1] ^ response2a[2] ^ response2a[3]; + response2a[0] = data[3]; + response2a[1] = data[4]; + response2a[2] = data[5]; + response2a[3] = data[6]; //?? + response2a[4] = response2a[0] ^ response2a[1] ^ response2a[2] ^ response2a[3]; - // Configure the ATQA and SAK accordingly - response1[0] |= 0x40; - sak |= 0x04; + // Configure the ATQA and SAK accordingly + response1[0] |= 0x40; + sak |= 0x04; - cuid = bytes_to_num(data+3, 4); - } else { - memcpy(response2, data, 4); - // Configure the ATQA and SAK accordingly - response1[0] &= 0xBF; - sak &= 0xFB; - cuid = bytes_to_num(data, 4); - } + cuid = bytes_to_num(data+3, 4); + } else { + memcpy(response2, data, 4); + // Configure the ATQA and SAK accordingly + response1[0] &= 0xBF; + sak &= 0xFB; + cuid = bytes_to_num(data, 4); + } - // Calculate the BitCountCheck (BCC) for the first 4 bytes of the UID. - response2[4] = response2[0] ^ response2[1] ^ response2[2] ^ response2[3]; + // Calculate the BitCountCheck (BCC) for the first 4 bytes of the UID. + response2[4] = response2[0] ^ response2[1] ^ response2[2] ^ response2[3]; - // Prepare the mandatory SAK (for 4 and 7 byte UID) - uint8_t response3[3] = {sak, 0x00, 0x00}; - compute_crc(CRC_14443_A, response3, 1, &response3[1], &response3[2]); + // Prepare the mandatory SAK (for 4 and 7 byte UID) + uint8_t response3[3] = {sak, 0x00, 0x00}; + compute_crc(CRC_14443_A, response3, 1, &response3[1], &response3[2]); - // Prepare the optional second SAK (for 7 byte UID), drop the cascade bit - uint8_t response3a[3] = {0x00}; - response3a[0] = sak & 0xFB; - compute_crc(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]); + // Prepare the optional second SAK (for 7 byte UID), drop the cascade bit + uint8_t response3a[3] = {0x00}; + response3a[0] = sak & 0xFB; + compute_crc(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]); - // Tag NONCE. - uint8_t response5[4]; + // Tag NONCE. + uint8_t response5[4]; - uint8_t response6[] = { 0x04, 0x58, 0x80, 0x02, 0x00, 0x00 }; // dummy ATS (pseudo-ATR), answer to RATS: + uint8_t response6[] = { 0x04, 0x58, 0x80, 0x02, 0x00, 0x00 }; // dummy ATS (pseudo-ATR), answer to RATS: - // Format byte = 0x58: FSCI=0x08 (FSC=256), TA(1) and TC(1) present, - // TA(1) = 0x80: different divisors not supported, DR = 1, DS = 1 - // TB(1) = not present. Defaults: FWI = 4 (FWT = 256 * 16 * 2^4 * 1/fc = 4833us), SFGI = 0 (SFG = 256 * 16 * 2^0 * 1/fc = 302us) - // TC(1) = 0x02: CID supported, NAD not supported - compute_crc(CRC_14443_A, response6, 4, &response6[4], &response6[5]); + // Format byte = 0x58: FSCI=0x08 (FSC=256), TA(1) and TC(1) present, + // TA(1) = 0x80: different divisors not supported, DR = 1, DS = 1 + // TB(1) = not present. Defaults: FWI = 4 (FWT = 256 * 16 * 2^4 * 1/fc = 4833us), SFGI = 0 (SFG = 256 * 16 * 2^0 * 1/fc = 302us) + // TC(1) = 0x02: CID supported, NAD not supported + compute_crc(CRC_14443_A, response6, 4, &response6[4], &response6[5]); - // Prepare GET_VERSION (different for UL EV-1 / NTAG) - // uint8_t response7_EV1[] = {0x00, 0x04, 0x03, 0x01, 0x01, 0x00, 0x0b, 0x03, 0xfd, 0xf7}; //EV1 48bytes VERSION. - // uint8_t response7_NTAG[] = {0x00, 0x04, 0x04, 0x02, 0x01, 0x00, 0x11, 0x03, 0x01, 0x9e}; //NTAG 215 - // Prepare CHK_TEARING - // uint8_t response9[] = {0xBD,0x90,0x3f}; + // Prepare GET_VERSION (different for UL EV-1 / NTAG) + // uint8_t response7_EV1[] = {0x00, 0x04, 0x03, 0x01, 0x01, 0x00, 0x0b, 0x03, 0xfd, 0xf7}; //EV1 48bytes VERSION. + // uint8_t response7_NTAG[] = {0x00, 0x04, 0x04, 0x02, 0x01, 0x00, 0x11, 0x03, 0x01, 0x9e}; //NTAG 215 + // Prepare CHK_TEARING + // uint8_t response9[] = {0xBD,0x90,0x3f}; - #define TAG_RESPONSE_COUNT 10 - tag_response_info_t responses[TAG_RESPONSE_COUNT] = { - { .response = response1, .response_n = sizeof(response1) }, // Answer to request - respond with card type - { .response = response2, .response_n = sizeof(response2) }, // Anticollision cascade1 - respond with uid - { .response = response2a, .response_n = sizeof(response2a) }, // Anticollision cascade2 - respond with 2nd half of uid if asked - { .response = response3, .response_n = sizeof(response3) }, // Acknowledge select - cascade 1 - { .response = response3a, .response_n = sizeof(response3a) }, // Acknowledge select - cascade 2 - { .response = response5, .response_n = sizeof(response5) }, // Authentication answer (random nonce) - { .response = response6, .response_n = sizeof(response6) }, // dummy ATS (pseudo-ATR), answer to RATS + #define TAG_RESPONSE_COUNT 10 + tag_response_info_t responses[TAG_RESPONSE_COUNT] = { + { .response = response1, .response_n = sizeof(response1) }, // Answer to request - respond with card type + { .response = response2, .response_n = sizeof(response2) }, // Anticollision cascade1 - respond with uid + { .response = response2a, .response_n = sizeof(response2a) }, // Anticollision cascade2 - respond with 2nd half of uid if asked + { .response = response3, .response_n = sizeof(response3) }, // Acknowledge select - cascade 1 + { .response = response3a, .response_n = sizeof(response3a) }, // Acknowledge select - cascade 2 + { .response = response5, .response_n = sizeof(response5) }, // Authentication answer (random nonce) + { .response = response6, .response_n = sizeof(response6) }, // dummy ATS (pseudo-ATR), answer to RATS - { .response = response8, .response_n = sizeof(response8) } // EV1/NTAG PACK response - }; - // { .response = response7_NTAG, .response_n = sizeof(response7_NTAG)}, // EV1/NTAG GET_VERSION response - // { .response = response9, .response_n = sizeof(response9) } // EV1/NTAG CHK_TEAR response + { .response = response8, .response_n = sizeof(response8) } // EV1/NTAG PACK response + }; + // { .response = response7_NTAG, .response_n = sizeof(response7_NTAG)}, // EV1/NTAG GET_VERSION response + // { .response = response9, .response_n = sizeof(response9) } // EV1/NTAG CHK_TEAR response - // Allocate 512 bytes for the dynamic modulation, created when the reader queries for it - // Such a response is less time critical, so we can prepare them on the fly - #define DYNAMIC_RESPONSE_BUFFER_SIZE 64 - #define DYNAMIC_MODULATION_BUFFER_SIZE 512 - uint8_t dynamic_response_buffer[DYNAMIC_RESPONSE_BUFFER_SIZE]; - uint8_t dynamic_modulation_buffer[DYNAMIC_MODULATION_BUFFER_SIZE]; - tag_response_info_t dynamic_response_info = { - .response = dynamic_response_buffer, - .response_n = 0, - .modulation = dynamic_modulation_buffer, - .modulation_n = 0 - }; + // Allocate 512 bytes for the dynamic modulation, created when the reader queries for it + // Such a response is less time critical, so we can prepare them on the fly + #define DYNAMIC_RESPONSE_BUFFER_SIZE 64 + #define DYNAMIC_MODULATION_BUFFER_SIZE 512 + uint8_t dynamic_response_buffer[DYNAMIC_RESPONSE_BUFFER_SIZE]; + uint8_t dynamic_modulation_buffer[DYNAMIC_MODULATION_BUFFER_SIZE]; + tag_response_info_t dynamic_response_info = { + .response = dynamic_response_buffer, + .response_n = 0, + .modulation = dynamic_modulation_buffer, + .modulation_n = 0 + }; - // We need to listen to the high-frequency, peak-detected path. - iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN); + // We need to listen to the high-frequency, peak-detected path. + iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN); - BigBuf_free_keep_EM(); - clear_trace(); - set_tracing(true); + BigBuf_free_keep_EM(); + clear_trace(); + set_tracing(true); - // allocate buffers: - uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); - uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE); - free_buffer_pointer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE); + // allocate buffers: + uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); + uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE); + free_buffer_pointer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE); - // Prepare the responses of the anticollision phase - // there will be not enough time to do this at the moment the reader sends it REQA - for (size_t i=0; i 2) { - // send NACK 0x0 == invalid argument - uint8_t nack[] = {0x00}; - EmSendCmd(nack,sizeof(nack)); - } else { - uint8_t cmd[] = {0x00,0x00,0x00,0x14,0xa5}; - num_to_bytes(counters[index], 3, cmd); - AddCrc14A(cmd, sizeof(cmd)-2); - EmSendCmd(cmd,sizeof(cmd)); - } - p_response = NULL; - } else if (receivedCmd[0] == MIFARE_ULEV1_INCR_CNT && tagType == 7) { // Received a INC COUNTER -- - uint8_t index = receivedCmd[1]; - if ( index > 2) { - // send NACK 0x0 == invalid argument - uint8_t nack[] = {0x00}; - EmSendCmd(nack,sizeof(nack)); - } else { + // Okay, look at the command now. + lastorder = order; + if (receivedCmd[0] == ISO14443A_CMD_REQA) { // Received a REQUEST + p_response = &responses[0]; order = 1; + } else if (receivedCmd[0] == ISO14443A_CMD_WUPA) { // Received a WAKEUP + p_response = &responses[0]; order = 6; + } else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { // Received request for UID (cascade 1) + p_response = &responses[1]; order = 2; + } else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received request for UID (cascade 2) + p_response = &responses[2]; order = 20; + } else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { // Received a SELECT (cascade 1) + p_response = &responses[3]; order = 3; + } else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received a SELECT (cascade 2) + p_response = &responses[4]; order = 30; + } else if (receivedCmd[0] == ISO14443A_CMD_READBLOCK) { // Received a (plain) READ + uint8_t block = receivedCmd[1]; + // if Ultralight or NTAG (4 byte blocks) + if ( tagType == 7 || tagType == 2 ) { + // first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] + uint16_t start = 4 * (block+12); + uint8_t emdata[MAX_MIFARE_FRAME_SIZE]; + emlGetMemBt( emdata, start, 16); + AddCrc14A(emdata, 16); + EmSendCmd(emdata, sizeof(emdata)); + // We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below + p_response = NULL; + } else if ( tagType == 9 && block == 1 ) { + // FM11005SH. 16blocks, 4bytes / block. + // block0 = 2byte Customer ID (CID), 2byte Manufacture ID (MID) + // block1 = 4byte UID. + p_response = &responses[1]; + } else { // all other tags (16 byte block tags) + uint8_t emdata[MAX_MIFARE_FRAME_SIZE]; + emlGetMemBt( emdata, block, 16); + AddCrc14A(emdata, 16); + EmSendCmd(emdata, sizeof(emdata)); + // EmSendCmd(data+(4*receivedCmd[1]),16); + // Dbprintf("Read request from reader: %x %x",receivedCmd[0],receivedCmd[1]); + // We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below + p_response = NULL; + } + } else if (receivedCmd[0] == MIFARE_ULEV1_FASTREAD) { // Received a FAST READ (ranged read) + uint8_t emdata[MAX_FRAME_SIZE]; + // first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] + int start = (receivedCmd[1]+12) * 4; + int len = (receivedCmd[2] - receivedCmd[1] + 1) * 4; + emlGetMemBt( emdata, start, len); + AddCrc14A(emdata, len); + EmSendCmd(emdata, len+2); + p_response = NULL; + } else if (receivedCmd[0] == MIFARE_ULEV1_READSIG && tagType == 7) { // Received a READ SIGNATURE -- + // first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] + uint16_t start = 4 * 4; + uint8_t emdata[34]; + emlGetMemBt( emdata, start, 32); + AddCrc14A(emdata, 32); + EmSendCmd(emdata, sizeof(emdata)); + p_response = NULL; + } else if (receivedCmd[0] == MIFARE_ULEV1_READ_CNT && tagType == 7) { // Received a READ COUNTER -- + uint8_t index = receivedCmd[1]; + if (index > 2) { + // send NACK 0x0 == invalid argument + uint8_t nack[] = {0x00}; + EmSendCmd(nack,sizeof(nack)); + } else { + uint8_t cmd[] = {0x00,0x00,0x00,0x14,0xa5}; + num_to_bytes(counters[index], 3, cmd); + AddCrc14A(cmd, sizeof(cmd)-2); + EmSendCmd(cmd,sizeof(cmd)); + } + p_response = NULL; + } else if (receivedCmd[0] == MIFARE_ULEV1_INCR_CNT && tagType == 7) { // Received a INC COUNTER -- + uint8_t index = receivedCmd[1]; + if ( index > 2) { + // send NACK 0x0 == invalid argument + uint8_t nack[] = {0x00}; + EmSendCmd(nack,sizeof(nack)); + } else { - uint32_t val = bytes_to_num(receivedCmd+2,4); + uint32_t val = bytes_to_num(receivedCmd+2,4); - // if new value + old value is bigger 24bits, fail - if ( val + counters[index] > 0xFFFFFF ) { - // send NACK 0x4 == counter overflow - uint8_t nack[] = {0x04}; - EmSendCmd(nack,sizeof(nack)); - } else { - counters[index] = val; - // send ACK - uint8_t ack[] = {0x0a}; - EmSendCmd(ack,sizeof(ack)); - } - } - p_response = NULL; - } else if (receivedCmd[0] == MIFARE_ULEV1_CHECKTEAR && tagType == 7) { // Received a CHECK_TEARING_EVENT -- - // first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] - uint8_t emdata[3]; - uint8_t index = receivedCmd[1]; - if ( index > 2) { - // send NACK 0x0 == invalid argument - uint8_t nack[] = {0x00}; - EmSendCmd(nack,sizeof(nack)); - } else { - emlGetMemBt( emdata, 10+index, 1); - AddCrc14A(emdata, sizeof(emdata)-2); - EmSendCmd(emdata, sizeof(emdata)); - } - p_response = NULL; - } else if (receivedCmd[0] == ISO14443A_CMD_HALT) { // Received a HALT - LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); - p_response = NULL; - } else if (receivedCmd[0] == MIFARE_AUTH_KEYA || receivedCmd[0] == MIFARE_AUTH_KEYB) { // Received an authentication request - if ( tagType == 7 ) { // IF NTAG /EV1 0x60 == GET_VERSION, not a authentication request. - uint8_t emdata[10]; - emlGetMemBt( emdata, 0, 8 ); - AddCrc14A(emdata, sizeof(emdata)-2); - EmSendCmd(emdata, sizeof(emdata)); - p_response = NULL; - } else { + // if new value + old value is bigger 24bits, fail + if ( val + counters[index] > 0xFFFFFF ) { + // send NACK 0x4 == counter overflow + uint8_t nack[] = {0x04}; + EmSendCmd(nack,sizeof(nack)); + } else { + counters[index] = val; + // send ACK + uint8_t ack[] = {0x0a}; + EmSendCmd(ack,sizeof(ack)); + } + } + p_response = NULL; + } else if (receivedCmd[0] == MIFARE_ULEV1_CHECKTEAR && tagType == 7) { // Received a CHECK_TEARING_EVENT -- + // first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] + uint8_t emdata[3]; + uint8_t index = receivedCmd[1]; + if ( index > 2) { + // send NACK 0x0 == invalid argument + uint8_t nack[] = {0x00}; + EmSendCmd(nack,sizeof(nack)); + } else { + emlGetMemBt( emdata, 10+index, 1); + AddCrc14A(emdata, sizeof(emdata)-2); + EmSendCmd(emdata, sizeof(emdata)); + } + p_response = NULL; + } else if (receivedCmd[0] == ISO14443A_CMD_HALT) { // Received a HALT + LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + p_response = NULL; + } else if (receivedCmd[0] == MIFARE_AUTH_KEYA || receivedCmd[0] == MIFARE_AUTH_KEYB) { // Received an authentication request + if ( tagType == 7 ) { // IF NTAG /EV1 0x60 == GET_VERSION, not a authentication request. + uint8_t emdata[10]; + emlGetMemBt( emdata, 0, 8 ); + AddCrc14A(emdata, sizeof(emdata)-2); + EmSendCmd(emdata, sizeof(emdata)); + p_response = NULL; + } else { - cardAUTHKEY = receivedCmd[0] - 0x60; - cardAUTHSC = receivedCmd[1] / 4; // received block num + cardAUTHKEY = receivedCmd[0] - 0x60; + cardAUTHSC = receivedCmd[1] / 4; // received block num - // incease nonce at AUTH requests. this is time consuming. - nonce = prng_successor( GetTickCount(), 32 ); - //num_to_bytes(nonce, 4, response5); - num_to_bytes(nonce, 4, dynamic_response_info.response); - dynamic_response_info.response_n = 4; + // incease nonce at AUTH requests. this is time consuming. + nonce = prng_successor( GetTickCount(), 32 ); + //num_to_bytes(nonce, 4, response5); + num_to_bytes(nonce, 4, dynamic_response_info.response); + dynamic_response_info.response_n = 4; - //prepare_tag_modulation(&responses[5], DYNAMIC_MODULATION_BUFFER_SIZE); - prepare_tag_modulation(&dynamic_response_info, DYNAMIC_MODULATION_BUFFER_SIZE); - p_response = &dynamic_response_info; - //p_response = &responses[5]; - order = 7; - } - } else if (receivedCmd[0] == ISO14443A_CMD_RATS) { // Received a RATS request - if (tagType == 1 || tagType == 2) { // RATS not supported - EmSend4bit(CARD_NACK_NA); - p_response = NULL; - } else { - p_response = &responses[6]; order = 70; - } - } else if (order == 7 && len == 8) { // Received {nr] and {ar} (part of authentication) - LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); - uint32_t nr = bytes_to_num(receivedCmd,4); - uint32_t ar = bytes_to_num(receivedCmd+4,4); + //prepare_tag_modulation(&responses[5], DYNAMIC_MODULATION_BUFFER_SIZE); + prepare_tag_modulation(&dynamic_response_info, DYNAMIC_MODULATION_BUFFER_SIZE); + p_response = &dynamic_response_info; + //p_response = &responses[5]; + order = 7; + } + } else if (receivedCmd[0] == ISO14443A_CMD_RATS) { // Received a RATS request + if (tagType == 1 || tagType == 2) { // RATS not supported + EmSend4bit(CARD_NACK_NA); + p_response = NULL; + } else { + p_response = &responses[6]; order = 70; + } + } else if (order == 7 && len == 8) { // Received {nr] and {ar} (part of authentication) + LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + uint32_t nr = bytes_to_num(receivedCmd,4); + uint32_t ar = bytes_to_num(receivedCmd+4,4); - // Collect AR/NR per keytype & sector - if ( (flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK ) { + // Collect AR/NR per keytype & sector + if ( (flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK ) { - int8_t index = -1; - int8_t empty = -1; - for (uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) { - // find which index to use - if ( (cardAUTHSC == ar_nr_nonces[i].sector) && (cardAUTHKEY == ar_nr_nonces[i].keytype)) - index = i; + int8_t index = -1; + int8_t empty = -1; + for (uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) { + // find which index to use + if ( (cardAUTHSC == ar_nr_nonces[i].sector) && (cardAUTHKEY == ar_nr_nonces[i].keytype)) + index = i; - // keep track of empty slots. - if ( ar_nr_nonces[i].state == EMPTY) - empty = i; - } - // if no empty slots. Choose first and overwrite. - if ( index == -1 ) { - if ( empty == -1 ) { - index = 0; - ar_nr_nonces[index].state = EMPTY; - } else { - index = empty; - } - } + // keep track of empty slots. + if ( ar_nr_nonces[i].state == EMPTY) + empty = i; + } + // if no empty slots. Choose first and overwrite. + if ( index == -1 ) { + if ( empty == -1 ) { + index = 0; + ar_nr_nonces[index].state = EMPTY; + } else { + index = empty; + } + } - switch(ar_nr_nonces[index].state) { - case EMPTY: { - // first nonce collect - ar_nr_nonces[index].cuid = cuid; - ar_nr_nonces[index].sector = cardAUTHSC; - ar_nr_nonces[index].keytype = cardAUTHKEY; - ar_nr_nonces[index].nonce = nonce; - ar_nr_nonces[index].nr = nr; - ar_nr_nonces[index].ar = ar; - ar_nr_nonces[index].state = FIRST; - break; - } - case FIRST : { - // second nonce collect - ar_nr_nonces[index].nonce2 = nonce; - ar_nr_nonces[index].nr2 = nr; - ar_nr_nonces[index].ar2 = ar; - ar_nr_nonces[index].state = SECOND; + switch(ar_nr_nonces[index].state) { + case EMPTY: { + // first nonce collect + ar_nr_nonces[index].cuid = cuid; + ar_nr_nonces[index].sector = cardAUTHSC; + ar_nr_nonces[index].keytype = cardAUTHKEY; + ar_nr_nonces[index].nonce = nonce; + ar_nr_nonces[index].nr = nr; + ar_nr_nonces[index].ar = ar; + ar_nr_nonces[index].state = FIRST; + break; + } + case FIRST : { + // second nonce collect + ar_nr_nonces[index].nonce2 = nonce; + ar_nr_nonces[index].nr2 = nr; + ar_nr_nonces[index].ar2 = ar; + ar_nr_nonces[index].state = SECOND; - // send to client - cmd_send(CMD_ACK, CMD_SIMULATE_MIFARE_CARD, 0, 0, &ar_nr_nonces[index], sizeof(nonces_t)); + // send to client + cmd_send(CMD_ACK, CMD_SIMULATE_MIFARE_CARD, 0, 0, &ar_nr_nonces[index], sizeof(nonces_t)); - ar_nr_nonces[index].state = EMPTY; - ar_nr_nonces[index].sector = 0; - ar_nr_nonces[index].keytype = 0; + ar_nr_nonces[index].state = EMPTY; + ar_nr_nonces[index].sector = 0; + ar_nr_nonces[index].keytype = 0; - moebius_count++; - break; - } - default: break; - } - } - p_response = NULL; + moebius_count++; + break; + } + default: break; + } + } + p_response = NULL; - } else if (receivedCmd[0] == MIFARE_ULC_AUTH_1 ) { // ULC authentication, or Desfire Authentication - } else if (receivedCmd[0] == MIFARE_ULEV1_AUTH) { // NTAG / EV-1 authentication - if ( tagType == 7 ) { - uint16_t start = 13; // first 4 blocks of emu are [getversion answer - check tearing - pack - 0x00] - uint8_t emdata[4]; - emlGetMemBt( emdata, start, 2); - AddCrc14A(emdata, 2); - EmSendCmd(emdata, sizeof(emdata)); - p_response = NULL; - uint32_t pwd = bytes_to_num(receivedCmd+1,4); + } else if (receivedCmd[0] == MIFARE_ULC_AUTH_1 ) { // ULC authentication, or Desfire Authentication + } else if (receivedCmd[0] == MIFARE_ULEV1_AUTH) { // NTAG / EV-1 authentication + if ( tagType == 7 ) { + uint16_t start = 13; // first 4 blocks of emu are [getversion answer - check tearing - pack - 0x00] + uint8_t emdata[4]; + emlGetMemBt( emdata, start, 2); + AddCrc14A(emdata, 2); + EmSendCmd(emdata, sizeof(emdata)); + p_response = NULL; + uint32_t pwd = bytes_to_num(receivedCmd+1,4); - if ( MF_DBGLEVEL >= 3) Dbprintf("Auth attempt: %08x", pwd); - } - } else { - // Check for ISO 14443A-4 compliant commands, look at left nibble - switch (receivedCmd[0]) { - case 0x02: - case 0x03: { // IBlock (command no CID) - dynamic_response_info.response[0] = receivedCmd[0]; - dynamic_response_info.response[1] = 0x90; - dynamic_response_info.response[2] = 0x00; - dynamic_response_info.response_n = 3; - } break; - case 0x0B: - case 0x0A: { // IBlock (command CID) - dynamic_response_info.response[0] = receivedCmd[0]; - dynamic_response_info.response[1] = 0x00; - dynamic_response_info.response[2] = 0x90; - dynamic_response_info.response[3] = 0x00; - dynamic_response_info.response_n = 4; - } break; + if ( MF_DBGLEVEL >= 3) Dbprintf("Auth attempt: %08x", pwd); + } + } else { + // Check for ISO 14443A-4 compliant commands, look at left nibble + switch (receivedCmd[0]) { + case 0x02: + case 0x03: { // IBlock (command no CID) + dynamic_response_info.response[0] = receivedCmd[0]; + dynamic_response_info.response[1] = 0x90; + dynamic_response_info.response[2] = 0x00; + dynamic_response_info.response_n = 3; + } break; + case 0x0B: + case 0x0A: { // IBlock (command CID) + dynamic_response_info.response[0] = receivedCmd[0]; + dynamic_response_info.response[1] = 0x00; + dynamic_response_info.response[2] = 0x90; + dynamic_response_info.response[3] = 0x00; + dynamic_response_info.response_n = 4; + } break; - case 0x1A: - case 0x1B: { // Chaining command - dynamic_response_info.response[0] = 0xaa | ((receivedCmd[0]) & 1); - dynamic_response_info.response_n = 2; - } break; + case 0x1A: + case 0x1B: { // Chaining command + dynamic_response_info.response[0] = 0xaa | ((receivedCmd[0]) & 1); + dynamic_response_info.response_n = 2; + } break; - case 0xAA: - case 0xBB: { - dynamic_response_info.response[0] = receivedCmd[0] ^ 0x11; - dynamic_response_info.response_n = 2; - } break; + case 0xAA: + case 0xBB: { + dynamic_response_info.response[0] = receivedCmd[0] ^ 0x11; + dynamic_response_info.response_n = 2; + } break; - case 0xBA: { // ping / pong - dynamic_response_info.response[0] = 0xAB; - dynamic_response_info.response[1] = 0x00; - dynamic_response_info.response_n = 2; - } break; + case 0xBA: { // ping / pong + dynamic_response_info.response[0] = 0xAB; + dynamic_response_info.response[1] = 0x00; + dynamic_response_info.response_n = 2; + } break; - case 0xCA: - case 0xC2: { // Readers sends deselect command - dynamic_response_info.response[0] = 0xCA; - dynamic_response_info.response[1] = 0x00; - dynamic_response_info.response_n = 2; - } break; + case 0xCA: + case 0xC2: { // Readers sends deselect command + dynamic_response_info.response[0] = 0xCA; + dynamic_response_info.response[1] = 0x00; + dynamic_response_info.response_n = 2; + } break; - default: { - // Never seen this command before - LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); - Dbprintf("Received unknown command (len=%d):",len); - Dbhexdump(len,receivedCmd,false); - // Do not respond - dynamic_response_info.response_n = 0; - } break; - } + default: { + // Never seen this command before + LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + Dbprintf("Received unknown command (len=%d):",len); + Dbhexdump(len,receivedCmd,false); + // Do not respond + dynamic_response_info.response_n = 0; + } break; + } - if (dynamic_response_info.response_n > 0) { - // Copy the CID from the reader query - dynamic_response_info.response[1] = receivedCmd[1]; + if (dynamic_response_info.response_n > 0) { + // Copy the CID from the reader query + dynamic_response_info.response[1] = receivedCmd[1]; - // Add CRC bytes, always used in ISO 14443A-4 compliant cards - AddCrc14A(dynamic_response_info.response, dynamic_response_info.response_n); - dynamic_response_info.response_n += 2; + // Add CRC bytes, always used in ISO 14443A-4 compliant cards + AddCrc14A(dynamic_response_info.response, dynamic_response_info.response_n); + dynamic_response_info.response_n += 2; - if (prepare_tag_modulation(&dynamic_response_info,DYNAMIC_MODULATION_BUFFER_SIZE) == false) { - DbpString("Error preparing tag response"); - LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); - break; - } - p_response = &dynamic_response_info; - } - } + if (prepare_tag_modulation(&dynamic_response_info,DYNAMIC_MODULATION_BUFFER_SIZE) == false) { + DbpString("Error preparing tag response"); + LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + break; + } + p_response = &dynamic_response_info; + } + } - // Count number of wakeups received after a halt - if (order == 6 && lastorder == 5) { happened++; } + // Count number of wakeups received after a halt + if (order == 6 && lastorder == 5) { happened++; } - // Count number of other messages after a halt - if (order != 6 && lastorder == 5) { happened2++; } + // Count number of other messages after a halt + if (order != 6 && lastorder == 5) { happened2++; } - cmdsRecvd++; + cmdsRecvd++; - if (p_response != NULL) { - EmSendCmd14443aRaw(p_response->modulation, p_response->modulation_n); - // do the tracing for the previous reader request and this tag answer: - uint8_t par[MAX_PARITY_SIZE] = {0x00}; - GetParity(p_response->response, p_response->response_n, par); + if (p_response != NULL) { + EmSendCmd14443aRaw(p_response->modulation, p_response->modulation_n); + // do the tracing for the previous reader request and this tag answer: + uint8_t par[MAX_PARITY_SIZE] = {0x00}; + GetParity(p_response->response, p_response->response_n, par); - EmLogTrace(Uart.output, - Uart.len, - Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, - Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, - Uart.parity, - p_response->response, - p_response->response_n, - LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_TAG, - (LastTimeProxToAirStart + p_response->ProxToAirDuration)*16 + DELAY_ARM2AIR_AS_TAG, - par); - } - } + EmLogTrace(Uart.output, + Uart.len, + Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, + Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, + Uart.parity, + p_response->response, + p_response->response_n, + LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_TAG, + (LastTimeProxToAirStart + p_response->ProxToAirDuration)*16 + DELAY_ARM2AIR_AS_TAG, + par); + } + } - cmd_send(CMD_ACK,1,0,0,0,0); - switch_off(); + cmd_send(CMD_ACK,1,0,0,0,0); + switch_off(); - BigBuf_free_keep_EM(); + BigBuf_free_keep_EM(); - if (MF_DBGLEVEL >= 4){ - Dbprintf("-[ Wake ups after halt [%d]", happened); - Dbprintf("-[ Messages after halt [%d]", happened2); - Dbprintf("-[ Num of received cmd [%d]", cmdsRecvd); - Dbprintf("-[ Num of moebius tries [%d]", moebius_count); - } + if (MF_DBGLEVEL >= 4){ + Dbprintf("-[ Wake ups after halt [%d]", happened); + Dbprintf("-[ Messages after halt [%d]", happened2); + Dbprintf("-[ Num of received cmd [%d]", cmdsRecvd); + Dbprintf("-[ Num of moebius tries [%d]", moebius_count); + } } // prepare a delayed transfer. This simply shifts ToSend[] by a number // of bits specified in the delay parameter. void PrepareDelayedTransfer(uint16_t delay) { - delay &= 0x07; - if (!delay) return; + delay &= 0x07; + if (!delay) return; - uint8_t bitmask = 0; - uint8_t bits_to_shift = 0; - uint8_t bits_shifted = 0; - uint16_t i = 0; + uint8_t bitmask = 0; + uint8_t bits_to_shift = 0; + uint8_t bits_shifted = 0; + uint16_t i = 0; - for (i = 0; i < delay; i++) - bitmask |= (0x01 << i); + for (i = 0; i < delay; i++) + bitmask |= (0x01 << i); - ToSend[ToSendMax++] = 0x00; + ToSend[ToSendMax++] = 0x00; - for (i = 0; i < ToSendMax; i++) { - bits_to_shift = ToSend[i] & bitmask; - ToSend[i] = ToSend[i] >> delay; - ToSend[i] = ToSend[i] | (bits_shifted << (8 - delay)); - bits_shifted = bits_to_shift; - } - } + for (i = 0; i < ToSendMax; i++) { + bits_to_shift = ToSend[i] & bitmask; + ToSend[i] = ToSend[i] >> delay; + ToSend[i] = ToSend[i] | (bits_shifted << (8 - delay)); + bits_shifted = bits_to_shift; + } + } //------------------------------------------------------------------------------------- // Transmit the command (to the tag) that was placed in ToSend[]. // Parameter timing: // if NULL: transfer at next possible time, taking into account -// request guard time and frame delay time -// if == 0: transfer immediately and return time of transfer +// request guard time and frame delay time +// if == 0: transfer immediately and return time of transfer // if != 0: delay transfer until time specified //------------------------------------------------------------------------------------- static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); - if (timing) { - if (*timing == 0) // Measure time - *timing = (GetCountSspClk() + 8) & 0xfffffff8; - else - PrepareDelayedTransfer(*timing & 0x00000007); // Delay transfer (fine tuning - up to 7 MF clock ticks) + if (timing) { + if (*timing == 0) // Measure time + *timing = (GetCountSspClk() + 8) & 0xfffffff8; + else + PrepareDelayedTransfer(*timing & 0x00000007); // Delay transfer (fine tuning - up to 7 MF clock ticks) - if(MF_DBGLEVEL >= 4 && GetCountSspClk() >= (*timing & 0xfffffff8)) - Dbprintf("TransmitFor14443a: Missed timing"); - while (GetCountSspClk() < (*timing & 0xfffffff8)) {}; // Delay transfer (multiple of 8 MF clock ticks) - LastTimeProxToAirStart = *timing; - } else { + if(MF_DBGLEVEL >= 4 && GetCountSspClk() >= (*timing & 0xfffffff8)) + Dbprintf("TransmitFor14443a: Missed timing"); + while (GetCountSspClk() < (*timing & 0xfffffff8)) {}; // Delay transfer (multiple of 8 MF clock ticks) + LastTimeProxToAirStart = *timing; + } else { - uint32_t ThisTransferTime = 0; - ThisTransferTime = ((MAX(NextTransferTime, GetCountSspClk()) & 0xfffffff8) + 8); + uint32_t ThisTransferTime = 0; + ThisTransferTime = ((MAX(NextTransferTime, GetCountSspClk()) & 0xfffffff8) + 8); - while (GetCountSspClk() < ThisTransferTime) {}; + while (GetCountSspClk() < ThisTransferTime) {}; - LastTimeProxToAirStart = ThisTransferTime; - } + LastTimeProxToAirStart = ThisTransferTime; + } - // clear TXRDY - AT91C_BASE_SSC->SSC_THR = SEC_Y; + // clear TXRDY + AT91C_BASE_SSC->SSC_THR = SEC_Y; - volatile uint8_t b; - uint16_t c = 0; - while (c < len) { - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = cmd[c++]; - } - //iceman test - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); (void)b; - } - } + volatile uint8_t b; + uint16_t c = 0; + while (c < len) { + if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = cmd[c++]; + } + //iceman test + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); (void)b; + } + } - NextTransferTime = MAX(NextTransferTime, LastTimeProxToAirStart + REQUEST_GUARD_TIME); + NextTransferTime = MAX(NextTransferTime, LastTimeProxToAirStart + REQUEST_GUARD_TIME); } //----------------------------------------------------------------------------- // Prepare reader command (in bits, support short frames) to send to FPGA //----------------------------------------------------------------------------- void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8_t *parity) { - int i, j; - int last = 0; - uint8_t b; + int i, j; + int last = 0; + uint8_t b; - ToSendReset(); + ToSendReset(); - // Start of Communication (Seq. Z) - ToSend[++ToSendMax] = SEC_Z; - LastProxToAirDuration = 8 * (ToSendMax+1) - 6; + // Start of Communication (Seq. Z) + ToSend[++ToSendMax] = SEC_Z; + LastProxToAirDuration = 8 * (ToSendMax+1) - 6; - size_t bytecount = nbytes(bits); - // Generate send structure for the data bits - for (i = 0; i < bytecount; i++) { - // Get the current byte to send - b = cmd[i]; - size_t bitsleft = MIN((bits-(i*8)),8); + size_t bytecount = nbytes(bits); + // Generate send structure for the data bits + for (i = 0; i < bytecount; i++) { + // Get the current byte to send + b = cmd[i]; + size_t bitsleft = MIN((bits-(i*8)),8); - for (j = 0; j < bitsleft; j++) { - if (b & 1) { - // Sequence X - ToSend[++ToSendMax] = SEC_X; - LastProxToAirDuration = 8 * (ToSendMax+1) - 2; - last = 1; - } else { - if (last == 0) { - // Sequence Z - ToSend[++ToSendMax] = SEC_Z; - LastProxToAirDuration = 8 * (ToSendMax+1) - 6; - } else { - // Sequence Y - ToSend[++ToSendMax] = SEC_Y; - last = 0; - } - } - b >>= 1; - } + for (j = 0; j < bitsleft; j++) { + if (b & 1) { + // Sequence X + ToSend[++ToSendMax] = SEC_X; + LastProxToAirDuration = 8 * (ToSendMax+1) - 2; + last = 1; + } else { + if (last == 0) { + // Sequence Z + ToSend[++ToSendMax] = SEC_Z; + LastProxToAirDuration = 8 * (ToSendMax+1) - 6; + } else { + // Sequence Y + ToSend[++ToSendMax] = SEC_Y; + last = 0; + } + } + b >>= 1; + } - // Only transmit parity bit if we transmitted a complete byte - if (j == 8 && parity != NULL) { - // Get the parity bit - if (parity[i>>3] & (0x80 >> (i&0x0007))) { - // Sequence X - ToSend[++ToSendMax] = SEC_X; - LastProxToAirDuration = 8 * (ToSendMax+1) - 2; - last = 1; - } else { - if (last == 0) { - // Sequence Z - ToSend[++ToSendMax] = SEC_Z; - LastProxToAirDuration = 8 * (ToSendMax+1) - 6; - } else { - // Sequence Y - ToSend[++ToSendMax] = SEC_Y; - last = 0; - } - } - } - } + // Only transmit parity bit if we transmitted a complete byte + if (j == 8 && parity != NULL) { + // Get the parity bit + if (parity[i>>3] & (0x80 >> (i&0x0007))) { + // Sequence X + ToSend[++ToSendMax] = SEC_X; + LastProxToAirDuration = 8 * (ToSendMax+1) - 2; + last = 1; + } else { + if (last == 0) { + // Sequence Z + ToSend[++ToSendMax] = SEC_Z; + LastProxToAirDuration = 8 * (ToSendMax+1) - 6; + } else { + // Sequence Y + ToSend[++ToSendMax] = SEC_Y; + last = 0; + } + } + } + } - // End of Communication: Logic 0 followed by Sequence Y - if (last == 0) { - // Sequence Z - ToSend[++ToSendMax] = SEC_Z; - LastProxToAirDuration = 8 * (ToSendMax+1) - 6; - } else { - // Sequence Y - ToSend[++ToSendMax] = SEC_Y; - last = 0; - } - ToSend[++ToSendMax] = SEC_Y; + // End of Communication: Logic 0 followed by Sequence Y + if (last == 0) { + // Sequence Z + ToSend[++ToSendMax] = SEC_Z; + LastProxToAirDuration = 8 * (ToSendMax+1) - 6; + } else { + // Sequence Y + ToSend[++ToSendMax] = SEC_Y; + last = 0; + } + ToSend[++ToSendMax] = SEC_Y; - // Convert to length of command: - ToSendMax++; + // Convert to length of command: + ToSendMax++; } //----------------------------------------------------------------------------- @@ -1556,196 +1556,196 @@ void CodeIso14443aAsReaderPar(const uint8_t *cmd, uint16_t len, const uint8_t *p // Or return 0 when command is captured //----------------------------------------------------------------------------- int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) { - *len = 0; + *len = 0; - uint32_t timer = 0, vtime = 0; - int analogCnt = 0; - int analogAVG = 0; + uint32_t timer = 0, vtime = 0; + int analogCnt = 0; + int analogAVG = 0; - // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen - // only, since we are receiving, not transmitting). - // Signal field is off with the appropriate LED - LED_D_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN); + // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen + // only, since we are receiving, not transmitting). + // Signal field is off with the appropriate LED + LED_D_OFF(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN); - // Set ADC to read field strength - AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST; - AT91C_BASE_ADC->ADC_MR = - ADC_MODE_PRESCALE(63) | - ADC_MODE_STARTUP_TIME(1) | - ADC_MODE_SAMPLE_HOLD_TIME(15); - AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ADC_CHAN_HF); - // start ADC - AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; + // Set ADC to read field strength + AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST; + AT91C_BASE_ADC->ADC_MR = + ADC_MODE_PRESCALE(63) | + ADC_MODE_STARTUP_TIME(1) | + ADC_MODE_SAMPLE_HOLD_TIME(15); + AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ADC_CHAN_HF); + // start ADC + AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; - // Now run a 'software UART' on the stream of incoming samples. - UartInit(received, parity); + // Now run a 'software UART' on the stream of incoming samples. + UartInit(received, parity); - // Clear RXRDY: + // Clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - for(;;) { - WDT_HIT(); + for(;;) { + WDT_HIT(); - if (BUTTON_PRESS()) return 1; + if (BUTTON_PRESS()) return 1; - // test if the field exists - if (AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ADC_CHAN_HF)) { - analogCnt++; - analogAVG += AT91C_BASE_ADC->ADC_CDR[ADC_CHAN_HF]; - AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; - if (analogCnt >= 32) { - if ((MAX_ADC_HF_VOLTAGE * (analogAVG / analogCnt) >> 10) < MF_MINFIELDV) { - vtime = GetTickCount(); - if (!timer) timer = vtime; - // 50ms no field --> card to idle state - if (vtime - timer > 50) return 2; - } else - if (timer) timer = 0; - analogCnt = 0; - analogAVG = 0; - } - } + // test if the field exists + if (AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ADC_CHAN_HF)) { + analogCnt++; + analogAVG += AT91C_BASE_ADC->ADC_CDR[ADC_CHAN_HF]; + AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; + if (analogCnt >= 32) { + if ((MAX_ADC_HF_VOLTAGE * (analogAVG / analogCnt) >> 10) < MF_MINFIELDV) { + vtime = GetTickCount(); + if (!timer) timer = vtime; + // 50ms no field --> card to idle state + if (vtime - timer > 50) return 2; + } else + if (timer) timer = 0; + analogCnt = 0; + analogAVG = 0; + } + } - // receive and test the miller decoding + // receive and test the miller decoding if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - if(MillerDecoding(b, 0)) { - *len = Uart.len; - return 0; - } + if(MillerDecoding(b, 0)) { + *len = Uart.len; + return 0; + } } - } + } } int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) { - volatile uint8_t b; - uint16_t i = 0; - uint32_t ThisTransferTime; - bool correctionNeeded; + volatile uint8_t b; + uint16_t i = 0; + uint32_t ThisTransferTime; + bool correctionNeeded; - // Modulate Manchester - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD); + // Modulate Manchester + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD); - // Include correction bit if necessary - if (Uart.bitCount == 7) - { - // Short tags (7 bits) don't have parity, determine the correct value from MSB - correctionNeeded = Uart.output[0] & 0x40; - } - else - { - // The parity bits are left-aligned - correctionNeeded = Uart.parity[(Uart.len-1)/8] & (0x80 >> ((Uart.len-1) & 7)); - } - // 1236, so correction bit needed - i = (correctionNeeded) ? 0 : 1; + // Include correction bit if necessary + if (Uart.bitCount == 7) + { + // Short tags (7 bits) don't have parity, determine the correct value from MSB + correctionNeeded = Uart.output[0] & 0x40; + } + else + { + // The parity bits are left-aligned + correctionNeeded = Uart.parity[(Uart.len-1)/8] & (0x80 >> ((Uart.len-1) & 7)); + } + // 1236, so correction bit needed + i = (correctionNeeded) ? 0 : 1; - // clear receiving shift register and holding register - while(!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)); - b = AT91C_BASE_SSC->SSC_RHR; (void) b; - while(!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)); - b = AT91C_BASE_SSC->SSC_RHR; (void) b; + // clear receiving shift register and holding register + while(!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)); + b = AT91C_BASE_SSC->SSC_RHR; (void) b; + while(!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)); + b = AT91C_BASE_SSC->SSC_RHR; (void) b; - // wait for the FPGA to signal fdt_indicator == 1 (the FPGA is ready to queue new data in its delay line) - for (uint8_t j = 0; j < 5; j++) { // allow timeout - better late than never - while(!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)); - if (AT91C_BASE_SSC->SSC_RHR) break; - } + // wait for the FPGA to signal fdt_indicator == 1 (the FPGA is ready to queue new data in its delay line) + for (uint8_t j = 0; j < 5; j++) { // allow timeout - better late than never + while(!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)); + if (AT91C_BASE_SSC->SSC_RHR) break; + } - while ((ThisTransferTime = GetCountSspClk()) & 0x00000007); + while ((ThisTransferTime = GetCountSspClk()) & 0x00000007); - // Clear TXRDY: - AT91C_BASE_SSC->SSC_THR = SEC_F; + // Clear TXRDY: + AT91C_BASE_SSC->SSC_THR = SEC_F; - // send cycle - for(; i < respLen; ) { - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = resp[i++]; - FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - } + // send cycle + for(; i < respLen; ) { + if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = resp[i++]; + FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + } - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); (void)b; - } - if(BUTTON_PRESS()) break; - } + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); (void)b; + } + if(BUTTON_PRESS()) break; + } - // Ensure that the FPGA Delay Queue is empty before we switch to TAGSIM_LISTEN again: - uint8_t fpga_queued_bits = FpgaSendQueueDelay >> 3; - for (i = 0; i <= fpga_queued_bits/8 + 1; ) { - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = SEC_F; - FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - } - } - LastTimeProxToAirStart = ThisTransferTime + (correctionNeeded ? 8 : 0); - return 0; + // Ensure that the FPGA Delay Queue is empty before we switch to TAGSIM_LISTEN again: + uint8_t fpga_queued_bits = FpgaSendQueueDelay >> 3; + for (i = 0; i <= fpga_queued_bits/8 + 1; ) { + if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = SEC_F; + FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + i++; + } + } + LastTimeProxToAirStart = ThisTransferTime + (correctionNeeded ? 8 : 0); + return 0; } int EmSend4bit(uint8_t resp){ - Code4bitAnswerAsTag(resp); - int res = EmSendCmd14443aRaw(ToSend, ToSendMax); - // do the tracing for the previous reader request and this tag answer: - uint8_t par[1] = {0x00}; - GetParity(&resp, 1, par); - EmLogTrace(Uart.output, - Uart.len, - Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, - Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, - Uart.parity, - &resp, - 1, - LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_TAG, - (LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_TAG, - par); - return res; + Code4bitAnswerAsTag(resp); + int res = EmSendCmd14443aRaw(ToSend, ToSendMax); + // do the tracing for the previous reader request and this tag answer: + uint8_t par[1] = {0x00}; + GetParity(&resp, 1, par); + EmLogTrace(Uart.output, + Uart.len, + Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, + Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, + Uart.parity, + &resp, + 1, + LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_TAG, + (LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_TAG, + par); + return res; } int EmSendCmdPar(uint8_t *resp, uint16_t respLen, uint8_t *par) { - return EmSendCmdParEx(resp, respLen, par, false); + return EmSendCmdParEx(resp, respLen, par, false); } int EmSendCmdParEx(uint8_t *resp, uint16_t respLen, uint8_t *par, bool collision){ - CodeIso14443aAsTagPar(resp, respLen, par, collision); - int res = EmSendCmd14443aRaw(ToSend, ToSendMax); - // do the tracing for the previous reader request and this tag answer: - EmLogTrace(Uart.output, - Uart.len, - Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, - Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, - Uart.parity, - resp, - respLen, - LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_TAG, - (LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_TAG, - par); - return res; + CodeIso14443aAsTagPar(resp, respLen, par, collision); + int res = EmSendCmd14443aRaw(ToSend, ToSendMax); + // do the tracing for the previous reader request and this tag answer: + EmLogTrace(Uart.output, + Uart.len, + Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, + Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, + Uart.parity, + resp, + respLen, + LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_TAG, + (LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_TAG, + par); + return res; } int EmSendCmd(uint8_t *resp, uint16_t respLen){ - return EmSendCmdEx(resp, respLen, false); + return EmSendCmdEx(resp, respLen, false); } int EmSendCmdEx(uint8_t *resp, uint16_t respLen, bool collision){ - uint8_t par[MAX_PARITY_SIZE] = {0x00}; - GetParity(resp, respLen, par); - return EmSendCmdParEx(resp, respLen, par, collision); + uint8_t par[MAX_PARITY_SIZE] = {0x00}; + GetParity(resp, respLen, par); + return EmSendCmdParEx(resp, respLen, par, collision); } bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint8_t *reader_Parity, - uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity) + uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity) { - // we cannot exactly measure the end and start of a received command from reader. However we know that the delay from - // end of the received command to start of the tag's (simulated by us) answer is n*128+20 or n*128+84 resp. - // with n >= 9. The start of the tags answer can be measured and therefore the end of the received command be calculated: - uint16_t reader_modlen = reader_EndTime - reader_StartTime; - uint16_t approx_fdt = tag_StartTime - reader_EndTime; - uint16_t exact_fdt = (approx_fdt - 20 + 32)/64 * 64 + 20; - reader_EndTime = tag_StartTime - exact_fdt; - reader_StartTime = reader_EndTime - reader_modlen; + // we cannot exactly measure the end and start of a received command from reader. However we know that the delay from + // end of the received command to start of the tag's (simulated by us) answer is n*128+20 or n*128+84 resp. + // with n >= 9. The start of the tags answer can be measured and therefore the end of the received command be calculated: + uint16_t reader_modlen = reader_EndTime - reader_StartTime; + uint16_t approx_fdt = tag_StartTime - reader_EndTime; + uint16_t exact_fdt = (approx_fdt - 20 + 32)/64 * 64 + 20; + reader_EndTime = tag_StartTime - exact_fdt; + reader_StartTime = reader_EndTime - reader_modlen; - if (!LogTrace(reader_data, reader_len, reader_StartTime, reader_EndTime, reader_Parity, true)) - return false; - else - return(!LogTrace(tag_data, tag_len, tag_StartTime, tag_EndTime, tag_Parity, false)); + if (!LogTrace(reader_data, reader_len, reader_StartTime, reader_EndTime, reader_Parity, true)) + return false; + else + return(!LogTrace(tag_data, tag_len, tag_StartTime, tag_EndTime, tag_Parity, false)); } @@ -1755,44 +1755,44 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start // If it takes too long return FALSE //----------------------------------------------------------------------------- static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset) { - uint32_t c = 0; + uint32_t c = 0; - // Set FPGA mode to "reader listen mode", no modulation (listen - // only, since we are receiving, not transmitting). - // Signal field is on with the appropriate LED - LED_D_ON(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN); + // Set FPGA mode to "reader listen mode", no modulation (listen + // only, since we are receiving, not transmitting). + // Signal field is on with the appropriate LED + LED_D_ON(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN); - // Now get the answer from the card - DemodInit(receivedResponse, receivedResponsePar); + // Now get the answer from the card + DemodInit(receivedResponse, receivedResponsePar); - // clear RXRDY: + // clear RXRDY: uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - uint32_t timeout = iso14a_get_timeout(); - for(;;) { - WDT_HIT(); + uint32_t timeout = iso14a_get_timeout(); + for(;;) { + WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - if (ManchesterDecoding(b, offset, 0)) { - NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/16 + FRAME_DELAY_TIME_PICC_TO_PCD); - return true; - } else if (c++ > timeout && Demod.state == DEMOD_UNSYNCD) { - return false; - } - } - } + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (ManchesterDecoding(b, offset, 0)) { + NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/16 + FRAME_DELAY_TIME_PICC_TO_PCD); + return true; + } else if (c++ > timeout && Demod.state == DEMOD_UNSYNCD) { + return false; + } + } + } } void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t *timing) { - CodeIso14443aBitsAsReaderPar(frame, bits, par); - // Send command to tag - TransmitFor14443a(ToSend, ToSendMax, timing); - if(trigger) LED_A_ON(); + CodeIso14443aBitsAsReaderPar(frame, bits, par); + // Send command to tag + TransmitFor14443a(ToSend, ToSendMax, timing); + if(trigger) LED_A_ON(); - LogTrace(frame, nbytes(bits), (LastTimeProxToAirStart<<4) + DELAY_ARM2AIR_AS_READER, ((LastTimeProxToAirStart + LastProxToAirDuration)<<4) + DELAY_ARM2AIR_AS_READER, par, true); + LogTrace(frame, nbytes(bits), (LastTimeProxToAirStart<<4) + DELAY_ARM2AIR_AS_READER, ((LastTimeProxToAirStart + LastProxToAirDuration)<<4) + DELAY_ARM2AIR_AS_READER, par, true); } void ReaderTransmitPar(uint8_t* frame, uint16_t len, uint8_t *par, uint32_t *timing) { @@ -1800,31 +1800,31 @@ void ReaderTransmitPar(uint8_t* frame, uint16_t len, uint8_t *par, uint32_t *tim } void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing) { - // Generate parity and redirect - uint8_t par[MAX_PARITY_SIZE] = {0x00}; - GetParity(frame, len/8, par); - ReaderTransmitBitsPar(frame, len, par, timing); + // Generate parity and redirect + uint8_t par[MAX_PARITY_SIZE] = {0x00}; + GetParity(frame, len/8, par); + ReaderTransmitBitsPar(frame, len, par, timing); } void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing) { - // Generate parity and redirect - uint8_t par[MAX_PARITY_SIZE] = {0x00}; - GetParity(frame, len, par); - ReaderTransmitBitsPar(frame, len*8, par, timing); + // Generate parity and redirect + uint8_t par[MAX_PARITY_SIZE] = {0x00}; + GetParity(frame, len, par); + ReaderTransmitBitsPar(frame, len*8, par, timing); } int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t *parity) { - if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, offset)) - return false; - LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false); - return Demod.len; + if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, offset)) + return false; + LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false); + return Demod.len; } int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity) { - if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, 0)) - return false; - LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false); - return Demod.len; + if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, 0)) + return false; + LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false); + return Demod.len; } // This function misstreats the ISO 14443a anticollision procedure. @@ -1832,125 +1832,125 @@ int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity) { // increase the uid bytes. The might be an overflow, DoS will occure. void iso14443a_antifuzz(uint32_t flags){ - // We need to listen to the high-frequency, peak-detected path. - iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN); + // We need to listen to the high-frequency, peak-detected path. + iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN); - BigBuf_free_keep_EM(); - clear_trace(); - set_tracing(true); + BigBuf_free_keep_EM(); + clear_trace(); + set_tracing(true); - int len = 0; + int len = 0; - // allocate buffers: - uint8_t *received = BigBuf_malloc(MAX_FRAME_SIZE); - uint8_t *receivedPar = BigBuf_malloc(MAX_PARITY_SIZE); - uint8_t *resp = BigBuf_malloc(20); + // allocate buffers: + uint8_t *received = BigBuf_malloc(MAX_FRAME_SIZE); + uint8_t *receivedPar = BigBuf_malloc(MAX_PARITY_SIZE); + uint8_t *resp = BigBuf_malloc(20); - memset(resp, 0xFF , 20); + memset(resp, 0xFF , 20); - LED_A_ON(); - for (;;) { - WDT_HIT(); + LED_A_ON(); + for (;;) { + WDT_HIT(); - // Clean receive command buffer - if (!GetIso14443aCommandFromReader(received, receivedPar, &len)) { - Dbprintf("Anti-fuzz stopped. Trace length: %d ", BigBuf_get_traceLen()); - break; - } - if ( received[0] == ISO14443A_CMD_WUPA || received[0] == ISO14443A_CMD_REQA) { - resp[0] = 0x04; - resp[1] = 0x00; + // Clean receive command buffer + if (!GetIso14443aCommandFromReader(received, receivedPar, &len)) { + Dbprintf("Anti-fuzz stopped. Trace length: %d ", BigBuf_get_traceLen()); + break; + } + if ( received[0] == ISO14443A_CMD_WUPA || received[0] == ISO14443A_CMD_REQA) { + resp[0] = 0x04; + resp[1] = 0x00; - if ( (flags & FLAG_7B_UID_IN_DATA) == FLAG_7B_UID_IN_DATA ) { - resp[0] = 0x44; - } + if ( (flags & FLAG_7B_UID_IN_DATA) == FLAG_7B_UID_IN_DATA ) { + resp[0] = 0x44; + } - EmSendCmd(resp, 2); - continue; - } + EmSendCmd(resp, 2); + continue; + } - // Received request for UID (cascade 1) - //if (received[1] >= 0x20 && received[1] <= 0x57 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { - if (received[1] >= 0x20 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { - resp[0] = 0xFF; - resp[1] = 0xFF; - resp[2] = 0xFF; - resp[3] = 0xFF; - resp[4] = resp[0] ^ resp[1] ^ resp[2] ^ resp[3]; - colpos = 0; + // Received request for UID (cascade 1) + //if (received[1] >= 0x20 && received[1] <= 0x57 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { + if (received[1] >= 0x20 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { + resp[0] = 0xFF; + resp[1] = 0xFF; + resp[2] = 0xFF; + resp[3] = 0xFF; + resp[4] = resp[0] ^ resp[1] ^ resp[2] ^ resp[3]; + colpos = 0; - if ( (flags & FLAG_7B_UID_IN_DATA) == FLAG_7B_UID_IN_DATA ) { - resp[0] = 0x88; - colpos = 8; - } + if ( (flags & FLAG_7B_UID_IN_DATA) == FLAG_7B_UID_IN_DATA ) { + resp[0] = 0x88; + colpos = 8; + } - EmSendCmdEx(resp, 5, true); - if (MF_DBGLEVEL >= 4) Dbprintf("ANTICOLL or SELECT %x", received[1]); - LED_D_INV(); + EmSendCmdEx(resp, 5, true); + if (MF_DBGLEVEL >= 4) Dbprintf("ANTICOLL or SELECT %x", received[1]); + LED_D_INV(); - continue; - } else if (received[1] == 0x20 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received request for UID (cascade 2) - if (MF_DBGLEVEL >= 4) Dbprintf("ANTICOLL or SELECT_2"); - } else if (received[1] == 0x70 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { // Received a SELECT (cascade 1) - } else if (received[1] == 0x70 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received a SELECT (cascade 2) - } else { - Dbprintf("unknown command %x", received[0]); - } - } + continue; + } else if (received[1] == 0x20 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received request for UID (cascade 2) + if (MF_DBGLEVEL >= 4) Dbprintf("ANTICOLL or SELECT_2"); + } else if (received[1] == 0x70 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { // Received a SELECT (cascade 1) + } else if (received[1] == 0x70 && received[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received a SELECT (cascade 2) + } else { + Dbprintf("unknown command %x", received[0]); + } + } - cmd_send(CMD_ACK,1,0,0,0,0); - switch_off(); - BigBuf_free_keep_EM(); + cmd_send(CMD_ACK,1,0,0,0,0); + switch_off(); + BigBuf_free_keep_EM(); } static void iso14a_set_ATS_times(uint8_t *ats) { - uint8_t tb1; - uint8_t fwi, sfgi; - uint32_t fwt, sfgt; + uint8_t tb1; + uint8_t fwi, sfgi; + uint32_t fwt, sfgt; - if (ats[0] > 1) { // there is a format byte T0 - if ((ats[1] & 0x20) == 0x20) { // there is an interface byte TB(1) - if ((ats[1] & 0x10) == 0x10) { // there is an interface byte TA(1) preceding TB(1) - tb1 = ats[3]; - } else { - tb1 = ats[2]; - } - fwi = (tb1 & 0xf0) >> 4; // frame waiting time integer (FWI) - if (fwi != 15) { - fwt = 256 * 16 * (1 << fwi); // frame waiting time (FWT) in 1/fc - iso14a_set_timeout(fwt/(8*16)); - } - sfgi = tb1 & 0x0f; // startup frame guard time integer (SFGI) - if (sfgi != 0 && sfgi != 15) { - sfgt = 256 * 16 * (1 << sfgi); // startup frame guard time (SFGT) in 1/fc - NextTransferTime = MAX(NextTransferTime, Demod.endTime + (sfgt - DELAY_AIR2ARM_AS_READER - DELAY_ARM2AIR_AS_READER)/16); - } - } - } + if (ats[0] > 1) { // there is a format byte T0 + if ((ats[1] & 0x20) == 0x20) { // there is an interface byte TB(1) + if ((ats[1] & 0x10) == 0x10) { // there is an interface byte TA(1) preceding TB(1) + tb1 = ats[3]; + } else { + tb1 = ats[2]; + } + fwi = (tb1 & 0xf0) >> 4; // frame waiting time integer (FWI) + if (fwi != 15) { + fwt = 256 * 16 * (1 << fwi); // frame waiting time (FWT) in 1/fc + iso14a_set_timeout(fwt/(8*16)); + } + sfgi = tb1 & 0x0f; // startup frame guard time integer (SFGI) + if (sfgi != 0 && sfgi != 15) { + sfgt = 256 * 16 * (1 << sfgi); // startup frame guard time (SFGT) in 1/fc + NextTransferTime = MAX(NextTransferTime, Demod.endTime + (sfgt - DELAY_AIR2ARM_AS_READER - DELAY_ARM2AIR_AS_READER)/16); + } + } + } } static int GetATQA(uint8_t *resp, uint8_t *resp_par) { -#define WUPA_RETRY_TIMEOUT 10 // 10ms - uint8_t wupa[] = { ISO14443A_CMD_WUPA }; // 0x26 - REQA 0x52 - WAKE-UP +#define WUPA_RETRY_TIMEOUT 10 // 10ms + uint8_t wupa[] = { ISO14443A_CMD_WUPA }; // 0x26 - REQA 0x52 - WAKE-UP - uint32_t save_iso14a_timeout = iso14a_get_timeout(); - iso14a_set_timeout(1236/(16*8)+1); // response to WUPA is expected at exactly 1236/fc. No need to wait longer. + uint32_t save_iso14a_timeout = iso14a_get_timeout(); + iso14a_set_timeout(1236/(16*8)+1); // response to WUPA is expected at exactly 1236/fc. No need to wait longer. - uint32_t start_time = GetTickCount(); - int len; + uint32_t start_time = GetTickCount(); + int len; - // we may need several tries if we did send an unknown command or a wrong authentication before... - do { - // Broadcast for a card, WUPA (0x52) will force response from all cards in the field - ReaderTransmitBitsPar(wupa, 7, NULL, NULL); - // Receive the ATQA - len = ReaderReceive(resp, resp_par); - } while (len == 0 && GetTickCount() <= start_time + WUPA_RETRY_TIMEOUT); + // we may need several tries if we did send an unknown command or a wrong authentication before... + do { + // Broadcast for a card, WUPA (0x52) will force response from all cards in the field + ReaderTransmitBitsPar(wupa, 7, NULL, NULL); + // Receive the ATQA + len = ReaderReceive(resp, resp_par); + } while (len == 0 && GetTickCount() <= start_time + WUPA_RETRY_TIMEOUT); - iso14a_set_timeout(save_iso14a_timeout); - return len; + iso14a_set_timeout(save_iso14a_timeout); + return len; } // performs iso14443a anticollision (optional) and card select procedure @@ -1961,238 +1961,238 @@ static int GetATQA(uint8_t *resp, uint8_t *resp_par) { // requests ATS unless no_rats is true int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats) { - uint8_t sel_all[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT,0x20 }; - uint8_t sel_uid[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - uint8_t rats[] = { ISO14443A_CMD_RATS,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0 - uint8_t resp[MAX_FRAME_SIZE] = {0}; // theoretically. A usual RATS will be much smaller - uint8_t resp_par[MAX_PARITY_SIZE] = {0}; - uint8_t uid_resp[4] = {0}; - size_t uid_resp_len = 0; + uint8_t sel_all[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT,0x20 }; + uint8_t sel_uid[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + uint8_t rats[] = { ISO14443A_CMD_RATS,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0 + uint8_t resp[MAX_FRAME_SIZE] = {0}; // theoretically. A usual RATS will be much smaller + uint8_t resp_par[MAX_PARITY_SIZE] = {0}; + uint8_t uid_resp[4] = {0}; + size_t uid_resp_len = 0; - uint8_t sak = 0x04; // cascade uid - int cascade_level = 0; - int len; + uint8_t sak = 0x04; // cascade uid + int cascade_level = 0; + int len; - if (p_card) { - p_card->uidlen = 0; - memset(p_card->uid, 0, 10); - p_card->ats_len = 0; - } + if (p_card) { + p_card->uidlen = 0; + memset(p_card->uid, 0, 10); + p_card->ats_len = 0; + } - if (!GetATQA(resp, resp_par)) { - return 0; - } + if (!GetATQA(resp, resp_par)) { + return 0; + } - if (p_card) { - p_card->atqa[0] = resp[0]; - p_card->atqa[1] = resp[1]; - } + if (p_card) { + p_card->atqa[0] = resp[0]; + p_card->atqa[1] = resp[1]; + } - if (anticollision) { - // clear uid - if (uid_ptr) - memset(uid_ptr, 0, 10); - } + if (anticollision) { + // clear uid + if (uid_ptr) + memset(uid_ptr, 0, 10); + } - // check for proprietary anticollision: - if ((resp[0] & 0x1F) == 0) return 3; + // check for proprietary anticollision: + if ((resp[0] & 0x1F) == 0) return 3; - // OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in - // which case we need to make a cascade 2 request and select - this is a long UID - // While the UID is not complete, the 3nd bit (from the right) is set in the SAK. - for(; sak & 0x04; cascade_level++) { - // SELECT_* (L1: 0x93, L2: 0x95, L3: 0x97) - sel_uid[0] = sel_all[0] = 0x93 + cascade_level * 2; + // OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in + // which case we need to make a cascade 2 request and select - this is a long UID + // While the UID is not complete, the 3nd bit (from the right) is set in the SAK. + for(; sak & 0x04; cascade_level++) { + // SELECT_* (L1: 0x93, L2: 0x95, L3: 0x97) + sel_uid[0] = sel_all[0] = 0x93 + cascade_level * 2; - if (anticollision) { - // SELECT_ALL - ReaderTransmit(sel_all, sizeof(sel_all), NULL); - if (!ReaderReceive(resp, resp_par)) return 0; + if (anticollision) { + // SELECT_ALL + ReaderTransmit(sel_all, sizeof(sel_all), NULL); + if (!ReaderReceive(resp, resp_par)) return 0; - if (Demod.collisionPos) { // we had a collision and need to construct the UID bit by bit - memset(uid_resp, 0, 4); - uint16_t uid_resp_bits = 0; - uint16_t collision_answer_offset = 0; - // anti-collision-loop: - while (Demod.collisionPos) { - Dbprintf("Multiple tags detected. Collision after Bit %d", Demod.collisionPos); - for (uint16_t i = collision_answer_offset; i < Demod.collisionPos; i++, uid_resp_bits++) { // add valid UID bits before collision point - uint16_t UIDbit = (resp[i/8] >> (i % 8)) & 0x01; - uid_resp[uid_resp_bits / 8] |= UIDbit << (uid_resp_bits % 8); - } - uid_resp[uid_resp_bits/8] |= 1 << (uid_resp_bits % 8); // next time select the card(s) with a 1 in the collision position - uid_resp_bits++; - // construct anticollosion command: - sel_uid[1] = ((2 + uid_resp_bits/8) << 4) | (uid_resp_bits & 0x07); // length of data in bytes and bits - for (uint16_t i = 0; i <= uid_resp_bits/8; i++) { - sel_uid[2+i] = uid_resp[i]; - } - collision_answer_offset = uid_resp_bits%8; - ReaderTransmitBits(sel_uid, 16 + uid_resp_bits, NULL); - if (!ReaderReceiveOffset(resp, collision_answer_offset, resp_par)) return 0; - } - // finally, add the last bits and BCC of the UID - for (uint16_t i = collision_answer_offset; i < (Demod.len-1)*8; i++, uid_resp_bits++) { - uint16_t UIDbit = (resp[i/8] >> (i%8)) & 0x01; - uid_resp[uid_resp_bits/8] |= UIDbit << (uid_resp_bits % 8); - } + if (Demod.collisionPos) { // we had a collision and need to construct the UID bit by bit + memset(uid_resp, 0, 4); + uint16_t uid_resp_bits = 0; + uint16_t collision_answer_offset = 0; + // anti-collision-loop: + while (Demod.collisionPos) { + Dbprintf("Multiple tags detected. Collision after Bit %d", Demod.collisionPos); + for (uint16_t i = collision_answer_offset; i < Demod.collisionPos; i++, uid_resp_bits++) { // add valid UID bits before collision point + uint16_t UIDbit = (resp[i/8] >> (i % 8)) & 0x01; + uid_resp[uid_resp_bits / 8] |= UIDbit << (uid_resp_bits % 8); + } + uid_resp[uid_resp_bits/8] |= 1 << (uid_resp_bits % 8); // next time select the card(s) with a 1 in the collision position + uid_resp_bits++; + // construct anticollosion command: + sel_uid[1] = ((2 + uid_resp_bits/8) << 4) | (uid_resp_bits & 0x07); // length of data in bytes and bits + for (uint16_t i = 0; i <= uid_resp_bits/8; i++) { + sel_uid[2+i] = uid_resp[i]; + } + collision_answer_offset = uid_resp_bits%8; + ReaderTransmitBits(sel_uid, 16 + uid_resp_bits, NULL); + if (!ReaderReceiveOffset(resp, collision_answer_offset, resp_par)) return 0; + } + // finally, add the last bits and BCC of the UID + for (uint16_t i = collision_answer_offset; i < (Demod.len-1)*8; i++, uid_resp_bits++) { + uint16_t UIDbit = (resp[i/8] >> (i%8)) & 0x01; + uid_resp[uid_resp_bits/8] |= UIDbit << (uid_resp_bits % 8); + } - } else { // no collision, use the response to SELECT_ALL as current uid - memcpy(uid_resp, resp, 4); - } + } else { // no collision, use the response to SELECT_ALL as current uid + memcpy(uid_resp, resp, 4); + } - } else { - if (cascade_level < num_cascades - 1) { - uid_resp[0] = 0x88; - memcpy(uid_resp+1, uid_ptr+cascade_level*3, 3); - } else { - memcpy(uid_resp, uid_ptr+cascade_level*3, 4); - } - } - uid_resp_len = 4; + } else { + if (cascade_level < num_cascades - 1) { + uid_resp[0] = 0x88; + memcpy(uid_resp+1, uid_ptr+cascade_level*3, 3); + } else { + memcpy(uid_resp, uid_ptr+cascade_level*3, 4); + } + } + uid_resp_len = 4; - // calculate crypto UID. Always use last 4 Bytes. - if(cuid_ptr) - *cuid_ptr = bytes_to_num(uid_resp, 4); + // calculate crypto UID. Always use last 4 Bytes. + if(cuid_ptr) + *cuid_ptr = bytes_to_num(uid_resp, 4); - // Construct SELECT UID command - sel_uid[1] = 0x70; // transmitting a full UID (1 Byte cmd, 1 Byte NVB, 4 Byte UID, 1 Byte BCC, 2 Bytes CRC) - memcpy(sel_uid+2, uid_resp, 4); // the UID received during anticollision, or the provided UID - sel_uid[6] = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5]; // calculate and add BCC - AddCrc14A(sel_uid, 7); // calculate and add CRC - ReaderTransmit(sel_uid, sizeof(sel_uid), NULL); + // Construct SELECT UID command + sel_uid[1] = 0x70; // transmitting a full UID (1 Byte cmd, 1 Byte NVB, 4 Byte UID, 1 Byte BCC, 2 Bytes CRC) + memcpy(sel_uid+2, uid_resp, 4); // the UID received during anticollision, or the provided UID + sel_uid[6] = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5]; // calculate and add BCC + AddCrc14A(sel_uid, 7); // calculate and add CRC + ReaderTransmit(sel_uid, sizeof(sel_uid), NULL); - // Receive the SAK - if (!ReaderReceive(resp, resp_par)) return 0; + // Receive the SAK + if (!ReaderReceive(resp, resp_par)) return 0; - sak = resp[0]; + sak = resp[0]; - // Test if more parts of the uid are coming - if ((sak & 0x04) /* && uid_resp[0] == 0x88 */) { - // Remove first byte, 0x88 is not an UID byte, it CT, see page 3 of: - // http://www.nxp.com/documents/application_note/AN10927.pdf - uid_resp[0] = uid_resp[1]; - uid_resp[1] = uid_resp[2]; - uid_resp[2] = uid_resp[3]; - uid_resp_len = 3; - } + // Test if more parts of the uid are coming + if ((sak & 0x04) /* && uid_resp[0] == 0x88 */) { + // Remove first byte, 0x88 is not an UID byte, it CT, see page 3 of: + // http://www.nxp.com/documents/application_note/AN10927.pdf + uid_resp[0] = uid_resp[1]; + uid_resp[1] = uid_resp[2]; + uid_resp[2] = uid_resp[3]; + uid_resp_len = 3; + } - if(uid_ptr && anticollision) - memcpy(uid_ptr + (cascade_level*3), uid_resp, uid_resp_len); + if(uid_ptr && anticollision) + memcpy(uid_ptr + (cascade_level*3), uid_resp, uid_resp_len); - if(p_card) { - memcpy(p_card->uid + (cascade_level*3), uid_resp, uid_resp_len); - p_card->uidlen += uid_resp_len; - } - } + if(p_card) { + memcpy(p_card->uid + (cascade_level*3), uid_resp, uid_resp_len); + p_card->uidlen += uid_resp_len; + } + } - if (p_card) { - p_card->sak = sak; - } + if (p_card) { + p_card->sak = sak; + } - // PICC compilant with iso14443a-4 ---> (SAK & 0x20 != 0) - if( (sak & 0x20) == 0) return 2; + // PICC compilant with iso14443a-4 ---> (SAK & 0x20 != 0) + if( (sak & 0x20) == 0) return 2; - // RATS, Request for answer to select - if ( !no_rats ) { + // RATS, Request for answer to select + if ( !no_rats ) { - AddCrc14A(rats, 2); - ReaderTransmit(rats, sizeof(rats), NULL); - len = ReaderReceive(resp, resp_par); + AddCrc14A(rats, 2); + ReaderTransmit(rats, sizeof(rats), NULL); + len = ReaderReceive(resp, resp_par); - if (!len) return 0; + if (!len) return 0; - if (p_card) { - memcpy(p_card->ats, resp, sizeof(p_card->ats)); - p_card->ats_len = len; - } + if (p_card) { + memcpy(p_card->ats, resp, sizeof(p_card->ats)); + p_card->ats_len = len; + } - // reset the PCB block number - iso14_pcb_blocknum = 0; + // reset the PCB block number + iso14_pcb_blocknum = 0; - // set default timeout and delay next transfer based on ATS - iso14a_set_ATS_times(resp); - } - return 1; + // set default timeout and delay next transfer based on ATS + iso14a_set_ATS_times(resp); + } + return 1; } int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades) { - uint8_t sel_all[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT,0x20 }; - uint8_t sel_uid[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - uint8_t resp[5] = {0}; // theoretically. A usual RATS will be much smaller - uint8_t resp_par[1] = {0}; - uint8_t uid_resp[4] = {0}; + uint8_t sel_all[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT,0x20 }; + uint8_t sel_uid[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + uint8_t resp[5] = {0}; // theoretically. A usual RATS will be much smaller + uint8_t resp_par[1] = {0}; + uint8_t uid_resp[4] = {0}; - uint8_t sak = 0x04; // cascade uid - int cascade_level = 0; + uint8_t sak = 0x04; // cascade uid + int cascade_level = 0; - if (!GetATQA(resp, resp_par)) { - return 0; - } + if (!GetATQA(resp, resp_par)) { + return 0; + } - // OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in - // which case we need to make a cascade 2 request and select - this is a long UID - // While the UID is not complete, the 3nd bit (from the right) is set in the SAK. - for(; sak & 0x04; cascade_level++) { - // SELECT_* (L1: 0x93, L2: 0x95, L3: 0x97) - sel_uid[0] = sel_all[0] = 0x93 + cascade_level * 2; + // OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in + // which case we need to make a cascade 2 request and select - this is a long UID + // While the UID is not complete, the 3nd bit (from the right) is set in the SAK. + for(; sak & 0x04; cascade_level++) { + // SELECT_* (L1: 0x93, L2: 0x95, L3: 0x97) + sel_uid[0] = sel_all[0] = 0x93 + cascade_level * 2; - if (cascade_level < num_cascades - 1) { - uid_resp[0] = 0x88; - memcpy(uid_resp+1, uid_ptr+cascade_level*3, 3); - } else { - memcpy(uid_resp, uid_ptr+cascade_level*3, 4); - } + if (cascade_level < num_cascades - 1) { + uid_resp[0] = 0x88; + memcpy(uid_resp+1, uid_ptr+cascade_level*3, 3); + } else { + memcpy(uid_resp, uid_ptr+cascade_level*3, 4); + } - // Construct SELECT UID command - //sel_uid[1] = 0x70; // transmitting a full UID (1 Byte cmd, 1 Byte NVB, 4 Byte UID, 1 Byte BCC, 2 Bytes CRC) - memcpy(sel_uid+2, uid_resp, 4); // the UID received during anticollision, or the provided UID - sel_uid[6] = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5]; // calculate and add BCC - AddCrc14A(sel_uid, 7); // calculate and add CRC - ReaderTransmit(sel_uid, sizeof(sel_uid), NULL); + // Construct SELECT UID command + //sel_uid[1] = 0x70; // transmitting a full UID (1 Byte cmd, 1 Byte NVB, 4 Byte UID, 1 Byte BCC, 2 Bytes CRC) + memcpy(sel_uid+2, uid_resp, 4); // the UID received during anticollision, or the provided UID + sel_uid[6] = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5]; // calculate and add BCC + AddCrc14A(sel_uid, 7); // calculate and add CRC + ReaderTransmit(sel_uid, sizeof(sel_uid), NULL); - // Receive the SAK - if (!ReaderReceive(resp, resp_par)) return 0; + // Receive the SAK + if (!ReaderReceive(resp, resp_par)) return 0; - sak = resp[0]; + sak = resp[0]; - // Test if more parts of the uid are coming - if ((sak & 0x04) /* && uid_resp[0] == 0x88 */) { - // Remove first byte, 0x88 is not an UID byte, it CT, see page 3 of: - // http://www.nxp.com/documents/application_note/AN10927.pdf - uid_resp[0] = uid_resp[1]; - uid_resp[1] = uid_resp[2]; - uid_resp[2] = uid_resp[3]; - } - } - return 1; + // Test if more parts of the uid are coming + if ((sak & 0x04) /* && uid_resp[0] == 0x88 */) { + // Remove first byte, 0x88 is not an UID byte, it CT, see page 3 of: + // http://www.nxp.com/documents/application_note/AN10927.pdf + uid_resp[0] = uid_resp[1]; + uid_resp[1] = uid_resp[2]; + uid_resp[2] = uid_resp[3]; + } + } + return 1; } void iso14443a_setup(uint8_t fpga_minor_mode) { - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - // Set up the synchronous serial port - FpgaSetupSsc(); - // connect Demodulated Signal to ADC: - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + // Set up the synchronous serial port + FpgaSetupSsc(); + // connect Demodulated Signal to ADC: + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - LED_D_OFF(); - // Signal field is on with the appropriate LED - if (fpga_minor_mode == FPGA_HF_ISO14443A_READER_MOD || - fpga_minor_mode == FPGA_HF_ISO14443A_READER_LISTEN) - LED_D_ON(); + LED_D_OFF(); + // Signal field is on with the appropriate LED + if (fpga_minor_mode == FPGA_HF_ISO14443A_READER_MOD || + fpga_minor_mode == FPGA_HF_ISO14443A_READER_LISTEN) + LED_D_ON(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | fpga_minor_mode); - SpinDelay(100); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | fpga_minor_mode); + SpinDelay(100); - // Start the timer - StartCountSspClk(); + // Start the timer + StartCountSspClk(); - // Prepare the demodulation functions - DemodReset(); - UartReset(); - NextTransferTime = 2 * DELAY_ARM2AIR_AS_READER; - iso14a_set_timeout(1060); // 106 * 10ms default + // Prepare the demodulation functions + DemodReset(); + UartReset(); + NextTransferTime = 2 * DELAY_ARM2AIR_AS_READER; + iso14a_set_timeout(1060); // 106 * 10ms default } /* Peter Fillmore 2015 @@ -2220,187 +2220,187 @@ b5,b6 = 00 - DESELECT 11 - WTX */ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint8_t *res) { - uint8_t parity[MAX_PARITY_SIZE] = {0x00}; - uint8_t real_cmd[cmd_len + 4]; + uint8_t parity[MAX_PARITY_SIZE] = {0x00}; + uint8_t real_cmd[cmd_len + 4]; - if (cmd_len) { - // ISO 14443 APDU frame: PCB [CID] [NAD] APDU CRC PCB=0x02 - real_cmd[0] = 0x02; // bnr,nad,cid,chn=0; i-block(0x00) - if (send_chaining) { - real_cmd[0] |= 0x10; - } - // put block number into the PCB - real_cmd[0] |= iso14_pcb_blocknum; - memcpy(real_cmd + 1, cmd, cmd_len); - } else { - // R-block. ACK - real_cmd[0] = 0xA2; // r-block + ACK - real_cmd[0] |= iso14_pcb_blocknum; - } - AddCrc14A(real_cmd, cmd_len + 1); + if (cmd_len) { + // ISO 14443 APDU frame: PCB [CID] [NAD] APDU CRC PCB=0x02 + real_cmd[0] = 0x02; // bnr,nad,cid,chn=0; i-block(0x00) + if (send_chaining) { + real_cmd[0] |= 0x10; + } + // put block number into the PCB + real_cmd[0] |= iso14_pcb_blocknum; + memcpy(real_cmd + 1, cmd, cmd_len); + } else { + // R-block. ACK + real_cmd[0] = 0xA2; // r-block + ACK + real_cmd[0] |= iso14_pcb_blocknum; + } + AddCrc14A(real_cmd, cmd_len + 1); - ReaderTransmit(real_cmd, cmd_len + 3, NULL); + ReaderTransmit(real_cmd, cmd_len + 3, NULL); - size_t len = ReaderReceive(data, parity); - uint8_t *data_bytes = (uint8_t *) data; + size_t len = ReaderReceive(data, parity); + uint8_t *data_bytes = (uint8_t *) data; - if (!len) { - return 0; //DATA LINK ERROR - } else{ - // S-Block WTX - while(len && ((data_bytes[0] & 0xF2) == 0xF2)) { - uint32_t save_iso14a_timeout = iso14a_get_timeout(); - // temporarily increase timeout - iso14a_set_timeout( MAX((data_bytes[1] & 0x3f) * save_iso14a_timeout, MAX_ISO14A_TIMEOUT) ); - // Transmit WTX back - // byte1 - WTXM [1..59]. command FWT=FWT*WTXM - data_bytes[1] = data_bytes[1] & 0x3f; // 2 high bits mandatory set to 0b - // now need to fix CRC. - AddCrc14A(data_bytes, len - 2); - // transmit S-Block - ReaderTransmit(data_bytes, len, NULL); - // retrieve the result again (with increased timeout) - len = ReaderReceive(data, parity); - data_bytes = data; - // restore timeout - iso14a_set_timeout(save_iso14a_timeout); - } + if (!len) { + return 0; //DATA LINK ERROR + } else{ + // S-Block WTX + while(len && ((data_bytes[0] & 0xF2) == 0xF2)) { + uint32_t save_iso14a_timeout = iso14a_get_timeout(); + // temporarily increase timeout + iso14a_set_timeout( MAX((data_bytes[1] & 0x3f) * save_iso14a_timeout, MAX_ISO14A_TIMEOUT) ); + // Transmit WTX back + // byte1 - WTXM [1..59]. command FWT=FWT*WTXM + data_bytes[1] = data_bytes[1] & 0x3f; // 2 high bits mandatory set to 0b + // now need to fix CRC. + AddCrc14A(data_bytes, len - 2); + // transmit S-Block + ReaderTransmit(data_bytes, len, NULL); + // retrieve the result again (with increased timeout) + len = ReaderReceive(data, parity); + data_bytes = data; + // restore timeout + iso14a_set_timeout(save_iso14a_timeout); + } - // if we received an I- or R(ACK)-Block with a block number equal to the - // current block number, toggle the current block number - if (len >= 3 // PCB+CRC = 3 bytes - && ((data_bytes[0] & 0xC0) == 0 // I-Block - || (data_bytes[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0 - && (data_bytes[0] & 0x01) == iso14_pcb_blocknum) // equal block numbers - { - iso14_pcb_blocknum ^= 1; - } + // if we received an I- or R(ACK)-Block with a block number equal to the + // current block number, toggle the current block number + if (len >= 3 // PCB+CRC = 3 bytes + && ((data_bytes[0] & 0xC0) == 0 // I-Block + || (data_bytes[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0 + && (data_bytes[0] & 0x01) == iso14_pcb_blocknum) // equal block numbers + { + iso14_pcb_blocknum ^= 1; + } - // if we received I-block with chaining we need to send ACK and receive another block of data - if (res) - *res = data_bytes[0]; + // if we received I-block with chaining we need to send ACK and receive another block of data + if (res) + *res = data_bytes[0]; - // crc check - if (len >= 3 && !check_crc(CRC_14443_A, data_bytes, len)) { - return -1; - } + // crc check + if (len >= 3 && !check_crc(CRC_14443_A, data_bytes, len)) { + return -1; + } - } + } - if (len) { - // cut frame byte - len -= 1; - // memmove(data_bytes, data_bytes + 1, len); - for (int i = 0; i < len; i++) - data_bytes[i] = data_bytes[i + 1]; - } + if (len) { + // cut frame byte + len -= 1; + // memmove(data_bytes, data_bytes + 1, len); + for (int i = 0; i < len; i++) + data_bytes[i] = data_bytes[i + 1]; + } - return len; + return len; } //----------------------------------------------------------------------------- // Read an ISO 14443a tag. Send out commands and store answers. //----------------------------------------------------------------------------- -// arg0 iso_14a flags -// arg1 high :: number of bits, if you want to send 7bits etc -// low :: len of commandbytes -// arg2 timeout +// arg0 iso_14a flags +// arg1 high :: number of bits, if you want to send 7bits etc +// low :: len of commandbytes +// arg2 timeout // d.asBytes command bytes to send void ReaderIso14443a(UsbCommand *c) { - iso14a_command_t param = c->arg[0]; - size_t len = c->arg[1] & 0xffff; - size_t lenbits = c->arg[1] >> 16; - uint32_t timeout = c->arg[2]; - uint8_t *cmd = c->d.asBytes; - uint32_t arg0 = 0; - uint8_t buf[USB_CMD_DATA_SIZE] = {0x00}; - uint8_t par[MAX_PARITY_SIZE] = {0x00}; + iso14a_command_t param = c->arg[0]; + size_t len = c->arg[1] & 0xffff; + size_t lenbits = c->arg[1] >> 16; + uint32_t timeout = c->arg[2]; + uint8_t *cmd = c->d.asBytes; + uint32_t arg0 = 0; + uint8_t buf[USB_CMD_DATA_SIZE] = {0x00}; + uint8_t par[MAX_PARITY_SIZE] = {0x00}; - if ((param & ISO14A_CONNECT)) - clear_trace(); + if ((param & ISO14A_CONNECT)) + clear_trace(); - set_tracing(true); + set_tracing(true); - if ((param & ISO14A_REQUEST_TRIGGER)) - iso14a_set_trigger(true); + if ((param & ISO14A_REQUEST_TRIGGER)) + iso14a_set_trigger(true); - if ((param & ISO14A_CONNECT)) { - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + if ((param & ISO14A_CONNECT)) { + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - // notify client selecting status. - // if failed selecting, turn off antenna and quite. - if( !(param & ISO14A_NO_SELECT) ) { - iso14a_card_select_t *card = (iso14a_card_select_t*)buf; - arg0 = iso14443a_select_card(NULL, card, NULL, true, 0, param & ISO14A_NO_RATS ); - cmd_send(CMD_ACK, arg0, card->uidlen, 0, buf, sizeof(iso14a_card_select_t)); - if ( arg0 == 0 ) - goto OUT; - } - } + // notify client selecting status. + // if failed selecting, turn off antenna and quite. + if( !(param & ISO14A_NO_SELECT) ) { + iso14a_card_select_t *card = (iso14a_card_select_t*)buf; + arg0 = iso14443a_select_card(NULL, card, NULL, true, 0, param & ISO14A_NO_RATS ); + cmd_send(CMD_ACK, arg0, card->uidlen, 0, buf, sizeof(iso14a_card_select_t)); + if ( arg0 == 0 ) + goto OUT; + } + } - if ((param & ISO14A_SET_TIMEOUT)) - iso14a_set_timeout(timeout); + if ((param & ISO14A_SET_TIMEOUT)) + iso14a_set_timeout(timeout); - if ((param & ISO14A_APDU)) { - uint8_t res; - arg0 = iso14_apdu(cmd, len, (param & ISO14A_SEND_CHAINING), buf, &res); - cmd_send(CMD_ACK, arg0, res, 0, buf, sizeof(buf)); - } + if ((param & ISO14A_APDU)) { + uint8_t res; + arg0 = iso14_apdu(cmd, len, (param & ISO14A_SEND_CHAINING), buf, &res); + cmd_send(CMD_ACK, arg0, res, 0, buf, sizeof(buf)); + } - if ((param & ISO14A_RAW)) { + if ((param & ISO14A_RAW)) { - if ((param & ISO14A_APPEND_CRC)) { - // Don't append crc on empty bytearray... - if ( len > 0 ) { - if ((param & ISO14A_TOPAZMODE)) - AddCrc14B(cmd, len); - else - AddCrc14A(cmd, len); + if ((param & ISO14A_APPEND_CRC)) { + // Don't append crc on empty bytearray... + if ( len > 0 ) { + if ((param & ISO14A_TOPAZMODE)) + AddCrc14B(cmd, len); + else + AddCrc14A(cmd, len); - len += 2; - if (lenbits) lenbits += 16; - } - } + len += 2; + if (lenbits) lenbits += 16; + } + } - if (lenbits > 0) { // want to send a specific number of bits (e.g. short commands) - if ((param & ISO14A_TOPAZMODE)) { - int bits_to_send = lenbits; - uint16_t i = 0; - ReaderTransmitBitsPar(&cmd[i++], MIN(bits_to_send, 7), NULL, NULL); // first byte is always short (7bits) and no parity - bits_to_send -= 7; - while (bits_to_send > 0) { - ReaderTransmitBitsPar(&cmd[i++], MIN(bits_to_send, 8), NULL, NULL); // following bytes are 8 bit and no parity - bits_to_send -= 8; - } - } else { - GetParity(cmd, lenbits/8, par); - ReaderTransmitBitsPar(cmd, lenbits, par, NULL); // bytes are 8 bit with odd parity - } - } else { // want to send complete bytes only - if ((param & ISO14A_TOPAZMODE)) { - uint16_t i = 0; - ReaderTransmitBitsPar(&cmd[i++], 7, NULL, NULL); // first byte: 7 bits, no paritiy - while (i < len) { - ReaderTransmitBitsPar(&cmd[i++], 8, NULL, NULL); // following bytes: 8 bits, no paritiy - } - } else { - ReaderTransmit(cmd, len, NULL); // 8 bits, odd parity - } - } - arg0 = ReaderReceive(buf, par); - cmd_send(CMD_ACK, arg0, 0, 0, buf, sizeof(buf)); - } + if (lenbits > 0) { // want to send a specific number of bits (e.g. short commands) + if ((param & ISO14A_TOPAZMODE)) { + int bits_to_send = lenbits; + uint16_t i = 0; + ReaderTransmitBitsPar(&cmd[i++], MIN(bits_to_send, 7), NULL, NULL); // first byte is always short (7bits) and no parity + bits_to_send -= 7; + while (bits_to_send > 0) { + ReaderTransmitBitsPar(&cmd[i++], MIN(bits_to_send, 8), NULL, NULL); // following bytes are 8 bit and no parity + bits_to_send -= 8; + } + } else { + GetParity(cmd, lenbits/8, par); + ReaderTransmitBitsPar(cmd, lenbits, par, NULL); // bytes are 8 bit with odd parity + } + } else { // want to send complete bytes only + if ((param & ISO14A_TOPAZMODE)) { + uint16_t i = 0; + ReaderTransmitBitsPar(&cmd[i++], 7, NULL, NULL); // first byte: 7 bits, no paritiy + while (i < len) { + ReaderTransmitBitsPar(&cmd[i++], 8, NULL, NULL); // following bytes: 8 bits, no paritiy + } + } else { + ReaderTransmit(cmd, len, NULL); // 8 bits, odd parity + } + } + arg0 = ReaderReceive(buf, par); + cmd_send(CMD_ACK, arg0, 0, 0, buf, sizeof(buf)); + } - if ((param & ISO14A_REQUEST_TRIGGER)) - iso14a_set_trigger(false); + if ((param & ISO14A_REQUEST_TRIGGER)) + iso14a_set_trigger(false); - if ((param & ISO14A_NO_DISCONNECT)) - return; + if ((param & ISO14A_NO_DISCONNECT)) + return; OUT: - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - set_tracing(false); - LEDsoff(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + set_tracing(false); + LEDsoff(); } // Determine the distance between two nonces. @@ -2408,26 +2408,26 @@ OUT: // Therefore try in alternating directions. int32_t dist_nt(uint32_t nt1, uint32_t nt2) { - if (nt1 == nt2) return 0; + if (nt1 == nt2) return 0; - uint32_t nttmp1 = nt1; - uint32_t nttmp2 = nt2; + uint32_t nttmp1 = nt1; + uint32_t nttmp2 = nt2; - for (uint16_t i = 1; i < 32768; i++) { - nttmp1 = prng_successor(nttmp1, 1); - if (nttmp1 == nt2) return i; + for (uint16_t i = 1; i < 32768; i++) { + nttmp1 = prng_successor(nttmp1, 1); + if (nttmp1 == nt2) return i; - nttmp2 = prng_successor(nttmp2, 1); - if (nttmp2 == nt1) return -i; - } + nttmp2 = prng_successor(nttmp2, 1); + if (nttmp2 == nt1) return -i; + } - return(-99999); // either nt1 or nt2 are invalid nonces + return(-99999); // either nt1 or nt2 are invalid nonces } -#define PRNG_SEQUENCE_LENGTH (1 << 16) -#define MAX_UNEXPECTED_RANDOM 4 // maximum number of unexpected (i.e. real) random numbers when trying to sync. Then give up. -#define MAX_SYNC_TRIES 32 +#define PRNG_SEQUENCE_LENGTH (1 << 16) +#define MAX_UNEXPECTED_RANDOM 4 // maximum number of unexpected (i.e. real) random numbers when trying to sync. Then give up. +#define MAX_SYNC_TRIES 32 //----------------------------------------------------------------------------- // Recover several bits of the cypher stream. This implements (first stages of) @@ -2437,259 +2437,259 @@ int32_t dist_nt(uint32_t nt1, uint32_t nt2) { //----------------------------------------------------------------------------- void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ) { - iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); + iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); - BigBuf_free(); BigBuf_Clear_ext(false); - clear_trace(); - set_tracing(true); + BigBuf_free(); BigBuf_Clear_ext(false); + clear_trace(); + set_tracing(true); - uint8_t mf_auth[] = { keytype, block, 0x00, 0x00 }; - uint8_t mf_nr_ar[] = {0,0,0,0,0,0,0,0}; - uint8_t uid[10] = {0,0,0,0,0,0,0,0,0,0}; - uint8_t par_list[8] = {0,0,0,0,0,0,0,0}; - uint8_t ks_list[8] = {0,0,0,0,0,0,0,0}; - uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; - uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; - uint8_t par[1] = {0}; // maximum 8 Bytes to be sent here, 1 byte parity is therefore enough - uint8_t nt_diff = 0; + uint8_t mf_auth[] = { keytype, block, 0x00, 0x00 }; + uint8_t mf_nr_ar[] = {0,0,0,0,0,0,0,0}; + uint8_t uid[10] = {0,0,0,0,0,0,0,0,0,0}; + uint8_t par_list[8] = {0,0,0,0,0,0,0,0}; + uint8_t ks_list[8] = {0,0,0,0,0,0,0,0}; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; + uint8_t par[1] = {0}; // maximum 8 Bytes to be sent here, 1 byte parity is therefore enough + uint8_t nt_diff = 0; - uint32_t nt = 0, previous_nt = 0, cuid = 0; - uint32_t sync_time = GetCountSspClk() & 0xfffffff8; + uint32_t nt = 0, previous_nt = 0, cuid = 0; + uint32_t sync_time = GetCountSspClk() & 0xfffffff8; - int32_t catch_up_cycles = 0; - int32_t last_catch_up = 0; - int32_t isOK = 0; + int32_t catch_up_cycles = 0; + int32_t last_catch_up = 0; + int32_t isOK = 0; - uint16_t elapsed_prng_sequences = 1; - uint16_t consecutive_resyncs = 0; - uint16_t unexpected_random = 0; - uint16_t sync_tries = 0; + uint16_t elapsed_prng_sequences = 1; + uint16_t consecutive_resyncs = 0; + uint16_t unexpected_random = 0; + uint16_t sync_tries = 0; - bool have_uid = false; - bool received_nack; - uint8_t cascade_levels = 0; + bool have_uid = false; + bool received_nack; + uint8_t cascade_levels = 0; - // static variables here, is re-used in the next call - static uint32_t nt_attacked = 0; - static int32_t sync_cycles = 0; - static uint8_t par_low = 0; - static uint8_t mf_nr_ar3 = 0; + // static variables here, is re-used in the next call + static uint32_t nt_attacked = 0; + static int32_t sync_cycles = 0; + static uint8_t par_low = 0; + static uint8_t mf_nr_ar3 = 0; - AddCrc14A(mf_auth, 2); + AddCrc14A(mf_auth, 2); - if (first_try) { - sync_cycles = PRNG_SEQUENCE_LENGTH; // Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces). - nt_attacked = 0; - mf_nr_ar3 = 0; - par_low = 0; - } else { - // we were unsuccessful on a previous call. - // Try another READER nonce (first 3 parity bits remain the same) - mf_nr_ar3++; - mf_nr_ar[3] = mf_nr_ar3; - par[0] = par_low; - } + if (first_try) { + sync_cycles = PRNG_SEQUENCE_LENGTH; // Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces). + nt_attacked = 0; + mf_nr_ar3 = 0; + par_low = 0; + } else { + // we were unsuccessful on a previous call. + // Try another READER nonce (first 3 parity bits remain the same) + mf_nr_ar3++; + mf_nr_ar[3] = mf_nr_ar3; + par[0] = par_low; + } - LED_C_ON(); - uint16_t i; - for (i = 0; true; ++i) { + LED_C_ON(); + uint16_t i; + for (i = 0; true; ++i) { - received_nack = false; + received_nack = false; - WDT_HIT(); + WDT_HIT(); - // Test if the action was cancelled - if (BUTTON_PRESS()) { - isOK = -1; - break; - } + // Test if the action was cancelled + if (BUTTON_PRESS()) { + isOK = -1; + break; + } - // this part is from Piwi's faster nonce collecting part in Hardnested. - if (!have_uid) { // need a full select cycle to get the uid first - iso14a_card_select_t card_info; - if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Can't select card (ALL)"); - continue; - } - switch (card_info.uidlen) { - case 4 : cascade_levels = 1; break; - case 7 : cascade_levels = 2; break; - case 10: cascade_levels = 3; break; - default: break; - } - have_uid = true; - } else { // no need for anticollision. We can directly select the card - if (!iso14443a_fast_select_card(uid, cascade_levels)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Can't select card (UID)"); - continue; - } - } + // this part is from Piwi's faster nonce collecting part in Hardnested. + if (!have_uid) { // need a full select cycle to get the uid first + iso14a_card_select_t card_info; + if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Can't select card (ALL)"); + continue; + } + switch (card_info.uidlen) { + case 4 : cascade_levels = 1; break; + case 7 : cascade_levels = 2; break; + case 10: cascade_levels = 3; break; + default: break; + } + have_uid = true; + } else { // no need for anticollision. We can directly select the card + if (!iso14443a_fast_select_card(uid, cascade_levels)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Can't select card (UID)"); + continue; + } + } - elapsed_prng_sequences = 1; + elapsed_prng_sequences = 1; - // Sending timeslot of ISO14443a frame - sync_time = (sync_time & 0xfffffff8 ) + sync_cycles + catch_up_cycles; - catch_up_cycles = 0; + // Sending timeslot of ISO14443a frame + sync_time = (sync_time & 0xfffffff8 ) + sync_cycles + catch_up_cycles; + catch_up_cycles = 0; - #define SYNC_TIME_BUFFER 16 // if there is only SYNC_TIME_BUFFER left before next planned sync, wait for next PRNG cycle + #define SYNC_TIME_BUFFER 16 // if there is only SYNC_TIME_BUFFER left before next planned sync, wait for next PRNG cycle - // if we missed the sync time already or are about to miss it, advance to the next nonce repeat - while ( sync_time < GetCountSspClk() + SYNC_TIME_BUFFER) { - ++elapsed_prng_sequences; - sync_time = (sync_time & 0xfffffff8 ) + sync_cycles; - } + // if we missed the sync time already or are about to miss it, advance to the next nonce repeat + while ( sync_time < GetCountSspClk() + SYNC_TIME_BUFFER) { + ++elapsed_prng_sequences; + sync_time = (sync_time & 0xfffffff8 ) + sync_cycles; + } - // Transmit MIFARE_CLASSIC_AUTH at synctime. Should result in returning the same tag nonce (== nt_attacked) - ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time); + // Transmit MIFARE_CLASSIC_AUTH at synctime. Should result in returning the same tag nonce (== nt_attacked) + ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time); - // Receive the (4 Byte) "random" TAG nonce - if (!ReaderReceive(receivedAnswer, receivedAnswerPar)) - continue; + // Receive the (4 Byte) "random" TAG nonce + if (!ReaderReceive(receivedAnswer, receivedAnswerPar)) + continue; - previous_nt = nt; - nt = bytes_to_num(receivedAnswer, 4); + previous_nt = nt; + nt = bytes_to_num(receivedAnswer, 4); - // Transmit reader nonce with fake par - ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL); + // Transmit reader nonce with fake par + ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL); - // Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding - if (ReaderReceive(receivedAnswer, receivedAnswerPar)) - received_nack = true; + // Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding + if (ReaderReceive(receivedAnswer, receivedAnswerPar)) + received_nack = true; - // we didn't calibrate our clock yet, - // iceman: has to be calibrated every time. - if (previous_nt && !nt_attacked) { + // we didn't calibrate our clock yet, + // iceman: has to be calibrated every time. + if (previous_nt && !nt_attacked) { - int nt_distance = dist_nt(previous_nt, nt); + int nt_distance = dist_nt(previous_nt, nt); - // if no distance between, then we are in sync. - if (nt_distance == 0) { - nt_attacked = nt; - } else { - if (nt_distance == -99999) { // invalid nonce received - unexpected_random++; - if (unexpected_random > MAX_UNEXPECTED_RANDOM) { - isOK = -3; // Card has an unpredictable PRNG. Give up - break; - } else { - continue; // continue trying... - } - } + // if no distance between, then we are in sync. + if (nt_distance == 0) { + nt_attacked = nt; + } else { + if (nt_distance == -99999) { // invalid nonce received + unexpected_random++; + if (unexpected_random > MAX_UNEXPECTED_RANDOM) { + isOK = -3; // Card has an unpredictable PRNG. Give up + break; + } else { + continue; // continue trying... + } + } - if (++sync_tries > MAX_SYNC_TRIES) { - isOK = -4; // Card's PRNG runs at an unexpected frequency or resets unexpectedly - break; - } + if (++sync_tries > MAX_SYNC_TRIES) { + isOK = -4; // Card's PRNG runs at an unexpected frequency or resets unexpectedly + break; + } - sync_cycles = (sync_cycles - nt_distance)/elapsed_prng_sequences; + sync_cycles = (sync_cycles - nt_distance)/elapsed_prng_sequences; - // no negative sync_cycles - if (sync_cycles <= 0) sync_cycles += PRNG_SEQUENCE_LENGTH; + // no negative sync_cycles + if (sync_cycles <= 0) sync_cycles += PRNG_SEQUENCE_LENGTH; - // reset sync_cycles - if (sync_cycles > PRNG_SEQUENCE_LENGTH * 2 ) { - sync_cycles = PRNG_SEQUENCE_LENGTH; - sync_time = GetCountSspClk() & 0xfffffff8; - } + // reset sync_cycles + if (sync_cycles > PRNG_SEQUENCE_LENGTH * 2 ) { + sync_cycles = PRNG_SEQUENCE_LENGTH; + sync_time = GetCountSspClk() & 0xfffffff8; + } - if (MF_DBGLEVEL >= 4) - Dbprintf("calibrating in cycle %d. nt_distance=%d, elapsed_prng_sequences=%d, new sync_cycles: %d\n", i, nt_distance, elapsed_prng_sequences, sync_cycles); + if (MF_DBGLEVEL >= 4) + Dbprintf("calibrating in cycle %d. nt_distance=%d, elapsed_prng_sequences=%d, new sync_cycles: %d\n", i, nt_distance, elapsed_prng_sequences, sync_cycles); - LED_B_OFF(); - continue; - } - } - LED_B_OFF(); + LED_B_OFF(); + continue; + } + } + LED_B_OFF(); - if ( (nt != nt_attacked) && nt_attacked) { // we somehow lost sync. Try to catch up again... + if ( (nt != nt_attacked) && nt_attacked) { // we somehow lost sync. Try to catch up again... - catch_up_cycles = -dist_nt(nt_attacked, nt); - if (catch_up_cycles == 99999) { // invalid nonce received. Don't resync on that one. - catch_up_cycles = 0; - continue; - } - // average? - catch_up_cycles /= elapsed_prng_sequences; + catch_up_cycles = -dist_nt(nt_attacked, nt); + if (catch_up_cycles == 99999) { // invalid nonce received. Don't resync on that one. + catch_up_cycles = 0; + continue; + } + // average? + catch_up_cycles /= elapsed_prng_sequences; - if (catch_up_cycles == last_catch_up) { - consecutive_resyncs++; - } else { - last_catch_up = catch_up_cycles; - consecutive_resyncs = 0; - } + if (catch_up_cycles == last_catch_up) { + consecutive_resyncs++; + } else { + last_catch_up = catch_up_cycles; + consecutive_resyncs = 0; + } - if (consecutive_resyncs < 3) { - if (MF_DBGLEVEL >= 4) { - Dbprintf("Lost sync in cycle %d. nt_distance=%d. Consecutive Resyncs = %d. Trying one time catch up...\n", i, catch_up_cycles, consecutive_resyncs); - } - } else { - sync_cycles += catch_up_cycles; + if (consecutive_resyncs < 3) { + if (MF_DBGLEVEL >= 4) { + Dbprintf("Lost sync in cycle %d. nt_distance=%d. Consecutive Resyncs = %d. Trying one time catch up...\n", i, catch_up_cycles, consecutive_resyncs); + } + } else { + sync_cycles += catch_up_cycles; - if (MF_DBGLEVEL >= 4) - Dbprintf("Lost sync in cycle %d for the fourth time consecutively (nt_distance = %d). Adjusting sync_cycles to %d.\n", i, catch_up_cycles, sync_cycles); + if (MF_DBGLEVEL >= 4) + Dbprintf("Lost sync in cycle %d for the fourth time consecutively (nt_distance = %d). Adjusting sync_cycles to %d.\n", i, catch_up_cycles, sync_cycles); - last_catch_up = 0; - catch_up_cycles = 0; - consecutive_resyncs = 0; - } - continue; - } + last_catch_up = 0; + catch_up_cycles = 0; + consecutive_resyncs = 0; + } + continue; + } - // Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding - if (received_nack) { - catch_up_cycles = 8; // the PRNG is delayed by 8 cycles due to the NAC (4Bits = 0x05 encrypted) transfer + // Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding + if (received_nack) { + catch_up_cycles = 8; // the PRNG is delayed by 8 cycles due to the NAC (4Bits = 0x05 encrypted) transfer - if (nt_diff == 0) - par_low = par[0] & 0xE0; // there is no need to check all parities for other nt_diff. Parity Bits for mf_nr_ar[0..2] won't change + if (nt_diff == 0) + par_low = par[0] & 0xE0; // there is no need to check all parities for other nt_diff. Parity Bits for mf_nr_ar[0..2] won't change - par_list[nt_diff] = reflect8(par[0]); - ks_list[nt_diff] = receivedAnswer[0] ^ 0x05; // xor with NACK value to get keystream + par_list[nt_diff] = reflect8(par[0]); + ks_list[nt_diff] = receivedAnswer[0] ^ 0x05; // xor with NACK value to get keystream - // Test if the information is complete - if (nt_diff == 0x07) { - isOK = 1; - break; - } + // Test if the information is complete + if (nt_diff == 0x07) { + isOK = 1; + break; + } - nt_diff = (nt_diff + 1) & 0x07; - mf_nr_ar[3] = (mf_nr_ar[3] & 0x1F) | (nt_diff << 5); - par[0] = par_low; + nt_diff = (nt_diff + 1) & 0x07; + mf_nr_ar[3] = (mf_nr_ar[3] & 0x1F) | (nt_diff << 5); + par[0] = par_low; - } else { - // No NACK. - if (nt_diff == 0 && first_try) { - par[0]++; - if (par[0] == 0) { // tried all 256 possible parities without success. Card doesn't send NACK. - isOK = -2; - break; - } - } else { - // Why this? - par[0] = ((par[0] & 0x1F) + 1) | par_low; - } - } + } else { + // No NACK. + if (nt_diff == 0 && first_try) { + par[0]++; + if (par[0] == 0) { // tried all 256 possible parities without success. Card doesn't send NACK. + isOK = -2; + break; + } + } else { + // Why this? + par[0] = ((par[0] & 0x1F) + 1) | par_low; + } + } - // reset the resyncs since we got a complete transaction on right time. - consecutive_resyncs = 0; - } // end for loop + // reset the resyncs since we got a complete transaction on right time. + consecutive_resyncs = 0; + } // end for loop - mf_nr_ar[3] &= 0x1F; + mf_nr_ar[3] &= 0x1F; - if (MF_DBGLEVEL >= 4) Dbprintf("Number of sent auth requestes: %u", i); + if (MF_DBGLEVEL >= 4) Dbprintf("Number of sent auth requestes: %u", i); - uint8_t buf[32] = {0x00}; - memset(buf, 0x00, sizeof(buf)); - num_to_bytes(cuid, 4, buf); - num_to_bytes(nt, 4, buf + 4); - memcpy(buf + 8, par_list, 8); - memcpy(buf + 16, ks_list, 8); - memcpy(buf + 24, mf_nr_ar, 8); + uint8_t buf[32] = {0x00}; + memset(buf, 0x00, sizeof(buf)); + num_to_bytes(cuid, 4, buf); + num_to_bytes(nt, 4, buf + 4); + memcpy(buf + 8, par_list, 8); + memcpy(buf + 16, ks_list, 8); + memcpy(buf + 24, mf_nr_ar, 8); - cmd_send(CMD_ACK, isOK, 0, 0, buf, sizeof(buf) ); + cmd_send(CMD_ACK, isOK, 0, 0, buf, sizeof(buf) ); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - set_tracing(false); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + set_tracing(false); } /* @@ -2697,819 +2697,820 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ) { * Thanks to @doegox for the feedback and new approaches. */ void DetectNACKbug() { - uint8_t mf_auth[] = {0x60, 0x00, 0xF5, 0x7B}; - uint8_t mf_nr_ar[] = {0,0,0,0,0,0,0,0}; - uint8_t uid[10] = {0,0,0,0,0,0,0,0,0,0}; - uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; - uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; - uint8_t par[1] = {0}; // maximum 8 Bytes to be sent here, 1 byte parity is therefore enough + uint8_t mf_auth[] = {0x60, 0x00, 0xF5, 0x7B}; + uint8_t mf_nr_ar[] = {0,0,0,0,0,0,0,0}; + uint8_t uid[10] = {0,0,0,0,0,0,0,0,0,0}; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; + uint8_t par[1] = {0}; // maximum 8 Bytes to be sent here, 1 byte parity is therefore enough - uint32_t nt = 0, previous_nt = 0, nt_attacked = 0, cuid = 0; - int32_t isOK = 0, catch_up_cycles = 0, last_catch_up = 0; - uint8_t cascade_levels = 0, num_nacks = 0; - uint16_t elapsed_prng_sequences = 1; - uint16_t consecutive_resyncs = 0; - uint16_t unexpected_random = 0; - uint16_t sync_tries = 0; - uint32_t sync_time = 0; - bool have_uid = false; - bool received_nack; + uint32_t nt = 0, previous_nt = 0, nt_attacked = 0, cuid = 0; + int32_t isOK = 0, catch_up_cycles = 0, last_catch_up = 0; + uint8_t cascade_levels = 0, num_nacks = 0; + uint16_t elapsed_prng_sequences = 1; + uint16_t consecutive_resyncs = 0; + uint16_t unexpected_random = 0; + uint16_t sync_tries = 0; + uint32_t sync_time = 0; + bool have_uid = false; + bool received_nack; - // Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces). - uint32_t sync_cycles = PRNG_SEQUENCE_LENGTH; + // Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces). + uint32_t sync_cycles = PRNG_SEQUENCE_LENGTH; - BigBuf_free(); BigBuf_Clear_ext(false); - clear_trace(); - set_tracing(true); - iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); + BigBuf_free(); BigBuf_Clear_ext(false); + clear_trace(); + set_tracing(true); + iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); - sync_time = GetCountSspClk() & 0xfffffff8; + sync_time = GetCountSspClk() & 0xfffffff8; - LED_C_ON(); - uint16_t i; - for (i = 1; true; ++i) { + LED_C_ON(); + uint16_t i; + for (i = 1; true; ++i) { - received_nack = false; + received_nack = false; - // Cards always leaks a NACK, no matter the parity - if ((i==10) && (num_nacks == i-1)) { - isOK = 2; - break; - } + // Cards always leaks a NACK, no matter the parity + if ((i==10) && (num_nacks == i-1)) { + isOK = 2; + break; + } - WDT_HIT(); + WDT_HIT(); - // Test if the action was cancelled - if (BUTTON_PRESS()) { - isOK = 99; - break; - } + // Test if the action was cancelled + if (BUTTON_PRESS()) { + isOK = 99; + break; + } - // this part is from Piwi's faster nonce collecting part in Hardnested. - if (!have_uid) { // need a full select cycle to get the uid first - iso14a_card_select_t card_info; - if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Can't select card (ALL)"); - continue; - } - switch (card_info.uidlen) { - case 4 : cascade_levels = 1; break; - case 7 : cascade_levels = 2; break; - case 10: cascade_levels = 3; break; - default: break; - } - have_uid = true; - } else { // no need for anticollision. We can directly select the card - if (!iso14443a_fast_select_card(uid, cascade_levels)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Can't select card (UID)"); - continue; - } - } + // this part is from Piwi's faster nonce collecting part in Hardnested. + if (!have_uid) { // need a full select cycle to get the uid first + iso14a_card_select_t card_info; + if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Can't select card (ALL)"); + continue; + } + switch (card_info.uidlen) { + case 4 : cascade_levels = 1; break; + case 7 : cascade_levels = 2; break; + case 10: cascade_levels = 3; break; + default: break; + } + have_uid = true; + } else { // no need for anticollision. We can directly select the card + if (!iso14443a_fast_select_card(uid, cascade_levels)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Can't select card (UID)"); + continue; + } + } - elapsed_prng_sequences = 1; + elapsed_prng_sequences = 1; - // Sending timeslot of ISO14443a frame - sync_time = (sync_time & 0xfffffff8 ) + sync_cycles + catch_up_cycles; - catch_up_cycles = 0; + // Sending timeslot of ISO14443a frame + sync_time = (sync_time & 0xfffffff8 ) + sync_cycles + catch_up_cycles; + catch_up_cycles = 0; - // if we missed the sync time already, advance to the next nonce repeat - while ( GetCountSspClk() > sync_time) { - ++elapsed_prng_sequences; - sync_time = (sync_time & 0xfffffff8 ) + sync_cycles; - } + // if we missed the sync time already, advance to the next nonce repeat + while ( GetCountSspClk() > sync_time) { + ++elapsed_prng_sequences; + sync_time = (sync_time & 0xfffffff8 ) + sync_cycles; + } - // Transmit MIFARE_CLASSIC_AUTH at synctime. Should result in returning the same tag nonce (== nt_attacked) - ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time); + // Transmit MIFARE_CLASSIC_AUTH at synctime. Should result in returning the same tag nonce (== nt_attacked) + ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time); - // Receive the (4 Byte) "random" TAG nonce - if (!ReaderReceive(receivedAnswer, receivedAnswerPar)) - continue; + // Receive the (4 Byte) "random" TAG nonce + if (!ReaderReceive(receivedAnswer, receivedAnswerPar)) + continue; - previous_nt = nt; - nt = bytes_to_num(receivedAnswer, 4); + previous_nt = nt; + nt = bytes_to_num(receivedAnswer, 4); - // Transmit reader nonce with fake par - ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL); + // Transmit reader nonce with fake par + ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL); - if (ReaderReceive(receivedAnswer, receivedAnswerPar)) { - received_nack = true; - num_nacks++; - // ALWAYS leak Detection. - if ( i == num_nacks ) { - continue; - } - } + if (ReaderReceive(receivedAnswer, receivedAnswerPar)) { + received_nack = true; + num_nacks++; + // ALWAYS leak Detection. + if ( i == num_nacks ) { + continue; + } + } - // we didn't calibrate our clock yet, - // iceman: has to be calibrated every time. - if (previous_nt && !nt_attacked) { + // we didn't calibrate our clock yet, + // iceman: has to be calibrated every time. + if (previous_nt && !nt_attacked) { - int nt_distance = dist_nt(previous_nt, nt); + int nt_distance = dist_nt(previous_nt, nt); - // if no distance between, then we are in sync. - if (nt_distance == 0) { - nt_attacked = nt; - } else { - if (nt_distance == -99999) { // invalid nonce received - unexpected_random++; - if (unexpected_random > MAX_UNEXPECTED_RANDOM ) { - // Card has an unpredictable PRNG. Give up - isOK = 98; - break; - } else { - if (sync_cycles <= 0) { - sync_cycles += PRNG_SEQUENCE_LENGTH; - } - continue; - } - } + // if no distance between, then we are in sync. + if (nt_distance == 0) { + nt_attacked = nt; + } else { + if (nt_distance == -99999) { // invalid nonce received + unexpected_random++; + if (unexpected_random > MAX_UNEXPECTED_RANDOM ) { + // Card has an unpredictable PRNG. Give up + isOK = 98; + break; + } else { + if (sync_cycles <= 0) { + sync_cycles += PRNG_SEQUENCE_LENGTH; + } + continue; + } + } - if (++sync_tries > MAX_SYNC_TRIES) { - isOK = 97; // Card's PRNG runs at an unexpected frequency or resets unexpectedly - break; - } + if (++sync_tries > MAX_SYNC_TRIES) { + isOK = 97; // Card's PRNG runs at an unexpected frequency or resets unexpectedly + break; + } - sync_cycles = (sync_cycles - nt_distance)/elapsed_prng_sequences; + sync_cycles = (sync_cycles - nt_distance)/elapsed_prng_sequences; - if (sync_cycles <= 0) - sync_cycles += PRNG_SEQUENCE_LENGTH; + if (sync_cycles <= 0) + sync_cycles += PRNG_SEQUENCE_LENGTH; - if (sync_cycles > PRNG_SEQUENCE_LENGTH * 2 ) { - isOK = 96; // Card's PRNG runs at an unexpected frequency or resets unexpectedly - break; - } + if (sync_cycles > PRNG_SEQUENCE_LENGTH * 2 ) { + isOK = 96; // Card's PRNG runs at an unexpected frequency or resets unexpectedly + break; + } - if (MF_DBGLEVEL >= 4) - Dbprintf("calibrating in cycle %d. nt_distance=%d, elapsed_prng_sequences=%d, new sync_cycles: %d\n", i, nt_distance, elapsed_prng_sequences, sync_cycles); + if (MF_DBGLEVEL >= 4) + Dbprintf("calibrating in cycle %d. nt_distance=%d, elapsed_prng_sequences=%d, new sync_cycles: %d\n", i, nt_distance, elapsed_prng_sequences, sync_cycles); - continue; - } - } + continue; + } + } - if ( (nt != nt_attacked) && nt_attacked) { - // we somehow lost sync. Try to catch up again... - catch_up_cycles = -dist_nt(nt_attacked, nt); + if ( (nt != nt_attacked) && nt_attacked) { + // we somehow lost sync. Try to catch up again... + catch_up_cycles = -dist_nt(nt_attacked, nt); - if (catch_up_cycles == 99999) { - // invalid nonce received. Don't resync on that one. - catch_up_cycles = 0; - continue; - } - // average? - catch_up_cycles /= elapsed_prng_sequences; + if (catch_up_cycles == 99999) { + // invalid nonce received. Don't resync on that one. + catch_up_cycles = 0; + continue; + } + // average? + catch_up_cycles /= elapsed_prng_sequences; - if (catch_up_cycles == last_catch_up) { - consecutive_resyncs++; - } else { - last_catch_up = catch_up_cycles; - consecutive_resyncs = 0; - } + if (catch_up_cycles == last_catch_up) { + consecutive_resyncs++; + } else { + last_catch_up = catch_up_cycles; + consecutive_resyncs = 0; + } - if (consecutive_resyncs < 3) { - if (MF_DBGLEVEL >= 4) { - Dbprintf("Lost sync in cycle %d. nt_distance=%d. Consecutive Resyncs = %d. Trying one time catch up...\n", i, catch_up_cycles, consecutive_resyncs); - } - } else { - sync_cycles += catch_up_cycles; + if (consecutive_resyncs < 3) { + if (MF_DBGLEVEL >= 4) { + Dbprintf("Lost sync in cycle %d. nt_distance=%d. Consecutive Resyncs = %d. Trying one time catch up...\n", i, catch_up_cycles, consecutive_resyncs); + } + } else { + sync_cycles += catch_up_cycles; - if (MF_DBGLEVEL >= 4) { - Dbprintf("Lost sync in cycle %d for the fourth time consecutively (nt_distance = %d). Adjusting sync_cycles to %d.\n", i, catch_up_cycles, sync_cycles); - Dbprintf("nt [%08x] attacted [%08x]", nt, nt_attacked ); - } - last_catch_up = 0; - catch_up_cycles = 0; - consecutive_resyncs = 0; - } - continue; - } + if (MF_DBGLEVEL >= 4) { + Dbprintf("Lost sync in cycle %d for the fourth time consecutively (nt_distance = %d). Adjusting sync_cycles to %d.\n", i, catch_up_cycles, sync_cycles); + Dbprintf("nt [%08x] attacted [%08x]", nt, nt_attacked ); + } + last_catch_up = 0; + catch_up_cycles = 0; + consecutive_resyncs = 0; + } + continue; + } - // Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding - if (received_nack) - catch_up_cycles = 8; // the PRNG is delayed by 8 cycles due to the NAC (4Bits = 0x05 encrypted) transfer + // Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding + if (received_nack) + catch_up_cycles = 8; // the PRNG is delayed by 8 cycles due to the NAC (4Bits = 0x05 encrypted) transfer - // we are testing all 256 possibilities. - par[0]++; + // we are testing all 256 possibilities. + par[0]++; - // tried all 256 possible parities without success. - if (par[0] == 0) { - if ( num_nacks == 1 ) - isOK = 1; - break; - } + // tried all 256 possible parities without success. + if (par[0] == 0) { + if ( num_nacks == 1 ) + isOK = 1; + break; + } - // reset the resyncs since we got a complete transaction on right time. - consecutive_resyncs = 0; - } // end for loop + // reset the resyncs since we got a complete transaction on right time. + consecutive_resyncs = 0; + } // end for loop - // num_nacks = number of nacks recieved. should be only 1. if not its a clone card which always sends NACK (parity == 0) ? - // i = number of authentications sent. Not always 256, since we are trying to sync but close to it. - cmd_send(CMD_ACK, isOK, num_nacks, i, 0, 0 ); + // num_nacks = number of nacks recieved. should be only 1. if not its a clone card which always sends NACK (parity == 0) ? + // i = number of authentications sent. Not always 256, since we are trying to sync but close to it. + cmd_send(CMD_ACK, isOK, num_nacks, i, 0, 0 ); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - set_tracing(false); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + set_tracing(false); } /** *MIFARE 1K simulate. * *@param flags : - * FLAG_INTERACTIVE - In interactive mode, we are expected to finish the operation with an ACK - * FLAG_4B_UID_IN_DATA - use 4-byte UID in the data-section - * FLAG_7B_UID_IN_DATA - use 7-byte UID in the data-section - * FLAG_10B_UID_IN_DATA - use 10-byte UID in the data-section - * FLAG_UID_IN_EMUL - use 4-byte UID from emulator memory - * FLAG_NR_AR_ATTACK - collect NR_AR responses for bruteforcing later + * FLAG_INTERACTIVE - In interactive mode, we are expected to finish the operation with an ACK + * FLAG_4B_UID_IN_DATA - use 4-byte UID in the data-section + * FLAG_7B_UID_IN_DATA - use 7-byte UID in the data-section + * FLAG_10B_UID_IN_DATA - use 10-byte UID in the data-section + * FLAG_UID_IN_EMUL - use 4-byte UID from emulator memory + * FLAG_NR_AR_ATTACK - collect NR_AR responses for bruteforcing later *@param exitAfterNReads, exit simulation after n blocks have been read, 0 is inifite * (unless reader attack mode enabled then it runs util it gets enough nonces to recover all keys attmpted) */ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *datain) { - int cardSTATE = MFEMUL_NOFIELD; - int _UID_LEN = 0; // 4, 7, 10 - int vHf = 0; // in mV - int res = 0; - uint32_t selTimer = 0; - uint32_t authTimer = 0; - uint16_t len = 0; - uint8_t cardWRBL = 0; - uint8_t cardAUTHSC = 0; - uint8_t cardAUTHKEY = 0xff; // no authentication - uint32_t cuid = 0; - uint32_t ans = 0; - uint32_t cardINTREG = 0; - uint8_t cardINTBLOCK = 0; - struct Crypto1State mpcs = {0, 0}; - struct Crypto1State *pcs; - pcs = &mpcs; - uint32_t numReads = 0; // Counts numer of times reader read a block - uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE] = {0x00}; - uint8_t receivedCmd_par[MAX_MIFARE_PARITY_SIZE] = {0x00}; - uint8_t response[MAX_MIFARE_FRAME_SIZE] = {0x00}; - uint8_t response_par[MAX_MIFARE_PARITY_SIZE] = {0x00}; + int cardSTATE = MFEMUL_NOFIELD; + int _UID_LEN = 0; // 4, 7, 10 + int vHf = 0; // in mV + int res = 0; + uint32_t selTimer = 0; + uint32_t authTimer = 0; + uint16_t len = 0; + uint8_t cardWRBL = 0; + uint8_t cardAUTHSC = 0; + uint8_t cardAUTHKEY = 0xff; // no authentication + uint32_t cuid = 0; + uint32_t ans = 0; + uint32_t cardINTREG = 0; + uint8_t cardINTBLOCK = 0; + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; + uint32_t numReads = 0; // Counts numer of times reader read a block + uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE] = {0x00}; + uint8_t receivedCmd_par[MAX_MIFARE_PARITY_SIZE] = {0x00}; + uint8_t response[MAX_MIFARE_FRAME_SIZE] = {0x00}; + uint8_t response_par[MAX_MIFARE_PARITY_SIZE] = {0x00}; - uint8_t atqa[] = {0x04, 0x00}; // Mifare classic 1k - uint8_t sak_4[] = {0x0C, 0x00, 0x00}; // CL1 - 4b uid - uint8_t sak_7[] = {0x0C, 0x00, 0x00}; // CL2 - 7b uid - uint8_t sak_10[] = {0x0C, 0x00, 0x00}; // CL3 - 10b uid - // uint8_t sak[] = {0x09, 0x3f, 0xcc }; // Mifare Mini + uint8_t atqa[] = {0x04, 0x00}; // Mifare classic 1k + uint8_t sak_4[] = {0x0C, 0x00, 0x00}; // CL1 - 4b uid + uint8_t sak_7[] = {0x0C, 0x00, 0x00}; // CL2 - 7b uid + uint8_t sak_10[] = {0x0C, 0x00, 0x00}; // CL3 - 10b uid + // uint8_t sak[] = {0x09, 0x3f, 0xcc }; // Mifare Mini - uint8_t rUIDBCC1[] = {0xde, 0xad, 0xbe, 0xaf, 0x62}; - uint8_t rUIDBCC2[] = {0xde, 0xad, 0xbe, 0xaf, 0x62}; - uint8_t rUIDBCC3[] = {0xde, 0xad, 0xbe, 0xaf, 0x62}; + uint8_t rUIDBCC1[] = {0xde, 0xad, 0xbe, 0xaf, 0x62}; + uint8_t rUIDBCC2[] = {0xde, 0xad, 0xbe, 0xaf, 0x62}; + uint8_t rUIDBCC3[] = {0xde, 0xad, 0xbe, 0xaf, 0x62}; - // TAG Nonce - Authenticate response - uint8_t rAUTH_NT[4]; - uint32_t nonce = prng_successor( GetTickCount(), 32 ); - num_to_bytes(nonce, 4, rAUTH_NT); + // TAG Nonce - Authenticate response + uint8_t rAUTH_NT[4]; + uint32_t nonce = prng_successor( GetTickCount(), 32 ); + num_to_bytes(nonce, 4, rAUTH_NT); - // uint8_t rAUTH_NT[] = {0x55, 0x41, 0x49, 0x92};// nonce from nested? why this? - uint8_t rAUTH_AT[] = {0x00, 0x00, 0x00, 0x00}; + // uint8_t rAUTH_NT[] = {0x55, 0x41, 0x49, 0x92};// nonce from nested? why this? + uint8_t rAUTH_AT[] = {0x00, 0x00, 0x00, 0x00}; - // Here, we collect CUID, NT, NR, AR, CUID2, NT2, NR2, AR2 - // This can be used in a reader-only attack. - nonces_t ar_nr_nonces[ATTACK_KEY_COUNT]; - memset(ar_nr_nonces, 0x00, sizeof(ar_nr_nonces)); + // Here, we collect CUID, NT, NR, AR, CUID2, NT2, NR2, AR2 + // This can be used in a reader-only attack. + nonces_t ar_nr_nonces[ATTACK_KEY_COUNT]; + memset(ar_nr_nonces, 0x00, sizeof(ar_nr_nonces)); - // -- Determine the UID - // Can be set from emulator memory or incoming data - // Length: 4,7,or 10 bytes - if ( (flags & FLAG_UID_IN_EMUL) == FLAG_UID_IN_EMUL) - emlGetMemBt(datain, 0, 10); // load 10bytes from EMUL to the datain pointer. to be used below. + // -- Determine the UID + // Can be set from emulator memory or incoming data + // Length: 4,7,or 10 bytes + if ( (flags & FLAG_UID_IN_EMUL) == FLAG_UID_IN_EMUL) + emlGetMemBt(datain, 0, 10); // load 10bytes from EMUL to the datain pointer. to be used below. - if ( (flags & FLAG_4B_UID_IN_DATA) == FLAG_4B_UID_IN_DATA) { - memcpy(rUIDBCC1, datain, 4); - _UID_LEN = 4; - } else if ( (flags & FLAG_7B_UID_IN_DATA) == FLAG_7B_UID_IN_DATA) { - memcpy(&rUIDBCC1[1], datain, 3); - memcpy( rUIDBCC2, datain+3, 4); - _UID_LEN = 7; - } else if ( (flags & FLAG_10B_UID_IN_DATA) == FLAG_10B_UID_IN_DATA) { - memcpy(&rUIDBCC1[1], datain, 3); - memcpy(&rUIDBCC2[1], datain+3, 3); - memcpy( rUIDBCC3, datain+6, 4); - _UID_LEN = 10; - } + if ( (flags & FLAG_4B_UID_IN_DATA) == FLAG_4B_UID_IN_DATA) { + memcpy(rUIDBCC1, datain, 4); + _UID_LEN = 4; + } else if ( (flags & FLAG_7B_UID_IN_DATA) == FLAG_7B_UID_IN_DATA) { + memcpy(&rUIDBCC1[1], datain, 3); + memcpy( rUIDBCC2, datain+3, 4); + _UID_LEN = 7; + } else if ( (flags & FLAG_10B_UID_IN_DATA) == FLAG_10B_UID_IN_DATA) { + memcpy(&rUIDBCC1[1], datain, 3); + memcpy(&rUIDBCC2[1], datain+3, 3); + memcpy( rUIDBCC3, datain+6, 4); + _UID_LEN = 10; + } - switch (_UID_LEN) { - case 4: - sak_4[0] &= 0xFB; - // save CUID - cuid = bytes_to_num(rUIDBCC1, 4); - // BCC - rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3]; - if (MF_DBGLEVEL >= 2) { - Dbprintf("4B UID: %02x%02x%02x%02x", - rUIDBCC1[0], - rUIDBCC1[1], - rUIDBCC1[2], - rUIDBCC1[3] - ); - } - break; - case 7: - atqa[0] |= 0x40; - sak_7[0] &= 0xFB; - // save CUID - cuid = bytes_to_num(rUIDBCC2, 4); - // CascadeTag, CT - rUIDBCC1[0] = 0x88; - // BCC - rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3]; - rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3]; - if (MF_DBGLEVEL >= 2) { - Dbprintf("7B UID: %02x %02x %02x %02x %02x %02x %02x", - rUIDBCC1[1], - rUIDBCC1[2], - rUIDBCC1[3], - rUIDBCC2[0], - rUIDBCC2[1], - rUIDBCC2[2], - rUIDBCC2[3] - ); - } - break; - case 10: - atqa[0] |= 0x80; - sak_10[0] &= 0xFB; - // save CUID - cuid = bytes_to_num(rUIDBCC3, 4); - // CascadeTag, CT - rUIDBCC1[0] = 0x88; - rUIDBCC2[0] = 0x88; - // BCC - rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3]; - rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3]; - rUIDBCC3[4] = rUIDBCC3[0] ^ rUIDBCC3[1] ^ rUIDBCC3[2] ^ rUIDBCC3[3]; + switch (_UID_LEN) { + case 4: + sak_4[0] &= 0xFB; + // save CUID + cuid = bytes_to_num(rUIDBCC1, 4); + // BCC + rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3]; + if (MF_DBGLEVEL >= 2) { + Dbprintf("4B UID: %02x%02x%02x%02x", + rUIDBCC1[0], + rUIDBCC1[1], + rUIDBCC1[2], + rUIDBCC1[3] + ); + } + break; + case 7: + atqa[0] |= 0x40; + sak_7[0] &= 0xFB; + // save CUID + cuid = bytes_to_num(rUIDBCC2, 4); + // CascadeTag, CT + rUIDBCC1[0] = 0x88; + // BCC + rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3]; + rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3]; + if (MF_DBGLEVEL >= 2) { + Dbprintf("7B UID: %02x %02x %02x %02x %02x %02x %02x", + rUIDBCC1[1], + rUIDBCC1[2], + rUIDBCC1[3], + rUIDBCC2[0], + rUIDBCC2[1], + rUIDBCC2[2], + rUIDBCC2[3] + ); + } + break; + case 10: + atqa[0] |= 0x80; + sak_10[0] &= 0xFB; + // save CUID + cuid = bytes_to_num(rUIDBCC3, 4); + // CascadeTag, CT + rUIDBCC1[0] = 0x88; + rUIDBCC2[0] = 0x88; + // BCC + rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3]; + rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3]; + rUIDBCC3[4] = rUIDBCC3[0] ^ rUIDBCC3[1] ^ rUIDBCC3[2] ^ rUIDBCC3[3]; - if (MF_DBGLEVEL >= 2) { - Dbprintf("10B UID: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", - rUIDBCC1[1], - rUIDBCC1[2], - rUIDBCC1[3], - rUIDBCC2[1], - rUIDBCC2[2], - rUIDBCC2[3], - rUIDBCC3[0], - rUIDBCC3[1], - rUIDBCC3[2], - rUIDBCC3[3] - ); - } - break; - default: - break; - } - // calc some crcs - compute_crc(CRC_14443_A, sak_4, 1, &sak_4[1], &sak_4[2]); - compute_crc(CRC_14443_A, sak_7, 1, &sak_7[1], &sak_7[2]); - compute_crc(CRC_14443_A, sak_10, 1, &sak_10[1], &sak_10[2]); + if (MF_DBGLEVEL >= 2) { + Dbprintf("10B UID: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", + rUIDBCC1[1], + rUIDBCC1[2], + rUIDBCC1[3], + rUIDBCC2[1], + rUIDBCC2[2], + rUIDBCC2[3], + rUIDBCC3[0], + rUIDBCC3[1], + rUIDBCC3[2], + rUIDBCC3[3] + ); + } + break; + default: + break; + } + // calc some crcs + compute_crc(CRC_14443_A, sak_4, 1, &sak_4[1], &sak_4[2]); + compute_crc(CRC_14443_A, sak_7, 1, &sak_7[1], &sak_7[2]); + compute_crc(CRC_14443_A, sak_10, 1, &sak_10[1], &sak_10[2]); - // We need to listen to the high-frequency, peak-detected path. - iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN); + // We need to listen to the high-frequency, peak-detected path. + iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN); - // free eventually allocated BigBuf memory but keep Emulator Memory - BigBuf_free_keep_EM(); - clear_trace(); - set_tracing(true); - LED_D_ON(); + // free eventually allocated BigBuf memory but keep Emulator Memory + BigBuf_free_keep_EM(); + clear_trace(); + set_tracing(true); + LED_D_ON(); - bool finished = false; - while (!BUTTON_PRESS() && !finished && !usb_poll_validate_length()) { - WDT_HIT(); + bool finished = false; + while (!BUTTON_PRESS() && !finished && !usb_poll_validate_length()) { + WDT_HIT(); - // find reader field - if (cardSTATE == MFEMUL_NOFIELD) { + // find reader field + if (cardSTATE == MFEMUL_NOFIELD) { - vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; - if (vHf > MF_MINFIELDV) { - cardSTATE_TO_IDLE(); - LED_A_ON(); - } - } - if (cardSTATE == MFEMUL_NOFIELD) continue; + vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; + if (vHf > MF_MINFIELDV) { + cardSTATE_TO_IDLE(); + LED_A_ON(); + } + } + if (cardSTATE == MFEMUL_NOFIELD) continue; - // Now, get data - res = EmGetCmd(receivedCmd, &len, receivedCmd_par); - if (res == 2) { //Field is off! - cardSTATE = MFEMUL_NOFIELD; - LEDsoff(); - continue; - } else if (res == 1) { - break; // return value 1 means button press - } + // Now, get data + res = EmGetCmd(receivedCmd, &len, receivedCmd_par); + if (res == 2) { //Field is off! + cardSTATE = MFEMUL_NOFIELD; + LEDsoff(); + continue; + } else if (res == 1) { + break; // return value 1 means button press + } - // REQ or WUP request in ANY state and WUP in HALTED state - // this if-statement doesn't match the specification above. (iceman) - if (len == 1 && ((receivedCmd[0] == ISO14443A_CMD_REQA && cardSTATE != MFEMUL_HALTED) || receivedCmd[0] == ISO14443A_CMD_WUPA)) { - selTimer = GetTickCount(); - EmSendCmd(atqa, sizeof(atqa)); - cardSTATE = MFEMUL_SELECT1; - crypto1_destroy(pcs); - cardAUTHKEY = 0xff; - nonce = prng_successor(selTimer, 32); - continue; - } + // REQ or WUP request in ANY state and WUP in HALTED state + // this if-statement doesn't match the specification above. (iceman) + if (len == 1 && ((receivedCmd[0] == ISO14443A_CMD_REQA && cardSTATE != MFEMUL_HALTED) || receivedCmd[0] == ISO14443A_CMD_WUPA)) { + selTimer = GetTickCount(); + EmSendCmd(atqa, sizeof(atqa)); + cardSTATE = MFEMUL_SELECT1; + crypto1_destroy(pcs); + cardAUTHKEY = 0xff; + nonce = prng_successor(selTimer, 32); + continue; + } - switch (cardSTATE) { - case MFEMUL_NOFIELD: - case MFEMUL_HALTED: - case MFEMUL_IDLE:{ - LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); - break; - } - case MFEMUL_SELECT1:{ - if (len == 2 && (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && receivedCmd[1] == 0x20)) { - if (MF_DBGLEVEL >= 4) Dbprintf("SELECT ALL received"); - EmSendCmd(rUIDBCC1, sizeof(rUIDBCC1)); - break; - } - // select card - if (len == 9 && - ( receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && - receivedCmd[1] == 0x70 && - memcmp(&receivedCmd[2], rUIDBCC1, 4) == 0)) { + switch (cardSTATE) { + case MFEMUL_NOFIELD: + case MFEMUL_HALTED: + case MFEMUL_IDLE:{ + LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + break; + } + case MFEMUL_SELECT1:{ + if (len == 2 && (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && receivedCmd[1] == 0x20)) { + if (MF_DBGLEVEL >= 4) Dbprintf("SELECT ALL received"); + EmSendCmd(rUIDBCC1, sizeof(rUIDBCC1)); + break; + } + // select card + if (len == 9 && + ( receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && + receivedCmd[1] == 0x70 && + memcmp(&receivedCmd[2], rUIDBCC1, 4) == 0)) { - // SAK 4b - EmSendCmd(sak_4, sizeof(sak_4)); - switch(_UID_LEN){ - case 4: - cardSTATE = MFEMUL_WORK; - LED_B_ON(); - if (MF_DBGLEVEL >= 4) Dbprintf("--> WORK. anticol1 time: %d", GetTickCount() - selTimer); - continue; - case 7: - case 10: - cardSTATE = MFEMUL_SELECT2; - continue; - default:break; - } - } else { - cardSTATE_TO_IDLE(); - } - break; - } - case MFEMUL_SELECT2:{ - if (!len) { - LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); - break; - } - if (len == 2 && (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 && receivedCmd[1] == 0x20)) { - EmSendCmd(rUIDBCC2, sizeof(rUIDBCC2)); - break; - } - if (len == 9 && - (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 && - receivedCmd[1] == 0x70 && - memcmp(&receivedCmd[2], rUIDBCC2, 4) == 0) ) { + // SAK 4b + EmSendCmd(sak_4, sizeof(sak_4)); + switch(_UID_LEN){ + case 4: + cardSTATE = MFEMUL_WORK; + LED_B_ON(); + if (MF_DBGLEVEL >= 4) Dbprintf("--> WORK. anticol1 time: %d", GetTickCount() - selTimer); + continue; + case 7: + case 10: + cardSTATE = MFEMUL_SELECT2; + continue; + default:break; + } + } else { + cardSTATE_TO_IDLE(); + } + break; + } + case MFEMUL_SELECT2:{ + if (!len) { + LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + break; + } + if (len == 2 && (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 && receivedCmd[1] == 0x20)) { + EmSendCmd(rUIDBCC2, sizeof(rUIDBCC2)); + break; + } + if (len == 9 && + (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 && + receivedCmd[1] == 0x70 && + memcmp(&receivedCmd[2], rUIDBCC2, 4) == 0) ) { - EmSendCmd(sak_7, sizeof(sak_7)); - switch(_UID_LEN){ - case 7: - cardSTATE = MFEMUL_WORK; - LED_B_ON(); - if (MF_DBGLEVEL >= 4) Dbprintf("--> WORK. anticol2 time: %d", GetTickCount() - selTimer); - continue; - case 10: - cardSTATE = MFEMUL_SELECT3; - continue; - default:break; - } - } - cardSTATE_TO_IDLE(); - break; - } - case MFEMUL_SELECT3:{ - if (!len) { - LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); - break; - } - if (len == 2 && (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3 && receivedCmd[1] == 0x20)) { - EmSendCmd(rUIDBCC3, sizeof(rUIDBCC3)); - break; - } - if (len == 9 && - (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3 && - receivedCmd[1] == 0x70 && - memcmp(&receivedCmd[2], rUIDBCC3, 4) == 0) ) { + EmSendCmd(sak_7, sizeof(sak_7)); + switch(_UID_LEN){ + case 7: + cardSTATE = MFEMUL_WORK; + LED_B_ON(); + if (MF_DBGLEVEL >= 4) Dbprintf("--> WORK. anticol2 time: %d", GetTickCount() - selTimer); + continue; + case 10: + cardSTATE = MFEMUL_SELECT3; + continue; + default:break; + } + } + cardSTATE_TO_IDLE(); + break; + } + case MFEMUL_SELECT3:{ + if (!len) { + LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + break; + } + if (len == 2 && (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3 && receivedCmd[1] == 0x20)) { + EmSendCmd(rUIDBCC3, sizeof(rUIDBCC3)); + break; + } + if (len == 9 && + (receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3 && + receivedCmd[1] == 0x70 && + memcmp(&receivedCmd[2], rUIDBCC3, 4) == 0) ) { - EmSendCmd(sak_10, sizeof(sak_10)); - cardSTATE = MFEMUL_WORK; - LED_B_ON(); - if (MF_DBGLEVEL >= 4) Dbprintf("--> WORK. anticol3 time: %d", GetTickCount() - selTimer); - break; - } - cardSTATE_TO_IDLE(); - break; - } - case MFEMUL_AUTH1:{ - if( len != 8) { - cardSTATE_TO_IDLE(); - LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); - break; - } + EmSendCmd(sak_10, sizeof(sak_10)); + cardSTATE = MFEMUL_WORK; + LED_B_ON(); + if (MF_DBGLEVEL >= 4) Dbprintf("--> WORK. anticol3 time: %d", GetTickCount() - selTimer); + break; + } + cardSTATE_TO_IDLE(); + break; + } + case MFEMUL_AUTH1:{ + if( len != 8) { + cardSTATE_TO_IDLE(); + LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + break; + } - uint32_t nr = bytes_to_num(receivedCmd, 4); - uint32_t ar = bytes_to_num(&receivedCmd[4], 4); + uint32_t nr = bytes_to_num(receivedCmd, 4); + uint32_t ar = bytes_to_num(&receivedCmd[4], 4); - // Collect AR/NR per keytype & sector - if ( (flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK ) { + // Collect AR/NR per keytype & sector + if ( (flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK ) { - int8_t index = -1; - int8_t empty = -1; - for (uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) { - // find which index to use - if ( (cardAUTHSC == ar_nr_nonces[i].sector) && (cardAUTHKEY == ar_nr_nonces[i].keytype)) - index = i; + int8_t index = -1; + int8_t empty = -1; + for (uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) { + // find which index to use + if ( (cardAUTHSC == ar_nr_nonces[i].sector) && (cardAUTHKEY == ar_nr_nonces[i].keytype)) + index = i; - // keep track of empty slots. - if ( ar_nr_nonces[i].state == EMPTY) - empty = i; - } - // if no empty slots. Choose first and overwrite. - if ( index == -1 ) { - if ( empty == -1 ) { - index = 0; - ar_nr_nonces[index].state = EMPTY; - } else { - index = empty; - } - } + // keep track of empty slots. + if ( ar_nr_nonces[i].state == EMPTY) + empty = i; + } + // if no empty slots. Choose first and overwrite. + if ( index == -1 ) { + if ( empty == -1 ) { + index = 0; + ar_nr_nonces[index].state = EMPTY; + } else { + index = empty; + } + } - switch(ar_nr_nonces[index].state) { - case EMPTY: { - // first nonce collect - ar_nr_nonces[index].cuid = cuid; - ar_nr_nonces[index].sector = cardAUTHSC; - ar_nr_nonces[index].keytype = cardAUTHKEY; - ar_nr_nonces[index].nonce = nonce; - ar_nr_nonces[index].nr = nr; - ar_nr_nonces[index].ar = ar; - ar_nr_nonces[index].state = FIRST; - break; - } - case FIRST : { - // second nonce collect - ar_nr_nonces[index].nonce2 = nonce; - ar_nr_nonces[index].nr2 = nr; - ar_nr_nonces[index].ar2 = ar; - ar_nr_nonces[index].state = SECOND; + switch(ar_nr_nonces[index].state) { + case EMPTY: { + // first nonce collect + ar_nr_nonces[index].cuid = cuid; + ar_nr_nonces[index].sector = cardAUTHSC; + ar_nr_nonces[index].keytype = cardAUTHKEY; + ar_nr_nonces[index].nonce = nonce; + ar_nr_nonces[index].nr = nr; + ar_nr_nonces[index].ar = ar; + ar_nr_nonces[index].state = FIRST; + break; + } + case FIRST : { + // second nonce collect + ar_nr_nonces[index].nonce2 = nonce; + ar_nr_nonces[index].nr2 = nr; + ar_nr_nonces[index].ar2 = ar; + ar_nr_nonces[index].state = SECOND; - // send to client - cmd_send(CMD_ACK, CMD_SIMULATE_MIFARE_CARD, 0, 0, &ar_nr_nonces[index], sizeof(nonces_t)); + // send to client + cmd_send(CMD_ACK, CMD_SIMULATE_MIFARE_CARD, 0, 0, &ar_nr_nonces[index], sizeof(nonces_t)); - ar_nr_nonces[index].state = EMPTY; - ar_nr_nonces[index].sector = 0; - ar_nr_nonces[index].keytype = 0; - break; - } - default: break; - } - } + ar_nr_nonces[index].state = EMPTY; + ar_nr_nonces[index].sector = 0; + ar_nr_nonces[index].keytype = 0; + break; + } + default: break; + } + } - crypto1_word(pcs, nr , 1); - uint32_t cardRr = ar ^ crypto1_word(pcs, 0, 0); + crypto1_word(pcs, nr , 1); + uint32_t cardRr = ar ^ crypto1_word(pcs, 0, 0); - //test if auth OK - if (cardRr != prng_successor(nonce, 64)){ + //test if auth OK + if (cardRr != prng_successor(nonce, 64)){ - if (MF_DBGLEVEL >= 3) { - Dbprintf("AUTH FAILED for sector %d with key %c. [nr=%08x cardRr=%08x] [nt=%08x succ=%08x]" - , cardAUTHSC - , (cardAUTHKEY == 0) ? 'A' : 'B' - , nr - , cardRr - , nonce // nt - , prng_successor(nonce, 64) - ); - } - // Shouldn't we respond anything here? - // Right now, we don't nack or anything, which causes the - // reader to do a WUPA after a while. /Martin - // -- which is the correct response. /piwi - cardSTATE_TO_IDLE(); - LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); - break; - } + if (MF_DBGLEVEL >= 3) { + Dbprintf("AUTH FAILED for sector %d with key %c. [nr=%08x cardRr=%08x] [nt=%08x succ=%08x]" + , cardAUTHSC + , (cardAUTHKEY == 0) ? 'A' : 'B' + , nr + , cardRr + , nonce // nt + , prng_successor(nonce, 64) + ); + } + // Shouldn't we respond anything here? + // Right now, we don't nack or anything, which causes the + // reader to do a WUPA after a while. /Martin + // -- which is the correct response. /piwi + cardSTATE_TO_IDLE(); + LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + break; + } - ans = prng_successor(nonce, 96) ^ crypto1_word(pcs, 0, 0); - num_to_bytes(ans, 4, rAUTH_AT); - EmSendCmd(rAUTH_AT, sizeof(rAUTH_AT)); - LED_C_ON(); + ans = prng_successor(nonce, 96) ^ crypto1_word(pcs, 0, 0); + num_to_bytes(ans, 4, rAUTH_AT); + EmSendCmd(rAUTH_AT, sizeof(rAUTH_AT)); + LED_C_ON(); - if (MF_DBGLEVEL >= 3) { - Dbprintf("AUTH COMPLETED for sector %d with key %c. time=%d", - cardAUTHSC, - cardAUTHKEY == 0 ? 'A' : 'B', - GetTickCount() - authTimer - ); - } - cardSTATE = MFEMUL_WORK; - break; - } - case MFEMUL_WORK:{ - if (len == 0) { - LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); - break; - } - bool encrypted_data = (cardAUTHKEY != 0xFF) ; + if (MF_DBGLEVEL >= 3) { + Dbprintf("AUTH COMPLETED for sector %d with key %c. time=%d", + cardAUTHSC, + cardAUTHKEY == 0 ? 'A' : 'B', + GetTickCount() - authTimer + ); + } + cardSTATE = MFEMUL_WORK; + break; + } + case MFEMUL_WORK:{ + if (len == 0) { + LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + break; + } + bool encrypted_data = (cardAUTHKEY != 0xFF) ; - if(encrypted_data) - mf_crypto1_decrypt(pcs, receivedCmd, len); + if(encrypted_data) + mf_crypto1_decrypt(pcs, receivedCmd, len); - if (len == 4 && (receivedCmd[0] == MIFARE_AUTH_KEYA || - receivedCmd[0] == MIFARE_AUTH_KEYB) ) { + if (len == 4 && (receivedCmd[0] == MIFARE_AUTH_KEYA || + receivedCmd[0] == MIFARE_AUTH_KEYB) ) { - authTimer = GetTickCount(); - cardAUTHSC = receivedCmd[1] / 4; // received block -> sector - cardAUTHKEY = receivedCmd[0] & 0x1; - crypto1_destroy(pcs); + authTimer = GetTickCount(); + cardAUTHSC = receivedCmd[1] / 4; // received block -> sector + cardAUTHKEY = receivedCmd[0] & 0x1; + crypto1_destroy(pcs); - // load key into crypto - crypto1_create(pcs, emlGetKey(cardAUTHSC, cardAUTHKEY)); + // load key into crypto + crypto1_create(pcs, emlGetKey(cardAUTHSC, cardAUTHKEY)); - if (!encrypted_data) { - // first authentication - // Update crypto state init (UID ^ NONCE) - crypto1_word(pcs, cuid ^ nonce, 0); - num_to_bytes(nonce, 4, rAUTH_AT); - } else { - // nested authentication - ans = nonce ^ crypto1_word(pcs, cuid ^ nonce, 0); - num_to_bytes(ans, 4, rAUTH_AT); + if (!encrypted_data) { + // first authentication + // Update crypto state init (UID ^ NONCE) + crypto1_word(pcs, cuid ^ nonce, 0); + num_to_bytes(nonce, 4, rAUTH_AT); + } else { + // nested authentication + ans = nonce ^ crypto1_word(pcs, cuid ^ nonce, 0); + num_to_bytes(ans, 4, rAUTH_AT); - if (MF_DBGLEVEL >= 3) Dbprintf("Reader doing nested authentication for block %d (0x%02x) with key %c", receivedCmd[1], receivedCmd[1], cardAUTHKEY == 0 ? 'A' : 'B'); - } + if (MF_DBGLEVEL >= 3) Dbprintf("Reader doing nested authentication for block %d (0x%02x) with key %c", receivedCmd[1], receivedCmd[1], cardAUTHKEY == 0 ? 'A' : 'B'); + } - EmSendCmd(rAUTH_AT, sizeof(rAUTH_AT)); - cardSTATE = MFEMUL_AUTH1; - break; - } + EmSendCmd(rAUTH_AT, sizeof(rAUTH_AT)); + cardSTATE = MFEMUL_AUTH1; + break; + } - // rule 13 of 7.5.3. in ISO 14443-4. chaining shall be continued - // BUT... ACK --> NACK - if (len == 1 && receivedCmd[0] == CARD_ACK) { - EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); - break; - } + // rule 13 of 7.5.3. in ISO 14443-4. chaining shall be continued + // BUT... ACK --> NACK + if (len == 1 && receivedCmd[0] == CARD_ACK) { + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + break; + } - // rule 12 of 7.5.3. in ISO 14443-4. R(NAK) --> R(ACK) - if (len == 1 && receivedCmd[0] == CARD_NACK_NA) { - EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); - break; - } + // rule 12 of 7.5.3. in ISO 14443-4. R(NAK) --> R(ACK) + if (len == 1 && receivedCmd[0] == CARD_NACK_NA) { + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); + break; + } - if(len != 4) { - LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); - break; - } + if(len != 4) { + LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + break; + } - if ( receivedCmd[0] == ISO14443A_CMD_READBLOCK || - receivedCmd[0] == ISO14443A_CMD_WRITEBLOCK || - receivedCmd[0] == MIFARE_CMD_INC || - receivedCmd[0] == MIFARE_CMD_DEC || - receivedCmd[0] == MIFARE_CMD_RESTORE || - receivedCmd[0] == MIFARE_CMD_TRANSFER ) { + if ( receivedCmd[0] == ISO14443A_CMD_READBLOCK || + receivedCmd[0] == ISO14443A_CMD_WRITEBLOCK || + receivedCmd[0] == MIFARE_CMD_INC || + receivedCmd[0] == MIFARE_CMD_DEC || + receivedCmd[0] == MIFARE_CMD_RESTORE || + receivedCmd[0] == MIFARE_CMD_TRANSFER ) { - if (receivedCmd[1] >= 16 * 4) { - EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); - if (MF_DBGLEVEL >= 4) Dbprintf("Reader tried to operate (0x%02) on out of range block: %d (0x%02x), nacking",receivedCmd[0],receivedCmd[1],receivedCmd[1]); - break; - } + if (receivedCmd[1] >= 16 * 4) { + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + if (MF_DBGLEVEL >= 4) Dbprintf("Reader tried to operate (0x%02) on out of range block: %d (0x%02x), nacking",receivedCmd[0],receivedCmd[1],receivedCmd[1]); + break; + } - if (receivedCmd[1] / 4 != cardAUTHSC) { - EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); - if (MF_DBGLEVEL >= 4) Dbprintf("Reader tried to operate (0x%02) on block (0x%02x) not authenticated for (0x%02x), nacking",receivedCmd[0],receivedCmd[1],cardAUTHSC); - break; - } - } - // read block - if (receivedCmd[0] == ISO14443A_CMD_READBLOCK) { - if (MF_DBGLEVEL >= 4) Dbprintf("Reader reading block %d (0x%02x)", receivedCmd[1], receivedCmd[1]); + if (receivedCmd[1] / 4 != cardAUTHSC) { + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + if (MF_DBGLEVEL >= 4) Dbprintf("Reader tried to operate (0x%02) on block (0x%02x) not authenticated for (0x%02x), nacking",receivedCmd[0],receivedCmd[1],cardAUTHSC); + break; + } + } + // read block + if (receivedCmd[0] == ISO14443A_CMD_READBLOCK) { + if (MF_DBGLEVEL >= 4) Dbprintf("Reader reading block %d (0x%02x)", receivedCmd[1], receivedCmd[1]); - emlGetMem(response, receivedCmd[1], 1); - AddCrc14A(response, 16); - mf_crypto1_encrypt(pcs, response, 18, response_par); - EmSendCmdPar(response, 18, response_par); - numReads++; - if(exitAfterNReads > 0 && numReads >= exitAfterNReads) { - Dbprintf("%d reads done, exiting", numReads); - finished = true; - } - break; - } - // write block - if (receivedCmd[0] == ISO14443A_CMD_WRITEBLOCK) { - 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]; - break; - } - // increment, decrement, restore - if ( receivedCmd[0] == MIFARE_CMD_INC || - receivedCmd[0] == MIFARE_CMD_DEC || - receivedCmd[0] == MIFARE_CMD_RESTORE) { + emlGetMem(response, receivedCmd[1], 1); + AddCrc14A(response, 16); + mf_crypto1_encrypt(pcs, response, 18, response_par); + EmSendCmdPar(response, 18, response_par); + numReads++; + if(exitAfterNReads > 0 && numReads >= exitAfterNReads) { + Dbprintf("%d reads done, exiting", numReads); + finished = true; + } + break; + } + // write block + if (receivedCmd[0] == ISO14443A_CMD_WRITEBLOCK) { + 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]; + break; + } + // increment, decrement, restore + if ( receivedCmd[0] == MIFARE_CMD_INC || + receivedCmd[0] == MIFARE_CMD_DEC || + receivedCmd[0] == MIFARE_CMD_RESTORE) { - if (MF_DBGLEVEL >= 4) 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 >= 4) Dbprintf("Reader tried to operate on block, but emlCheckValBl failed, nacking"); - EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); - break; - } - EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); - if (receivedCmd[0] == MIFARE_CMD_INC) cardSTATE = MFEMUL_INTREG_INC; - if (receivedCmd[0] == MIFARE_CMD_DEC) cardSTATE = MFEMUL_INTREG_DEC; - if (receivedCmd[0] == MIFARE_CMD_RESTORE) cardSTATE = MFEMUL_INTREG_REST; - cardWRBL = receivedCmd[1]; - break; - } - // transfer - if (receivedCmd[0] == MIFARE_CMD_TRANSFER) { - 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 - EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); - break; - } - // halt - if (receivedCmd[0] == ISO14443A_CMD_HALT && receivedCmd[1] == 0x00) { - LED_B_OFF(); - LED_C_OFF(); - cardSTATE = MFEMUL_HALTED; - if (MF_DBGLEVEL >= 4) Dbprintf("--> HALTED. Selected time: %d ms", GetTickCount() - selTimer); - LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); - break; - } - // RATS - if (receivedCmd[0] == ISO14443A_CMD_RATS) { - EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); - break; - } - // command not allowed - if (MF_DBGLEVEL >= 4) Dbprintf("Received command not allowed, nacking"); - EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); - break; - } - case MFEMUL_WRITEBL2:{ - if (len == 18) { - mf_crypto1_decrypt(pcs, receivedCmd, len); - emlSetMem(receivedCmd, cardWRBL, 1); - EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); - cardSTATE = MFEMUL_WORK; - } else { - cardSTATE_TO_IDLE(); - LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); - } - break; - } - case MFEMUL_INTREG_INC:{ - mf_crypto1_decrypt(pcs, receivedCmd, len); - memcpy(&ans, receivedCmd, 4); - if (emlGetValBl(&cardINTREG, &cardINTBLOCK, cardWRBL)) { - EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); - cardSTATE_TO_IDLE(); - break; - } - LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); - cardINTREG = cardINTREG + ans; - cardSTATE = MFEMUL_WORK; - break; - } - case MFEMUL_INTREG_DEC:{ - mf_crypto1_decrypt(pcs, receivedCmd, len); - memcpy(&ans, receivedCmd, 4); - if (emlGetValBl(&cardINTREG, &cardINTBLOCK, cardWRBL)) { - EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); - cardSTATE_TO_IDLE(); - break; - } - LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); - cardINTREG = cardINTREG - ans; - cardSTATE = MFEMUL_WORK; - break; - } - case MFEMUL_INTREG_REST:{ - mf_crypto1_decrypt(pcs, receivedCmd, len); - memcpy(&ans, receivedCmd, 4); - if (emlGetValBl(&cardINTREG, &cardINTBLOCK, cardWRBL)) { - EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); - cardSTATE_TO_IDLE(); - break; - } - LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); - cardSTATE = MFEMUL_WORK; - break; - } - } - } + if (emlCheckValBl(receivedCmd[1])) { + if (MF_DBGLEVEL >= 4) Dbprintf("Reader tried to operate on block, but emlCheckValBl failed, nacking"); + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + break; + } + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); + if (receivedCmd[0] == MIFARE_CMD_INC) cardSTATE = MFEMUL_INTREG_INC; + if (receivedCmd[0] == MIFARE_CMD_DEC) cardSTATE = MFEMUL_INTREG_DEC; + if (receivedCmd[0] == MIFARE_CMD_RESTORE) cardSTATE = MFEMUL_INTREG_REST; + cardWRBL = receivedCmd[1]; + break; + } + // transfer + if (receivedCmd[0] == MIFARE_CMD_TRANSFER) { + 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 + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); + break; + } + // halt + if (receivedCmd[0] == ISO14443A_CMD_HALT && receivedCmd[1] == 0x00) { + LED_B_OFF(); + LED_C_OFF(); + cardSTATE = MFEMUL_HALTED; + if (MF_DBGLEVEL >= 4) Dbprintf("--> HALTED. Selected time: %d ms", GetTickCount() - selTimer); + LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + break; + } + // RATS + if (receivedCmd[0] == ISO14443A_CMD_RATS) { + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + break; + } + // command not allowed + if (MF_DBGLEVEL >= 4) Dbprintf("Received command not allowed, nacking"); + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + break; + } + case MFEMUL_WRITEBL2:{ + if (len == 18) { + mf_crypto1_decrypt(pcs, receivedCmd, len); + emlSetMem(receivedCmd, cardWRBL, 1); + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); + cardSTATE = MFEMUL_WORK; + } else { + cardSTATE_TO_IDLE(); + LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + } + break; + } + case MFEMUL_INTREG_INC:{ + mf_crypto1_decrypt(pcs, receivedCmd, len); + memcpy(&ans, receivedCmd, 4); + if (emlGetValBl(&cardINTREG, &cardINTBLOCK, cardWRBL)) { + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + cardSTATE_TO_IDLE(); + break; + } + LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + cardINTREG = cardINTREG + ans; + cardSTATE = MFEMUL_WORK; + break; + } + case MFEMUL_INTREG_DEC:{ + mf_crypto1_decrypt(pcs, receivedCmd, len); + memcpy(&ans, receivedCmd, 4); + if (emlGetValBl(&cardINTREG, &cardINTBLOCK, cardWRBL)) { + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + cardSTATE_TO_IDLE(); + break; + } + LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + cardINTREG = cardINTREG - ans; + cardSTATE = MFEMUL_WORK; + break; + } + case MFEMUL_INTREG_REST:{ + mf_crypto1_decrypt(pcs, receivedCmd, len); + memcpy(&ans, receivedCmd, 4); + if (emlGetValBl(&cardINTREG, &cardINTBLOCK, cardWRBL)) { + EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); + cardSTATE_TO_IDLE(); + break; + } + LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); + cardSTATE = MFEMUL_WORK; + break; + } + } + } - if (MF_DBGLEVEL >= 1) - Dbprintf("Emulator stopped. Trace length: %d ", BigBuf_get_traceLen()); + if (MF_DBGLEVEL >= 1) + Dbprintf("Emulator stopped. Trace length: %d ", BigBuf_get_traceLen()); - cmd_send(CMD_ACK,1,0,0,0,0); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - set_tracing(false); + cmd_send(CMD_ACK,1,0,0,0,0); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + set_tracing(false); } diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index c5e1e62f1..38d0b99e1 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -31,66 +31,66 @@ extern "C" { #include "mifare.h" // structs typedef struct { - enum { - DEMOD_UNSYNCD, - // DEMOD_HALF_SYNCD, - // DEMOD_MOD_FIRST_HALF, - // DEMOD_NOMOD_FIRST_HALF, - DEMOD_MANCHESTER_DATA - } state; - uint16_t twoBits; - uint16_t highCnt; - uint16_t bitCount; - uint16_t collisionPos; - uint16_t syncBit; - uint8_t parityBits; - uint8_t parityLen; - uint16_t shiftReg; - uint16_t samples; - uint16_t len; - uint32_t startTime, endTime; - uint8_t *output; - uint8_t *parity; + enum { + DEMOD_UNSYNCD, + // DEMOD_HALF_SYNCD, + // DEMOD_MOD_FIRST_HALF, + // DEMOD_NOMOD_FIRST_HALF, + DEMOD_MANCHESTER_DATA + } state; + uint16_t twoBits; + uint16_t highCnt; + uint16_t bitCount; + uint16_t collisionPos; + uint16_t syncBit; + uint8_t parityBits; + uint8_t parityLen; + uint16_t shiftReg; + uint16_t samples; + uint16_t len; + uint32_t startTime, endTime; + uint8_t *output; + uint8_t *parity; } tDemod; /* typedef enum { - MOD_NOMOD = 0, - MOD_SECOND_HALF, - MOD_FIRST_HALF, - MOD_BOTH_HALVES - } Modulation_t; + MOD_NOMOD = 0, + MOD_SECOND_HALF, + MOD_FIRST_HALF, + MOD_BOTH_HALVES + } Modulation_t; */ typedef struct { - enum { - STATE_UNSYNCD, - STATE_START_OF_COMMUNICATION, - STATE_MILLER_X, - STATE_MILLER_Y, - STATE_MILLER_Z, - // DROP_NONE, - // DROP_FIRST_HALF, - } state; - uint16_t shiftReg; - int16_t bitCount; - uint16_t len; - //uint16_t byteCntMax; - uint16_t posCnt; - uint16_t syncBit; - uint8_t parityBits; - uint8_t parityLen; - uint32_t fourBits; - uint32_t startTime, endTime; + enum { + STATE_UNSYNCD, + STATE_START_OF_COMMUNICATION, + STATE_MILLER_X, + STATE_MILLER_Y, + STATE_MILLER_Z, + // DROP_NONE, + // DROP_FIRST_HALF, + } state; + uint16_t shiftReg; + int16_t bitCount; + uint16_t len; + //uint16_t byteCntMax; + uint16_t posCnt; + uint16_t syncBit; + uint8_t parityBits; + uint8_t parityLen; + uint32_t fourBits; + uint32_t startTime, endTime; uint8_t *output; - uint8_t *parity; + uint8_t *parity; } tUart; #ifndef AddCrc14A -# define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1) +# define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1) #endif #ifndef AddCrc14B -# define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1) +# define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1) #endif extern void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par); @@ -129,7 +129,7 @@ extern int EmSendCmdParEx(uint8_t *resp, uint16_t respLen, uint8_t *par, bool co extern int EmSendPrecompiledCmd(tag_response_info_t *response_info); bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint8_t *reader_Parity, - uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity); + uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity); //extern bool prepare_allocated_tag_modulation(tag_response_info_t *response_info, uint8_t **buffer, size_t *buffer_size); diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index f093fb1a7..2e2aec7cd 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -40,7 +40,7 @@ //#define SEND4STUFFBIT(x) ToSendStuffBit(x); // iceman, this threshold value, what makes 8 a good amplitude for this IQ values? #ifndef SUBCARRIER_DETECT_THRESHOLD -# define SUBCARRIER_DETECT_THRESHOLD 8 +# define SUBCARRIER_DETECT_THRESHOLD 8 #endif static void iso14b_set_timeout(uint32_t timeout); @@ -63,80 +63,80 @@ static uint32_t iso14b_timeout = FWT_TIMEOUT_14B; // The software UART that receives commands from the reader, and its state variables. //----------------------------------------------------------------------------- static struct { - enum { - STATE_UNSYNCD, - STATE_GOT_FALLING_EDGE_OF_SOF, - STATE_AWAITING_START_BIT, - STATE_RECEIVING_DATA - } state; - uint16_t shiftReg; - int bitCnt; - int byteCnt; - int byteCntMax; - int posCnt; - uint8_t *output; + enum { + STATE_UNSYNCD, + STATE_GOT_FALLING_EDGE_OF_SOF, + STATE_AWAITING_START_BIT, + STATE_RECEIVING_DATA + } state; + uint16_t shiftReg; + int bitCnt; + int byteCnt; + int byteCntMax; + int posCnt; + uint8_t *output; } Uart; static void UartReset() { - Uart.state = STATE_UNSYNCD; - Uart.shiftReg = 0; - Uart.bitCnt = 0; - Uart.byteCnt = 0; - Uart.byteCntMax = MAX_FRAME_SIZE; - Uart.posCnt = 0; + Uart.state = STATE_UNSYNCD; + Uart.shiftReg = 0; + Uart.bitCnt = 0; + Uart.byteCnt = 0; + Uart.byteCntMax = MAX_FRAME_SIZE; + Uart.posCnt = 0; } static void UartInit(uint8_t *data) { - Uart.output = data; - UartReset(); -// memset(Uart.output, 0x00, MAX_FRAME_SIZE); + Uart.output = data; + UartReset(); +// memset(Uart.output, 0x00, MAX_FRAME_SIZE); } //----------------------------------------------------------------------------- // The software Demod that receives commands from the tag, and its state variables. //----------------------------------------------------------------------------- static struct { - enum { - DEMOD_UNSYNCD, - DEMOD_PHASE_REF_TRAINING, - DEMOD_AWAITING_FALLING_EDGE_OF_SOF, - DEMOD_GOT_FALLING_EDGE_OF_SOF, - DEMOD_AWAITING_START_BIT, - DEMOD_RECEIVING_DATA - } state; - uint16_t bitCount; - int posCount; - int thisBit; + enum { + DEMOD_UNSYNCD, + DEMOD_PHASE_REF_TRAINING, + DEMOD_AWAITING_FALLING_EDGE_OF_SOF, + DEMOD_GOT_FALLING_EDGE_OF_SOF, + DEMOD_AWAITING_START_BIT, + DEMOD_RECEIVING_DATA + } state; + uint16_t bitCount; + int posCount; + int thisBit; /* this had been used to add RSSI (Received Signal Strength Indication) to traces. Currently not implemented. - int metric; - int metricN; + int metric; + int metricN; */ - uint16_t shiftReg; - uint8_t *output; - uint16_t len; - int sumI; - int sumQ; - uint32_t startTime, endTime; + uint16_t shiftReg; + uint8_t *output; + uint16_t len; + int sumI; + int sumQ; + uint32_t startTime, endTime; } Demod; // Clear out the state of the "UART" that receives from the tag. static void DemodReset() { - Demod.state = DEMOD_UNSYNCD; - Demod.bitCount = 0; - Demod.posCount = 0; - Demod.thisBit = 0; - Demod.shiftReg = 0; - Demod.len = 0; - Demod.sumI = 0; - Demod.sumQ = 0; - Demod.startTime = 0; - Demod.endTime = 0; + Demod.state = DEMOD_UNSYNCD; + Demod.bitCount = 0; + Demod.posCount = 0; + Demod.thisBit = 0; + Demod.shiftReg = 0; + Demod.len = 0; + Demod.sumI = 0; + Demod.sumQ = 0; + Demod.startTime = 0; + Demod.endTime = 0; } static void DemodInit(uint8_t *data) { - Demod.output = data; - DemodReset(); - // memset(Demod.output, 0x00, MAX_FRAME_SIZE); + Demod.output = data; + DemodReset(); + // memset(Demod.output, 0x00, MAX_FRAME_SIZE); } @@ -154,19 +154,19 @@ static void DemodInit(uint8_t *data) { * @param timeout is in frame wait time, fwt, measured in ETUs */ static void iso14b_set_timeout(uint32_t timeout) { - #define MAX_TIMEOUT 40542464 // 13560000Hz * 1000ms / (2^32-1) * (8*16) - if(timeout > MAX_TIMEOUT) - timeout = MAX_TIMEOUT; + #define MAX_TIMEOUT 40542464 // 13560000Hz * 1000ms / (2^32-1) * (8*16) + if(timeout > MAX_TIMEOUT) + timeout = MAX_TIMEOUT; - iso14b_timeout = timeout; - if(MF_DBGLEVEL >= 3) Dbprintf("ISO14443B Timeout set to %ld fwt", iso14b_timeout); + iso14b_timeout = timeout; + if(MF_DBGLEVEL >= 3) Dbprintf("ISO14443B Timeout set to %ld fwt", iso14b_timeout); } static void iso14b_set_maxframesize(uint16_t size) { - if (size > 256) - size = MAX_FRAME_SIZE; + if (size > 256) + size = MAX_FRAME_SIZE; - Uart.byteCntMax = size; - if(MF_DBGLEVEL >= 3) Dbprintf("ISO14443B Max frame size set to %d bytes", Uart.byteCntMax); + Uart.byteCntMax = size; + if(MF_DBGLEVEL >= 3) Dbprintf("ISO14443B Max frame size set to %d bytes", Uart.byteCntMax); } //----------------------------------------------------------------------------- @@ -175,132 +175,132 @@ static void iso14b_set_maxframesize(uint16_t size) { // them yet, just leaves them ready to send in ToSend[]. //----------------------------------------------------------------------------- static void CodeIso14443bAsTag(const uint8_t *cmd, int len) { - /* ISO 14443 B - * - * Reader to card | ASK - Amplitude Shift Keying Modulation (PCD to PICC for Type B) (NRZ-L encodig) - * Card to reader | BPSK - Binary Phase Shift Keying Modulation, (PICC to PCD for Type B) - * - * fc - carrier frequency 13.56mHz - * TR0 - Guard Time per 14443-2 - * TR1 - Synchronization Time per 14443-2 - * TR2 - PICC to PCD Frame Delay Time (per 14443-3 Amendment 1) - * - * Elementary Time Unit (ETU) is - * - 128 Carrier Cycles (9.4395 µS) = 8 Subcarrier Units - * - 1 ETU = 1 bit - * - 10 ETU = 1 startbit, 8 databits, 1 stopbit (10bits length) - * - startbit is a 0 - * - stopbit is a 1 - * - * Start of frame (SOF) is - * - [10-11] ETU of ZEROS, unmodulated time - * - [2-3] ETU of ONES, - * - * End of frame (EOF) is - * - [10-11] ETU of ZEROS, unmodulated time - * - * -TO VERIFY THIS BELOW- - * The mode FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK which we use to simulate tag - * works like this: - * - A 1-bit input to the FPGA becomes 8 pulses at 847.5kHz (1.18µS / pulse) == 9.44us - * - A 0-bit input to the FPGA becomes an unmodulated time of 1.18µS or does it become 8 nonpulses for 9.44us - * - * FPGA doesn't seem to work with ETU. It seems to work with pulse / duration instead. - * - * Card sends data ub 847.e kHz subcarrier - * subcar |duration| FC division - * -------+--------+------------ - * 106kHz | 9.44µS | FC/128 - * 212kHz | 4.72µS | FC/64 - * 424kHz | 2.36µS | FC/32 - * 848kHz | 1.18µS | FC/16 - * -------+--------+------------ - * - * Reader data transmission: - * - no modulation ONES - * - SOF - * - Command, data and CRC_B - * - EOF - * - no modulation ONES - * - * Card data transmission - * - TR1 - * - SOF - * - data (each bytes is: 1startbit, 8bits, 1stopbit) - * - CRC_B - * - EOF - * - * FPGA implementation : - * At this point only Type A is implemented. This means that we are using a - * bit rate of 106 kbit/s, or fc/128. Oversample by 4, which ought to make - * things practical for the ARM (fc/32, 423.8 kbits/s, ~50 kbytes/s) - * - */ + /* ISO 14443 B + * + * Reader to card | ASK - Amplitude Shift Keying Modulation (PCD to PICC for Type B) (NRZ-L encodig) + * Card to reader | BPSK - Binary Phase Shift Keying Modulation, (PICC to PCD for Type B) + * + * fc - carrier frequency 13.56mHz + * TR0 - Guard Time per 14443-2 + * TR1 - Synchronization Time per 14443-2 + * TR2 - PICC to PCD Frame Delay Time (per 14443-3 Amendment 1) + * + * Elementary Time Unit (ETU) is + * - 128 Carrier Cycles (9.4395 µS) = 8 Subcarrier Units + * - 1 ETU = 1 bit + * - 10 ETU = 1 startbit, 8 databits, 1 stopbit (10bits length) + * - startbit is a 0 + * - stopbit is a 1 + * + * Start of frame (SOF) is + * - [10-11] ETU of ZEROS, unmodulated time + * - [2-3] ETU of ONES, + * + * End of frame (EOF) is + * - [10-11] ETU of ZEROS, unmodulated time + * + * -TO VERIFY THIS BELOW- + * The mode FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK which we use to simulate tag + * works like this: + * - A 1-bit input to the FPGA becomes 8 pulses at 847.5kHz (1.18µS / pulse) == 9.44us + * - A 0-bit input to the FPGA becomes an unmodulated time of 1.18µS or does it become 8 nonpulses for 9.44us + * + * FPGA doesn't seem to work with ETU. It seems to work with pulse / duration instead. + * + * Card sends data ub 847.e kHz subcarrier + * subcar |duration| FC division + * -------+--------+------------ + * 106kHz | 9.44µS | FC/128 + * 212kHz | 4.72µS | FC/64 + * 424kHz | 2.36µS | FC/32 + * 848kHz | 1.18µS | FC/16 + * -------+--------+------------ + * + * Reader data transmission: + * - no modulation ONES + * - SOF + * - Command, data and CRC_B + * - EOF + * - no modulation ONES + * + * Card data transmission + * - TR1 + * - SOF + * - data (each bytes is: 1startbit, 8bits, 1stopbit) + * - CRC_B + * - EOF + * + * FPGA implementation : + * At this point only Type A is implemented. This means that we are using a + * bit rate of 106 kbit/s, or fc/128. Oversample by 4, which ought to make + * things practical for the ARM (fc/32, 423.8 kbits/s, ~50 kbytes/s) + * + */ - int i,j; - uint8_t b; + int i,j; + uint8_t b; - ToSendReset(); + ToSendReset(); - // Transmit a burst of ones, as the initial thing that lets the - // reader get phase sync. - // This loop is TR1, per specification - // TR1 minimum must be > 80/fs - // TR1 maximum 200/fs - // 80/fs < TR1 < 200/fs - // 10 ETU < TR1 < 24 ETU + // Transmit a burst of ones, as the initial thing that lets the + // reader get phase sync. + // This loop is TR1, per specification + // TR1 minimum must be > 80/fs + // TR1 maximum 200/fs + // 80/fs < TR1 < 200/fs + // 10 ETU < TR1 < 24 ETU - // Send SOF. - // 10-11 ETU * 4times samples ZEROS - for(i = 0; i < 10; i++) { SEND4STUFFBIT(0); } - //for(i = 0; i < 10; i++) { ToSendStuffBit(0); } + // Send SOF. + // 10-11 ETU * 4times samples ZEROS + for(i = 0; i < 10; i++) { SEND4STUFFBIT(0); } + //for(i = 0; i < 10; i++) { ToSendStuffBit(0); } - // 2-3 ETU * 4times samples ONES - for(i = 0; i < 3; i++) { SEND4STUFFBIT(1); } - //for(i = 0; i < 3; i++) { ToSendStuffBit(1); } + // 2-3 ETU * 4times samples ONES + for(i = 0; i < 3; i++) { SEND4STUFFBIT(1); } + //for(i = 0; i < 3; i++) { ToSendStuffBit(1); } - // data - for(i = 0; i < len; ++i) { + // data + for(i = 0; i < len; ++i) { - // Start bit - SEND4STUFFBIT(0); - //ToSendStuffBit(0); + // Start bit + SEND4STUFFBIT(0); + //ToSendStuffBit(0); - // Data bits - b = cmd[i]; - for(j = 0; j < 8; ++j) { - // if(b & 1) { - // SEND4STUFFBIT(1); - // //ToSendStuffBit(1); - // } else { - // SEND4STUFFBIT(0); - // //ToSendStuffBit(0); - // } - SEND4STUFFBIT( b & 1 ); - b >>= 1; - } + // Data bits + b = cmd[i]; + for(j = 0; j < 8; ++j) { + // if(b & 1) { + // SEND4STUFFBIT(1); + // //ToSendStuffBit(1); + // } else { + // SEND4STUFFBIT(0); + // //ToSendStuffBit(0); + // } + SEND4STUFFBIT( b & 1 ); + b >>= 1; + } - // Stop bit - SEND4STUFFBIT(1); - //ToSendStuffBit(1); + // Stop bit + SEND4STUFFBIT(1); + //ToSendStuffBit(1); - // Extra Guard bit - // For PICC it ranges 0-18us (1etu = 9us) - SEND4STUFFBIT(1); - //ToSendStuffBit(1); - } + // Extra Guard bit + // For PICC it ranges 0-18us (1etu = 9us) + SEND4STUFFBIT(1); + //ToSendStuffBit(1); + } - // Send EOF. - // 10-11 ETU * 4 sample rate = ZEROS - for(i = 0; i < 10; i++) { SEND4STUFFBIT(0); } - //for(i = 0; i < 10; i++) { ToSendStuffBit(0); } + // Send EOF. + // 10-11 ETU * 4 sample rate = ZEROS + for(i = 0; i < 10; i++) { SEND4STUFFBIT(0); } + //for(i = 0; i < 10; i++) { ToSendStuffBit(0); } - // why this? - for(i = 0; i < 40; i++) { SEND4STUFFBIT(1); } - //for(i = 0; i < 40; i++) { ToSendStuffBit(1); } + // why this? + for(i = 0; i < 40; i++) { SEND4STUFFBIT(1); } + //for(i = 0; i < 40; i++) { ToSendStuffBit(1); } - // Convert from last byte pos to length - ++ToSendMax; + // Convert from last byte pos to length + ++ToSendMax; } @@ -317,111 +317,111 @@ static void CodeIso14443bAsTag(const uint8_t *cmd, int len) { * false if we are still waiting for some more */ static RAMFUNC int Handle14443bReaderUartBit(uint8_t bit) { - switch (Uart.state) { - case STATE_UNSYNCD: - if (!bit) { - // we went low, so this could be the beginning of an SOF - Uart.state = STATE_GOT_FALLING_EDGE_OF_SOF; - Uart.posCnt = 0; - Uart.bitCnt = 0; - } - break; + switch (Uart.state) { + case STATE_UNSYNCD: + if (!bit) { + // we went low, so this could be the beginning of an SOF + Uart.state = STATE_GOT_FALLING_EDGE_OF_SOF; + Uart.posCnt = 0; + Uart.bitCnt = 0; + } + break; - case STATE_GOT_FALLING_EDGE_OF_SOF: - Uart.posCnt++; - if (Uart.posCnt == 2) { // sample every 4 1/fs in the middle of a bit - if (bit) { - if (Uart.bitCnt > 9) { - // we've seen enough consecutive - // zeros that it's a valid SOF - Uart.posCnt = 0; - Uart.byteCnt = 0; - Uart.state = STATE_AWAITING_START_BIT; - LED_A_ON(); // Indicate we got a valid SOF - } else { - // didn't stay down long enough before going high, error - Uart.state = STATE_UNSYNCD; - } - } else { - // do nothing, keep waiting - } - Uart.bitCnt++; - } - if (Uart.posCnt >= 4) Uart.posCnt = 0; - if (Uart.bitCnt > 12) { - // Give up if we see too many zeros without a one, too. - LED_A_OFF(); - Uart.state = STATE_UNSYNCD; - } - break; + case STATE_GOT_FALLING_EDGE_OF_SOF: + Uart.posCnt++; + if (Uart.posCnt == 2) { // sample every 4 1/fs in the middle of a bit + if (bit) { + if (Uart.bitCnt > 9) { + // we've seen enough consecutive + // zeros that it's a valid SOF + Uart.posCnt = 0; + Uart.byteCnt = 0; + Uart.state = STATE_AWAITING_START_BIT; + LED_A_ON(); // Indicate we got a valid SOF + } else { + // didn't stay down long enough before going high, error + Uart.state = STATE_UNSYNCD; + } + } else { + // do nothing, keep waiting + } + Uart.bitCnt++; + } + if (Uart.posCnt >= 4) Uart.posCnt = 0; + if (Uart.bitCnt > 12) { + // Give up if we see too many zeros without a one, too. + LED_A_OFF(); + Uart.state = STATE_UNSYNCD; + } + break; - case STATE_AWAITING_START_BIT: - Uart.posCnt++; - if (bit) { - if (Uart.posCnt > 50/2) { // max 57us between characters = 49 1/fs, max 3 etus after low phase of SOF = 24 1/fs - // stayed high for too long between characters, error - Uart.state = STATE_UNSYNCD; - } - } else { - // falling edge, this starts the data byte - Uart.posCnt = 0; - Uart.bitCnt = 0; - Uart.shiftReg = 0; - Uart.state = STATE_RECEIVING_DATA; - } - break; + case STATE_AWAITING_START_BIT: + Uart.posCnt++; + if (bit) { + if (Uart.posCnt > 50/2) { // max 57us between characters = 49 1/fs, max 3 etus after low phase of SOF = 24 1/fs + // stayed high for too long between characters, error + Uart.state = STATE_UNSYNCD; + } + } else { + // falling edge, this starts the data byte + Uart.posCnt = 0; + Uart.bitCnt = 0; + Uart.shiftReg = 0; + Uart.state = STATE_RECEIVING_DATA; + } + break; - case STATE_RECEIVING_DATA: - Uart.posCnt++; - if (Uart.posCnt == 2) { - // time to sample a bit - Uart.shiftReg >>= 1; - if (bit) { - Uart.shiftReg |= 0x200; - } - Uart.bitCnt++; - } - if (Uart.posCnt >= 4) { - Uart.posCnt = 0; - } - if (Uart.bitCnt == 10) { - if ((Uart.shiftReg & 0x200) && !(Uart.shiftReg & 0x001)) - { - // this is a data byte, with correct - // start and stop bits - Uart.output[Uart.byteCnt] = (Uart.shiftReg >> 1) & 0xff; - Uart.byteCnt++; + case STATE_RECEIVING_DATA: + Uart.posCnt++; + if (Uart.posCnt == 2) { + // time to sample a bit + Uart.shiftReg >>= 1; + if (bit) { + Uart.shiftReg |= 0x200; + } + Uart.bitCnt++; + } + if (Uart.posCnt >= 4) { + Uart.posCnt = 0; + } + if (Uart.bitCnt == 10) { + if ((Uart.shiftReg & 0x200) && !(Uart.shiftReg & 0x001)) + { + // this is a data byte, with correct + // start and stop bits + Uart.output[Uart.byteCnt] = (Uart.shiftReg >> 1) & 0xff; + Uart.byteCnt++; - if (Uart.byteCnt >= Uart.byteCntMax) { - // Buffer overflowed, give up - LED_A_OFF(); - Uart.state = STATE_UNSYNCD; - } else { - // so get the next byte now - Uart.posCnt = 0; - Uart.state = STATE_AWAITING_START_BIT; - } - } else if (Uart.shiftReg == 0x000) { - // this is an EOF byte - LED_A_OFF(); // Finished receiving - Uart.state = STATE_UNSYNCD; - if (Uart.byteCnt != 0) - return true; + if (Uart.byteCnt >= Uart.byteCntMax) { + // Buffer overflowed, give up + LED_A_OFF(); + Uart.state = STATE_UNSYNCD; + } else { + // so get the next byte now + Uart.posCnt = 0; + Uart.state = STATE_AWAITING_START_BIT; + } + } else if (Uart.shiftReg == 0x000) { + // this is an EOF byte + LED_A_OFF(); // Finished receiving + Uart.state = STATE_UNSYNCD; + if (Uart.byteCnt != 0) + return true; - } else { - // this is an error - LED_A_OFF(); - Uart.state = STATE_UNSYNCD; - } - } - break; + } else { + // this is an error + LED_A_OFF(); + Uart.state = STATE_UNSYNCD; + } + } + break; - default: - LED_A_OFF(); - Uart.state = STATE_UNSYNCD; - break; - } - return false; + default: + LED_A_OFF(); + Uart.state = STATE_UNSYNCD; + break; + } + return false; } //----------------------------------------------------------------------------- @@ -434,123 +434,123 @@ static RAMFUNC int Handle14443bReaderUartBit(uint8_t bit) { // correctly. //----------------------------------------------------------------------------- static int GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len) { - // Set FPGA mode to "simulated ISO 14443B tag", no modulation (listen - // only, since we are receiving, not transmitting). - // Signal field is off with the appropriate LED - LED_D_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION); + // Set FPGA mode to "simulated ISO 14443B tag", no modulation (listen + // only, since we are receiving, not transmitting). + // Signal field is off with the appropriate LED + LED_D_OFF(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION); - StartCountSspClk(); + StartCountSspClk(); - volatile uint8_t b = 0; + volatile uint8_t b = 0; - // clear receiving shift register and holding register - // What does this loop do? Is it TR1? - // loop is a wait/delay ? + // clear receiving shift register and holding register + // What does this loop do? Is it TR1? + // loop is a wait/delay ? /* - for(uint8_t c = 0; c < 10;) { + for(uint8_t c = 0; c < 10;) { - // keep tx buffer in a defined state anyway. - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0xFF; - ++c; - } - } - */ - // Now run a `software UART' on the stream of incoming samples. - UartInit(received); + // keep tx buffer in a defined state anyway. + if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = 0xFF; + ++c; + } + } + */ + // Now run a `software UART' on the stream of incoming samples. + UartInit(received); - uint8_t mask; - while( !BUTTON_PRESS() ) { - WDT_HIT(); + uint8_t mask; + while( !BUTTON_PRESS() ) { + WDT_HIT(); - // keep tx buffer in a defined state anyway. - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0x00; - } + // keep tx buffer in a defined state anyway. + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = 0x00; + } - // Wait for byte be become available in rx holding register - if ( AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY ) { + // Wait for byte be become available in rx holding register + if ( AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY ) { - b = (uint8_t) AT91C_BASE_SSC->SSC_RHR; + b = (uint8_t) AT91C_BASE_SSC->SSC_RHR; - for ( mask = 0x80; mask != 0; mask >>= 1) { - if ( Handle14443bReaderUartBit(b & mask)) { - *len = Uart.byteCnt; - return true; - } - } - } - } - return false; + for ( mask = 0x80; mask != 0; mask >>= 1) { + if ( Handle14443bReaderUartBit(b & mask)) { + *len = Uart.byteCnt; + return true; + } + } + } + } + return false; } void ClearFpgaShiftingRegisters(void){ - volatile uint8_t b; + volatile uint8_t b; - // clear receiving shift register and holding register - while(!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) {}; + // clear receiving shift register and holding register + while(!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) {}; - b = AT91C_BASE_SSC->SSC_RHR; (void) b; + b = AT91C_BASE_SSC->SSC_RHR; (void) b; - while(!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) {}; + while(!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) {}; - b = AT91C_BASE_SSC->SSC_RHR; (void) b; + b = AT91C_BASE_SSC->SSC_RHR; (void) b; - // wait for the FPGA to signal fdt_indicator == 1 (the FPGA is ready to queue new data in its delay line) - for (uint8_t j = 0; j < 5; j++) { // allow timeout - better late than never - while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) {}; - if (AT91C_BASE_SSC->SSC_RHR) break; - } + // wait for the FPGA to signal fdt_indicator == 1 (the FPGA is ready to queue new data in its delay line) + for (uint8_t j = 0; j < 5; j++) { // allow timeout - better late than never + while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) {}; + if (AT91C_BASE_SSC->SSC_RHR) break; + } - // Clear TXRDY: - //AT91C_BASE_SSC->SSC_THR = 0xFF; + // Clear TXRDY: + //AT91C_BASE_SSC->SSC_THR = 0xFF; } void WaitForFpgaDelayQueueIsEmpty( uint16_t delay ){ - // Ensure that the FPGA Delay Queue is empty before we switch to TAGSIM_LISTEN again: - uint8_t fpga_queued_bits = delay >> 3; // twich /8 ?? >>3, - for (uint8_t i = 0; i <= fpga_queued_bits/8 + 1; ) { - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0xFF; - i++; - } - } + // Ensure that the FPGA Delay Queue is empty before we switch to TAGSIM_LISTEN again: + uint8_t fpga_queued_bits = delay >> 3; // twich /8 ?? >>3, + for (uint8_t i = 0; i <= fpga_queued_bits/8 + 1; ) { + if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = 0xFF; + i++; + } + } } static void TransmitFor14443b_AsTag( uint8_t *response, uint16_t len) { - volatile uint32_t b; + volatile uint32_t b; - // Signal field is off with the appropriate LED - LED_D_OFF(); - //uint16_t fpgasendQueueDelay = 0; + // Signal field is off with the appropriate LED + LED_D_OFF(); + //uint16_t fpgasendQueueDelay = 0; - // Modulate BPSK - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK); - SpinDelay(40); + // Modulate BPSK + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK); + SpinDelay(40); - ClearFpgaShiftingRegisters(); + ClearFpgaShiftingRegisters(); - FpgaSetupSsc(); + FpgaSetupSsc(); - // Transmit the response. - for(uint16_t i = 0; i < len;) { + // Transmit the response. + for(uint16_t i = 0; i < len;) { - // Put byte into tx holding register as soon as it is ready - if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = response[++i]; - } + // Put byte into tx holding register as soon as it is ready + if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = response[++i]; + } - // Prevent rx holding register from overflowing - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - b = AT91C_BASE_SSC->SSC_RHR;(void)b; - } - } + // Prevent rx holding register from overflowing + if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + b = AT91C_BASE_SSC->SSC_RHR;(void)b; + } + } - //WaitForFpgaDelayQueueIsEmpty(fpgasendQueueDelay); - AT91C_BASE_SSC->SSC_THR = 0xFF; + //WaitForFpgaDelayQueueIsEmpty(fpgasendQueueDelay); + AT91C_BASE_SSC->SSC_THR = 0xFF; } //----------------------------------------------------------------------------- // Main loop of simulated tag: receive commands from reader, decide what @@ -558,160 +558,160 @@ static void TransmitFor14443b_AsTag( uint8_t *response, uint16_t len) { //----------------------------------------------------------------------------- void SimulateIso14443bTag(uint32_t pupi) { - // setup device. - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - // connect Demodulated Signal to ADC: - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - // Set up the synchronous serial port - FpgaSetupSsc(); + // setup device. + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + // connect Demodulated Signal to ADC: + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + // Set up the synchronous serial port + FpgaSetupSsc(); - // allocate command receive buffer - BigBuf_free(); BigBuf_Clear_ext(false); + // allocate command receive buffer + BigBuf_free(); BigBuf_Clear_ext(false); - clear_trace(); //sim - set_tracing(true); + clear_trace(); //sim + set_tracing(true); - uint16_t len, cmdsReceived = 0; - int cardSTATE = SIM_NOFIELD; - int vHf = 0; // in mV - // uint32_t time_0 = 0; - // uint32_t t2r_time = 0; - // uint32_t r2t_time = 0; - uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); + uint16_t len, cmdsReceived = 0; + int cardSTATE = SIM_NOFIELD; + int vHf = 0; // in mV + // uint32_t time_0 = 0; + // uint32_t t2r_time = 0; + // uint32_t r2t_time = 0; + uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); - // the only commands we understand is WUPB, AFI=0, Select All, N=1: -// static const uint8_t cmdWUPB[] = { ISO14443B_REQB, 0x00, 0x08, 0x39, 0x73 }; // WUPB - // ... and REQB, AFI=0, Normal Request, N=1: -// static const uint8_t cmdREQB[] = { ISO14443B_REQB, 0x00, 0x00, 0x71, 0xFF }; // REQB - // ... and ATTRIB -// static const uint8_t cmdATTRIB[] = { ISO14443B_ATTRIB, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; // ATTRIB + // the only commands we understand is WUPB, AFI=0, Select All, N=1: +// static const uint8_t cmdWUPB[] = { ISO14443B_REQB, 0x00, 0x08, 0x39, 0x73 }; // WUPB + // ... and REQB, AFI=0, Normal Request, N=1: +// static const uint8_t cmdREQB[] = { ISO14443B_REQB, 0x00, 0x00, 0x71, 0xFF }; // REQB + // ... and ATTRIB +// static const uint8_t cmdATTRIB[] = { ISO14443B_ATTRIB, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; // ATTRIB - // ... if not PUPI/UID is supplied we always respond with ATQB, PUPI = 820de174, Application Data = 0x20381922, - // supports only 106kBit/s in both directions, max frame size = 32Bytes, - // supports ISO14443-4, FWI=8 (77ms), NAD supported, CID not supported: - uint8_t respATQB[] = { 0x50, 0x82, 0x0d, 0xe1, 0x74, 0x20, 0x38, 0x19, - 0x22, 0x00, 0x21, 0x85, 0x5e, 0xd7 }; + // ... if not PUPI/UID is supplied we always respond with ATQB, PUPI = 820de174, Application Data = 0x20381922, + // supports only 106kBit/s in both directions, max frame size = 32Bytes, + // supports ISO14443-4, FWI=8 (77ms), NAD supported, CID not supported: + uint8_t respATQB[] = { 0x50, 0x82, 0x0d, 0xe1, 0x74, 0x20, 0x38, 0x19, + 0x22, 0x00, 0x21, 0x85, 0x5e, 0xd7 }; - // response to HLTB and ATTRIB - static const uint8_t respOK[] = {0x00, 0x78, 0xF0}; + // response to HLTB and ATTRIB + static const uint8_t respOK[] = {0x00, 0x78, 0xF0}; - // ...PUPI/UID supplied from user. Adjust ATQB response accordingly - if ( pupi > 0 ) { - num_to_bytes(pupi, 4, respATQB+1); - AddCrc14B(respATQB, 12); - } + // ...PUPI/UID supplied from user. Adjust ATQB response accordingly + if ( pupi > 0 ) { + num_to_bytes(pupi, 4, respATQB+1); + AddCrc14B(respATQB, 12); + } - // prepare "ATQB" tag answer (encoded): - CodeIso14443bAsTag(respATQB, sizeof(respATQB)); - uint8_t *encodedATQB = BigBuf_malloc(ToSendMax); - uint16_t encodedATQBLen = ToSendMax; - memcpy(encodedATQB, ToSend, ToSendMax); + // prepare "ATQB" tag answer (encoded): + CodeIso14443bAsTag(respATQB, sizeof(respATQB)); + uint8_t *encodedATQB = BigBuf_malloc(ToSendMax); + uint16_t encodedATQBLen = ToSendMax; + memcpy(encodedATQB, ToSend, ToSendMax); - // prepare "OK" tag answer (encoded): - CodeIso14443bAsTag(respOK, sizeof(respOK)); - uint8_t *encodedOK = BigBuf_malloc(ToSendMax); - uint16_t encodedOKLen = ToSendMax; - memcpy(encodedOK, ToSend, ToSendMax); + // prepare "OK" tag answer (encoded): + CodeIso14443bAsTag(respOK, sizeof(respOK)); + uint8_t *encodedOK = BigBuf_malloc(ToSendMax); + uint16_t encodedOKLen = ToSendMax; + memcpy(encodedOK, ToSend, ToSendMax); - // Simulation loop - while (!BUTTON_PRESS() && !usb_poll_validate_length()) { - WDT_HIT(); + // Simulation loop + while (!BUTTON_PRESS() && !usb_poll_validate_length()) { + WDT_HIT(); - // find reader field - if (cardSTATE == SIM_NOFIELD) { - vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; - if ( vHf > MF_MINFIELDV ) { - cardSTATE = SIM_IDLE; - LED_A_ON(); - } - } - if (cardSTATE == SIM_NOFIELD) continue; + // find reader field + if (cardSTATE == SIM_NOFIELD) { + vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; + if ( vHf > MF_MINFIELDV ) { + cardSTATE = SIM_IDLE; + LED_A_ON(); + } + } + if (cardSTATE == SIM_NOFIELD) continue; - // Get reader command - if (!GetIso14443bCommandFromReader(receivedCmd, &len)) { - Dbprintf("button pressed, received %d commands", cmdsReceived); - break; - } + // Get reader command + if (!GetIso14443bCommandFromReader(receivedCmd, &len)) { + Dbprintf("button pressed, received %d commands", cmdsReceived); + break; + } - // ISO14443-B protocol states: - // REQ or WUP request in ANY state - // WUP in HALTED state - if (len == 5 ) { - if ( (receivedCmd[0] == ISO14443B_REQB && (receivedCmd[2] & 0x8)== 0x8 && cardSTATE == SIM_HALTED) || - receivedCmd[0] == ISO14443B_REQB ){ - LogTrace(receivedCmd, len, 0, 0, NULL, true); - cardSTATE = SIM_SELECTING; - } - } + // ISO14443-B protocol states: + // REQ or WUP request in ANY state + // WUP in HALTED state + if (len == 5 ) { + if ( (receivedCmd[0] == ISO14443B_REQB && (receivedCmd[2] & 0x8)== 0x8 && cardSTATE == SIM_HALTED) || + receivedCmd[0] == ISO14443B_REQB ){ + LogTrace(receivedCmd, len, 0, 0, NULL, true); + cardSTATE = SIM_SELECTING; + } + } - /* - * How should this flow go? - * REQB or WUPB - * send response ( waiting for Attrib) - * ATTRIB - * send response ( waiting for commands 7816) - * HALT - send halt response ( waiting for wupb ) - */ + /* + * How should this flow go? + * REQB or WUPB + * send response ( waiting for Attrib) + * ATTRIB + * send response ( waiting for commands 7816) + * HALT + send halt response ( waiting for wupb ) + */ - switch (cardSTATE) { - //case SIM_NOFIELD: - case SIM_HALTED: - case SIM_IDLE: { - LogTrace(receivedCmd, len, 0, 0, NULL, true); - break; - } - case SIM_SELECTING: { - TransmitFor14443b_AsTag( encodedATQB, encodedATQBLen ); - LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, false); - cardSTATE = SIM_WORK; - break; - } - case SIM_HALTING: { - TransmitFor14443b_AsTag( encodedOK, encodedOKLen ); - LogTrace(respOK, sizeof(respOK), 0, 0, NULL, false); - cardSTATE = SIM_HALTED; - break; - } - case SIM_ACKNOWLEDGE: { - TransmitFor14443b_AsTag( encodedOK, encodedOKLen ); - LogTrace(respOK, sizeof(respOK), 0, 0, NULL, false); - cardSTATE = SIM_IDLE; - break; - } - case SIM_WORK: { - if ( len == 7 && receivedCmd[0] == ISO14443B_HALT ) { - cardSTATE = SIM_HALTED; - } else if ( len == 11 && receivedCmd[0] == ISO14443B_ATTRIB ) { - cardSTATE = SIM_ACKNOWLEDGE; - } else { - // Todo: - // - SLOT MARKER - // - ISO7816 - // - emulate with a memory dump - Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsReceived); + switch (cardSTATE) { + //case SIM_NOFIELD: + case SIM_HALTED: + case SIM_IDLE: { + LogTrace(receivedCmd, len, 0, 0, NULL, true); + break; + } + case SIM_SELECTING: { + TransmitFor14443b_AsTag( encodedATQB, encodedATQBLen ); + LogTrace(respATQB, sizeof(respATQB), 0, 0, NULL, false); + cardSTATE = SIM_WORK; + break; + } + case SIM_HALTING: { + TransmitFor14443b_AsTag( encodedOK, encodedOKLen ); + LogTrace(respOK, sizeof(respOK), 0, 0, NULL, false); + cardSTATE = SIM_HALTED; + break; + } + case SIM_ACKNOWLEDGE: { + TransmitFor14443b_AsTag( encodedOK, encodedOKLen ); + LogTrace(respOK, sizeof(respOK), 0, 0, NULL, false); + cardSTATE = SIM_IDLE; + break; + } + case SIM_WORK: { + if ( len == 7 && receivedCmd[0] == ISO14443B_HALT ) { + cardSTATE = SIM_HALTED; + } else if ( len == 11 && receivedCmd[0] == ISO14443B_ATTRIB ) { + cardSTATE = SIM_ACKNOWLEDGE; + } else { + // Todo: + // - SLOT MARKER + // - ISO7816 + // - emulate with a memory dump + Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsReceived); - // CRC Check - if (len >= 3){ // if crc exists + // CRC Check + if (len >= 3){ // if crc exists - if (!check_crc(CRC_14443_B, receivedCmd, len)) - DbpString("+++CRC fail"); - else - DbpString("CRC passes"); - } - cardSTATE = SIM_IDLE; - } - break; - } - default: break; - } + if (!check_crc(CRC_14443_B, receivedCmd, len)) + DbpString("+++CRC fail"); + else + DbpString("CRC passes"); + } + cardSTATE = SIM_IDLE; + } + break; + } + default: break; + } - ++cmdsReceived; - } - if (MF_DBGLEVEL >= 2) - Dbprintf("Emulator stopped. Trace length: %d ", BigBuf_get_traceLen()); - switch_off(); //simulate + ++cmdsReceived; + } + if (MF_DBGLEVEL >= 2) + Dbprintf("Emulator stopped. Trace length: %d ", BigBuf_get_traceLen()); + switch_off(); //simulate } //============================================================================= @@ -736,202 +736,202 @@ void SimulateIso14443bTag(uint32_t pupi) { * */ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) { - int v = 0, myI = ABS(ci), myQ = ABS(cq); + int v = 0, myI = ABS(ci), myQ = ABS(cq); // The soft decision on the bit uses an estimate of just the // quadrant of the reference angle, not the exact angle. #define MAKE_SOFT_DECISION() { \ - if (Demod.sumI > 0) { \ - v = ci; \ - } else { \ - v = -ci; \ - } \ - if (Demod.sumQ > 0) { \ - v += cq; \ - } else { \ - v -= cq; \ - } \ - } + if (Demod.sumI > 0) { \ + v = ci; \ + } else { \ + v = -ci; \ + } \ + if (Demod.sumQ > 0) { \ + v += cq; \ + } else { \ + v -= cq; \ + } \ + } // Subcarrier amplitude v = sqrt(ci^2 + cq^2), approximated here by abs(ci) + abs(cq) // Subcarrier amplitude v = sqrt(ci^2 + cq^2), approximated here by max(abs(ci),abs(cq)) + 1/2*min(abs(ci),abs(cq))) #define CHECK_FOR_SUBCARRIER_old() { \ - if (ci < 0) { \ - if (cq < 0) { /* ci < 0, cq < 0 */ \ - if (cq < ci) { \ - v = -cq - (ci >> 1); \ - } else { \ - v = -ci - (cq >> 1); \ - } \ - } else { /* ci < 0, cq >= 0 */ \ - if (cq < -ci) { \ - v = -ci + (cq >> 1); \ - } else { \ - v = cq - (ci >> 1); \ - } \ - } \ - } else { \ - if (cq < 0) { /* ci >= 0, cq < 0 */ \ - if (-cq < ci) { \ - v = ci - (cq >> 1); \ - } else { \ - v = -cq + (ci >> 1); \ - } \ - } else { /* ci >= 0, cq >= 0 */ \ - if (cq < ci) { \ - v = ci + (cq >> 1); \ - } else { \ - v = cq + (ci >> 1); \ - } \ - } \ - } \ - } + if (ci < 0) { \ + if (cq < 0) { /* ci < 0, cq < 0 */ \ + if (cq < ci) { \ + v = -cq - (ci >> 1); \ + } else { \ + v = -ci - (cq >> 1); \ + } \ + } else { /* ci < 0, cq >= 0 */ \ + if (cq < -ci) { \ + v = -ci + (cq >> 1); \ + } else { \ + v = cq - (ci >> 1); \ + } \ + } \ + } else { \ + if (cq < 0) { /* ci >= 0, cq < 0 */ \ + if (-cq < ci) { \ + v = ci - (cq >> 1); \ + } else { \ + v = -cq + (ci >> 1); \ + } \ + } else { /* ci >= 0, cq >= 0 */ \ + if (cq < ci) { \ + v = ci + (cq >> 1); \ + } else { \ + v = cq + (ci >> 1); \ + } \ + } \ + } \ + } //note: couldn't we just use MAX(ABS(ci),ABS(cq)) + (MIN(ABS(ci),ABS(cq))/2) from common.h - marshmellow #define CHECK_FOR_SUBCARRIER() { v = MAX(myI, myQ) + (MIN(myI, myQ) >> 1); } - switch(Demod.state) { - case DEMOD_UNSYNCD: + switch(Demod.state) { + case DEMOD_UNSYNCD: - CHECK_FOR_SUBCARRIER(); + CHECK_FOR_SUBCARRIER(); - // subcarrier detected + // subcarrier detected - if (v > SUBCARRIER_DETECT_THRESHOLD) { - Demod.state = DEMOD_PHASE_REF_TRAINING; - Demod.sumI = ci; - Demod.sumQ = cq; - Demod.posCount = 1; - } - break; + if (v > SUBCARRIER_DETECT_THRESHOLD) { + Demod.state = DEMOD_PHASE_REF_TRAINING; + Demod.sumI = ci; + Demod.sumQ = cq; + Demod.posCount = 1; + } + break; - case DEMOD_PHASE_REF_TRAINING: - if (Demod.posCount < 8) { + case DEMOD_PHASE_REF_TRAINING: + if (Demod.posCount < 8) { - CHECK_FOR_SUBCARRIER(); + CHECK_FOR_SUBCARRIER(); - if (v > SUBCARRIER_DETECT_THRESHOLD) { - // set the reference phase (will code a logic '1') by averaging over 32 1/fs. - // note: synchronization time > 80 1/fs - Demod.sumI += ci; - Demod.sumQ += cq; - Demod.posCount++; - } else { - // subcarrier lost - Demod.state = DEMOD_UNSYNCD; - } - } else { - Demod.state = DEMOD_AWAITING_FALLING_EDGE_OF_SOF; - } - break; + if (v > SUBCARRIER_DETECT_THRESHOLD) { + // set the reference phase (will code a logic '1') by averaging over 32 1/fs. + // note: synchronization time > 80 1/fs + Demod.sumI += ci; + Demod.sumQ += cq; + Demod.posCount++; + } else { + // subcarrier lost + Demod.state = DEMOD_UNSYNCD; + } + } else { + Demod.state = DEMOD_AWAITING_FALLING_EDGE_OF_SOF; + } + break; - case DEMOD_AWAITING_FALLING_EDGE_OF_SOF: + case DEMOD_AWAITING_FALLING_EDGE_OF_SOF: - MAKE_SOFT_DECISION(); + MAKE_SOFT_DECISION(); - if (v < 0) { // logic '0' detected - Demod.state = DEMOD_GOT_FALLING_EDGE_OF_SOF; - Demod.posCount = 0; // start of SOF sequence - } else { - // maximum length of TR1 = 200 1/fs - if (Demod.posCount > 200/4) Demod.state = DEMOD_UNSYNCD; - } - Demod.posCount++; - break; + if (v < 0) { // logic '0' detected + Demod.state = DEMOD_GOT_FALLING_EDGE_OF_SOF; + Demod.posCount = 0; // start of SOF sequence + } else { + // maximum length of TR1 = 200 1/fs + if (Demod.posCount > 200/4) Demod.state = DEMOD_UNSYNCD; + } + Demod.posCount++; + break; - case DEMOD_GOT_FALLING_EDGE_OF_SOF: - Demod.posCount++; + case DEMOD_GOT_FALLING_EDGE_OF_SOF: + Demod.posCount++; - MAKE_SOFT_DECISION(); + MAKE_SOFT_DECISION(); - if (v > 0) { - // low phase of SOF too short (< 9 etu). Note: spec is >= 10, but FPGA tends to "smear" edges - if (Demod.posCount < 9*2) { - Demod.state = DEMOD_UNSYNCD; - } else { - LED_C_ON(); // Got SOF - Demod.state = DEMOD_AWAITING_START_BIT; - Demod.posCount = 0; - Demod.len = 0; - } - } else { - // low phase of SOF too long (> 12 etu) - if (Demod.posCount > 14*2) { - Demod.state = DEMOD_UNSYNCD; - LED_C_OFF(); - } - } - break; + if (v > 0) { + // low phase of SOF too short (< 9 etu). Note: spec is >= 10, but FPGA tends to "smear" edges + if (Demod.posCount < 9*2) { + Demod.state = DEMOD_UNSYNCD; + } else { + LED_C_ON(); // Got SOF + Demod.state = DEMOD_AWAITING_START_BIT; + Demod.posCount = 0; + Demod.len = 0; + } + } else { + // low phase of SOF too long (> 12 etu) + if (Demod.posCount > 14*2) { + Demod.state = DEMOD_UNSYNCD; + LED_C_OFF(); + } + } + break; - case DEMOD_AWAITING_START_BIT: - Demod.posCount++; + case DEMOD_AWAITING_START_BIT: + Demod.posCount++; - MAKE_SOFT_DECISION(); + MAKE_SOFT_DECISION(); - if (v > 0) { - if (Demod.posCount > 6*2) { // max 19us between characters = 16 1/fs, max 3 etu after low phase of SOF = 24 1/fs - Demod.state = DEMOD_UNSYNCD; - LED_C_OFF(); - } - } else { // start bit detected - Demod.bitCount = 0; - Demod.posCount = 1; // this was the first half - Demod.thisBit = v; - Demod.shiftReg = 0; - Demod.state = DEMOD_RECEIVING_DATA; - } - break; + if (v > 0) { + if (Demod.posCount > 6*2) { // max 19us between characters = 16 1/fs, max 3 etu after low phase of SOF = 24 1/fs + Demod.state = DEMOD_UNSYNCD; + LED_C_OFF(); + } + } else { // start bit detected + Demod.bitCount = 0; + Demod.posCount = 1; // this was the first half + Demod.thisBit = v; + Demod.shiftReg = 0; + Demod.state = DEMOD_RECEIVING_DATA; + } + break; - case DEMOD_RECEIVING_DATA: + case DEMOD_RECEIVING_DATA: - MAKE_SOFT_DECISION(); + MAKE_SOFT_DECISION(); - if (Demod.posCount == 0) { - // first half of bit - Demod.thisBit = v; - Demod.posCount = 1; - } else { - // second half of bit - Demod.thisBit += v; - Demod.shiftReg >>= 1; + if (Demod.posCount == 0) { + // first half of bit + Demod.thisBit = v; + Demod.posCount = 1; + } else { + // second half of bit + Demod.thisBit += v; + Demod.shiftReg >>= 1; - // OR in a logic '1' - if (Demod.thisBit > 0) - Demod.shiftReg |= 0x200; + // OR in a logic '1' + if (Demod.thisBit > 0) + Demod.shiftReg |= 0x200; - Demod.bitCount++; + Demod.bitCount++; - // 1 start 8 data 1 stop = 10 - if (Demod.bitCount == 10) { + // 1 start 8 data 1 stop = 10 + if (Demod.bitCount == 10) { - uint16_t s = Demod.shiftReg; + uint16_t s = Demod.shiftReg; - // stop bit == '1', start bit == '0' - if ((s & 0x200) && (s & 0x001) == 0 ) { - // left shift to drop the startbit - uint8_t b = (s >> 1); - Demod.output[Demod.len] = b; - ++Demod.len; - Demod.state = DEMOD_AWAITING_START_BIT; - } else { - // this one is a bit hard, either its a correc byte or its unsynced. - Demod.state = DEMOD_UNSYNCD; - LED_C_OFF(); + // stop bit == '1', start bit == '0' + if ((s & 0x200) && (s & 0x001) == 0 ) { + // left shift to drop the startbit + uint8_t b = (s >> 1); + Demod.output[Demod.len] = b; + ++Demod.len; + Demod.state = DEMOD_AWAITING_START_BIT; + } else { + // this one is a bit hard, either its a correc byte or its unsynced. + Demod.state = DEMOD_UNSYNCD; + LED_C_OFF(); - // This is EOF (start, stop and all data bits == '0' - if (s == 0) return true; - } - } - Demod.posCount = 0; - } - break; + // This is EOF (start, stop and all data bits == '0' + if (s == 0) return true; + } + } + Demod.posCount = 0; + } + break; - default: - Demod.state = DEMOD_UNSYNCD; - LED_C_OFF(); - break; - } - return false; + default: + Demod.state = DEMOD_UNSYNCD; + LED_C_OFF(); + break; + } + return false; } @@ -940,99 +940,99 @@ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) { * quiet: set to 'TRUE' to disable debug output */ static void GetTagSamplesFor14443bDemod() { - bool gotFrame = false, finished = false; - int lastRxCounter = ISO14443B_DMA_BUFFER_SIZE; - int ci = 0, cq = 0; - uint32_t time_0 = 0, time_stop = 0; + bool gotFrame = false, finished = false; + int lastRxCounter = ISO14443B_DMA_BUFFER_SIZE; + int ci = 0, cq = 0; + uint32_t time_0 = 0, time_stop = 0; - BigBuf_free(); + BigBuf_free(); - // Set up the demodulator for tag -> reader responses. - DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); + // Set up the demodulator for tag -> reader responses. + DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); - // The DMA buffer, used to stream samples from the FPGA - int8_t *dmaBuf = (int8_t*) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE); - int8_t *upTo = dmaBuf; + // The DMA buffer, used to stream samples from the FPGA + int8_t *dmaBuf = (int8_t*) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE); + int8_t *upTo = dmaBuf; - // Setup and start DMA. - if ( !FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE) ){ - if (MF_DBGLEVEL > 1) Dbprintf("FpgaSetupSscDma failed. Exiting"); - return; - } + // Setup and start DMA. + if ( !FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE) ){ + if (MF_DBGLEVEL > 1) Dbprintf("FpgaSetupSscDma failed. Exiting"); + return; + } - // And put the FPGA in the appropriate mode - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ); + // And put the FPGA in the appropriate mode + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ); - // get current clock - time_0 = GetCountSspClk(); + // get current clock + time_0 = GetCountSspClk(); - // rx counter - dma counter? (how much?) & (mod) mask > 2. (since 2bytes at the time is read) - while ( !finished ) { + // rx counter - dma counter? (how much?) & (mod) mask > 2. (since 2bytes at the time is read) + while ( !finished ) { - LED_A_INV(); - WDT_HIT(); + LED_A_INV(); + WDT_HIT(); - // LSB is a fpga signal bit. - ci = upTo[0]; - cq = upTo[1]; - upTo += 2; - lastRxCounter -= 2; + // LSB is a fpga signal bit. + ci = upTo[0]; + cq = upTo[1]; + upTo += 2; + lastRxCounter -= 2; - // restart DMA buffer to receive again. - if(upTo >= dmaBuf + ISO14443B_DMA_BUFFER_SIZE) { - upTo = dmaBuf; - lastRxCounter = ISO14443B_DMA_BUFFER_SIZE; - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; - AT91C_BASE_PDC_SSC->PDC_RNCR = ISO14443B_DMA_BUFFER_SIZE; - } + // restart DMA buffer to receive again. + if(upTo >= dmaBuf + ISO14443B_DMA_BUFFER_SIZE) { + upTo = dmaBuf; + lastRxCounter = ISO14443B_DMA_BUFFER_SIZE; + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; + AT91C_BASE_PDC_SSC->PDC_RNCR = ISO14443B_DMA_BUFFER_SIZE; + } - // https://github.com/Proxmark/proxmark3/issues/103 - gotFrame = Handle14443bTagSamplesDemod(ci, cq); - time_stop = GetCountSspClk() - time_0; + // https://github.com/Proxmark/proxmark3/issues/103 + gotFrame = Handle14443bTagSamplesDemod(ci, cq); + time_stop = GetCountSspClk() - time_0; - finished = (time_stop > iso14b_timeout || gotFrame); - } + finished = (time_stop > iso14b_timeout || gotFrame); + } - FpgaDisableSscDma(); + FpgaDisableSscDma(); - if ( upTo ) - upTo = NULL; + if ( upTo ) + upTo = NULL; - if ( Demod.len > 0 ) - LogTrace(Demod.output, Demod.len, time_0, time_stop, NULL, false); + if ( Demod.len > 0 ) + LogTrace(Demod.output, Demod.len, time_0, time_stop, NULL, false); } //----------------------------------------------------------------------------- // Transmit the command (to the tag) that was placed in ToSend[]. //----------------------------------------------------------------------------- static void TransmitFor14443b_AsReader(void) { - int c; + int c; - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD); - SpinDelay(60); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD); + SpinDelay(60); - // What does this loop do? Is it TR1? - // 0xFF = 8 bits of 1. 1 bit == 1Etu,.. - // loop 10 * 8 = 80 ETU of delay, with a non modulated signal. why? - // 80*9 = 720us. + // What does this loop do? Is it TR1? + // 0xFF = 8 bits of 1. 1 bit == 1Etu,.. + // loop 10 * 8 = 80 ETU of delay, with a non modulated signal. why? + // 80*9 = 720us. - for(c = 0; c < 50;) { + for(c = 0; c < 50;) { - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0xFF; - c++; - } - } + if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = 0xFF; + c++; + } + } - // Send frame loop - for(c = 0; c < ToSendMax;) { + // Send frame loop + for(c = 0; c < ToSendMax;) { - // Put byte into tx holding register as soon as it is ready - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = ToSend[c++]; - } - } - WDT_HIT(); + // Put byte into tx holding register as soon as it is ready + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = ToSend[c++]; + } + } + WDT_HIT(); } //----------------------------------------------------------------------------- @@ -1040,81 +1040,81 @@ static void TransmitFor14443b_AsReader(void) { // so that it is ready to transmit to the tag using TransmitFor14443b(). //----------------------------------------------------------------------------- static void CodeIso14443bAsReader(const uint8_t *cmd, int len) { - /* - * Reader data transmission: - * - no modulation ONES - * - SOF - * - Command, data and CRC_B - * - EOF - * - no modulation ONES - * - * 1 ETU == 1 BIT! - * TR0 - 8 ETUS minimum. - * - * QUESTION: how long is a 1 or 0 in pulses in the xcorr_848 mode? - * 1 "stuffbit" = 1ETU (9us) - */ - int i; - uint8_t b; + /* + * Reader data transmission: + * - no modulation ONES + * - SOF + * - Command, data and CRC_B + * - EOF + * - no modulation ONES + * + * 1 ETU == 1 BIT! + * TR0 - 8 ETUS minimum. + * + * QUESTION: how long is a 1 or 0 in pulses in the xcorr_848 mode? + * 1 "stuffbit" = 1ETU (9us) + */ + int i; + uint8_t b; - ToSendReset(); + ToSendReset(); - // Send SOF - // 10-11 ETUs of ZERO - for(i = 0; i < 10; ++i) ToSendStuffBit(0); + // Send SOF + // 10-11 ETUs of ZERO + for(i = 0; i < 10; ++i) ToSendStuffBit(0); - // 2-3 ETUs of ONE - ToSendStuffBit(1); - ToSendStuffBit(1); -// ToSendStuffBit(1); + // 2-3 ETUs of ONE + ToSendStuffBit(1); + ToSendStuffBit(1); +// ToSendStuffBit(1); - // Sending cmd, LSB - // from here we add BITS - for(i = 0; i < len; ++i) { - // Start bit - ToSendStuffBit(0); - // Data bits - b = cmd[i]; - // if ( b & 1 ) ToSendStuffBit(1); else ToSendStuffBit(0); - // if ( (b>>1) & 1) ToSendStuffBit(1); else ToSendStuffBit(0); - // if ( (b>>2) & 1) ToSendStuffBit(1); else ToSendStuffBit(0); - // if ( (b>>3) & 1) ToSendStuffBit(1); else ToSendStuffBit(0); - // if ( (b>>4) & 1) ToSendStuffBit(1); else ToSendStuffBit(0); - // if ( (b>>5) & 1) ToSendStuffBit(1); else ToSendStuffBit(0); - // if ( (b>>6) & 1) ToSendStuffBit(1); else ToSendStuffBit(0); - // if ( (b>>7) & 1) ToSendStuffBit(1); else ToSendStuffBit(0); + // Sending cmd, LSB + // from here we add BITS + for(i = 0; i < len; ++i) { + // Start bit + ToSendStuffBit(0); + // Data bits + b = cmd[i]; + // if ( b & 1 ) ToSendStuffBit(1); else ToSendStuffBit(0); + // if ( (b>>1) & 1) ToSendStuffBit(1); else ToSendStuffBit(0); + // if ( (b>>2) & 1) ToSendStuffBit(1); else ToSendStuffBit(0); + // if ( (b>>3) & 1) ToSendStuffBit(1); else ToSendStuffBit(0); + // if ( (b>>4) & 1) ToSendStuffBit(1); else ToSendStuffBit(0); + // if ( (b>>5) & 1) ToSendStuffBit(1); else ToSendStuffBit(0); + // if ( (b>>6) & 1) ToSendStuffBit(1); else ToSendStuffBit(0); + // if ( (b>>7) & 1) ToSendStuffBit(1); else ToSendStuffBit(0); - ToSendStuffBit( b & 1); - ToSendStuffBit( (b>>1) & 1); - ToSendStuffBit( (b>>2) & 1); - ToSendStuffBit( (b>>3) & 1); - ToSendStuffBit( (b>>4) & 1); - ToSendStuffBit( (b>>5) & 1); - ToSendStuffBit( (b>>6) & 1); - ToSendStuffBit( (b>>7) & 1); + ToSendStuffBit( b & 1); + ToSendStuffBit( (b>>1) & 1); + ToSendStuffBit( (b>>2) & 1); + ToSendStuffBit( (b>>3) & 1); + ToSendStuffBit( (b>>4) & 1); + ToSendStuffBit( (b>>5) & 1); + ToSendStuffBit( (b>>6) & 1); + ToSendStuffBit( (b>>7) & 1); - // Stop bit - ToSendStuffBit(1); - // EGT extra guard time - // For PCD it ranges 0-57us (1etu = 9us) - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - } + // Stop bit + ToSendStuffBit(1); + // EGT extra guard time + // For PCD it ranges 0-57us (1etu = 9us) + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + } - // Send EOF - // 10-11 ETUs of ZERO - for(i = 0; i < 10; ++i) ToSendStuffBit(0); + // Send EOF + // 10-11 ETUs of ZERO + for(i = 0; i < 10; ++i) ToSendStuffBit(0); - // Transition time. TR0 - guard time - // 8ETUS minum? - // Per specification, Subcarrier must be stopped no later than 2 ETUs after EOF. - // I'm guessing this is for the FPGA to be able to send all bits before we switch to listening mode - for(i = 0; i < 24 ; ++i) ToSendStuffBit(1); + // Transition time. TR0 - guard time + // 8ETUS minum? + // Per specification, Subcarrier must be stopped no later than 2 ETUs after EOF. + // I'm guessing this is for the FPGA to be able to send all bits before we switch to listening mode + for(i = 0; i < 24 ; ++i) ToSendStuffBit(1); - // TR1 - Synchronization time - // Convert from last character reference to length - ToSendMax++; + // TR1 - Synchronization time + // Convert from last character reference to length + ToSendMax++; } /* @@ -1122,15 +1122,15 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len) { */ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len) { - uint32_t time_start = GetCountSspClk(); + uint32_t time_start = GetCountSspClk(); - CodeIso14443bAsReader(cmd, len); + CodeIso14443bAsReader(cmd, len); - TransmitFor14443b_AsReader(); + TransmitFor14443b_AsReader(); - if(trigger) LED_A_ON(); + if(trigger) LED_A_ON(); - LogTrace(cmd, len, time_start, GetCountSspClk()-time_start, NULL, true); + LogTrace(cmd, len, time_start, GetCountSspClk()-time_start, NULL, true); } /* Sends an APDU to the tag @@ -1138,91 +1138,91 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len) { */ uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response) { - uint8_t message_frame[message_length + 4]; - // PCB - message_frame[0] = 0x0A | pcb_blocknum; - pcb_blocknum ^= 1; - // CID - message_frame[1] = 0; - // INF - memcpy(message_frame + 2, message, message_length); - // EDC (CRC) - AddCrc14B(message_frame, message_length + 2); - // send - CodeAndTransmit14443bAsReader(message_frame, message_length + 4); //no - // get response - GetTagSamplesFor14443bDemod(); //no - if(Demod.len < 3) - return 0; + uint8_t message_frame[message_length + 4]; + // PCB + message_frame[0] = 0x0A | pcb_blocknum; + pcb_blocknum ^= 1; + // CID + message_frame[1] = 0; + // INF + memcpy(message_frame + 2, message, message_length); + // EDC (CRC) + AddCrc14B(message_frame, message_length + 2); + // send + CodeAndTransmit14443bAsReader(message_frame, message_length + 4); //no + // get response + GetTagSamplesFor14443bDemod(); //no + if(Demod.len < 3) + return 0; - // VALIDATE CRC - if (!check_crc(CRC_14443_B, Demod.output, Demod.len)){ - if (MF_DBGLEVEL > 3) Dbprintf("crc fail ICE"); - return 0; - } - // copy response contents - if(response != NULL) - memcpy(response, Demod.output, Demod.len); + // VALIDATE CRC + if (!check_crc(CRC_14443_B, Demod.output, Demod.len)){ + if (MF_DBGLEVEL > 3) Dbprintf("crc fail ICE"); + return 0; + } + // copy response contents + if(response != NULL) + memcpy(response, Demod.output, Demod.len); - return Demod.len; + return Demod.len; } /** * SRx Initialise. */ uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card ) { - // INITIATE command: wake up the tag using the INITIATE - static const uint8_t init_srx[] = { ISO14443B_INITIATE, 0x00, 0x97, 0x5b }; - // SELECT command (with space for CRC) - uint8_t select_srx[] = { ISO14443B_SELECT, 0x00, 0x00, 0x00}; + // INITIATE command: wake up the tag using the INITIATE + static const uint8_t init_srx[] = { ISO14443B_INITIATE, 0x00, 0x97, 0x5b }; + // SELECT command (with space for CRC) + uint8_t select_srx[] = { ISO14443B_SELECT, 0x00, 0x00, 0x00}; - CodeAndTransmit14443bAsReader(init_srx, sizeof(init_srx)); - GetTagSamplesFor14443bDemod(); //no + CodeAndTransmit14443bAsReader(init_srx, sizeof(init_srx)); + GetTagSamplesFor14443bDemod(); //no - if (Demod.len == 0) - return 2; + if (Demod.len == 0) + return 2; - // Randomly generated Chip ID - if (card) card->chipid = Demod.output[0]; + // Randomly generated Chip ID + if (card) card->chipid = Demod.output[0]; - select_srx[1] = Demod.output[0]; + select_srx[1] = Demod.output[0]; - AddCrc14B(select_srx, 2); + AddCrc14B(select_srx, 2); - CodeAndTransmit14443bAsReader(select_srx, sizeof(select_srx)); - GetTagSamplesFor14443bDemod(); //no + CodeAndTransmit14443bAsReader(select_srx, sizeof(select_srx)); + GetTagSamplesFor14443bDemod(); //no - if (Demod.len != 3) - return 2; + if (Demod.len != 3) + return 2; - // Check the CRC of the answer: - if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) - return 3; + // Check the CRC of the answer: + if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) + return 3; - // Check response from the tag: should be the same UID as the command we just sent: - if (select_srx[1] != Demod.output[0]) - return 1; + // Check response from the tag: should be the same UID as the command we just sent: + if (select_srx[1] != Demod.output[0]) + return 1; - // First get the tag's UID: - select_srx[0] = ISO14443B_GET_UID; + // First get the tag's UID: + select_srx[0] = ISO14443B_GET_UID; - AddCrc14B(select_srx, 1); - CodeAndTransmit14443bAsReader(select_srx, 3); // Only first three bytes for this one - GetTagSamplesFor14443bDemod(); //no + AddCrc14B(select_srx, 1); + CodeAndTransmit14443bAsReader(select_srx, 3); // Only first three bytes for this one + GetTagSamplesFor14443bDemod(); //no - if (Demod.len != 10) - return 2; + if (Demod.len != 10) + return 2; - // The check the CRC of the answer - if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) - return 3; + // The check the CRC of the answer + if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) + return 3; - if (card) { - card->uidlen = 8; - memcpy(card->uid, Demod.output, 8); - } + if (card) { + card->uidlen = 8; + memcpy(card->uid, Demod.output, 8); + } - return 0; + return 0; } /* Perform the ISO 14443 B Card Selection procedure * Currently does NOT do any collision handling. @@ -1231,29 +1231,29 @@ uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card ) { * TODO: Verify CRC checksums */ uint8_t iso14443b_select_card(iso14b_card_select_t *card ) { - // WUPB command (including CRC) - // Note: WUPB wakes up all tags, REQB doesn't wake up tags in HALT state - static const uint8_t wupb[] = { ISO14443B_REQB, 0x00, 0x08, 0x39, 0x73 }; - // ATTRIB command (with space for CRC) - uint8_t attrib[] = { ISO14443B_ATTRIB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00}; + // WUPB command (including CRC) + // Note: WUPB wakes up all tags, REQB doesn't wake up tags in HALT state + static const uint8_t wupb[] = { ISO14443B_REQB, 0x00, 0x08, 0x39, 0x73 }; + // ATTRIB command (with space for CRC) + uint8_t attrib[] = { ISO14443B_ATTRIB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00}; - // first, wake up the tag - CodeAndTransmit14443bAsReader(wupb, sizeof(wupb)); - GetTagSamplesFor14443bDemod(); //select_card + // first, wake up the tag + CodeAndTransmit14443bAsReader(wupb, sizeof(wupb)); + GetTagSamplesFor14443bDemod(); //select_card - // ATQB too short? - if (Demod.len < 14) - return 2; + // ATQB too short? + if (Demod.len < 14) + return 2; - // VALIDATE CRC - if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) - return 3; + // VALIDATE CRC + if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) + return 3; - if (card) { - card->uidlen = 4; - memcpy(card->uid, Demod.output+1, 4); - memcpy(card->atqb, Demod.output+5, 7); - } + if (card) { + card->uidlen = 4; + memcpy(card->uid, Demod.output+1, 4); + memcpy(card->atqb, Demod.output+5, 7); + } // copy the PUPI to ATTRIB ( PUPI == UID ) memcpy(attrib + 1, Demod.output + 1, 4); @@ -1267,63 +1267,63 @@ uint8_t iso14443b_select_card(iso14b_card_select_t *card ) { // Answer to ATTRIB too short? if(Demod.len < 3) - return 2; + return 2; - // VALIDATE CRC - if (!check_crc(CRC_14443_B, Demod.output, Demod.len) ) - return 3; + // VALIDATE CRC + if (!check_crc(CRC_14443_B, Demod.output, Demod.len) ) + return 3; - if (card) { + if (card) { - // CID - card->cid = Demod.output[0]; + // CID + card->cid = Demod.output[0]; - // MAX FRAME - uint16_t maxFrame = card->atqb[5] >> 4; - if (maxFrame < 5) maxFrame = 8 * maxFrame + 16; - else if (maxFrame == 5) maxFrame = 64; - else if (maxFrame == 6) maxFrame = 96; - else if (maxFrame == 7) maxFrame = 128; - else if (maxFrame == 8) maxFrame = 256; - else maxFrame = 257; - iso14b_set_maxframesize(maxFrame); + // MAX FRAME + uint16_t maxFrame = card->atqb[5] >> 4; + if (maxFrame < 5) maxFrame = 8 * maxFrame + 16; + else if (maxFrame == 5) maxFrame = 64; + else if (maxFrame == 6) maxFrame = 96; + else if (maxFrame == 7) maxFrame = 128; + else if (maxFrame == 8) maxFrame = 256; + else maxFrame = 257; + iso14b_set_maxframesize(maxFrame); - // FWT - uint8_t fwt = card->atqb[6] >> 4; - if ( fwt < 16 ){ - uint32_t fwt_time = (302 << fwt); - iso14b_set_timeout( fwt_time); - } - } - // reset PCB block number - pcb_blocknum = 0; - return 0; + // FWT + uint8_t fwt = card->atqb[6] >> 4; + if ( fwt < 16 ){ + uint32_t fwt_time = (302 << fwt); + iso14b_set_timeout( fwt_time); + } + } + // reset PCB block number + pcb_blocknum = 0; + return 0; } // Set up ISO 14443 Type B communication (similar to iso14443a_setup) // field is setup for "Sending as Reader" void iso14443b_setup() { - LEDsoff(); - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + LEDsoff(); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - // Initialize Demod and Uart structs - DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); - UartInit(BigBuf_malloc(MAX_FRAME_SIZE)); + // Initialize Demod and Uart structs + DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); + UartInit(BigBuf_malloc(MAX_FRAME_SIZE)); - // connect Demodulated Signal to ADC: - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + // connect Demodulated Signal to ADC: + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - // Set up the synchronous serial port - FpgaSetupSsc(); + // Set up the synchronous serial port + FpgaSetupSsc(); - // Signal field is on with the appropriate LED - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD); - SpinDelay(100); + // Signal field is on with the appropriate LED + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD); + SpinDelay(100); - // Start the timer - StartCountSspClk(); + // Start the timer + StartCountSspClk(); - LED_D_ON(); + LED_D_ON(); } //----------------------------------------------------------------------------- @@ -1336,106 +1336,106 @@ void iso14443b_setup() { // I tried to be systematic and check every answer of the tag, every CRC, etc... //----------------------------------------------------------------------------- static bool ReadSTBlock(uint8_t block) { - uint8_t cmd[] = {ISO14443B_READ_BLK, block, 0x00, 0x00}; - AddCrc14B(cmd, 2); - CodeAndTransmit14443bAsReader(cmd, sizeof(cmd)); - GetTagSamplesFor14443bDemod(); + uint8_t cmd[] = {ISO14443B_READ_BLK, block, 0x00, 0x00}; + AddCrc14B(cmd, 2); + CodeAndTransmit14443bAsReader(cmd, sizeof(cmd)); + GetTagSamplesFor14443bDemod(); - // Check if we got an answer from the tag - if (Demod.len != 6) { - DbpString("[!] expected 6 bytes from tag, got less..."); - return false; - } - // The check the CRC of the answer - if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) { - DbpString("[!] CRC Error block!"); - return false; - } - return true; + // Check if we got an answer from the tag + if (Demod.len != 6) { + DbpString("[!] expected 6 bytes from tag, got less..."); + return false; + } + // The check the CRC of the answer + if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) { + DbpString("[!] CRC Error block!"); + return false; + } + return true; } void ReadSTMemoryIso14443b(uint8_t numofblocks) { - // Make sure that we start from off, since the tags are stateful; - // confusing things will happen if we don't reset them between reads. - //switch_off(); + // Make sure that we start from off, since the tags are stateful; + // confusing things will happen if we don't reset them between reads. + //switch_off(); - uint8_t i = 0x00; - uint8_t *buf = BigBuf_malloc(sizeof(iso14b_card_select_t)); + uint8_t i = 0x00; + uint8_t *buf = BigBuf_malloc(sizeof(iso14b_card_select_t)); - iso14443b_setup(); + iso14443b_setup(); - iso14b_card_select_t *card = (iso14b_card_select_t*)buf; - uint8_t res = iso14443b_select_srx_card(card); + iso14b_card_select_t *card = (iso14b_card_select_t*)buf; + uint8_t res = iso14443b_select_srx_card(card); - // 0: OK 2: attrib fail, 3:crc fail, - if ( res > 0 ) goto out; + // 0: OK 2: attrib fail, 3:crc fail, + if ( res > 0 ) goto out; - Dbprintf("[+] Tag memory dump, block 0 to %d", numofblocks); + Dbprintf("[+] Tag memory dump, block 0 to %d", numofblocks); - ++numofblocks; + ++numofblocks; - for (;;) { - if (i == numofblocks) { - DbpString("System area block (0xFF):"); - i = 0xff; - } + for (;;) { + if (i == numofblocks) { + DbpString("System area block (0xFF):"); + i = 0xff; + } - uint8_t retries = 3; - do { - res = ReadSTBlock(i); - } while (!res && --retries); + uint8_t retries = 3; + do { + res = ReadSTBlock(i); + } while (!res && --retries); - if (!res && !retries) { - goto out; - } + if (!res && !retries) { + goto out; + } - // Now print out the memory location: - Dbprintf("Address=%02x, Contents=%08x, CRC=%04x", i, - (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0], - (Demod.output[4]<<8)+Demod.output[5]); + // Now print out the memory location: + Dbprintf("Address=%02x, Contents=%08x, CRC=%04x", i, + (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0], + (Demod.output[4]<<8)+Demod.output[5]); - if (i == 0xff) break; - ++i; - } + if (i == 0xff) break; + ++i; + } out: - switch_off(); // disconnect raw - SpinDelay(20); + switch_off(); // disconnect raw + SpinDelay(20); } static void iso1444b_setup_sniff(void){ - LEDsoff(); - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - BigBuf_free(); - BigBuf_Clear_ext(false); - clear_trace();//setup snoop - set_tracing(true); + LEDsoff(); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + BigBuf_free(); + BigBuf_Clear_ext(false); + clear_trace();//setup snoop + set_tracing(true); - // Initialize Demod and Uart structs - DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); - UartInit(BigBuf_malloc(MAX_FRAME_SIZE)); + // Initialize Demod and Uart structs + DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); + UartInit(BigBuf_malloc(MAX_FRAME_SIZE)); - if (MF_DBGLEVEL > 1) { - // Print debug information about the buffer sizes - Dbprintf("[+] Sniff buffers initialized:"); - Dbprintf("[+] trace: %i bytes", BigBuf_max_traceLen()); - Dbprintf("[+] reader -> tag: %i bytes", MAX_FRAME_SIZE); - Dbprintf("[+] tag -> reader: %i bytes", MAX_FRAME_SIZE); - Dbprintf("[+] DMA: %i bytes", ISO14443B_DMA_BUFFER_SIZE); - } + if (MF_DBGLEVEL > 1) { + // Print debug information about the buffer sizes + Dbprintf("[+] Sniff buffers initialized:"); + Dbprintf("[+] trace: %i bytes", BigBuf_max_traceLen()); + Dbprintf("[+] reader -> tag: %i bytes", MAX_FRAME_SIZE); + Dbprintf("[+] tag -> reader: %i bytes", MAX_FRAME_SIZE); + Dbprintf("[+] DMA: %i bytes", ISO14443B_DMA_BUFFER_SIZE); + } - // connect Demodulated Signal to ADC: - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + // connect Demodulated Signal to ADC: + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - // Setup for the DMA. - FpgaSetupSsc(); + // Setup for the DMA. + FpgaSetupSsc(); - // Set FPGA in the appropriate mode - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | FPGA_HF_READER_RX_XCORR_SNOOP); - SpinDelay(20); + // Set FPGA in the appropriate mode + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | FPGA_HF_READER_RX_XCORR_SNOOP); + SpinDelay(20); - // Start the SSP timer - StartCountSspClk(); + // Start the SSP timer + StartCountSspClk(); } //============================================================================= @@ -1457,98 +1457,98 @@ static void iso1444b_setup_sniff(void){ */ void RAMFUNC SniffIso14443b(void) { - uint32_t time_0 = 0, time_start = 0, time_stop = 0; - int ci = 0, cq = 0; + uint32_t time_0 = 0, time_start = 0, time_stop = 0; + int ci = 0, cq = 0; - // 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 - // response from the tag. - bool TagIsActive = false; - bool ReaderIsActive = false; + // 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 + // response from the tag. + bool TagIsActive = false; + bool ReaderIsActive = false; - iso1444b_setup_sniff(); + iso1444b_setup_sniff(); - // The DMA buffer, used to stream samples from the FPGA - int8_t *dmaBuf = (int8_t*) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE); - int8_t *data = dmaBuf; + // The DMA buffer, used to stream samples from the FPGA + int8_t *dmaBuf = (int8_t*) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE); + int8_t *data = dmaBuf; - // Setup and start DMA. - if ( !FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE) ){ - if (MF_DBGLEVEL > 1) Dbprintf("[!] FpgaSetupSscDma failed. Exiting"); - BigBuf_free(); - return; - } + // Setup and start DMA. + if ( !FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE) ){ + if (MF_DBGLEVEL > 1) Dbprintf("[!] FpgaSetupSscDma failed. Exiting"); + BigBuf_free(); + return; + } - // time ZERO, the point from which it all is calculated. - time_0 = GetCountSspClk(); + // time ZERO, the point from which it all is calculated. + time_0 = GetCountSspClk(); // loop and listen - while (!BUTTON_PRESS()) { - WDT_HIT(); + while (!BUTTON_PRESS()) { + WDT_HIT(); - ci = data[0]; - cq = data[1]; - data += 2; + ci = data[0]; + cq = data[1]; + data += 2; - if (data >= dmaBuf + ISO14443B_DMA_BUFFER_SIZE) { - data = dmaBuf; - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; - AT91C_BASE_PDC_SSC->PDC_RNCR = ISO14443B_DMA_BUFFER_SIZE; - } + if (data >= dmaBuf + ISO14443B_DMA_BUFFER_SIZE) { + data = dmaBuf; + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; + AT91C_BASE_PDC_SSC->PDC_RNCR = ISO14443B_DMA_BUFFER_SIZE; + } - // no need to try decoding reader data if the tag is sending - if (!TagIsActive) { + // no need to try decoding reader data if the tag is sending + if (!TagIsActive) { - LED_A_INV(); + LED_A_INV(); - if (Handle14443bReaderUartBit(ci & 0x01)) { - time_stop = GetCountSspClk() - time_0; - LogTrace(Uart.output, Uart.byteCnt, time_start, time_stop, NULL, true); - UartReset(); - DemodReset(); - } else { - time_start = GetCountSspClk() - time_0; - } + if (Handle14443bReaderUartBit(ci & 0x01)) { + time_stop = GetCountSspClk() - time_0; + LogTrace(Uart.output, Uart.byteCnt, time_start, time_stop, NULL, true); + UartReset(); + DemodReset(); + } else { + time_start = GetCountSspClk() - time_0; + } - if (Handle14443bReaderUartBit(cq & 0x01)) { - time_stop = GetCountSspClk() - time_0; - LogTrace(Uart.output, Uart.byteCnt, time_start, time_stop, NULL, true); - UartReset(); - DemodReset(); - } else { - time_start = GetCountSspClk() - time_0; - } - ReaderIsActive = (Uart.state > STATE_GOT_FALLING_EDGE_OF_SOF); - } + if (Handle14443bReaderUartBit(cq & 0x01)) { + time_stop = GetCountSspClk() - time_0; + LogTrace(Uart.output, Uart.byteCnt, time_start, time_stop, NULL, true); + UartReset(); + DemodReset(); + } else { + time_start = GetCountSspClk() - time_0; + } + ReaderIsActive = (Uart.state > STATE_GOT_FALLING_EDGE_OF_SOF); + } - // no need to try decoding tag data if the reader is sending - and we cannot afford the time - if (!ReaderIsActive) { + // no need to try decoding tag data if the reader is sending - and we cannot afford the time + if (!ReaderIsActive) { - // is this | 0x01 the error? & 0xfe in https://github.com/Proxmark/proxmark3/issues/103 - // LSB is a fpga signal bit. - if (Handle14443bTagSamplesDemod(ci, cq)) { - time_stop = GetCountSspClk() - time_0; - LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false); - UartReset(); - DemodReset(); - } else { - time_start = GetCountSspClk() - time_0; - } - TagIsActive = (Demod.state > DEMOD_GOT_FALLING_EDGE_OF_SOF); - } - } + // is this | 0x01 the error? & 0xfe in https://github.com/Proxmark/proxmark3/issues/103 + // LSB is a fpga signal bit. + if (Handle14443bTagSamplesDemod(ci, cq)) { + time_stop = GetCountSspClk() - time_0; + LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false); + UartReset(); + DemodReset(); + } else { + time_start = GetCountSspClk() - time_0; + } + TagIsActive = (Demod.state > DEMOD_GOT_FALLING_EDGE_OF_SOF); + } + } - if (MF_DBGLEVEL >= 2) { - DbpString("[+] Sniff statistics:"); - Dbprintf("[+] uart State: %x ByteCount: %i ByteCountMax: %i", Uart.state, Uart.byteCnt, Uart.byteCntMax); - Dbprintf("[+] trace length: %i", BigBuf_get_traceLen()); - } + if (MF_DBGLEVEL >= 2) { + DbpString("[+] Sniff statistics:"); + Dbprintf("[+] uart State: %x ByteCount: %i ByteCountMax: %i", Uart.state, Uart.byteCnt, Uart.byteCntMax); + Dbprintf("[+] trace length: %i", BigBuf_get_traceLen()); + } - switch_off(); + switch_off(); } void iso14b_set_trigger(bool enable) { - trigger = enable; + trigger = enable; } /* @@ -1563,70 +1563,70 @@ void iso14b_set_trigger(bool enable) { * */ void SendRawCommand14443B_Ex(UsbCommand *c) { - iso14b_command_t param = c->arg[0]; - size_t len = c->arg[1] & 0xffff; - uint8_t *cmd = c->d.asBytes; - uint8_t status = 0; - uint32_t sendlen = sizeof(iso14b_card_select_t); - uint8_t buf[USB_CMD_DATA_SIZE] = {0x00}; + iso14b_command_t param = c->arg[0]; + size_t len = c->arg[1] & 0xffff; + uint8_t *cmd = c->d.asBytes; + uint8_t status = 0; + uint32_t sendlen = sizeof(iso14b_card_select_t); + uint8_t buf[USB_CMD_DATA_SIZE] = {0x00}; - if (MF_DBGLEVEL > 3) Dbprintf("14b raw: param, %04x", param ); + if (MF_DBGLEVEL > 3) Dbprintf("14b raw: param, %04x", param ); - // turn on trigger (LED_A) - if ((param & ISO14B_REQUEST_TRIGGER) == ISO14B_REQUEST_TRIGGER) - iso14b_set_trigger(true); + // turn on trigger (LED_A) + if ((param & ISO14B_REQUEST_TRIGGER) == ISO14B_REQUEST_TRIGGER) + iso14b_set_trigger(true); - if ((param & ISO14B_CONNECT) == ISO14B_CONNECT) { - iso14443b_setup(); - clear_trace(); - } + if ((param & ISO14B_CONNECT) == ISO14B_CONNECT) { + iso14443b_setup(); + clear_trace(); + } - set_tracing(true); + set_tracing(true); - if ((param & ISO14B_SELECT_STD) == ISO14B_SELECT_STD) { - iso14b_card_select_t *card = (iso14b_card_select_t*)buf; - status = iso14443b_select_card(card); - cmd_send(CMD_ACK, status, sendlen, 0, buf, sendlen); - // 0: OK 2: attrib fail, 3:crc fail, - if ( status > 0 ) goto out; - } + if ((param & ISO14B_SELECT_STD) == ISO14B_SELECT_STD) { + iso14b_card_select_t *card = (iso14b_card_select_t*)buf; + status = iso14443b_select_card(card); + cmd_send(CMD_ACK, status, sendlen, 0, buf, sendlen); + // 0: OK 2: attrib fail, 3:crc fail, + if ( status > 0 ) goto out; + } - if ((param & ISO14B_SELECT_SR) == ISO14B_SELECT_SR) { - iso14b_card_select_t *card = (iso14b_card_select_t*)buf; - status = iso14443b_select_srx_card(card); - cmd_send(CMD_ACK, status, sendlen, 0, buf, sendlen); - // 0: OK 2: demod fail, 3:crc fail, - if ( status > 0 ) goto out; - } + if ((param & ISO14B_SELECT_SR) == ISO14B_SELECT_SR) { + iso14b_card_select_t *card = (iso14b_card_select_t*)buf; + status = iso14443b_select_srx_card(card); + cmd_send(CMD_ACK, status, sendlen, 0, buf, sendlen); + // 0: OK 2: demod fail, 3:crc fail, + if ( status > 0 ) goto out; + } - if ((param & ISO14B_APDU) == ISO14B_APDU) { - status = iso14443b_apdu(cmd, len, buf); - cmd_send(CMD_ACK, status, status, 0, buf, status); - } + if ((param & ISO14B_APDU) == ISO14B_APDU) { + status = iso14443b_apdu(cmd, len, buf); + cmd_send(CMD_ACK, status, status, 0, buf, status); + } - if ((param & ISO14B_RAW) == ISO14B_RAW) { - if((param & ISO14B_APPEND_CRC) == ISO14B_APPEND_CRC) { - AddCrc14B(cmd, len); - len += 2; - } + if ((param & ISO14B_RAW) == ISO14B_RAW) { + if((param & ISO14B_APPEND_CRC) == ISO14B_APPEND_CRC) { + AddCrc14B(cmd, len); + len += 2; + } - CodeAndTransmit14443bAsReader(cmd, len); // raw - GetTagSamplesFor14443bDemod(); // raw + CodeAndTransmit14443bAsReader(cmd, len); // raw + GetTagSamplesFor14443bDemod(); // raw - sendlen = MIN(Demod.len, USB_CMD_DATA_SIZE); - status = (Demod.len > 0) ? 0 : 1; - cmd_send(CMD_ACK, status, sendlen, 0, Demod.output, sendlen); - } + sendlen = MIN(Demod.len, USB_CMD_DATA_SIZE); + status = (Demod.len > 0) ? 0 : 1; + cmd_send(CMD_ACK, status, sendlen, 0, Demod.output, sendlen); + } out: - // turn off trigger (LED_A) - if ((param & ISO14B_REQUEST_TRIGGER) == ISO14B_REQUEST_TRIGGER) - iso14b_set_trigger(false); + // turn off trigger (LED_A) + if ((param & ISO14B_REQUEST_TRIGGER) == ISO14B_REQUEST_TRIGGER) + iso14b_set_trigger(false); - // turn off antenna et al - // we don't send a HALT command. - if ((param & ISO14B_DISCONNECT) == ISO14B_DISCONNECT) { - switch_off(); // disconnect raw - SpinDelay(20); - } + // turn off antenna et al + // we don't send a HALT command. + if ((param & ISO14B_DISCONNECT) == ISO14B_DISCONNECT) { + switch_off(); // disconnect raw + SpinDelay(20); + } } \ No newline at end of file diff --git a/armsrc/iso14443b.h b/armsrc/iso14443b.h index 84765537a..c7e98f182 100644 --- a/armsrc/iso14443b.h +++ b/armsrc/iso14443b.h @@ -18,7 +18,7 @@ extern "C" { #endif #include "proxmark3.h" -#include "common.h" // access to global variable: MF_DBGLEVEL +#include "common.h" // access to global variable: MF_DBGLEVEL #include "apps.h" #include "util.h" #include "string.h" @@ -27,11 +27,11 @@ extern "C" { #include "protocols.h" #ifndef AddCrc14A -# define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1) +# define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1) #endif #ifndef AddCrc14B -# define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1) +# define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1) #endif extern void SendRawCommand14443B_Ex(UsbCommand *c); @@ -45,13 +45,13 @@ extern void WaitForFpgaDelayQueueIsEmpty( uint16_t delay ); extern void ClearFpgaShiftingRegisters(void); // States for 14B SIM command -#define SIM_NOFIELD 0 -#define SIM_IDLE 1 -#define SIM_HALTED 2 -#define SIM_SELECTING 3 -#define SIM_HALTING 4 +#define SIM_NOFIELD 0 +#define SIM_IDLE 1 +#define SIM_HALTED 2 +#define SIM_SELECTING 3 +#define SIM_HALTING 4 #define SIM_ACKNOWLEDGE 5 -#define SIM_WORK 6 +#define SIM_WORK 6 #ifdef __cplusplus } diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 61e0e1130..1afaac95f 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -24,21 +24,21 @@ // // VCD (reader) -> VICC (tag) // 1 out of 256: -// data rate: 1,66 kbit/s (fc/8192) -// used for long range +// data rate: 1,66 kbit/s (fc/8192) +// used for long range // 1 out of 4: -// data rate: 26,48 kbit/s (fc/512) -// used for short range, high speed +// data rate: 26,48 kbit/s (fc/512) +// used for short range, high speed // // VICC (tag) -> VCD (reader) // Modulation: -// ASK / one subcarrier (423,75 khz) -// FSK / two subcarriers (423,75 khz && 484,28 khz) +// ASK / one subcarrier (423,75 khz) +// FSK / two subcarriers (423,75 khz && 484,28 khz) // Data Rates / Modes: -// low ASK: 6,62 kbit/s -// low FSK: 6.67 kbit/s -// high ASK: 26,48 kbit/s -// high FSK: 26,69 kbit/s +// low ASK: 6,62 kbit/s +// low FSK: 6.67 kbit/s +// high ASK: 26,48 kbit/s +// high FSK: 26,69 kbit/s //----------------------------------------------------------------------------- // added "1 out of 256" mode (for VCD->PICC) - atrox 20100911 @@ -54,8 +54,8 @@ // *) add anti-collission support for inventory-commands // *) read security status of a block // *) sniffing and simulation do only support one transmission mode. need to support -// all 8 transmission combinations -// *) remove or refactor code under "depricated" +// all 8 transmission combinations +// *) remove or refactor code under "depricated" // *) document all the functions #include "proxmark3.h" @@ -71,21 +71,21 @@ /////////////////////////////////////////////////////////////////////// // 32 + 2 crc + 1 -#define ISO15_MAX_FRAME 35 -#define CMD_ID_RESP 5 -#define CMD_READ_RESP 13 -#define CMD_INV_RESP 12 +#define ISO15_MAX_FRAME 35 +#define CMD_ID_RESP 5 +#define CMD_READ_RESP 13 +#define CMD_INV_RESP 12 #define FrameSOF Iso15693FrameSOF #define Logic0 Iso15693Logic0 #define Logic1 Iso15693Logic1 #define FrameEOF Iso15693FrameEOF -#define Crc(data, len) crc(CRC_15693, (data), (len)) -#define CheckCrc(data, len) check_crc(CRC_15693, (data), (len)) -#define AddCrc(data, len) compute_crc(CRC_15693, (data), (len), (data)+(len), (data)+(len)+1) +#define Crc(data, len) crc(CRC_15693, (data), (len)) +#define CheckCrc(data, len) check_crc(CRC_15693, (data), (len)) +#define AddCrc(data, len) compute_crc(CRC_15693, (data), (len), (data)+(len), (data)+(len)+1) -#define sprintUID(target,uid) Iso15693sprintUID((target), (uid)) +#define sprintUID(target,uid) Iso15693sprintUID((target), (uid)) static void BuildIdentifyRequest(uint8_t *cmdout); //static void BuildReadBlockRequest(uint8_t *cmdout, uint8_t *uid, uint8_t blockNumber ); @@ -100,156 +100,156 @@ static void BuildInventoryResponse(uint8_t *cmdout, uint8_t *uid); // cmd ... data // n ... length of data static void CodeIso15693AsReader(uint8_t *cmd, int n) { - int i, j; + int i, j; - ToSendReset(); + ToSendReset(); - // Give it a bit of slack at the beginning - for(i = 0; i < 24; i++) - ToSendStuffBit(1); + // Give it a bit of slack at the beginning + for(i = 0; i < 24; i++) + ToSendStuffBit(1); - // SOF for 1of4 - ToSendStuffBit(0); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(0); - ToSendStuffBit(1); - ToSendStuffBit(1); - for(i = 0; i < n; i++) { - for(j = 0; j < 8; j += 2) { - int these = (cmd[i] >> j) & 3; - switch(these) { - case 0: - ToSendStuffBit(1); - ToSendStuffBit(0); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - break; - case 1: - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(0); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - break; - case 2: - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(0); - ToSendStuffBit(1); - ToSendStuffBit(1); - break; - case 3: - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(0); - break; - } - } - } - // EOF - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(0); - ToSendStuffBit(1); + // SOF for 1of4 + ToSendStuffBit(0); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(0); + ToSendStuffBit(1); + ToSendStuffBit(1); + for(i = 0; i < n; i++) { + for(j = 0; j < 8; j += 2) { + int these = (cmd[i] >> j) & 3; + switch(these) { + case 0: + ToSendStuffBit(1); + ToSendStuffBit(0); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + break; + case 1: + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(0); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + break; + case 2: + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(0); + ToSendStuffBit(1); + ToSendStuffBit(1); + break; + case 3: + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(0); + break; + } + } + } + // EOF + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(0); + ToSendStuffBit(1); - // And slack at the end, too. - for(i = 0; i < 24; i++) - ToSendStuffBit(1); + // And slack at the end, too. + for(i = 0; i < 24; i++) + ToSendStuffBit(1); } // encode data using "1 out of 256" sheme // data rate is 1,66 kbit/s (fc/8192) // is designed for more robust communication over longer distances static void CodeIso15693AsReader256(uint8_t *cmd, int n) { - int i, j; + int i, j; - ToSendReset(); + ToSendReset(); - // Give it a bit of slack at the beginning - for(i = 0; i < 24; i++) - ToSendStuffBit(1); + // Give it a bit of slack at the beginning + for(i = 0; i < 24; i++) + ToSendStuffBit(1); - // SOF for 1of256 - ToSendStuffBit(0); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(0); + // SOF for 1of256 + ToSendStuffBit(0); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(0); - for(i = 0; i < n; i++) { - for (j = 0; j <= 255; j++) { - if (cmd[i] == j) { - ToSendStuffBit(1); - ToSendStuffBit(0); - } else { - ToSendStuffBit(1); - ToSendStuffBit(1); - } - } - } - // EOF - ToSendStuffBit(1); - ToSendStuffBit(1); - ToSendStuffBit(0); - ToSendStuffBit(1); + for(i = 0; i < n; i++) { + for (j = 0; j <= 255; j++) { + if (cmd[i] == j) { + ToSendStuffBit(1); + ToSendStuffBit(0); + } else { + ToSendStuffBit(1); + ToSendStuffBit(1); + } + } + } + // EOF + ToSendStuffBit(1); + ToSendStuffBit(1); + ToSendStuffBit(0); + ToSendStuffBit(1); - // And slack at the end, too. - for(i = 0; i < 24; i++) - ToSendStuffBit(1); + // And slack at the end, too. + for(i = 0; i < 24; i++) + ToSendStuffBit(1); } // Transmit the command (to the tag) that was placed in ToSend[]. static void TransmitTo15693Tag(const uint8_t *cmd, int len, int *samples, int *wait) { int c; - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX); - if (wait) { - for (c = 0; c < *wait;) { - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing! - ++c; - } - WDT_HIT(); - } - } + if (wait) { + for (c = 0; c < *wait;) { + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing! + ++c; + } + WDT_HIT(); + } + } c = 0; for(;;) { - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = cmd[c]; if( ++c >= len) break; } WDT_HIT(); } - if (samples) { - if (wait) - *samples = (c + *wait) << 3; - else - *samples = c << 3; - } + if (samples) { + if (wait) + *samples = (c + *wait) << 3; + else + *samples = c << 3; + } } //----------------------------------------------------------------------------- @@ -257,32 +257,32 @@ static void TransmitTo15693Tag(const uint8_t *cmd, int len, int *samples, int *w //----------------------------------------------------------------------------- static void TransmitTo15693Reader(const uint8_t *cmd, int len, int *samples, int *wait) { int c = 0; - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_424K); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_424K); - if (wait) { - for (c = 0; c < *wait;) { - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing! - ++c; - } - WDT_HIT(); - } - } + if (wait) { + for (c = 0; c < *wait;) { + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing! + ++c; + } + WDT_HIT(); + } + } c = 0; for(;;) { - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = cmd[c]; if( ++c >= len) break; } WDT_HIT(); } - if (samples) { - if (wait) - *samples = (c + *wait) << 3; - else - *samples = c << 3; - } + if (samples) { + if (wait) + *samples = (c + *wait) << 3; + else + *samples = c << 3; + } } //----------------------------------------------------------------------------- @@ -290,146 +290,146 @@ static void TransmitTo15693Reader(const uint8_t *cmd, int len, int *samples, int //----------------------------------------------------------------------------- static int DemodAnswer(uint8_t *received, uint8_t *dest, uint16_t samplecount) { - int i, j; - int max = 0, maxPos = 0, skip = 4; - int k = 0; // this will be our return value + int i, j; + int max = 0, maxPos = 0, skip = 4; + int k = 0; // this will be our return value - // First, correlate for SOF - for (i = 0; i < samplecount; i++) { - int corr = 0; - for ( j = 0; j < ARRAYLEN(FrameSOF); j += skip) { - corr += FrameSOF[j] * dest[i+(j/skip)]; - } - if (corr > max) { - max = corr; - maxPos = i; - } - } - // DbpString("SOF at %d, correlation %d", maxPos,max/(ARRAYLEN(FrameSOF)/skip)); + // First, correlate for SOF + for (i = 0; i < samplecount; i++) { + int corr = 0; + for ( j = 0; j < ARRAYLEN(FrameSOF); j += skip) { + corr += FrameSOF[j] * dest[i+(j/skip)]; + } + if (corr > max) { + max = corr; + maxPos = i; + } + } + // DbpString("SOF at %d, correlation %d", maxPos,max/(ARRAYLEN(FrameSOF)/skip)); - // greg - If correlation is less than 1 then there's little point in continuing - if ((max / (ARRAYLEN(FrameSOF)/skip) ) < 1) - return k; + // greg - If correlation is less than 1 then there's little point in continuing + if ((max / (ARRAYLEN(FrameSOF)/skip) ) < 1) + return k; - i = maxPos + ARRAYLEN(FrameSOF) / skip; + i = maxPos + ARRAYLEN(FrameSOF) / skip; - uint8_t outBuf[ISO15_MAX_FRAME]; - memset(outBuf, 0, sizeof(outBuf)); - uint8_t mask = 0x01; - for(;;) { - int corr0 = 0, corr1 = 0, corrEOF = 0; - for (j = 0; j < ARRAYLEN(Logic0); j += skip) { - corr0 += Logic0[j] * dest[i+(j/skip)]; - } - for (j = 0; j < ARRAYLEN(Logic1); j += skip) { - corr1 += Logic1[j] * dest[i+(j/skip)]; - } - for (j = 0; j < ARRAYLEN(FrameEOF); j += skip) { - corrEOF += FrameEOF[j] * dest[i+(j/skip)]; - } - // Even things out by the length of the target waveform. - corr0 *= 4; - corr1 *= 4; - // if (MF_DBGLEVEL >= MF_DBG_EXTENDED) - // Dbprintf("Corr1 %d, Corr0 %d, CorrEOF %d", corr1, corr0, corrEOF); + uint8_t outBuf[ISO15_MAX_FRAME]; + memset(outBuf, 0, sizeof(outBuf)); + uint8_t mask = 0x01; + for(;;) { + int corr0 = 0, corr1 = 0, corrEOF = 0; + for (j = 0; j < ARRAYLEN(Logic0); j += skip) { + corr0 += Logic0[j] * dest[i+(j/skip)]; + } + for (j = 0; j < ARRAYLEN(Logic1); j += skip) { + corr1 += Logic1[j] * dest[i+(j/skip)]; + } + for (j = 0; j < ARRAYLEN(FrameEOF); j += skip) { + corrEOF += FrameEOF[j] * dest[i+(j/skip)]; + } + // Even things out by the length of the target waveform. + corr0 *= 4; + corr1 *= 4; + // if (MF_DBGLEVEL >= MF_DBG_EXTENDED) + // Dbprintf("Corr1 %d, Corr0 %d, CorrEOF %d", corr1, corr0, corrEOF); - if (corrEOF > corr1 && corrEOF > corr0) - break; + if (corrEOF > corr1 && corrEOF > corr0) + break; - if (corr1 > corr0) { - i += ARRAYLEN(Logic1) / skip; - outBuf[k] |= mask; - } else { - i += ARRAYLEN(Logic0) / skip; - } + if (corr1 > corr0) { + i += ARRAYLEN(Logic1) / skip; + outBuf[k] |= mask; + } else { + i += ARRAYLEN(Logic0) / skip; + } - mask <<= 1; + mask <<= 1; - if (mask == 0) { - k++; - mask = 0x01; - } + if (mask == 0) { + k++; + mask = 0x01; + } - if ( ( i + (int)ARRAYLEN(FrameEOF)) >= samplecount-1) { - //Dbprintf("[!] ran off end! %d | %d",( i + (int)ARRAYLEN(FrameEOF)), samplecount-1); - break; - } - } + if ( ( i + (int)ARRAYLEN(FrameEOF)) >= samplecount-1) { + //Dbprintf("[!] ran off end! %d | %d",( i + (int)ARRAYLEN(FrameEOF)), samplecount-1); + break; + } + } - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("ice: demod bytes %u", k); + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("ice: demod bytes %u", k); - if (mask != 0x01) { // this happens, when we miss the EOF + if (mask != 0x01) { // this happens, when we miss the EOF - // TODO: for some reason this happens quite often - if (MF_DBGLEVEL >= MF_DBG_ERROR && k != 0) Dbprintf("[!] error, uneven octet! (extra bits!) mask %02x", mask); - //if (mask < 0x08) k--; // discard the last uneven octet; - // 0x08 is an assumption - but works quite often - } + // TODO: for some reason this happens quite often + if (MF_DBGLEVEL >= MF_DBG_ERROR && k != 0) Dbprintf("[!] error, uneven octet! (extra bits!) mask %02x", mask); + //if (mask < 0x08) k--; // discard the last uneven octet; + // 0x08 is an assumption - but works quite often + } - for(i = 0; i < k; i++) - received[i] = outBuf[i]; + for(i = 0; i < k; i++) + received[i] = outBuf[i]; - // return the number of bytes demodulated - return k; + // return the number of bytes demodulated + return k; } // Read from Tag // Parameters: -// received -// samples -// elapsed +// received +// samples +// elapsed // returns: -// number of decoded bytes +// number of decoded bytes // logging enabled static int GetIso15693AnswerFromTag(uint8_t *received, int *elapsed) { #define SIGNAL_BUFF_SIZE 15000 - // get current clock - uint32_t time_0 = GetCountSspClk(); - uint32_t time_stop = 0; - bool getNext = false; - int counter = 0, ci = 0, cq = 0; - uint8_t *buf = BigBuf_malloc(SIGNAL_BUFF_SIZE); + // get current clock + uint32_t time_0 = GetCountSspClk(); + uint32_t time_stop = 0; + bool getNext = false; + int counter = 0, ci = 0, cq = 0; + uint8_t *buf = BigBuf_malloc(SIGNAL_BUFF_SIZE); - if (elapsed) *elapsed = 0; + if (elapsed) *elapsed = 0; - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); - for(;;) { - WDT_HIT(); + for(;;) { + WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0x00; //0x43; - // To make use of exact timing of next command from reader!! - if (elapsed) (*elapsed)++; - } - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = 0x00; //0x43; + // To make use of exact timing of next command from reader!! + if (elapsed) (*elapsed)++; + } + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - ci = (int8_t)AT91C_BASE_SSC->SSC_RHR; - ci = ABS(ci); + ci = (int8_t)AT91C_BASE_SSC->SSC_RHR; + ci = ABS(ci); - // The samples are correlations against I and Q versions of the - // tone that the tag AM-modulates, so every other sample is I, - // every other is Q. We just want power, so abs(I) + abs(Q) is - // close to what we want. - // iceman 2016, amplitude sqrt(abs(i) + abs(q)) - if (getNext) { + // The samples are correlations against I and Q versions of the + // tone that the tag AM-modulates, so every other sample is I, + // every other is Q. We just want power, so abs(I) + abs(Q) is + // close to what we want. + // iceman 2016, amplitude sqrt(abs(i) + abs(q)) + if (getNext) { - buf[counter++] = (uint8_t)(MAX(ci,cq) + (MIN(ci, cq) >> 1)); + buf[counter++] = (uint8_t)(MAX(ci,cq) + (MIN(ci, cq) >> 1)); - if (counter >= SIGNAL_BUFF_SIZE) - break; - } else { - cq = ci; - } - getNext = !getNext; - } - } - time_stop = GetCountSspClk() - time_0 ; - int len = DemodAnswer(received, buf, counter); - LogTrace(received, len, time_0 << 4, time_stop << 4, NULL, false); - BigBuf_free(); - return len; + if (counter >= SIGNAL_BUFF_SIZE) + break; + } else { + cq = ci; + } + getNext = !getNext; + } + } + time_stop = GetCountSspClk() - time_0 ; + int len = DemodAnswer(received, buf, counter); + LogTrace(received, len, time_0 << 4, time_stop << 4, NULL, false); + BigBuf_free(); + return len; } @@ -437,45 +437,45 @@ static int GetIso15693AnswerFromTag(uint8_t *received, int *elapsed) { // logging enable, static int GetIso15693AnswerFromSniff(uint8_t *received, int *samples, int *elapsed) { - bool getNext = false; - int counter = 0, ci = 0, cq = 0; - uint32_t time_0 = 0, time_stop = 0; - uint8_t *buf = BigBuf_get_addr(); + bool getNext = false; + int counter = 0, ci = 0, cq = 0; + uint32_t time_0 = 0, time_stop = 0; + uint8_t *buf = BigBuf_get_addr(); - // get current clock - time_0 = GetCountSspClk(); + // get current clock + time_0 = GetCountSspClk(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); - for(;;) { - WDT_HIT(); + for(;;) { + WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - ci = (int8_t)AT91C_BASE_SSC->SSC_RHR; - ci = ABS(ci); + ci = (int8_t)AT91C_BASE_SSC->SSC_RHR; + ci = ABS(ci); - // The samples are correlations against I and Q versions of the - // tone that the tag AM-modulates, so every other sample is I, - // every other is Q. We just want power, so abs(I) + abs(Q) is - // close to what we want. - if (getNext) { + // The samples are correlations against I and Q versions of the + // tone that the tag AM-modulates, so every other sample is I, + // every other is Q. We just want power, so abs(I) + abs(Q) is + // close to what we want. + if (getNext) { - buf[counter++] = (uint8_t)(MAX(ci,cq) + (MIN(ci, cq) >> 1)); + buf[counter++] = (uint8_t)(MAX(ci,cq) + (MIN(ci, cq) >> 1)); - if(counter >= 20000) - break; - } else { - cq = ci; - } - getNext = !getNext; - } - } + if(counter >= 20000) + break; + } else { + cq = ci; + } + getNext = !getNext; + } + } - time_stop = GetCountSspClk() - time_0; - int k = DemodAnswer(received, buf, counter); - LogTrace(received, k, time_0 << 4, time_stop << 4, NULL, false); - return k; + time_stop = GetCountSspClk() - time_0; + int k = DemodAnswer(received, buf, counter); + LogTrace(received, k, time_0 << 4, time_stop << 4, NULL, false); + return k; } //----------------------------------------------------------------------------- @@ -484,134 +484,134 @@ static int GetIso15693AnswerFromSniff(uint8_t *received, int *samples, int *elap // so that it can be downloaded to a PC and processed there. //----------------------------------------------------------------------------- void AcquireRawAdcSamplesIso15693(void) { - int c = 0, getNext = false; - int ci = 0, cq = 0; + int c = 0, getNext = false; + int ci = 0, cq = 0; - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - FpgaSetupSsc(); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + FpgaSetupSsc(); - // Now send the command - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX); - SpinDelay(200); + // Now send the command + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX); + SpinDelay(200); - uint8_t *buf = BigBuf_get_addr(); + uint8_t *buf = BigBuf_get_addr(); - uint32_t time_start = GetCountSspClk(); - uint8_t cmd[CMD_ID_RESP] = {0}; - BuildIdentifyRequest(cmd); + uint32_t time_start = GetCountSspClk(); + uint8_t cmd[CMD_ID_RESP] = {0}; + BuildIdentifyRequest(cmd); - // sending command - c = 0; - for(;;) { - WDT_HIT(); + // sending command + c = 0; + for(;;) { + WDT_HIT(); - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = ToSend[c]; - c++; - if(c == ToSendMax + 3) { - break; - } - } - } + if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = ToSend[c]; + c++; + if(c == ToSendMax + 3) { + break; + } + } + } - LogTrace(cmd, CMD_ID_RESP, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true); + LogTrace(cmd, CMD_ID_RESP, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); - c = 0; - for(;;) { - WDT_HIT(); + c = 0; + for(;;) { + WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - ci = (int8_t)AT91C_BASE_SSC->SSC_RHR; - ci = ABS(ci); + ci = (int8_t)AT91C_BASE_SSC->SSC_RHR; + ci = ABS(ci); - // The samples are correlations against I and Q versions of the - // tone that the tag AM-modulates, so every other sample is I, - // every other is Q. We just want power, so abs(I) + abs(Q) is - // close to what we want. - // iceman 2016, amplitude sqrt(abs(i) + abs(q)) - if (getNext) { + // The samples are correlations against I and Q versions of the + // tone that the tag AM-modulates, so every other sample is I, + // every other is Q. We just want power, so abs(I) + abs(Q) is + // close to what we want. + // iceman 2016, amplitude sqrt(abs(i) + abs(q)) + if (getNext) { - buf[c++] = (uint8_t)(MAX(ci,cq) + (MIN(ci, cq) >> 1)); + buf[c++] = (uint8_t)(MAX(ci,cq) + (MIN(ci, cq) >> 1)); - if (c >= 7000) break; + if (c >= 7000) break; - } else { - cq = ci; - } - getNext = !getNext; - } - } + } else { + cq = ci; + } + getNext = !getNext; + } + } } // switch_off, initreader, no logging void RecordRawAdcSamplesIso15693(void) { - int c = 0, getNext = false; - int ci = 0, cq = 0; + int c = 0, getNext = false; + int ci = 0, cq = 0; - Iso15693InitReader(); + Iso15693InitReader(); - uint8_t *buf = BigBuf_get_addr(); + uint8_t *buf = BigBuf_get_addr(); - for(;;) { - WDT_HIT(); + for(;;) { + WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - ci = (int8_t)AT91C_BASE_SSC->SSC_RHR; - ci = ABS(ci); - // The samples are correlations against I and Q versions of the - // tone that the tag AM-modulates, so every other sample is I, - // every other is Q. We just want power, so abs(I) + abs(Q) is - // close to what we want. - if (getNext) { + ci = (int8_t)AT91C_BASE_SSC->SSC_RHR; + ci = ABS(ci); + // The samples are correlations against I and Q versions of the + // tone that the tag AM-modulates, so every other sample is I, + // every other is Q. We just want power, so abs(I) + abs(Q) is + // close to what we want. + if (getNext) { - buf[c++] = (uint8_t)(MAX(ci,cq) + (MIN(ci, cq) >> 1)); + buf[c++] = (uint8_t)(MAX(ci,cq) + (MIN(ci, cq) >> 1)); - if(c >= 7000) - break; - } else { - cq = ci; - } + if(c >= 7000) + break; + } else { + cq = ci; + } - getNext = !getNext; - } - } + getNext = !getNext; + } + } - Dbprintf("done"); - switch_off(); + Dbprintf("done"); + switch_off(); } // Initialize the proxmark as iso15k reader // (this might produces glitches that confuse some tags void Iso15693InitReader(void) { - LEDsoff(); - clear_trace(); - set_tracing(true); + LEDsoff(); + clear_trace(); + set_tracing(true); - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - // Start from off (no field generated) - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(10); + // Start from off (no field generated) + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(10); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - FpgaSetupSsc(); + FpgaSetupSsc(); - // Give the tags time to energize - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); - SpinDelay(200); + // Give the tags time to energize + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); + SpinDelay(200); - // Start the timer - StartCountSspClk(); + // Start the timer + StartCountSspClk(); - LED_A_ON(); + LED_A_ON(); } /////////////////////////////////////////////////////////////////////// @@ -623,109 +623,109 @@ void Iso15693InitReader(void) { // thing that you must send to a tag to get a response. static void BuildIdentifyRequest(uint8_t *out) { - uint8_t cmd[CMD_ID_RESP] = {0, ISO15_CMD_INVENTORY, 0, 0, 0}; - // flags - cmd[0] = ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1; - // no mask - cmd[2] = 0x00; - // CRC - AddCrc(cmd, 3); - // coding as high speed (1 out of 4) - CodeIso15693AsReader(cmd, CMD_ID_RESP); - memcpy(out, cmd, CMD_ID_RESP); + uint8_t cmd[CMD_ID_RESP] = {0, ISO15_CMD_INVENTORY, 0, 0, 0}; + // flags + cmd[0] = ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1; + // no mask + cmd[2] = 0x00; + // CRC + AddCrc(cmd, 3); + // coding as high speed (1 out of 4) + CodeIso15693AsReader(cmd, CMD_ID_RESP); + memcpy(out, cmd, CMD_ID_RESP); } // uid is in transmission order (which is reverse of display order) /* static void BuildReadBlockRequest(uint8_t **out, uint8_t *uid, uint8_t blockNumber ) { - uint8_t cmd[CMD_READ_RESP] = {0,0,0,0,0,0,0,0,0,0,0,0,0}; - // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block - // followed by teh block data - // one sub-carrier, inventory, 1 slot, fast rate - cmd[0] = (1 << 6)| (1 << 5) | (1 << 1); // no SELECT bit, ADDR bit, OPTION bit - // READ BLOCK command code - cmd[1] = 0x20; - // UID may be optionally specified here - // 64-bit UID - cmd[2] = uid[0]; - cmd[3] = uid[1]; - cmd[4] = uid[2]; - cmd[5] = uid[3]; - cmd[6] = uid[4]; - cmd[7] = uid[5]; - cmd[8] = uid[6]; - cmd[9] = uid[7]; // 0xe0; // always e0 (not exactly unique) - // Block number to read - cmd[10] = blockNumber;//0x00; - // CRC - AddCrc(cmd, 11); - CodeIso15693AsReader(cmd, CMD_READ_RESP); - memcpy(out, cmd, CMD_ID_RESP); + uint8_t cmd[CMD_READ_RESP] = {0,0,0,0,0,0,0,0,0,0,0,0,0}; + // If we set the Option_Flag in this request, the VICC will respond with the secuirty status of the block + // followed by teh block data + // one sub-carrier, inventory, 1 slot, fast rate + cmd[0] = (1 << 6)| (1 << 5) | (1 << 1); // no SELECT bit, ADDR bit, OPTION bit + // READ BLOCK command code + cmd[1] = 0x20; + // UID may be optionally specified here + // 64-bit UID + cmd[2] = uid[0]; + cmd[3] = uid[1]; + cmd[4] = uid[2]; + cmd[5] = uid[3]; + cmd[6] = uid[4]; + cmd[7] = uid[5]; + cmd[8] = uid[6]; + cmd[9] = uid[7]; // 0xe0; // always e0 (not exactly unique) + // Block number to read + cmd[10] = blockNumber;//0x00; + // CRC + AddCrc(cmd, 11); + CodeIso15693AsReader(cmd, CMD_READ_RESP); + memcpy(out, cmd, CMD_ID_RESP); } */ // Now the VICC>VCD responses when we are simulating a tag static void BuildInventoryResponse(uint8_t *out, uint8_t *uid) { - uint8_t cmd[CMD_INV_RESP] = {0,0,0,0,0,0,0,0,0,0,0,0}; + uint8_t cmd[CMD_INV_RESP] = {0,0,0,0,0,0,0,0,0,0,0,0}; - // one sub-carrier, inventory, 1 slot, fast rate - // AFI is at bit 5 (1<<4) when doing an INVENTORY + // one sub-carrier, inventory, 1 slot, fast rate + // AFI is at bit 5 (1<<4) when doing an INVENTORY //(1 << 2) | (1 << 5) | (1 << 1); - cmd[0] = 0; // - cmd[1] = 0; // DSFID (data storage format identifier). 0x00 = not supported - // 64-bit UID - cmd[2] = uid[7]; //0x32; - cmd[3] = uid[6]; //0x4b; - cmd[4] = uid[5]; //0x03; - cmd[5] = uid[4]; //0x01; - cmd[6] = uid[3]; //0x00; - cmd[7] = uid[2]; //0x10; - cmd[8] = uid[1]; //0x05; - cmd[9] = uid[0]; //0xe0; - // CRC - AddCrc(cmd, 10); - CodeIso15693AsReader(cmd, CMD_INV_RESP); - memcpy(out, cmd, CMD_ID_RESP); + cmd[0] = 0; // + cmd[1] = 0; // DSFID (data storage format identifier). 0x00 = not supported + // 64-bit UID + cmd[2] = uid[7]; //0x32; + cmd[3] = uid[6]; //0x4b; + cmd[4] = uid[5]; //0x03; + cmd[5] = uid[4]; //0x01; + cmd[6] = uid[3]; //0x00; + cmd[7] = uid[2]; //0x10; + cmd[8] = uid[1]; //0x05; + cmd[9] = uid[0]; //0xe0; + // CRC + AddCrc(cmd, 10); + CodeIso15693AsReader(cmd, CMD_INV_RESP); + memcpy(out, cmd, CMD_ID_RESP); } // Universal Method for sending to and recv bytes from a tag -// init ... should we initialize the reader? -// speed ... 0 low speed, 1 hi speed -// **recv will return you a pointer to the received data -// If you do not need the answer use NULL for *recv[] -// return: lenght of received data +// init ... should we initialize the reader? +// speed ... 0 low speed, 1 hi speed +// **recv will return you a pointer to the received data +// If you do not need the answer use NULL for *recv[] +// return: lenght of received data // logging enabled int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *outdata) { - int t_samples = 0, wait = 0, elapsed = 0, answer_len = 0; + int t_samples = 0, wait = 0, elapsed = 0, answer_len = 0; - LEDsoff(); + LEDsoff(); - if (init) Iso15693InitReader(); + if (init) Iso15693InitReader(); - LED_A_ON(); + LED_A_ON(); - if (!speed) - CodeIso15693AsReader256(send, sendlen); // low speed (1 out of 256) - else - CodeIso15693AsReader(send, sendlen); // high speed (1 out of 4) + if (!speed) + CodeIso15693AsReader256(send, sendlen); // low speed (1 out of 256) + else + CodeIso15693AsReader(send, sendlen); // high speed (1 out of 4) - LED_A_INV(); + LED_A_INV(); - uint32_t time_start = GetCountSspClk(); + uint32_t time_start = GetCountSspClk(); - TransmitTo15693Tag(ToSend, ToSendMax, &t_samples, &wait); - LogTrace(send, sendlen, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true); + TransmitTo15693Tag(ToSend, ToSendMax, &t_samples, &wait); + LogTrace(send, sendlen, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true); - // Now wait for a response - if (outdata != NULL) { - LED_B_INV(); - answer_len = GetIso15693AnswerFromTag(outdata, &elapsed); - } + // Now wait for a response + if (outdata != NULL) { + LED_B_INV(); + answer_len = GetIso15693AnswerFromTag(outdata, &elapsed); + } - LEDsoff(); - return answer_len; + LEDsoff(); + return answer_len; } // -------------------------------------------------------------------- @@ -735,57 +735,57 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *outda // Decodes a message from a tag and displays its metadata and content #define DBD15STATLEN 48 void DbdecodeIso15693Answer(int len, uint8_t *d) { - char status[DBD15STATLEN+1] = {0}; + char status[DBD15STATLEN+1] = {0}; - if (len > 3) { - if (d[0] & ( 1 << 3 )) - strncat(status, "ProtExt ", DBD15STATLEN); - if (d[0] & 1) { - // error - strncat(status, "Error ", DBD15STATLEN); - switch (d[1]) { - case 0x01: - strncat(status, "01: not supported", DBD15STATLEN); - break; - case 0x02: - strncat(status, "02: not recognized", DBD15STATLEN); - break; - case 0x03: - strncat(status, "03: opt not supported", DBD15STATLEN); - break; - case 0x0f: - strncat(status, "0F: no info", DBD15STATLEN); - break; - case 0x10: - strncat(status, "10: dont exist", DBD15STATLEN); - break; - case 0x11: - strncat(status, "11: lock again", DBD15STATLEN); - break; - case 0x12: - strncat(status, "12: locked", DBD15STATLEN); - break; - case 0x13: - strncat(status, "13: program error", DBD15STATLEN); - break; - case 0x14: - strncat(status, "14: lock error", DBD15STATLEN); - break; - default: - strncat(status, "unknown error", DBD15STATLEN); - } - strncat(status ," " ,DBD15STATLEN); - } else { - strncat(status ,"No error ", DBD15STATLEN); - } + if (len > 3) { + if (d[0] & ( 1 << 3 )) + strncat(status, "ProtExt ", DBD15STATLEN); + if (d[0] & 1) { + // error + strncat(status, "Error ", DBD15STATLEN); + switch (d[1]) { + case 0x01: + strncat(status, "01: not supported", DBD15STATLEN); + break; + case 0x02: + strncat(status, "02: not recognized", DBD15STATLEN); + break; + case 0x03: + strncat(status, "03: opt not supported", DBD15STATLEN); + break; + case 0x0f: + strncat(status, "0F: no info", DBD15STATLEN); + break; + case 0x10: + strncat(status, "10: dont exist", DBD15STATLEN); + break; + case 0x11: + strncat(status, "11: lock again", DBD15STATLEN); + break; + case 0x12: + strncat(status, "12: locked", DBD15STATLEN); + break; + case 0x13: + strncat(status, "13: program error", DBD15STATLEN); + break; + case 0x14: + strncat(status, "14: lock error", DBD15STATLEN); + break; + default: + strncat(status, "unknown error", DBD15STATLEN); + } + strncat(status ," " ,DBD15STATLEN); + } else { + strncat(status ,"No error ", DBD15STATLEN); + } - if (CheckCrc(d, len)) - strncat(status, "[+] crc OK", DBD15STATLEN); - else - strncat(status, "[!] crc fail", DBD15STATLEN); + if (CheckCrc(d, len)) + strncat(status, "[+] crc OK", DBD15STATLEN); + else + strncat(status, "[!] crc fail", DBD15STATLEN); - if ( MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("%s", status); - } + if ( MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("%s", status); + } } /////////////////////////////////////////////////////////////////////// @@ -799,204 +799,204 @@ void DbdecodeIso15693Answer(int len, uint8_t *d) { // ok // parameter is unused !?! void ReaderIso15693(uint32_t parameter) { - int answerLen1 = 0; - int tsamples = 0, wait = 0, elapsed = 0; + int answerLen1 = 0; + int tsamples = 0, wait = 0, elapsed = 0; - uint8_t uid[8] = {0,0,0,0,0,0,0,0}; + uint8_t uid[8] = {0,0,0,0,0,0,0,0}; - // set up device/fpga - Iso15693InitReader(); + // set up device/fpga + Iso15693InitReader(); - uint8_t *answer1 = BigBuf_malloc(50); - uint8_t *answer2 = BigBuf_malloc(50); + uint8_t *answer1 = BigBuf_malloc(50); + uint8_t *answer2 = BigBuf_malloc(50); - // Blank arrays - memset(answer1, 0x00, 50); - memset(answer2, 0x00, 50); + // Blank arrays + memset(answer1, 0x00, 50); + memset(answer2, 0x00, 50); - // Now send the IDENTIFY command - // FIRST WE RUN AN INVENTORY TO GET THE TAG UID - // THIS MEANS WE CAN PRE-BUILD REQUESTS TO SAVE CPU TIME - uint32_t time_start = GetCountSspClk(); - uint8_t cmd[CMD_ID_RESP] = {0}; - BuildIdentifyRequest( cmd ); - TransmitTo15693Tag(ToSend, ToSendMax, &tsamples, &wait); - LogTrace(cmd, CMD_ID_RESP, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true); + // Now send the IDENTIFY command + // FIRST WE RUN AN INVENTORY TO GET THE TAG UID + // THIS MEANS WE CAN PRE-BUILD REQUESTS TO SAVE CPU TIME + uint32_t time_start = GetCountSspClk(); + uint8_t cmd[CMD_ID_RESP] = {0}; + BuildIdentifyRequest( cmd ); + TransmitTo15693Tag(ToSend, ToSendMax, &tsamples, &wait); + LogTrace(cmd, CMD_ID_RESP, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true); - // Now wait for a response - answerLen1 = GetIso15693AnswerFromTag(answer1, &elapsed) ; + // Now wait for a response + answerLen1 = GetIso15693AnswerFromTag(answer1, &elapsed) ; - // we should do a better check than this - if (answerLen1 >= 12) { - uid[0] = answer1[9]; // always E0 - uid[1] = answer1[8]; // IC Manufacturer code - uid[2] = answer1[7]; - uid[3] = answer1[6]; - uid[4] = answer1[5]; - uid[5] = answer1[4]; - uid[6] = answer1[3]; - uid[7] = answer1[2]; + // we should do a better check than this + if (answerLen1 >= 12) { + uid[0] = answer1[9]; // always E0 + uid[1] = answer1[8]; // IC Manufacturer code + uid[2] = answer1[7]; + uid[3] = answer1[6]; + uid[4] = answer1[5]; + uid[5] = answer1[4]; + uid[6] = answer1[3]; + uid[7] = answer1[2]; - if ( MF_DBGLEVEL >= MF_DBG_EXTENDED) { - Dbprintf("[+] UID = %02X%02X%02X%02X%02X%02X%02X%02X", - uid[0], uid[1], uid[2], uid[3], - uid[4], uid[5], uid[5], uid[6] - ); - } - // send UID back to client. - // arg0 = 1 = OK - // arg1 = len of response (12 bytes) - // arg2 = rtf - // asbytes = uid. - cmd_send(CMD_ACK, 1, sizeof(uid), 0, uid, sizeof(uid)); - } + if ( MF_DBGLEVEL >= MF_DBG_EXTENDED) { + Dbprintf("[+] UID = %02X%02X%02X%02X%02X%02X%02X%02X", + uid[0], uid[1], uid[2], uid[3], + uid[4], uid[5], uid[5], uid[6] + ); + } + // send UID back to client. + // arg0 = 1 = OK + // arg1 = len of response (12 bytes) + // arg2 = rtf + // asbytes = uid. + cmd_send(CMD_ACK, 1, sizeof(uid), 0, uid, sizeof(uid)); + } - if ( MF_DBGLEVEL >= MF_DBG_EXTENDED) { - Dbprintf("[+] %d octets read from IDENTIFY request:", answerLen1); - DbdecodeIso15693Answer(answerLen1, answer1); - Dbhexdump(answerLen1, answer1, true); - } + if ( MF_DBGLEVEL >= MF_DBG_EXTENDED) { + Dbprintf("[+] %d octets read from IDENTIFY request:", answerLen1); + DbdecodeIso15693Answer(answerLen1, answer1); + Dbhexdump(answerLen1, answer1, true); + } - switch_off(); + switch_off(); } // Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands // all demodulation performed in arm rather than host. - greg void SimTagIso15693(uint32_t parameter, uint8_t *uid) { - LEDsoff(); - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - FpgaSetupSsc(); - // Start from off (no field generated) + LEDsoff(); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + FpgaSetupSsc(); + // Start from off (no field generated) FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(200); + SpinDelay(200); - LED_A_ON(); + LED_A_ON(); - uint32_t time_start = 0; - int ans = 0, samples = 0, tsamples = 0; - int wait = 0, elapsed = 0; + uint32_t time_start = 0; + int ans = 0, samples = 0, tsamples = 0; + int wait = 0, elapsed = 0; - Dbprintf("ISO-15963 Simulating uid: %02X%02X%02X%02X%02X%02X%02X%02X", uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7]); + Dbprintf("ISO-15963 Simulating uid: %02X%02X%02X%02X%02X%02X%02X%02X", uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7]); - uint8_t buf[ISO15_MAX_FRAME]; - memset(buf, 0x00, sizeof(buf)); + uint8_t buf[ISO15_MAX_FRAME]; + memset(buf, 0x00, sizeof(buf)); - LED_C_ON(); + LED_C_ON(); - // Build a suitable reponse to the reader INVENTORY cocmmand - // not so obsvious, but in the call to BuildInventoryResponse, the command is copied to the global ToSend buffer used below. - uint8_t cmd[CMD_INV_RESP] = {0}; - BuildInventoryResponse(cmd, uid); + // Build a suitable reponse to the reader INVENTORY cocmmand + // not so obsvious, but in the call to BuildInventoryResponse, the command is copied to the global ToSend buffer used below. + uint8_t cmd[CMD_INV_RESP] = {0}; + BuildInventoryResponse(cmd, uid); - while (!BUTTON_PRESS() && !usb_poll_validate_length() ) { - WDT_HIT(); + while (!BUTTON_PRESS() && !usb_poll_validate_length() ) { + WDT_HIT(); - // Listen to reader - ans = GetIso15693AnswerFromSniff(buf, &samples, &elapsed) ; + // Listen to reader + ans = GetIso15693AnswerFromSniff(buf, &samples, &elapsed) ; - // we should do a better check than this - if (ans >= 1 ) { + // we should do a better check than this + if (ans >= 1 ) { - time_start = GetCountSspClk(); - TransmitTo15693Reader(ToSend, ToSendMax, &tsamples, &wait); - LogTrace(cmd, CMD_INV_RESP, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true); + time_start = GetCountSspClk(); + TransmitTo15693Reader(ToSend, ToSendMax, &tsamples, &wait); + LogTrace(cmd, CMD_INV_RESP, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true); - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { - Dbprintf("[+] %d octets read from reader command: %x %x %x %x %x %x %x %x", ans, - buf[0], buf[1], buf[2], buf[3], - buf[4], buf[5], buf[6], buf[7] - ); - } - } - } - switch_off(); + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { + Dbprintf("[+] %d octets read from reader command: %x %x %x %x %x %x %x %x", ans, + buf[0], buf[1], buf[2], buf[3], + buf[4], buf[5], buf[6], buf[7] + ); + } + } + } + switch_off(); } // Since there is no standardized way of reading the AFI out of a tag, we will brute force it // (some manufactures offer a way to read the AFI, though) void BruteforceIso15693Afi(uint32_t speed) { - uint8_t data[7] = {0,0,0,0,0,0,0}; - uint8_t buf[ISO15_MAX_FRAME]; - memset(buf, 0x00, sizeof(buf)); - int datalen = 0, recvlen = 0; + uint8_t data[7] = {0,0,0,0,0,0,0}; + uint8_t buf[ISO15_MAX_FRAME]; + memset(buf, 0x00, sizeof(buf)); + int datalen = 0, recvlen = 0; - Iso15693InitReader(); + Iso15693InitReader(); - // first without AFI - // Tags should respond wihtout AFI and with AFI=0 even when AFI is active + // first without AFI + // Tags should respond wihtout AFI and with AFI=0 even when AFI is active - data[0] = ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1; - data[1] = ISO15_CMD_INVENTORY; - data[2] = 0; // mask length - AddCrc(data, 3); - datalen += 2; + data[0] = ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1; + data[1] = ISO15_CMD_INVENTORY; + data[2] = 0; // mask length + AddCrc(data, 3); + datalen += 2; - recvlen = SendDataTag(data, datalen, false, speed, buf); + recvlen = SendDataTag(data, datalen, false, speed, buf); - WDT_HIT(); + WDT_HIT(); - if (recvlen >= 12) { - Dbprintf("NoAFI UID = %s", sprintUID(NULL, buf + 2) ); - } + if (recvlen >= 12) { + Dbprintf("NoAFI UID = %s", sprintUID(NULL, buf + 2) ); + } - // now with AFI - data[0] |= ISO15_REQINV_AFI; - //data[1] = ISO15_CMD_INVENTORY; - data[2] = 0; // AFI - data[3] = 0; // mask length + // now with AFI + data[0] |= ISO15_REQINV_AFI; + //data[1] = ISO15_CMD_INVENTORY; + data[2] = 0; // AFI + data[3] = 0; // mask length - for (uint16_t i = 0; i < 256; i++) { - data[2] = i & 0xFF; - AddCrc(data, 4); - datalen += 2; - recvlen = SendDataTag(data, datalen, false, speed, buf); - WDT_HIT(); - if (recvlen >= 12) { - Dbprintf("AFI = %i UID = %s", i, sprintUID(NULL, buf + 2) ); - } + for (uint16_t i = 0; i < 256; i++) { + data[2] = i & 0xFF; + AddCrc(data, 4); + datalen += 2; + recvlen = SendDataTag(data, datalen, false, speed, buf); + WDT_HIT(); + if (recvlen >= 12) { + Dbprintf("AFI = %i UID = %s", i, sprintUID(NULL, buf + 2) ); + } - if (BUTTON_PRESS()) { - DbpString("button pressed, aborting.."); - break; - } - } + if (BUTTON_PRESS()) { + DbpString("button pressed, aborting.."); + break; + } + } - DbpString("AFI Bruteforcing done."); - switch_off(); + DbpString("AFI Bruteforcing done."); + switch_off(); } // Allows to directly send commands to the tag via the client // Has to increase dialog between device and client. void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t *data) { - bool init = true; - int buflen = 0; - uint8_t buf[ISO15_MAX_FRAME]; - memset(buf, 0x00, sizeof(buf)); + bool init = true; + int buflen = 0; + uint8_t buf[ISO15_MAX_FRAME]; + memset(buf, 0x00, sizeof(buf)); - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { - DbpString("[+] SEND"); - Dbhexdump(datalen, data, true); - } + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { + DbpString("[+] SEND"); + Dbhexdump(datalen, data, true); + } - buflen = SendDataTag(data, datalen, init, speed, (recv ? buf : NULL)); + buflen = SendDataTag(data, datalen, init, speed, (recv ? buf : NULL)); - if (recv) { - buflen = (buflen > ISO15_MAX_FRAME) ? ISO15_MAX_FRAME : buflen; + if (recv) { + buflen = (buflen > ISO15_MAX_FRAME) ? ISO15_MAX_FRAME : buflen; - LED_B_ON(); - cmd_send(CMD_ACK, buflen, 0, 0, buf, buflen); - LED_B_OFF(); + LED_B_ON(); + cmd_send(CMD_ACK, buflen, 0, 0, buf, buflen); + LED_B_OFF(); - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { - DbpString("[+] RECV"); - DbdecodeIso15693Answer(buflen, buf); - Dbhexdump(buflen, buf, true); - } - } else { - cmd_send(CMD_ACK,1,0,0,0,0); - } + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { + DbpString("[+] RECV"); + DbdecodeIso15693Answer(buflen, buf); + Dbhexdump(buflen, buf, true); + } + } else { + cmd_send(CMD_ACK,1,0,0,0,0); + } } \ No newline at end of file diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 3296aff8c..bd34e46df 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -22,10 +22,10 @@ #include "flashmem.h" // persistence on mem #ifndef SHORT_COIL -# define SHORT_COIL() LOW(GPIO_SSC_DOUT) +# define SHORT_COIL() LOW(GPIO_SSC_DOUT) #endif #ifndef OPEN_COIL -# define OPEN_COIL() HIGH(GPIO_SSC_DOUT) +# define OPEN_COIL() HIGH(GPIO_SSC_DOUT) #endif //#define START_GAP 31*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (15fc) @@ -53,99 +53,99 @@ // 1fc = 8us = 12ticks /* Default LF T55xx config is set to: - startgap = 31*8 - writegap = 17*8 - write_0 = 15*8 - write_1 = 47*8 - read_gap = 15*8 + startgap = 31*8 + writegap = 17*8 + write_0 = 15*8 + write_1 = 47*8 + read_gap = 15*8 */ t55xx_config t_config = { 29*8, 17*8, 15*8, 47*8, 15*8 } ; void printT55xxConfig(void) { - Dbprintf("LF T55XX config"); - Dbprintf(" [a] startgap............%d*8 (%d)", t_config.start_gap/8, t_config.start_gap); - Dbprintf(" [b] writegap............%d*8 (%d)", t_config.write_gap/8, t_config.write_gap); - Dbprintf(" [c] write_0.............%d*8 (%d)", t_config.write_0/8, t_config.write_0); - Dbprintf(" [d] write_1.............%d*8 (%d)", t_config.write_1/8, t_config.write_1); - Dbprintf(" [e] readgap.............%d*8 (%d)", t_config.read_gap/8, t_config.read_gap); + Dbprintf("LF T55XX config"); + Dbprintf(" [a] startgap............%d*8 (%d)", t_config.start_gap/8, t_config.start_gap); + Dbprintf(" [b] writegap............%d*8 (%d)", t_config.write_gap/8, t_config.write_gap); + Dbprintf(" [c] write_0.............%d*8 (%d)", t_config.write_0/8, t_config.write_0); + Dbprintf(" [d] write_1.............%d*8 (%d)", t_config.write_1/8, t_config.write_1); + Dbprintf(" [e] readgap.............%d*8 (%d)", t_config.read_gap/8, t_config.read_gap); } void setT55xxConfig(uint8_t arg0, t55xx_config *c) { - if (c->start_gap != 0) t_config.start_gap = c->start_gap; - if (c->write_gap != 0) t_config.write_gap = c->write_gap; - if (c->write_0 != 0) t_config.write_0 = c->write_0; - if (c->write_1 != 0) t_config.write_1 = c->write_1; - if (c->read_gap != 0) t_config.read_gap = c->read_gap; + if (c->start_gap != 0) t_config.start_gap = c->start_gap; + if (c->write_gap != 0) t_config.write_gap = c->write_gap; + if (c->write_0 != 0) t_config.write_0 = c->write_0; + if (c->write_1 != 0) t_config.write_1 = c->write_1; + if (c->read_gap != 0) t_config.read_gap = c->read_gap; - printT55xxConfig(); + printT55xxConfig(); #ifdef WITH_FLASH - // shall persist to flashmem - if (arg0 == 0) { - return; - } + // shall persist to flashmem + if (arg0 == 0) { + return; + } if (!FlashInit()) { return; - } + } - uint8_t *buf = BigBuf_malloc(T55XX_CONFIG_LEN); - Flash_CheckBusy(BUSY_TIMEOUT); - uint16_t res = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); - if ( res == 0) { - FlashStop(); - BigBuf_free(); - return; - } + uint8_t *buf = BigBuf_malloc(T55XX_CONFIG_LEN); + Flash_CheckBusy(BUSY_TIMEOUT); + uint16_t res = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); + if ( res == 0) { + FlashStop(); + BigBuf_free(); + return; + } - memcpy(buf, &t_config, T55XX_CONFIG_LEN); + memcpy(buf, &t_config, T55XX_CONFIG_LEN); - Flash_CheckBusy(BUSY_TIMEOUT); + Flash_CheckBusy(BUSY_TIMEOUT); Flash_WriteEnable(); - Flash_Erase4k(3, 0xD); - res = Flash_Write(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); + Flash_Erase4k(3, 0xD); + res = Flash_Write(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); - if ( res == T55XX_CONFIG_LEN && MF_DBGLEVEL > 1) { - DbpString("T55XX Config save success"); - } + if ( res == T55XX_CONFIG_LEN && MF_DBGLEVEL > 1) { + DbpString("T55XX Config save success"); + } - BigBuf_free(); + BigBuf_free(); #endif } t55xx_config* getT55xxConfig(void) { - return &t_config; + return &t_config; } void loadT55xxConfig(void) { #ifdef WITH_FLASH if (!FlashInit()) { return; - } + } - uint8_t *buf = BigBuf_malloc(T55XX_CONFIG_LEN); + uint8_t *buf = BigBuf_malloc(T55XX_CONFIG_LEN); - Flash_CheckBusy(BUSY_TIMEOUT); - uint16_t isok = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); - FlashStop(); + Flash_CheckBusy(BUSY_TIMEOUT); + uint16_t isok = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); + FlashStop(); - // verify read mem is actual data. - uint8_t cntA = T55XX_CONFIG_LEN, cntB = T55XX_CONFIG_LEN; - for (int i=0; i< T55XX_CONFIG_LEN; i++) { - if ( buf[i] == 0xFF) cntA--; - if ( buf[i] == 0x00) cntB--; - } - if ( !cntA || !cntB ) { - BigBuf_free(); - return; - } + // verify read mem is actual data. + uint8_t cntA = T55XX_CONFIG_LEN, cntB = T55XX_CONFIG_LEN; + for (int i=0; i< T55XX_CONFIG_LEN; i++) { + if ( buf[i] == 0xFF) cntA--; + if ( buf[i] == 0x00) cntB--; + } + if ( !cntA || !cntB ) { + BigBuf_free(); + return; + } - memcpy((uint8_t *)&t_config, buf, T55XX_CONFIG_LEN); + memcpy((uint8_t *)&t_config, buf, T55XX_CONFIG_LEN); - if ( isok == T55XX_CONFIG_LEN) { - if (MF_DBGLEVEL > 1) DbpString("T55XX Config load success"); - } + if ( isok == T55XX_CONFIG_LEN) { + if (MF_DBGLEVEL > 1) DbpString("T55XX Config load success"); + } #endif } @@ -158,98 +158,98 @@ void loadT55xxConfig(void) { */ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command) { - // start timer - StartTicks(); + // start timer + StartTicks(); - // use lf config settings - sample_config *sc = getSamplingConfig(); + // use lf config settings + sample_config *sc = getSamplingConfig(); - // Make sure the tag is reset - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - WaitMS(500); + // Make sure the tag is reset + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + WaitMS(500); - // clear read buffer - BigBuf_Clear_keep_EM(); + // clear read buffer + BigBuf_Clear_keep_EM(); - LFSetupFPGAForADC(sc->divisor, 1); + LFSetupFPGAForADC(sc->divisor, 1); - // little more time for the tag to fully power up - WaitMS(200); + // little more time for the tag to fully power up + WaitMS(200); - // if delay_off = 0 then just bitbang 1 = antenna on 0 = off for respective periods. - bool bitbang = delay_off == 0; - // now modulate the reader field - if (bitbang) { - // HACK it appears the loop and if statements take up about 7us so adjust waits accordingly... - uint8_t hack_cnt = 7; - if (period_0 < hack_cnt || period_1 < hack_cnt) { - DbpString("[!] Warning periods cannot be less than 7us in bit bang mode"); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - return; - } + // if delay_off = 0 then just bitbang 1 = antenna on 0 = off for respective periods. + bool bitbang = delay_off == 0; + // now modulate the reader field + if (bitbang) { + // HACK it appears the loop and if statements take up about 7us so adjust waits accordingly... + uint8_t hack_cnt = 7; + if (period_0 < hack_cnt || period_1 < hack_cnt) { + DbpString("[!] Warning periods cannot be less than 7us in bit bang mode"); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + return; + } - // hack2 needed--- it appears to take about 8-16us to turn the antenna back on - // leading to ~ 1 to 2 125khz samples extra in every off period - // so we should test for last 0 before next 1 and reduce period_0 by this extra amount... - // but is this time different for every antenna or other hw builds??? more testing needed + // hack2 needed--- it appears to take about 8-16us to turn the antenna back on + // leading to ~ 1 to 2 125khz samples extra in every off period + // so we should test for last 0 before next 1 and reduce period_0 by this extra amount... + // but is this time different for every antenna or other hw builds??? more testing needed - // prime cmd_len to save time comparing strings while modulating - int cmd_len = 0; - while(command[cmd_len] != '\0' && command[cmd_len] != ' ') - cmd_len++; + // prime cmd_len to save time comparing strings while modulating + int cmd_len = 0; + while(command[cmd_len] != '\0' && command[cmd_len] != ' ') + cmd_len++; - int counter = 0; - bool off = false; - for (counter = 0; counter < cmd_len; counter++) { - // if cmd = 0 then turn field off - if (command[counter] == '0') { - // if field already off leave alone (affects timing otherwise) - if (off == false) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - off = true; - } - // note we appear to take about 7us to switch over (or run the if statements/loop...) - WaitUS(period_0 - hack_cnt); - // else if cmd = 1 then turn field on - } else { - // if field already on leave alone (affects timing otherwise) - if (off) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - LED_D_ON(); - off = false; - } - // note we appear to take about 7us to switch over (or run the if statements/loop...) - WaitUS(period_1 - hack_cnt); - } - } - } else { // old mode of cmd read using delay as off period - while(*command != '\0' && *command != ' ') { - LED_D_ON(); - if (*(command++) == '0') - TurnReadLFOn(period_0); - else - TurnReadLFOn(period_1); + int counter = 0; + bool off = false; + for (counter = 0; counter < cmd_len; counter++) { + // if cmd = 0 then turn field off + if (command[counter] == '0') { + // if field already off leave alone (affects timing otherwise) + if (off == false) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + off = true; + } + // note we appear to take about 7us to switch over (or run the if statements/loop...) + WaitUS(period_0 - hack_cnt); + // else if cmd = 1 then turn field on + } else { + // if field already on leave alone (affects timing otherwise) + if (off) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + LED_D_ON(); + off = false; + } + // note we appear to take about 7us to switch over (or run the if statements/loop...) + WaitUS(period_1 - hack_cnt); + } + } + } else { // old mode of cmd read using delay as off period + while(*command != '\0' && *command != ' ') { + LED_D_ON(); + if (*(command++) == '0') + TurnReadLFOn(period_0); + else + TurnReadLFOn(period_1); - LED_D_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - WaitUS(delay_off); - } + LED_D_OFF(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + WaitUS(delay_off); + } - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor); - } + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor); + } - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // now do the read - DoAcquisition_config(false, 0); + // now do the read + DoAcquisition_config(false, 0); - // Turn off antenna - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - // tell client we are done - cmd_send(CMD_ACK,0,0,0,0,0); + // Turn off antenna + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // tell client we are done + cmd_send(CMD_ACK,0,0,0,0,0); } /* blank r/w tag data stream @@ -263,238 +263,238 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint */ void ReadTItag(void) { - StartTicks(); - // some hardcoded initial params - // when we read a TI tag we sample the zerocross line at 2Mhz - // TI tags modulate a 1 as 16 cycles of 123.2Khz - // TI tags modulate a 0 as 16 cycles of 134.2Khz - #define FSAMPLE 2000000 - #define FREQLO 123200 - #define FREQHI 134200 + StartTicks(); + // some hardcoded initial params + // when we read a TI tag we sample the zerocross line at 2Mhz + // TI tags modulate a 1 as 16 cycles of 123.2Khz + // TI tags modulate a 0 as 16 cycles of 134.2Khz + #define FSAMPLE 2000000 + #define FREQLO 123200 + #define FREQHI 134200 - signed char *dest = (signed char *)BigBuf_get_addr(); - uint16_t n = BigBuf_max_traceLen(); - // 128 bit shift register [shift3:shift2:shift1:shift0] - uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; + signed char *dest = (signed char *)BigBuf_get_addr(); + uint16_t n = BigBuf_max_traceLen(); + // 128 bit shift register [shift3:shift2:shift1:shift0] + uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; - int i, cycles=0, samples=0; - // how many sample points fit in 16 cycles of each frequency - uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI; - // when to tell if we're close enough to one freq or another - uint32_t threshold = (sampleslo - sampleshi + 1)>>1; + int i, cycles=0, samples=0; + // how many sample points fit in 16 cycles of each frequency + uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI; + // when to tell if we're close enough to one freq or another + 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 + // 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 - // connects to SSP_DIN and the SSP_DOUT logic level controls - // whether we're modulating the antenna (high) - // or listening to the antenna (low) - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); + // Place FPGA in passthrough mode, in this mode the CROSS_LO line + // connects to SSP_DIN and the SSP_DOUT logic level controls + // whether we're modulating the antenna (high) + // or listening to the antenna (low) + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); - // get TI tag data into the buffer - AcquireTiType(); + // get TI tag data into the buffer + AcquireTiType(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - for (i=0; i0) ) { - cycles++; - // after 16 cycles, measure the frequency - if (cycles>15) { - cycles=0; - samples=i-samples; // number of samples in these 16 cycles + for (i=0; i0) ) { + cycles++; + // after 16 cycles, measure the frequency + if (cycles>15) { + cycles=0; + samples=i-samples; // number of samples in these 16 cycles - // TI bits are coming to us lsb first so shift them - // right through our 128 bit right shift register - shift0 = (shift0>>1) | (shift1 << 31); - shift1 = (shift1>>1) | (shift2 << 31); - shift2 = (shift2>>1) | (shift3 << 31); - shift3 >>= 1; + // TI bits are coming to us lsb first so shift them + // right through our 128 bit right shift register + shift0 = (shift0>>1) | (shift1 << 31); + shift1 = (shift1>>1) | (shift2 << 31); + shift2 = (shift2>>1) | (shift3 << 31); + shift3 >>= 1; - // check if the cycles fall close to the number - // expected for either the low or high frequency - if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) { - // low frequency represents a 1 - shift3 |= (1<<31); - } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) { - // high frequency represents a 0 - } else { - // probably detected a gay waveform or noise - // use this as gaydar or discard shift register and start again - shift3 = shift2 = shift1 = shift0 = 0; - } - samples = i; + // check if the cycles fall close to the number + // expected for either the low or high frequency + if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) { + // low frequency represents a 1 + shift3 |= (1<<31); + } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) { + // high frequency represents a 0 + } else { + // probably detected a gay waveform or noise + // use this as gaydar or discard shift register and start again + shift3 = shift2 = shift1 = shift0 = 0; + } + samples = i; - // for each bit we receive, test if we've detected a valid tag + // for each bit we receive, test if we've detected a valid tag - // if we see 17 zeroes followed by 6 ones, we might have a tag - // remember the bits are backwards - if ( ((shift0 & 0x7fffff) == 0x7e0000) ) { - // if start and end bytes match, we have a tag so break out of the loop - if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) { - cycles = 0xF0B; //use this as a flag (ugly but whatever) - break; - } - } - } - } - } + // if we see 17 zeroes followed by 6 ones, we might have a tag + // remember the bits are backwards + if ( ((shift0 & 0x7fffff) == 0x7e0000) ) { + // if start and end bytes match, we have a tag so break out of the loop + if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) { + cycles = 0xF0B; //use this as a flag (ugly but whatever) + break; + } + } + } + } + } - // if flag is set we have a tag - if (cycles!=0xF0B) { - DbpString("Info: No valid tag detected."); - } else { - // put 64 bit data into shift1 and shift0 - shift0 = (shift0>>24) | (shift1 << 8); - shift1 = (shift1>>24) | (shift2 << 8); + // if flag is set we have a tag + if (cycles!=0xF0B) { + DbpString("Info: No valid tag detected."); + } else { + // put 64 bit data into shift1 and shift0 + shift0 = (shift0>>24) | (shift1 << 8); + shift1 = (shift1>>24) | (shift2 << 8); - // align 16 bit crc into lower half of shift2 - shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff; + // align 16 bit crc into lower half of shift2 + shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff; - // if r/w tag, check ident match - if (shift3 & (1<<15) ) { - DbpString("Info: TI tag is rewriteable"); - // only 15 bits compare, last bit of ident is not valid - if (((shift3 >> 16) ^ shift0) & 0x7fff ) { - DbpString("Error: Ident mismatch!"); - } else { - DbpString("Info: TI tag ident is valid"); - } - } else { - DbpString("Info: TI tag is readonly"); - } + // if r/w tag, check ident match + if (shift3 & (1<<15) ) { + DbpString("Info: TI tag is rewriteable"); + // only 15 bits compare, last bit of ident is not valid + if (((shift3 >> 16) ^ shift0) & 0x7fff ) { + DbpString("Error: Ident mismatch!"); + } else { + DbpString("Info: TI tag ident is valid"); + } + } else { + DbpString("Info: TI tag is readonly"); + } - // WARNING the order of the bytes in which we calc crc below needs checking - // i'm 99% sure the crc algorithm is correct, but it may need to eat the - // bytes in reverse or something - // calculate CRC - uint32_t crc=0; + // WARNING the order of the bytes in which we calc crc below needs checking + // i'm 99% sure the crc algorithm is correct, but it may need to eat the + // bytes in reverse or something + // calculate CRC + uint32_t crc=0; - crc = update_crc16(crc, (shift0)&0xff); - crc = update_crc16(crc, (shift0>>8)&0xff); - crc = update_crc16(crc, (shift0>>16)&0xff); - crc = update_crc16(crc, (shift0>>24)&0xff); - crc = update_crc16(crc, (shift1)&0xff); - crc = update_crc16(crc, (shift1>>8)&0xff); - crc = update_crc16(crc, (shift1>>16)&0xff); - crc = update_crc16(crc, (shift1>>24)&0xff); + crc = update_crc16(crc, (shift0)&0xff); + crc = update_crc16(crc, (shift0>>8)&0xff); + crc = update_crc16(crc, (shift0>>16)&0xff); + crc = update_crc16(crc, (shift0>>24)&0xff); + crc = update_crc16(crc, (shift1)&0xff); + crc = update_crc16(crc, (shift1>>8)&0xff); + crc = update_crc16(crc, (shift1>>16)&0xff); + crc = update_crc16(crc, (shift1>>24)&0xff); - Dbprintf("Info: Tag data: %x%08x, crc=%x", (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF); - if (crc != (shift2&0xffff)) { - Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc); - } else { - DbpString("Info: CRC is good"); - } - } - StopTicks(); + Dbprintf("Info: Tag data: %x%08x, crc=%x", (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF); + if (crc != (shift2&0xffff)) { + Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc); + } else { + DbpString("Info: CRC is good"); + } + } + StopTicks(); } void WriteTIbyte(uint8_t b) { - int i = 0; + int i = 0; - // modulate 8 bits out to the antenna - for (i=0; i<8; i++) - { - if ( b & ( 1 << i ) ) { - // stop modulating antenna 1ms - LOW(GPIO_SSC_DOUT); - WaitUS(1000); - // modulate antenna 1ms - HIGH(GPIO_SSC_DOUT); - WaitUS(1000); - } else { - // stop modulating antenna 0.3ms - LOW(GPIO_SSC_DOUT); - WaitUS(300); - // modulate antenna 1.7ms - HIGH(GPIO_SSC_DOUT); - WaitUS(1700); - } - } + // modulate 8 bits out to the antenna + for (i=0; i<8; i++) + { + if ( b & ( 1 << i ) ) { + // stop modulating antenna 1ms + LOW(GPIO_SSC_DOUT); + WaitUS(1000); + // modulate antenna 1ms + HIGH(GPIO_SSC_DOUT); + WaitUS(1000); + } else { + // stop modulating antenna 0.3ms + LOW(GPIO_SSC_DOUT); + WaitUS(300); + // modulate antenna 1.7ms + HIGH(GPIO_SSC_DOUT); + WaitUS(1700); + } + } } void AcquireTiType(void) { - int i, j, n; - // tag transmission is <20ms, sampling at 2M gives us 40K samples max - // each sample is 1 bit stuffed into a uint32_t so we need 1250 uint32_t - #define TIBUFLEN 1250 + int i, j, n; + // tag transmission is <20ms, sampling at 2M gives us 40K samples max + // each sample is 1 bit stuffed into a uint32_t so we need 1250 uint32_t + #define TIBUFLEN 1250 - // clear buffer - uint32_t *buf = (uint32_t *)BigBuf_get_addr(); + // clear buffer + uint32_t *buf = (uint32_t *)BigBuf_get_addr(); - //clear buffer now so it does not interfere with timing later - BigBuf_Clear_ext(false); + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_ext(false); - // Set up the synchronous serial port - AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN; - AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN; + // Set up the synchronous serial port + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN; + AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN; - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + // steal this pin from the SSP and use it to control the modulation + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; - // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long - // 48/2 = 24 MHz clock must be divided by 12 - AT91C_BASE_SSC->SSC_CMR = 12; + // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long + // 48/2 = 24 MHz clock must be divided by 12 + AT91C_BASE_SSC->SSC_CMR = 12; - AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0); - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF; - // Transmit Clock Mode Register - AT91C_BASE_SSC->SSC_TCMR = 0; - // Transmit Frame Mode Register - AT91C_BASE_SSC->SSC_TFMR = 0; - // iceman, FpgaSetupSsc() ?? the code above? can it be replaced? - LED_D_ON(); + AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0); + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF; + // Transmit Clock Mode Register + AT91C_BASE_SSC->SSC_TCMR = 0; + // Transmit Frame Mode Register + AT91C_BASE_SSC->SSC_TFMR = 0; + // iceman, FpgaSetupSsc() ?? the code above? can it be replaced? + LED_D_ON(); - // modulate antenna - HIGH(GPIO_SSC_DOUT); + // modulate antenna + HIGH(GPIO_SSC_DOUT); - // Charge TI tag for 50ms. - WaitMS(50); + // Charge TI tag for 50ms. + WaitMS(50); - // stop modulating antenna and listen - LOW(GPIO_SSC_DOUT); + // stop modulating antenna and listen + LOW(GPIO_SSC_DOUT); - LED_D_OFF(); + LED_D_OFF(); - i = 0; - for (;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - buf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer - i++; - if (i >= TIBUFLEN) break; - } - WDT_HIT(); - } + i = 0; + for (;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + buf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer + i++; + if (i >= TIBUFLEN) break; + } + WDT_HIT(); + } - // return stolen pin to SSP - AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; + // return stolen pin to SSP + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; - char *dest = (char *)BigBuf_get_addr(); - n = TIBUFLEN * 32; + char *dest = (char *)BigBuf_get_addr(); + n = TIBUFLEN * 32; - // unpack buffer - for (i = TIBUFLEN-1; i >= 0; i--) { - for (j = 0; j < 32; j++) { - if(buf[i] & (1 << j)) { - dest[--n] = 1; - } else { - dest[--n] = -1; - } - } - } + // unpack buffer + for (i = TIBUFLEN-1; i >= 0; i--) { + for (j = 0; j < 32; j++) { + if(buf[i] & (1 << j)) { + dest[--n] = 1; + } else { + dest[--n] = -1; + } + } + } - // reset SSC - FpgaSetupSsc(); + // reset SSC + FpgaSetupSsc(); } // arguments: 64bit data split into 32bit idhi:idlo and optional 16bit crc @@ -502,162 +502,163 @@ 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); - crc = update_crc16(crc, (idlo>>16)&0xff); - crc = update_crc16(crc, (idlo>>24)&0xff); - crc = update_crc16(crc, (idhi)&0xff); - crc = update_crc16(crc, (idhi>>8)&0xff); - crc = update_crc16(crc, (idhi>>16)&0xff); - crc = update_crc16(crc, (idhi>>24)&0xff); - } - Dbprintf("Writing to tag: %x%08x, crc=%x", idhi, idlo, crc); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + if(crc == 0) { + crc = update_crc16(crc, (idlo)&0xff); + crc = update_crc16(crc, (idlo>>8)&0xff); + crc = update_crc16(crc, (idlo>>16)&0xff); + crc = update_crc16(crc, (idlo>>24)&0xff); + crc = update_crc16(crc, (idhi)&0xff); + crc = update_crc16(crc, (idhi>>8)&0xff); + crc = update_crc16(crc, (idhi>>16)&0xff); + crc = update_crc16(crc, (idhi>>24)&0xff); + } + Dbprintf("Writing to tag: %x%08x, crc=%x", idhi, idlo, crc); - // TI tags charge at 134.2Khz - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - // Place FPGA in passthrough mode, in this mode the CROSS_LO line - // connects to SSP_DIN and the SSP_DOUT logic level controls - // whether we're modulating the antenna (high) - // or listening to the antenna (low) - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); - StartTicks(); + // TI tags charge at 134.2Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + // Place FPGA in passthrough mode, in this mode the CROSS_LO line + // connects to SSP_DIN and the SSP_DOUT logic level controls + // whether we're modulating the antenna (high) + // or listening to the antenna (low) + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); + StartTicks(); - LED_A_ON(); + LED_A_ON(); - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + // steal this pin from the SSP and use it to control the modulation + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - // writing algorithm: - // a high bit consists of a field off for 1ms and field on for 1ms - // a low bit consists of a field off for 0.3ms and field on for 1.7ms - // initiate a charge time of 50ms (field on) then immediately start writing bits - // start by writing 0xBB (keyword) and 0xEB (password) - // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer) - // finally end with 0x0300 (write frame) - // all data is sent lsb first - // finish with 50ms programming time + // writing algorithm: + // a high bit consists of a field off for 1ms and field on for 1ms + // a low bit consists of a field off for 0.3ms and field on for 1.7ms + // initiate a charge time of 50ms (field on) then immediately start writing bits + // start by writing 0xBB (keyword) and 0xEB (password) + // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer) + // finally end with 0x0300 (write frame) + // all data is sent lsb first + // finish with 50ms programming time - // modulate antenna - HIGH(GPIO_SSC_DOUT); - WaitMS(50); // charge time + // modulate antenna + HIGH(GPIO_SSC_DOUT); + WaitMS(50); // charge time - WriteTIbyte(0xbb); // keyword - WriteTIbyte(0xeb); // password - WriteTIbyte( (idlo )&0xff ); - WriteTIbyte( (idlo>>8 )&0xff ); - WriteTIbyte( (idlo>>16)&0xff ); - WriteTIbyte( (idlo>>24)&0xff ); - WriteTIbyte( (idhi )&0xff ); - WriteTIbyte( (idhi>>8 )&0xff ); - WriteTIbyte( (idhi>>16)&0xff ); - WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo - WriteTIbyte( (crc )&0xff ); // crc lo - WriteTIbyte( (crc>>8 )&0xff ); // crc hi - WriteTIbyte(0x00); // write frame lo - WriteTIbyte(0x03); // write frame hi - HIGH(GPIO_SSC_DOUT); - WaitMS(50); // programming time + WriteTIbyte(0xbb); // keyword + WriteTIbyte(0xeb); // password + WriteTIbyte( (idlo )&0xff ); + WriteTIbyte( (idlo>>8 )&0xff ); + WriteTIbyte( (idlo>>16)&0xff ); + WriteTIbyte( (idlo>>24)&0xff ); + WriteTIbyte( (idhi )&0xff ); + WriteTIbyte( (idhi>>8 )&0xff ); + WriteTIbyte( (idhi>>16)&0xff ); + WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo + WriteTIbyte( (crc )&0xff ); // crc lo + WriteTIbyte( (crc>>8 )&0xff ); // crc hi + WriteTIbyte(0x00); // write frame lo + WriteTIbyte(0x03); // write frame hi + HIGH(GPIO_SSC_DOUT); + WaitMS(50); // programming time - LED_A_OFF(); + LED_A_OFF(); - // get TI tag data into the buffer - AcquireTiType(); + // get TI tag data into the buffer + AcquireTiType(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("Now use `lf ti read` to check"); - StopTicks(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + DbpString("Now use `lf ti read` to check"); + StopTicks(); } // note: a call to FpgaDownloadAndGo(FPGA_BITSTREAM_LF) must be done before, but // this may destroy the bigbuf so be sure this is called before calling SimulateTagLowFrequencyEx void SimulateTagLowFrequencyEx(int period, int gap, int ledcontrol, int numcycles) { - // start us timer - StartTicks(); + // start us timer + StartTicks(); - //FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE ); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); - WaitMS(20); + //FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE ); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); + WaitMS(20); - int i = 0, x = 0; - uint8_t *buf = BigBuf_get_addr(); + int i = 0, x = 0; + uint8_t *buf = BigBuf_get_addr(); - // set frequency, get values from 'lf config' command - sample_config *sc = getSamplingConfig(); + // set frequency, get values from 'lf config' command + sample_config *sc = getSamplingConfig(); - if ( (sc->divisor == 1) || (sc->divisor < 0) || (sc->divisor > 255) ) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - else if (sc->divisor == 0) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - else - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor); + if ( (sc->divisor == 1) || (sc->divisor < 0) || (sc->divisor > 255) ) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + else if (sc->divisor == 0) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + else + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor); - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; - uint8_t check = 1; + uint8_t check = 1; - for(;;) { + for(;;) { - if ( numcycles > -1 ) { - if ( x != numcycles ) { - ++x; - } else { - // exit without turning of field - return; - } - } + if ( numcycles > -1 ) { + if ( x != numcycles ) { + ++x; + } else { + // exit without turning of field + return; + } + } - if (ledcontrol) LED_D_ON(); + if (ledcontrol) LED_D_ON(); - // wait until SSC_CLK goes HIGH - // used as a simple detection of a reader field? - while (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { - WDT_HIT(); - if ( !check ) { - if ( usb_poll_validate_length() || BUTTON_PRESS() ) - goto OUT; - } - ++check; } + // wait until SSC_CLK goes HIGH + // used as a simple detection of a reader field? + while (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { + WDT_HIT(); + if ( !check ) { + if ( usb_poll_validate_length() || BUTTON_PRESS() ) + goto OUT; + } + ++check; + } - if (buf[i]) - OPEN_COIL(); - else - SHORT_COIL(); + if (buf[i]) + OPEN_COIL(); + else + SHORT_COIL(); - //wait until SSC_CLK goes LOW - while (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { - WDT_HIT(); - if ( !check ) { - if ( usb_poll_validate_length() || BUTTON_PRESS() ) - goto OUT; - } - ++check; - } + //wait until SSC_CLK goes LOW + while (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { + WDT_HIT(); + if ( !check ) { + if ( usb_poll_validate_length() || BUTTON_PRESS() ) + goto OUT; + } + ++check; + } - i++; - if (i == period) { - i = 0; - if (gap) { - SHORT_COIL(); - WaitUS(gap); - } - } + i++; + if (i == period) { + i = 0; + if (gap) { + SHORT_COIL(); + WaitUS(gap); + } + } - if (ledcontrol) LED_D_OFF(); - } + if (ledcontrol) LED_D_OFF(); + } OUT: - StopTicks(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); + StopTicks(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); } void SimulateTagLowFrequency(int period, int gap, int ledcontrol) { - SimulateTagLowFrequencyEx(period, gap, ledcontrol, -1); + SimulateTagLowFrequencyEx(period, gap, ledcontrol, -1); } @@ -671,680 +672,680 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0) // also manchester, static void fc(int c, int *n) { - uint8_t *dest = BigBuf_get_addr(); - int idx; + uint8_t *dest = BigBuf_get_addr(); + int idx; - // for when we want an fc8 pattern every 4 logical bits - if (c == 0) { - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - } + // for when we want an fc8 pattern every 4 logical bits + if (c == 0) { + dest[((*n)++)] = 1; + dest[((*n)++)] = 1; + dest[((*n)++)] = 1; + dest[((*n)++)] = 1; + dest[((*n)++)] = 0; + dest[((*n)++)] = 0; + dest[((*n)++)] = 0; + dest[((*n)++)] = 0; + } - // an fc/8 encoded bit is a bit pattern of 11110000 x6 = 48 samples - if (c == 8) { - for (idx=0; idx < 6; idx++) { - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - } - } + // an fc/8 encoded bit is a bit pattern of 11110000 x6 = 48 samples + if (c == 8) { + for (idx=0; idx < 6; idx++) { + dest[((*n)++)] = 1; + dest[((*n)++)] = 1; + dest[((*n)++)] = 1; + dest[((*n)++)] = 1; + dest[((*n)++)] = 0; + dest[((*n)++)] = 0; + dest[((*n)++)] = 0; + dest[((*n)++)] = 0; + } + } - // an fc/10 encoded bit is a bit pattern of 1111100000 x5 = 50 samples - if (c == 10) { - for (idx = 0; idx < 5; idx++) { - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 1; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - dest[((*n)++)] = 0; - } - } + // an fc/10 encoded bit is a bit pattern of 1111100000 x5 = 50 samples + if (c == 10) { + for (idx = 0; idx < 5; idx++) { + dest[((*n)++)] = 1; + dest[((*n)++)] = 1; + dest[((*n)++)] = 1; + dest[((*n)++)] = 1; + dest[((*n)++)] = 1; + dest[((*n)++)] = 0; + dest[((*n)++)] = 0; + dest[((*n)++)] = 0; + dest[((*n)++)] = 0; + dest[((*n)++)] = 0; + } + } } // special start of frame marker containing invalid bit sequences // this one is focused on HID, with manchester encoding. static void fcSTT(int *n) { - fc(8, n); fc(8, n); // invalid - fc(8, n); fc(10, n); // logical 0 - fc(10, n); fc(10, n); // invalid - fc(8, n); fc(10, n); // logical 0 + fc(8, n); fc(8, n); // invalid + fc(8, n); fc(10, n); // logical 0 + fc(10, n); fc(10, n); // invalid + fc(8, n); fc(10, n); // logical 0 } // compose fc/X fc/Y waveform (FSKx) static void fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) { - uint8_t *dest = BigBuf_get_addr(); - uint8_t halfFC = fc >> 1; - uint8_t wavesPerClock = clock/fc; - uint8_t mod = clock % fc; //modifier - uint8_t modAdj = fc/mod; //how often to apply modifier - bool modAdjOk = !(fc % mod); //if (fc % mod==0) modAdjOk = true; + uint8_t *dest = BigBuf_get_addr(); + uint8_t halfFC = fc >> 1; + uint8_t wavesPerClock = clock/fc; + uint8_t mod = clock % fc; //modifier + uint8_t modAdj = fc/mod; //how often to apply modifier + bool modAdjOk = !(fc % mod); //if (fc % mod==0) modAdjOk = true; - // loop through clock - step field clock - for (uint8_t idx=0; idx < wavesPerClock; idx++){ - // put 1/2 FC length 1's and 1/2 0's per field clock wave (to create the wave) - memset(dest + (*n), 0, fc - halfFC); //in case of odd number use extra here - memset(dest + (*n) + (fc - halfFC), 1, halfFC); - *n += fc; - } - if (mod > 0) (*modCnt)++; + // loop through clock - step field clock + for (uint8_t idx=0; idx < wavesPerClock; idx++){ + // put 1/2 FC length 1's and 1/2 0's per field clock wave (to create the wave) + memset(dest + (*n), 0, fc - halfFC); //in case of odd number use extra here + memset(dest + (*n) + (fc - halfFC), 1, halfFC); + *n += fc; + } + if (mod > 0) (*modCnt)++; - if ((mod > 0) && modAdjOk){ //fsk2 - if ((*modCnt % modAdj) == 0){ //if 4th 8 length wave in a rf/50 add extra 8 length wave - memset(dest + (*n), 0, fc - halfFC); - memset(dest + (*n) + ( fc - halfFC), 1, halfFC); - *n += fc; - } - } - if (mod > 0 && !modAdjOk){ //fsk1 - memset(dest + (*n), 0, mod - (mod >> 1)); - memset(dest + (*n) + (mod - (mod >> 1)), 1, mod >> 1); - *n += mod; - } + if ((mod > 0) && modAdjOk){ //fsk2 + if ((*modCnt % modAdj) == 0){ //if 4th 8 length wave in a rf/50 add extra 8 length wave + memset(dest + (*n), 0, fc - halfFC); + memset(dest + (*n) + ( fc - halfFC), 1, halfFC); + *n += fc; + } + } + if (mod > 0 && !modAdjOk){ //fsk1 + memset(dest + (*n), 0, mod - (mod >> 1)); + memset(dest + (*n) + (mod - (mod >> 1)), 1, mod >> 1); + *n += mod; + } } // prepare a waveform pattern in the buffer based on the ID given then // simulate a HID tag until the button is pressed void CmdHIDsimTAGEx( uint32_t hi, uint32_t lo, int ledcontrol, int numcycles) { - if (hi > 0xFFF) { - DbpString("[!] tags can only have 44 bits. - USE lf simfsk for larger tags"); - return; - } + if (hi > 0xFFF) { + DbpString("[!] tags can only have 44 bits. - USE lf simfsk for larger tags"); + return; + } - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - set_tracing(false); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + set_tracing(false); - int n = 0, i = 0; - /* - HID tag bitstream format - The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits - A 1 bit is represented as 6 fc8 and 5 fc10 patterns (manchester 10) during 2 clock periods. (1bit = 1clock period) - A 0 bit is represented as 5 fc10 and 6 fc8 patterns (manchester 01) - A fc8 is inserted before every 4 bits - A special start of frame pattern is used consisting a0b0 where a and b are neither 0 - nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10) + int n = 0, i = 0; + /* + HID tag bitstream format + The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits + A 1 bit is represented as 6 fc8 and 5 fc10 patterns (manchester 10) during 2 clock periods. (1bit = 1clock period) + A 0 bit is represented as 5 fc10 and 6 fc8 patterns (manchester 01) + A fc8 is inserted before every 4 bits + A special start of frame pattern is used consisting a0b0 where a and b are neither 0 + nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10) - FSK2a - bit 1 = fc10 - bit 0 = fc8 - */ + FSK2a + bit 1 = fc10 + bit 0 = fc8 + */ - fc(0, &n); + fc(0, &n); - // special start of frame marker containing invalid bit sequences - fcSTT(&n); + // special start of frame marker containing invalid bit sequences + fcSTT(&n); - // manchester encode bits 43 to 32 - for (i = 11; i >= 0; i--) { + // manchester encode bits 43 to 32 + for (i = 11; i >= 0; i--) { - if ((i % 4) == 3) fc(0, &n); + if ((i % 4) == 3) fc(0, &n); - if ((hi >> i) & 1) { - fc(10, &n); fc(8, &n); // low-high transition - } else { - fc(8, &n); fc(10, &n); // high-low transition - } - } + if ((hi >> i) & 1) { + fc(10, &n); fc(8, &n); // low-high transition + } else { + fc(8, &n); fc(10, &n); // high-low transition + } + } - // manchester encode bits 31 to 0 - for (i = 31; i >= 0; i--) { + // manchester encode bits 31 to 0 + for (i = 31; i >= 0; i--) { - if ((i % 4) == 3) fc(0, &n); + if ((i % 4) == 3) fc(0, &n); - if (( lo >> i ) & 1) { - fc(10, &n); fc(8, &n); // low-high transition - } else { - fc(8, &n); fc(10, &n); // high-low transition - } - } + if (( lo >> i ) & 1) { + fc(10, &n); fc(8, &n); // low-high transition + } else { + fc(8, &n); fc(10, &n); // high-low transition + } + } - if (ledcontrol) LED_A_ON(); - SimulateTagLowFrequencyEx(n, 0, ledcontrol, numcycles); - if (ledcontrol) LED_A_OFF(); + if (ledcontrol) LED_A_ON(); + SimulateTagLowFrequencyEx(n, 0, ledcontrol, numcycles); + if (ledcontrol) LED_A_OFF(); } void CmdHIDsimTAG( uint32_t hi, uint32_t lo, int ledcontrol) { - CmdHIDsimTAGEx( hi, lo, ledcontrol, -1); - DbpString("[!] simulation finished"); + CmdHIDsimTAGEx( hi, lo, ledcontrol, -1); + DbpString("[!] simulation finished"); } // prepare a waveform pattern in the buffer based on the ID given then // simulate a FSK tag until the button is pressed // arg1 contains fcHigh and fcLow, arg2 contains STT marker and clock void CmdFSKsimTAG(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *bits) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - // free eventually allocated BigBuf memory - BigBuf_free(); BigBuf_Clear_ext(false); - clear_trace(); - set_tracing(false); + // free eventually allocated BigBuf memory + BigBuf_free(); BigBuf_Clear_ext(false); + clear_trace(); + set_tracing(false); - int ledcontrol = 1, n = 0, i = 0; - uint8_t fcHigh = arg1 >> 8; - uint8_t fcLow = arg1 & 0xFF; - uint16_t modCnt = 0; - uint8_t clk = arg2 & 0xFF; - uint8_t stt = (arg2 >> 8) & 1; + int ledcontrol = 1, n = 0, i = 0; + uint8_t fcHigh = arg1 >> 8; + uint8_t fcLow = arg1 & 0xFF; + uint16_t modCnt = 0; + uint8_t clk = arg2 & 0xFF; + uint8_t stt = (arg2 >> 8) & 1; - if ( stt ) { - //int fsktype = ( fcHigh == 8 && fcLow == 5) ? 1 : 2; - //fcSTT(&n); - } + if ( stt ) { + //int fsktype = ( fcHigh == 8 && fcLow == 5) ? 1 : 2; + //fcSTT(&n); + } - for (i=0; i> 8) & 0xFF; - uint8_t encoding = arg1 & 0xFF; - uint8_t separator = arg2 & 1; - uint8_t invert = (arg2 >> 8) & 1; + int ledcontrol = 1, n = 0, i = 0; + uint8_t clk = (arg1 >> 8) & 0xFF; + uint8_t encoding = arg1 & 0xFF; + uint8_t separator = arg2 & 1; + uint8_t invert = (arg2 >> 8) & 1; - if (encoding == 2){ //biphase - uint8_t phase = 0; - for (i=0; i> 8; - uint8_t carrier = arg1 & 0xFF; - uint8_t invert = arg2 & 0xFF; - uint8_t curPhase = 0; - for (i=0; i> 8; + uint8_t carrier = arg1 & 0xFF; + uint8_t invert = arg2 & 0xFF; + uint8_t curPhase = 0; + for (i=0; i 0 && lo > 0 && (size == 96 || size == 192)){ - // go over previously decoded manchester data and decode into usable tag ID - if (hi2 != 0){ //extra large HID tags 88/192 bits - Dbprintf("TAG ID: %x%08x%08x (%d)", - hi2, - hi, - lo, - (lo >> 1) & 0xFFFF - ); - } else { //standard HID tags 44/96 bits - uint8_t bitlen = 0; - uint32_t fc = 0; - uint32_t cardnum = 0; + if (idx > 0 && lo > 0 && (size == 96 || size == 192)){ + // go over previously decoded manchester data and decode into usable tag ID + if (hi2 != 0){ //extra large HID tags 88/192 bits + Dbprintf("TAG ID: %x%08x%08x (%d)", + hi2, + hi, + lo, + (lo >> 1) & 0xFFFF + ); + } else { //standard HID tags 44/96 bits + uint8_t bitlen = 0; + uint32_t fc = 0; + uint32_t cardnum = 0; - if (((hi >> 5) & 1) == 1){//if bit 38 is set then < 37 bit format is used - uint32_t lo2 = 0; - lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit - uint8_t idx3 = 1; - while (lo2 > 1){ //find last bit set to 1 (format len bit) - lo2 >>= 1; - idx3++; - } - bitlen = idx3 + 19; - fc = 0; - cardnum = 0; - if (bitlen == 26){ - cardnum = (lo >> 1) & 0xFFFF; - fc = (lo >> 17) & 0xFF; - } - if (bitlen == 37){ - cardnum = (lo >> 1 ) & 0x7FFFF; - fc = ((hi & 0xF) << 12) | (lo >> 20); - } - if (bitlen == 34){ - cardnum = (lo >> 1) & 0xFFFF; - fc = ((hi & 1) << 15) | (lo >> 17); - } - if (bitlen == 35){ - cardnum = (lo >> 1) & 0xFFFFF; - fc = ((hi & 1) << 11)|(lo >> 21); - } - } - else { //if bit 38 is not set then 37 bit format is used - bitlen= 37; - fc = 0; - cardnum = 0; - if (bitlen == 37){ - cardnum = (lo >> 1) & 0x7FFFF; - fc = ((hi & 0xF) << 12) | (lo >> 20); - } - } - Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", - hi, - lo, - (lo >> 1) & 0xFFFF, - bitlen, - fc, - cardnum - ); - } - if (findone){ - *high = hi; - *low = lo; - break; - } - // reset - } - hi2 = hi = lo = idx = 0; - } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + if (((hi >> 5) & 1) == 1){//if bit 38 is set then < 37 bit format is used + uint32_t lo2 = 0; + lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit + uint8_t idx3 = 1; + while (lo2 > 1){ //find last bit set to 1 (format len bit) + lo2 >>= 1; + idx3++; + } + bitlen = idx3 + 19; + fc = 0; + cardnum = 0; + if (bitlen == 26){ + cardnum = (lo >> 1) & 0xFFFF; + fc = (lo >> 17) & 0xFF; + } + if (bitlen == 37){ + cardnum = (lo >> 1 ) & 0x7FFFF; + fc = ((hi & 0xF) << 12) | (lo >> 20); + } + if (bitlen == 34){ + cardnum = (lo >> 1) & 0xFFFF; + fc = ((hi & 1) << 15) | (lo >> 17); + } + if (bitlen == 35){ + cardnum = (lo >> 1) & 0xFFFFF; + fc = ((hi & 1) << 11)|(lo >> 21); + } + } + else { //if bit 38 is not set then 37 bit format is used + bitlen= 37; + fc = 0; + cardnum = 0; + if (bitlen == 37){ + cardnum = (lo >> 1) & 0x7FFFF; + fc = ((hi & 0xF) << 12) | (lo >> 20); + } + } + Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", + hi, + lo, + (lo >> 1) & 0xFFFF, + bitlen, + fc, + cardnum + ); + } + if (findone){ + *high = hi; + *low = lo; + break; + } + // reset + } + hi2 = hi = lo = idx = 0; + } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } // loop to get raw HID waveform then FSK demodulate the TAG ID from it void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { - uint8_t *dest = BigBuf_get_addr(); + uint8_t *dest = BigBuf_get_addr(); - //big enough to catch 2 sequences of largest format - size_t size = 12800; //50 * 128 * 2; + //big enough to catch 2 sequences of largest format + size_t size = 12800; //50 * 128 * 2; - int idx = 0, dummyIdx = 0; + int idx = 0, dummyIdx = 0; - BigBuf_Clear_keep_EM(); + BigBuf_Clear_keep_EM(); - LFSetupFPGAForADC(95, true); + LFSetupFPGAForADC(95, true); - while (!BUTTON_PRESS() && !usb_poll_validate_length()) { + while (!BUTTON_PRESS() && !usb_poll_validate_length()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); + WDT_HIT(); + if (ledcontrol) LED_A_ON(); - DoAcquisition_default(-1, true); - // FSK demodulator + DoAcquisition_default(-1, true); + // FSK demodulator - idx = detectAWID(dest, &size, &dummyIdx); + idx = detectAWID(dest, &size, &dummyIdx); - if (idx <= 0 || size != 96) continue; - // Index map - // 0 10 20 30 40 50 60 - // | | | | | | | - // 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96 - // ----------------------------------------------------------------------------- - // 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1 - // premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96 - // |---26 bit---| |-----117----||-------------142-------------| - // b = format bit len, o = odd parity of last 3 bits - // f = facility code, c = card number - // w = wiegand parity - // (26 bit format shown) + if (idx <= 0 || size != 96) continue; + // Index map + // 0 10 20 30 40 50 60 + // | | | | | | | + // 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96 + // ----------------------------------------------------------------------------- + // 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1 + // premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96 + // |---26 bit---| |-----117----||-------------142-------------| + // b = format bit len, o = odd parity of last 3 bits + // f = facility code, c = card number + // w = wiegand parity + // (26 bit format shown) - //get raw ID before removing parities - uint32_t rawLo = bytebits_to_byte(dest+idx+64, 32); - uint32_t rawHi = bytebits_to_byte(dest+idx+32, 32); - uint32_t rawHi2 = bytebits_to_byte(dest+idx, 32); + //get raw ID before removing parities + uint32_t rawLo = bytebits_to_byte(dest+idx+64, 32); + uint32_t rawHi = bytebits_to_byte(dest+idx+32, 32); + uint32_t rawHi2 = bytebits_to_byte(dest+idx, 32); - size = removeParity(dest, idx+8, 4, 1, 88); - if (size != 66) continue; - // ok valid card found! + size = removeParity(dest, idx+8, 4, 1, 88); + if (size != 66) continue; + // ok valid card found! - // Index map - // 0 10 20 30 40 50 60 - // | | | | | | | - // 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456 - // ----------------------------------------------------------------------------- - // 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000 - // bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - // |26 bit| |-117--| |-----142------| - // b = format bit len, o = odd parity of last 3 bits - // f = facility code, c = card number - // w = wiegand parity - // (26 bit format shown) + // Index map + // 0 10 20 30 40 50 60 + // | | | | | | | + // 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456 + // ----------------------------------------------------------------------------- + // 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000 + // bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + // |26 bit| |-117--| |-----142------| + // b = format bit len, o = odd parity of last 3 bits + // f = facility code, c = card number + // w = wiegand parity + // (26 bit format shown) - uint32_t fc = 0; - uint32_t cardnum = 0; - uint32_t code1 = 0; - uint32_t code2 = 0; - uint8_t fmtLen = bytebits_to_byte(dest, 8); - if (fmtLen == 26){ - fc = bytebits_to_byte(dest+9, 8); - cardnum = bytebits_to_byte(dest+17, 16); - code1 = bytebits_to_byte(dest+8, fmtLen); - Dbprintf("AWID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo); - } else { - cardnum = bytebits_to_byte(dest+8+(fmtLen-17), 16); - if (fmtLen > 32){ - code1 = bytebits_to_byte(dest+8, fmtLen-32); - code2 = bytebits_to_byte(dest+8+(fmtLen-32), 32); - Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo); - } else{ - code1 = bytebits_to_byte(dest+8, fmtLen); - Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo); - } - } - if (findone){ - if (ledcontrol) LED_A_OFF(); - *high = rawHi; - *low = rawLo; - break; - } - // reset - idx = 0; - WDT_HIT(); - } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + uint32_t fc = 0; + uint32_t cardnum = 0; + uint32_t code1 = 0; + uint32_t code2 = 0; + uint8_t fmtLen = bytebits_to_byte(dest, 8); + if (fmtLen == 26){ + fc = bytebits_to_byte(dest+9, 8); + cardnum = bytebits_to_byte(dest+17, 16); + code1 = bytebits_to_byte(dest+8, fmtLen); + Dbprintf("AWID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo); + } else { + cardnum = bytebits_to_byte(dest+8+(fmtLen-17), 16); + if (fmtLen > 32){ + code1 = bytebits_to_byte(dest+8, fmtLen-32); + code2 = bytebits_to_byte(dest+8+(fmtLen-32), 32); + Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo); + } else{ + code1 = bytebits_to_byte(dest+8, fmtLen); + Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo); + } + } + if (findone){ + if (ledcontrol) LED_A_OFF(); + *high = rawHi; + *low = rawLo; + break; + } + // reset + idx = 0; + WDT_HIT(); + } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol) { - uint8_t *dest = BigBuf_get_addr(); + uint8_t *dest = BigBuf_get_addr(); - size_t size = 0, idx = 0; - int clk = 0, invert = 0, errCnt = 0, maxErr = 20; - uint32_t hi = 0; - uint64_t lo = 0; + size_t size = 0, idx = 0; + int clk = 0, invert = 0, errCnt = 0, maxErr = 20; + uint32_t hi = 0; + uint64_t lo = 0; - BigBuf_Clear_keep_EM(); + BigBuf_Clear_keep_EM(); - LFSetupFPGAForADC(95, true); + LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS() && !usb_poll_validate_length()) { + while(!BUTTON_PRESS() && !usb_poll_validate_length()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); + WDT_HIT(); + if (ledcontrol) LED_A_ON(); - DoAcquisition_default(-1, true); + DoAcquisition_default(-1, true); - size = BigBuf_max_traceLen(); - //askdemod and manchester decode - if (size > 16385) size = 16385; //big enough to catch 2 sequences of largest format - errCnt = askdemod(dest, &size, &clk, &invert, maxErr, 0, 1); - WDT_HIT(); + size = BigBuf_max_traceLen(); + //askdemod and manchester decode + if (size > 16385) size = 16385; //big enough to catch 2 sequences of largest format + errCnt = askdemod(dest, &size, &clk, &invert, maxErr, 0, 1); + WDT_HIT(); - if (errCnt < 0) continue; + if (errCnt < 0) continue; - errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo); - if (errCnt == 1){ - if (size == 128){ - Dbprintf("EM XL TAG ID: %06x%08x%08x - (%05d_%03d_%08d)", - hi, - (uint32_t)(lo >> 32), - (uint32_t)lo, - (uint32_t)(lo & 0xFFFF), - (uint32_t)((lo >> 16LL) & 0xFF), - (uint32_t)(lo & 0xFFFFFF)); - } else { - Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)", - (uint32_t)(lo >> 32), - (uint32_t)lo, - (uint32_t)(lo & 0xFFFF), - (uint32_t)((lo >> 16LL) & 0xFF), - (uint32_t)(lo & 0xFFFFFF)); - } + errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo); + if (errCnt == 1){ + if (size == 128){ + Dbprintf("EM XL TAG ID: %06x%08x%08x - (%05d_%03d_%08d)", + hi, + (uint32_t)(lo >> 32), + (uint32_t)lo, + (uint32_t)(lo & 0xFFFF), + (uint32_t)((lo >> 16LL) & 0xFF), + (uint32_t)(lo & 0xFFFFFF)); + } else { + Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)", + (uint32_t)(lo >> 32), + (uint32_t)lo, + (uint32_t)(lo & 0xFFFF), + (uint32_t)((lo >> 16LL) & 0xFF), + (uint32_t)(lo & 0xFFFFFF)); + } - if (findone){ - if (ledcontrol) LED_A_OFF(); - *high = hi; - *low = lo; - break; - } - } - WDT_HIT(); - hi = lo = size = idx = 0; - clk = invert = errCnt = 0; - } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + if (findone){ + if (ledcontrol) LED_A_OFF(); + *high = hi; + *low = lo; + break; + } + } + WDT_HIT(); + hi = lo = size = idx = 0; + clk = invert = errCnt = 0; + } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { - uint8_t *dest = BigBuf_get_addr(); + uint8_t *dest = BigBuf_get_addr(); - int dummyIdx = 0, idx = 0; - uint32_t code = 0, code2 = 0; - uint8_t version = 0, facilitycode = 0, crc = 0; - uint16_t number = 0, calccrc = 0; + int dummyIdx = 0, idx = 0; + uint32_t code = 0, code2 = 0; + uint8_t version = 0, facilitycode = 0, crc = 0; + uint16_t number = 0, calccrc = 0; - size_t size = BigBuf_max_traceLen(); + size_t size = BigBuf_max_traceLen(); - BigBuf_Clear_keep_EM(); + BigBuf_Clear_keep_EM(); - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(95, true); + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - while (!BUTTON_PRESS() && !usb_poll_validate_length()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); + while (!BUTTON_PRESS() && !usb_poll_validate_length()) { + WDT_HIT(); + if (ledcontrol) LED_A_ON(); - DoAcquisition_default(-1, true); + DoAcquisition_default(-1, true); - //fskdemod and get start index - WDT_HIT(); - idx = detectIOProx(dest, &size, &dummyIdx); - if (idx < 0) continue; - //valid tag found + //fskdemod and get start index + WDT_HIT(); + idx = detectIOProx(dest, &size, &dummyIdx); + if (idx < 0) continue; + //valid tag found - //Index map - //0 10 20 30 40 50 60 - //| | | | | | | - //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 - //----------------------------------------------------------------------------- + //Index map + //0 10 20 30 40 50 60 + //| | | | | | | + //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 + //----------------------------------------------------------------------------- //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 checksum 11 - // - //Checksum: - //00000000 0 11110000 1 11100000 1 00000001 1 00000011 1 10110110 1 01110101 11 - //preamble F0 E0 01 03 B6 75 - // How to calc checksum, - // http://www.proxmark.org/forum/viewtopic.php?id=364&p=6 - // F0 + E0 + 01 + 03 + B6 = 28A - // 28A & FF = 8A - // FF - 8A = 75 - // Checksum: 0x75 - //XSF(version)facility:codeone+codetwo - //Handle the data - // if(findone){ //only print binary if we are doing one - // Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); - // Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); - // Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]); - // Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]); - // Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]); - // Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]); - // Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]); - // } - code = bytebits_to_byte(dest+idx, 32); - code2 = bytebits_to_byte(dest+idx+32, 32); - version = bytebits_to_byte(dest+idx+27, 8); //14,4 - facilitycode = bytebits_to_byte(dest+idx+18, 8); - number = (bytebits_to_byte(dest+idx+36, 8) << 8) | (bytebits_to_byte(dest+idx+45, 8)); //36,9 + // + //Checksum: + //00000000 0 11110000 1 11100000 1 00000001 1 00000011 1 10110110 1 01110101 11 + //preamble F0 E0 01 03 B6 75 + // How to calc checksum, + // http://www.proxmark.org/forum/viewtopic.php?id=364&p=6 + // F0 + E0 + 01 + 03 + B6 = 28A + // 28A & FF = 8A + // FF - 8A = 75 + // Checksum: 0x75 + //XSF(version)facility:codeone+codetwo + //Handle the data + // if(findone){ //only print binary if we are doing one + // Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); + // Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); + // Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]); + // Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]); + // Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]); + // Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]); + // Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]); + // } + code = bytebits_to_byte(dest+idx, 32); + code2 = bytebits_to_byte(dest+idx+32, 32); + version = bytebits_to_byte(dest+idx+27, 8); //14,4 + facilitycode = bytebits_to_byte(dest+idx+18, 8); + number = (bytebits_to_byte(dest+idx+36, 8) << 8) | (bytebits_to_byte(dest+idx+45, 8)); //36,9 - crc = bytebits_to_byte(dest+idx+54, 8); - for (uint8_t i=1; i<6; ++i) - calccrc += bytebits_to_byte(dest+idx+9*i, 8); - calccrc &= 0xff; - calccrc = 0xff - calccrc; + crc = bytebits_to_byte(dest+idx+54, 8); + for (uint8_t i=1; i<6; ++i) + calccrc += bytebits_to_byte(dest+idx+9*i, 8); + calccrc &= 0xff; + calccrc = 0xff - calccrc; - char *crcStr = (crc == calccrc) ? "ok" : "!crc"; + char *crcStr = (crc == calccrc) ? "ok" : "!crc"; Dbprintf("IO Prox XSF(%02d)%02x:%05d (%08x%08x) [%02x %s]", version, facilitycode, number, code, code2, crc, crcStr); - // if we're only looking for one tag - if (findone){ - if (ledcontrol) LED_A_OFF(); - *high = code; - *low = code2; - break; - } - code = code2 = 0; - version = facilitycode = 0; - number = 0; - idx = 0; + // if we're only looking for one tag + if (findone){ + if (ledcontrol) LED_A_OFF(); + *high = code; + *low = code2; + break; + } + code = code2 = 0; + version = facilitycode = 0; + number = 0; + idx = 0; - WDT_HIT(); - } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + WDT_HIT(); + } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } /*------------------------------ @@ -1359,521 +1360,521 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { */ void TurnReadLFOn(uint32_t delay) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // measure antenna strength. - //int adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); - WaitUS(delay); + // measure antenna strength. + //int adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); + WaitUS(delay); } void TurnReadLF_off(uint32_t delay) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - WaitUS(delay); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + WaitUS(delay); } // Write one bit to card void T55xxWriteBit(int bit) { - if (!bit) - TurnReadLFOn(t_config.write_0); - else - TurnReadLFOn(t_config.write_1); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - WaitUS(t_config.write_gap); + if (!bit) + TurnReadLFOn(t_config.write_0); + else + TurnReadLFOn(t_config.write_1); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + WaitUS(t_config.write_gap); } // Send T5577 reset command then read stream (see if we can identify the start of the stream) void T55xxResetRead(void) { - LED_A_ON(); - //clear buffer now so it does not interfere with timing later - BigBuf_Clear_keep_EM(); + LED_A_ON(); + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_keep_EM(); - StartTicks(); + StartTicks(); - // Set up FPGA, 125kHz - LFSetupFPGAForADC(95, true); - // make sure tag is fully powered up... - WaitMS(4); + // Set up FPGA, 125kHz + LFSetupFPGAForADC(95, true); + // make sure tag is fully powered up... + WaitMS(4); - // Trigger T55x7 in mode. - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - WaitUS(t_config.start_gap); + // Trigger T55x7 in mode. + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + WaitUS(t_config.start_gap); - // reset tag - op code 00 - T55xxWriteBit(0); - T55xxWriteBit(0); + // reset tag - op code 00 + T55xxWriteBit(0); + T55xxWriteBit(0); - TurnReadLFOn(t_config.read_gap); + TurnReadLFOn(t_config.read_gap); - // Acquisition - DoPartialAcquisition(0, true, BigBuf_max_traceLen(), 0); + // Acquisition + DoPartialAcquisition(0, true, BigBuf_max_traceLen(), 0); - // Turn the field off - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - cmd_send(CMD_ACK,0,0,0,0,0); - LED_A_OFF(); + // Turn the field off + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + cmd_send(CMD_ACK,0,0,0,0,0); + LED_A_OFF(); } // Write one card block in page 0, no lock void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) { - LED_A_ON(); - bool PwdMode = arg & 0x1; - uint8_t Page = (arg & 0x2)>>1; - bool testMode = arg & 0x4; - uint32_t i = 0; + LED_A_ON(); + bool PwdMode = arg & 0x1; + uint8_t Page = (arg & 0x2)>>1; + bool testMode = arg & 0x4; + uint32_t i = 0; - StartTicks(); + StartTicks(); - // Set up FPGA, 125kHz - LFSetupFPGAForADC(95, true); + // Set up FPGA, 125kHz + LFSetupFPGAForADC(95, true); - // make sure tag is fully powered up... - WaitMS(4); - // Trigger T55x7 in mode. - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - WaitUS(t_config.start_gap); + // make sure tag is fully powered up... + WaitMS(4); + // Trigger T55x7 in mode. + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + WaitUS(t_config.start_gap); - if (testMode) Dbprintf("TestMODE"); - // Std Opcode 10 - T55xxWriteBit(testMode ? 0 : 1); - T55xxWriteBit(testMode ? 1 : Page); //Page 0 + if (testMode) Dbprintf("TestMODE"); + // Std Opcode 10 + T55xxWriteBit(testMode ? 0 : 1); + T55xxWriteBit(testMode ? 1 : Page); //Page 0 - if (PwdMode){ - // Send Pwd - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Pwd & i); - } - // Send Lock bit - T55xxWriteBit(0); + if (PwdMode){ + // Send Pwd + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Pwd & i); + } + // Send Lock bit + T55xxWriteBit(0); - // Send Data - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Data & i); + // Send Data + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Data & i); - // Send Block number - for (i = 0x04; i != 0; i >>= 1) - T55xxWriteBit(Block & i); + // Send Block number + for (i = 0x04; i != 0; i >>= 1) + T55xxWriteBit(Block & i); - // Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, - // so wait a little more) + // Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, + // so wait a little more) - // "there is a clock delay before programming" - // - programming takes ~5.6ms for t5577 ~18ms for E5550 or t5567 - // so we should wait 1 clock + 5.6ms then read response? - // but we need to know we are dealing with t5577 vs t5567 vs e5550 (or q5) marshmellow... - if (testMode) { - //TESTMODE TIMING TESTS: - // <566us does nothing - // 566-568 switches between wiping to 0s and doing nothing - // 5184 wipes and allows 1 block to be programmed. - // indefinite power on wipes and then programs all blocks with bitshifted data sent. - TurnReadLFOn(5184); + // "there is a clock delay before programming" + // - programming takes ~5.6ms for t5577 ~18ms for E5550 or t5567 + // so we should wait 1 clock + 5.6ms then read response? + // but we need to know we are dealing with t5577 vs t5567 vs e5550 (or q5) marshmellow... + if (testMode) { + //TESTMODE TIMING TESTS: + // <566us does nothing + // 566-568 switches between wiping to 0s and doing nothing + // 5184 wipes and allows 1 block to be programmed. + // indefinite power on wipes and then programs all blocks with bitshifted data sent. + TurnReadLFOn(5184); - } else { - TurnReadLFOn(20 * 1000); + } else { + TurnReadLFOn(20 * 1000); - //could attempt to do a read to confirm write took - // as the tag should repeat back the new block - // until it is reset, but to confirm it we would - // need to know the current block 0 config mode for - // modulation clock an other details to demod the response... - // response should be (for t55x7) a 0 bit then (ST if on) - // block data written in on repeat until reset. + //could attempt to do a read to confirm write took + // as the tag should repeat back the new block + // until it is reset, but to confirm it we would + // need to know the current block 0 config mode for + // modulation clock an other details to demod the response... + // response should be (for t55x7) a 0 bit then (ST if on) + // block data written in on repeat until reset. - //DoPartialAcquisition(20, true, 12000); - } + //DoPartialAcquisition(20, true, 12000); + } - // turn field off - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_A_OFF(); + // turn field off + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_A_OFF(); } // Write one card block in page 0, no lock void T55xxWriteBlock(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) { - T55xxWriteBlockExt(Data, Block, Pwd, arg); - cmd_send(CMD_ACK,0,0,0,0,0); + T55xxWriteBlockExt(Data, Block, Pwd, arg); + cmd_send(CMD_ACK,0,0,0,0,0); } // Read one card block in page [page] void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { - LED_A_ON(); - bool PwdMode = arg0 & 0x1; - uint8_t Page = ( arg0 & 0x2 ) >> 1; - bool brute_mem = arg0 & 0x4; + LED_A_ON(); + bool PwdMode = arg0 & 0x1; + uint8_t Page = ( arg0 & 0x2 ) >> 1; + bool brute_mem = arg0 & 0x4; - uint32_t i = 0; + uint32_t i = 0; - // regular read mode - bool RegReadMode = (Block == 0xFF); + // regular read mode + bool RegReadMode = (Block == 0xFF); - uint8_t start_wait = 4; - size_t samples = 12000; - if ( brute_mem ) { - start_wait = 0; - samples = 1024; - } + uint8_t start_wait = 4; + size_t samples = 12000; + if ( brute_mem ) { + start_wait = 0; + samples = 1024; + } - //clear buffer now so it does not interfere with timing later - BigBuf_Clear_keep_EM(); + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_keep_EM(); - //make sure block is at max 7 - Block &= 0x7; + //make sure block is at max 7 + Block &= 0x7; - StartTicks(); + StartTicks(); - // Set up FPGA, 125kHz to power up the tag - LFSetupFPGAForADC(95, true); - // make sure tag is fully powered up... - WaitMS(start_wait); + // Set up FPGA, 125kHz to power up the tag + LFSetupFPGAForADC(95, true); + // make sure tag is fully powered up... + WaitMS(start_wait); - // Trigger T55x7 Direct Access Mode with start gap - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - WaitUS(t_config.start_gap); + // Trigger T55x7 Direct Access Mode with start gap + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + WaitUS(t_config.start_gap); - // Opcode 1[page] - T55xxWriteBit(1); - T55xxWriteBit(Page); //Page 0 + // Opcode 1[page] + T55xxWriteBit(1); + T55xxWriteBit(Page); //Page 0 - if (PwdMode){ - // Send Pwd - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Pwd & i); - } - // Send a zero bit separation - T55xxWriteBit(0); + if (PwdMode){ + // Send Pwd + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Pwd & i); + } + // Send a zero bit separation + T55xxWriteBit(0); - // Send Block number (if direct access mode) - if (!RegReadMode) - for (i = 0x04; i != 0; i >>= 1) - T55xxWriteBit(Block & i); + // Send Block number (if direct access mode) + if (!RegReadMode) + for (i = 0x04; i != 0; i >>= 1) + T55xxWriteBit(Block & i); - // Turn field on to read the response - // 137*8 seems to get to the start of data pretty well... - // but we want to go past the start and let the repeating data settle in... - TurnReadLFOn(200*8); + // Turn field on to read the response + // 137*8 seems to get to the start of data pretty well... + // but we want to go past the start and let the repeating data settle in... + TurnReadLFOn(200*8); - // Acquisition - // Now do the acquisition - DoPartialAcquisition(0, true, samples, 0); + // Acquisition + // Now do the acquisition + DoPartialAcquisition(0, true, samples, 0); - // Turn the field off - if ( !brute_mem ) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - cmd_send(CMD_ACK,0,0,0,0,0); - LED_A_OFF(); - } + // Turn the field off + if ( !brute_mem ) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + cmd_send(CMD_ACK,0,0,0,0,0); + LED_A_OFF(); + } } void T55xx_ChkPwds() { - DbpString("[+] T55XX Check pwds using flashmemory starting"); + DbpString("[+] T55XX Check pwds using flashmemory starting"); - uint8_t ret = 0; - // First get baseline and setup LF mode. - // tends to mess up BigBuf - uint8_t *buf = BigBuf_get_addr(); + uint8_t ret = 0; + // First get baseline and setup LF mode. + // tends to mess up BigBuf + uint8_t *buf = BigBuf_get_addr(); - uint32_t b1, baseline = 0; + uint32_t b1, baseline = 0; - // collect baseline for failed attempt - uint8_t x = 32; - while (x--) { - b1 = 0; - T55xxReadBlock(4, 1, 0); - for (uint16_t j=0; j < 1024; ++j) - b1 += buf[j]; + // collect baseline for failed attempt + uint8_t x = 32; + while (x--) { + b1 = 0; + T55xxReadBlock(4, 1, 0); + for (uint16_t j=0; j < 1024; ++j) + b1 += buf[j]; - b1 *= b1; - b1 >>= 8; - baseline += b1; - } + b1 *= b1; + b1 >>= 8; + baseline += b1; + } - baseline >>= 5; - Dbprintf("[=] Baseline determined [%u]", baseline); + baseline >>= 5; + Dbprintf("[=] Baseline determined [%u]", baseline); - uint8_t *pwds = BigBuf_get_EM_addr(); - uint16_t pwdCount = 0; - uint32_t candidate = 0; + uint8_t *pwds = BigBuf_get_EM_addr(); + uint16_t pwdCount = 0; + uint32_t candidate = 0; #ifdef WITH_FLASH - bool use_flashmem = true; - if ( use_flashmem ) { - BigBuf_Clear_EM(); - uint16_t isok = 0; - uint8_t counter[2] = {0x00, 0x00}; - isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET, counter, sizeof(counter) ); - if ( isok != sizeof(counter) ) - goto OUT; + bool use_flashmem = true; + if ( use_flashmem ) { + BigBuf_Clear_EM(); + uint16_t isok = 0; + uint8_t counter[2] = {0x00, 0x00}; + isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET, counter, sizeof(counter) ); + if ( isok != sizeof(counter) ) + goto OUT; - pwdCount = counter[1] << 8 | counter[0]; + pwdCount = counter[1] << 8 | counter[0]; - if ( pwdCount == 0 && pwdCount == 0xFFFF) - goto OUT; + if ( pwdCount == 0 && pwdCount == 0xFFFF) + goto OUT; - isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET+2, pwds, pwdCount * 4); - if ( isok != pwdCount * 4 ) - goto OUT; + isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET+2, pwds, pwdCount * 4); + if ( isok != pwdCount * 4 ) + goto OUT; - Dbprintf("[=] Password dictionary count %d ", pwdCount); - } + Dbprintf("[=] Password dictionary count %d ", pwdCount); + } #endif - uint32_t pwd = 0, curr = 0, prev = 0; - for (uint16_t i =0; i< pwdCount; ++i) { + uint32_t pwd = 0, curr = 0, prev = 0; + for (uint16_t i =0; i< pwdCount; ++i) { - if (BUTTON_PRESS() && !usb_poll_validate_length()) { - goto OUT; - } + if (BUTTON_PRESS() && !usb_poll_validate_length()) { + goto OUT; + } - pwd = bytes_to_num(pwds + i * 4, 4); + pwd = bytes_to_num(pwds + i * 4, 4); - T55xxReadBlock(5, 0, pwd); + T55xxReadBlock(5, 0, pwd); - // calc mean of BigBuf 1024 samples. - uint32_t sum = 0; - for (uint16_t j=0; j<1024; ++j) { - sum += buf[j]; - } + // calc mean of BigBuf 1024 samples. + uint32_t sum = 0; + for (uint16_t j=0; j<1024; ++j) { + sum += buf[j]; + } - sum *= sum; - sum >>= 8; + sum *= sum; + sum >>= 8; - int32_t tmp = (sum - baseline); - curr = ABS(tmp); + int32_t tmp = (sum - baseline); + curr = ABS(tmp); - Dbprintf("[=] Pwd %08X | ABS %u", pwd, curr ); + Dbprintf("[=] Pwd %08X | ABS %u", pwd, curr ); - if ( curr > prev ) { + if ( curr > prev ) { - Dbprintf("[=] --> ABS %u Candidate %08X <--", curr, pwd ); - candidate = pwd; - prev = curr; - } - } + Dbprintf("[=] --> ABS %u Candidate %08X <--", curr, pwd ); + candidate = pwd; + prev = curr; + } + } - if ( candidate ) - ret = 1; + if ( candidate ) + ret = 1; OUT: - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - cmd_send(CMD_ACK,ret,candidate,0,0,0); - LEDsoff(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + cmd_send(CMD_ACK,ret,candidate,0,0,0); + LEDsoff(); } void T55xxWakeUp(uint32_t Pwd){ - LED_B_ON(); - uint32_t i = 0; + LED_B_ON(); + uint32_t i = 0; - StartTicks(); + StartTicks(); - // Set up FPGA, 125kHz - LFSetupFPGAForADC(95, true); - // make sure tag is fully powered up... - WaitMS(4); + // Set up FPGA, 125kHz + LFSetupFPGAForADC(95, true); + // make sure tag is fully powered up... + WaitMS(4); - // Trigger T55x7 Direct Access Mode - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - WaitUS(t_config.start_gap); + // Trigger T55x7 Direct Access Mode + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + WaitUS(t_config.start_gap); - // Opcode 10 - T55xxWriteBit(1); - T55xxWriteBit(0); //Page 0 + // Opcode 10 + T55xxWriteBit(1); + T55xxWriteBit(0); //Page 0 - // Send Pwd - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Pwd & i); + // Send Pwd + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Pwd & i); - // Turn and leave field on to let the begin repeating transmission - TurnReadLFOn(20*1000); + // Turn and leave field on to let the begin repeating transmission + TurnReadLFOn(20*1000); } /*-------------- Cloning routines -----------*/ void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) { - // write last block first and config block last (if included) - for (uint8_t i = numblocks+startblock; i > startblock; i--) - T55xxWriteBlockExt(blockdata[i-1], i-1, 0, 0); + // write last block first and config block last (if included) + for (uint8_t i = numblocks+startblock; i > startblock; i--) + T55xxWriteBlockExt(blockdata[i-1], i-1, 0, 0); } // Copy HID id to card and setup block 0 config void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) { - uint32_t data[] = {0,0,0,0,0,0,0}; - uint8_t last_block = 0; + uint32_t data[] = {0,0,0,0,0,0,0}; + uint8_t last_block = 0; - if (longFMT){ - // Ensure no more than 84 bits supplied - if (hi2 > 0xFFFFF) { - DbpString("Tags can only have 84 bits."); - return; - } - // Build the 6 data blocks for supplied 84bit ID - last_block = 6; - // load preamble (1D) & long format identifier (9E manchester encoded) - data[1] = 0x1D96A900 | (manchesterEncode2Bytes((hi2 >> 16) & 0xF) & 0xFF); - // load raw id from hi2, hi, lo to data blocks (manchester encoded) - data[2] = manchesterEncode2Bytes(hi2 & 0xFFFF); - data[3] = manchesterEncode2Bytes(hi >> 16); - data[4] = manchesterEncode2Bytes(hi & 0xFFFF); - data[5] = manchesterEncode2Bytes(lo >> 16); - data[6] = manchesterEncode2Bytes(lo & 0xFFFF); - } else { - // Ensure no more than 44 bits supplied - if (hi > 0xFFF) { - DbpString("Tags can only have 44 bits."); - return; - } - // Build the 3 data blocks for supplied 44bit ID - last_block = 3; - // load preamble - data[1] = 0x1D000000 | (manchesterEncode2Bytes(hi) & 0xFFFFFF); - data[2] = manchesterEncode2Bytes(lo >> 16); - data[3] = manchesterEncode2Bytes(lo & 0xFFFF); - } - // load chip config block - data[0] = T55x7_BITRATE_RF_50 | T55x7_MODULATION_FSK2a | last_block << T55x7_MAXBLOCK_SHIFT; + if (longFMT){ + // Ensure no more than 84 bits supplied + if (hi2 > 0xFFFFF) { + DbpString("Tags can only have 84 bits."); + return; + } + // Build the 6 data blocks for supplied 84bit ID + last_block = 6; + // load preamble (1D) & long format identifier (9E manchester encoded) + data[1] = 0x1D96A900 | (manchesterEncode2Bytes((hi2 >> 16) & 0xF) & 0xFF); + // load raw id from hi2, hi, lo to data blocks (manchester encoded) + data[2] = manchesterEncode2Bytes(hi2 & 0xFFFF); + data[3] = manchesterEncode2Bytes(hi >> 16); + data[4] = manchesterEncode2Bytes(hi & 0xFFFF); + data[5] = manchesterEncode2Bytes(lo >> 16); + data[6] = manchesterEncode2Bytes(lo & 0xFFFF); + } else { + // Ensure no more than 44 bits supplied + if (hi > 0xFFF) { + DbpString("Tags can only have 44 bits."); + return; + } + // Build the 3 data blocks for supplied 44bit ID + last_block = 3; + // load preamble + data[1] = 0x1D000000 | (manchesterEncode2Bytes(hi) & 0xFFFFFF); + data[2] = manchesterEncode2Bytes(lo >> 16); + data[3] = manchesterEncode2Bytes(lo & 0xFFFF); + } + // load chip config block + data[0] = T55x7_BITRATE_RF_50 | T55x7_MODULATION_FSK2a | last_block << T55x7_MAXBLOCK_SHIFT; - //TODO add selection of chip for Q5 or T55x7 - // data[0] = T5555_SET_BITRATE(50) | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | last_block << T5555_MAXBLOCK_SHIFT; + //TODO add selection of chip for Q5 or T55x7 + // data[0] = T5555_SET_BITRATE(50) | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | last_block << T5555_MAXBLOCK_SHIFT; - LED_D_ON(); - WriteT55xx(data, 0, last_block+1); - LED_D_OFF(); + LED_D_ON(); + WriteT55xx(data, 0, last_block+1); + LED_D_OFF(); } void CopyIOtoT55x7(uint32_t hi, uint32_t lo) { - uint32_t data[] = {T55x7_BITRATE_RF_64 | T55x7_MODULATION_FSK2a | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo}; - //TODO add selection of chip for Q5 or T55x7 - // data[0] = T5555_SET_BITRATE(64) | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | 2 << T5555_MAXBLOCK_SHIFT; + uint32_t data[] = {T55x7_BITRATE_RF_64 | T55x7_MODULATION_FSK2a | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo}; + //TODO add selection of chip for Q5 or T55x7 + // data[0] = T5555_SET_BITRATE(64) | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | 2 << T5555_MAXBLOCK_SHIFT; - LED_D_ON(); - // Program the data blocks for supplied ID - // and the block 0 config - WriteT55xx(data, 0, 3); - LED_D_OFF(); + LED_D_ON(); + // Program the data blocks for supplied ID + // and the block 0 config + WriteT55xx(data, 0, 3); + LED_D_OFF(); } // Clone Indala 64-bit tag by UID to T55x7 void CopyIndala64toT55x7(uint32_t hi, uint32_t lo) { - //Program the 2 data blocks for supplied 64bit UID - // and the Config for Indala 64 format (RF/32;PSK2 with RF/2;Maxblock=2) - uint32_t data[] = { T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK2 | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo}; - //TODO add selection of chip for Q5 or T55x7 - // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK2 | 2 << T5555_MAXBLOCK_SHIFT; + //Program the 2 data blocks for supplied 64bit UID + // and the Config for Indala 64 format (RF/32;PSK2 with RF/2;Maxblock=2) + uint32_t data[] = { T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK2 | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo}; + //TODO add selection of chip for Q5 or T55x7 + // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK2 | 2 << T5555_MAXBLOCK_SHIFT; - WriteT55xx(data, 0, 3); - //Alternative config for Indala (Extended mode;RF/32;PSK2 with RF/2;Maxblock=2;Inverse data) - // T5567WriteBlock(0x603E1042,0); + WriteT55xx(data, 0, 3); + //Alternative config for Indala (Extended mode;RF/32;PSK2 with RF/2;Maxblock=2;Inverse data) + // T5567WriteBlock(0x603E1042,0); } // Clone Indala 224-bit tag by UID to T55x7 void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7) { - //Program the 7 data blocks for supplied 224bit UID - uint32_t data[] = {0, uid1, uid2, uid3, uid4, uid5, uid6, uid7}; - // and the block 0 for Indala224 format - //Config for Indala (RF/32;PSK2 with RF/2;Maxblock=7) - data[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK2 | (7 << T55x7_MAXBLOCK_SHIFT); - //TODO add selection of chip for Q5 or T55x7 - // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK2 | 7 << T5555_MAXBLOCK_SHIFT; - WriteT55xx(data, 0, 8); - //Alternative config for Indala (Extended mode;RF/32;PSK2 with RF/2;Maxblock=7;Inverse data) - // T5567WriteBlock(0x603E10E2,0); + //Program the 7 data blocks for supplied 224bit UID + uint32_t data[] = {0, uid1, uid2, uid3, uid4, uid5, uid6, uid7}; + // and the block 0 for Indala224 format + //Config for Indala (RF/32;PSK2 with RF/2;Maxblock=7) + data[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK2 | (7 << T55x7_MAXBLOCK_SHIFT); + //TODO add selection of chip for Q5 or T55x7 + // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK2 | 7 << T5555_MAXBLOCK_SHIFT; + WriteT55xx(data, 0, 8); + //Alternative config for Indala (Extended mode;RF/32;PSK2 with RF/2;Maxblock=7;Inverse data) + // T5567WriteBlock(0x603E10E2,0); } // clone viking tag to T55xx void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5) { - uint32_t data[] = {T55x7_BITRATE_RF_32 | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT), block1, block2}; - if (Q5) data[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_MANCHESTER | 2 << T5555_MAXBLOCK_SHIFT; - // Program the data blocks for supplied ID and the block 0 config - WriteT55xx(data, 0, 3); - LED_D_OFF(); - cmd_send(CMD_ACK,0,0,0,0,0); + uint32_t data[] = {T55x7_BITRATE_RF_32 | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT), block1, block2}; + if (Q5) data[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_MANCHESTER | 2 << T5555_MAXBLOCK_SHIFT; + // Program the data blocks for supplied ID and the block 0 config + WriteT55xx(data, 0, 3); + LED_D_OFF(); + cmd_send(CMD_ACK,0,0,0,0,0); } // Define 9bit header for EM410x tags -#define EM410X_HEADER 0x1FF -#define EM410X_ID_LENGTH 40 +#define EM410X_HEADER 0x1FF +#define EM410X_ID_LENGTH 40 void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) { - int i, id_bit; - uint64_t id = EM410X_HEADER; - uint64_t rev_id = 0; // reversed ID - int c_parity[4]; // column parity - int r_parity = 0; // row parity - uint32_t clock = 0; + int i, id_bit; + uint64_t id = EM410X_HEADER; + uint64_t rev_id = 0; // reversed ID + int c_parity[4]; // column parity + int r_parity = 0; // row parity + uint32_t clock = 0; - // Reverse ID bits given as parameter (for simpler operations) - for (i = 0; i < EM410X_ID_LENGTH; ++i) { - if (i < 32) { - rev_id = (rev_id << 1) | (id_lo & 1); - id_lo >>= 1; - } else { - rev_id = (rev_id << 1) | (id_hi & 1); - id_hi >>= 1; - } - } + // Reverse ID bits given as parameter (for simpler operations) + for (i = 0; i < EM410X_ID_LENGTH; ++i) { + if (i < 32) { + rev_id = (rev_id << 1) | (id_lo & 1); + id_lo >>= 1; + } else { + rev_id = (rev_id << 1) | (id_hi & 1); + id_hi >>= 1; + } + } - for (i = 0; i < EM410X_ID_LENGTH; ++i) { - id_bit = rev_id & 1; + for (i = 0; i < EM410X_ID_LENGTH; ++i) { + id_bit = rev_id & 1; - if (i % 4 == 0) { - // Don't write row parity bit at start of parsing - if (i) - id = (id << 1) | r_parity; - // Start counting parity for new row - r_parity = id_bit; - } else { - // Count row parity - r_parity ^= id_bit; - } + if (i % 4 == 0) { + // Don't write row parity bit at start of parsing + if (i) + id = (id << 1) | r_parity; + // Start counting parity for new row + r_parity = id_bit; + } else { + // Count row parity + r_parity ^= id_bit; + } - // First elements in column? - if (i < 4) - // Fill out first elements - c_parity[i] = id_bit; - else - // Count column parity - c_parity[i % 4] ^= id_bit; + // First elements in column? + if (i < 4) + // Fill out first elements + c_parity[i] = id_bit; + else + // Count column parity + c_parity[i % 4] ^= id_bit; - // Insert ID bit - id = (id << 1) | id_bit; - rev_id >>= 1; - } + // Insert ID bit + id = (id << 1) | id_bit; + rev_id >>= 1; + } - // Insert parity bit of last row - id = (id << 1) | r_parity; + // Insert parity bit of last row + id = (id << 1) | r_parity; - // Fill out column parity at the end of tag - for (i = 0; i < 4; ++i) - id = (id << 1) | c_parity[i]; + // Fill out column parity at the end of tag + for (i = 0; i < 4; ++i) + id = (id << 1) | c_parity[i]; - // Add stop bit - id <<= 1; + // Add stop bit + id <<= 1; - Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555"); - LED_D_ON(); + Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555"); + LED_D_ON(); - // Write EM410x ID - uint32_t data[] = {0, (uint32_t)(id>>32), (uint32_t)(id & 0xFFFFFFFF)}; + // Write EM410x ID + uint32_t data[] = {0, (uint32_t)(id>>32), (uint32_t)(id & 0xFFFFFFFF)}; - clock = (card & 0xFF00) >> 8; - clock = (clock == 0) ? 64 : clock; - Dbprintf("Clock rate: %d", clock); - if (card & 0xFF) { //t55x7 - clock = GetT55xxClockBit(clock); - if (clock == 0) { - Dbprintf("Invalid clock rate: %d", clock); - return; - } - data[0] = clock | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT); - } else { //t5555 (Q5) - data[0] = T5555_SET_BITRATE(clock) | T5555_MODULATION_MANCHESTER | (2 << T5555_MAXBLOCK_SHIFT); - } + clock = (card & 0xFF00) >> 8; + clock = (clock == 0) ? 64 : clock; + Dbprintf("Clock rate: %d", clock); + if (card & 0xFF) { //t55x7 + clock = GetT55xxClockBit(clock); + if (clock == 0) { + Dbprintf("Invalid clock rate: %d", clock); + return; + } + data[0] = clock | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT); + } else { //t5555 (Q5) + data[0] = T5555_SET_BITRATE(clock) | T5555_MODULATION_MANCHESTER | (2 << T5555_MAXBLOCK_SHIFT); + } - WriteT55xx(data, 0, 3); + WriteT55xx(data, 0, 3); - LED_D_OFF(); - Dbprintf("Tag %s written with 0x%08x%08x\n", - card ? "T55x7":"T5555", - (uint32_t)(id >> 32), - (uint32_t)id); + LED_D_OFF(); + Dbprintf("Tag %s written with 0x%08x%08x\n", + card ? "T55x7":"T5555", + (uint32_t)(id >> 32), + (uint32_t)id); } //----------------------------------- @@ -1906,18 +1907,18 @@ uint8_t * fwd_write_ptr; //forwardlink bit pointer uint8_t Prepare_Cmd( uint8_t cmd ) { - *forward_ptr++ = 0; //start bit - *forward_ptr++ = 0; //second pause for 4050 code + *forward_ptr++ = 0; //start bit + *forward_ptr++ = 0; //second pause for 4050 code - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; - return 6; //return number of emited bits + return 6; //return number of emited bits } //==================================================================== @@ -1926,19 +1927,19 @@ uint8_t Prepare_Cmd( uint8_t cmd ) { //==================================================================== uint8_t Prepare_Addr( uint8_t addr ) { - register uint8_t line_parity; + register uint8_t line_parity; - uint8_t i; - line_parity = 0; - for( i=0; i<6; i++ ) { - *forward_ptr++ = addr; - line_parity ^= addr; - addr >>= 1; - } + uint8_t i; + line_parity = 0; + for( i=0; i<6; i++ ) { + *forward_ptr++ = addr; + line_parity ^= addr; + addr >>= 1; + } - *forward_ptr++ = (line_parity & 1); + *forward_ptr++ = (line_parity & 1); - return 7; //return number of emited bits + return 7; //return number of emited bits } //==================================================================== @@ -1947,34 +1948,34 @@ uint8_t Prepare_Addr( uint8_t addr ) { //==================================================================== uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { - register uint8_t line_parity; - register uint8_t column_parity; - register uint8_t i, j; - register uint16_t data; + register uint8_t line_parity; + register uint8_t column_parity; + register uint8_t i, j; + register uint16_t data; - data = data_low; - column_parity = 0; + data = data_low; + column_parity = 0; - for(i=0; i<4; i++) { - line_parity = 0; - for(j=0; j<8; j++) { - line_parity ^= data; - column_parity ^= (data & 1) << j; - *forward_ptr++ = data; - data >>= 1; - } - *forward_ptr++ = line_parity; - if(i == 1) - data = data_hi; - } + for(i=0; i<4; i++) { + line_parity = 0; + for(j=0; j<8; j++) { + line_parity ^= data; + column_parity ^= (data & 1) << j; + *forward_ptr++ = data; + data >>= 1; + } + *forward_ptr++ = line_parity; + if(i == 1) + data = data_hi; + } - for(j=0; j<8; j++) { - *forward_ptr++ = column_parity; - column_parity >>= 1; - } - *forward_ptr = 0; + for(j=0; j<8; j++) { + *forward_ptr++ = column_parity; + column_parity >>= 1; + } + *forward_ptr = 0; - return 45; //return number of emited bits + return 45; //return number of emited bits } //==================================================================== @@ -1992,108 +1993,108 @@ void SendForward(uint8_t fwd_bit_count) { #define EM_START_GAP 55*8 #endif - fwd_write_ptr = forwardLink_data; - fwd_bit_sz = fwd_bit_count; + fwd_write_ptr = forwardLink_data; + fwd_bit_sz = fwd_bit_count; - // Set up FPGA, 125kHz or 95 divisor - LFSetupFPGAForADC(95, true); + // Set up FPGA, 125kHz or 95 divisor + LFSetupFPGAForADC(95, true); - // force 1st mod pulse (start gap must be longer for 4305) - fwd_bit_sz--; //prepare next bit modulation - fwd_write_ptr++; + // force 1st mod pulse (start gap must be longer for 4305) + fwd_bit_sz--; //prepare next bit modulation + fwd_write_ptr++; - TurnReadLF_off(EM_START_GAP); - TurnReadLFOn(18*8); + TurnReadLF_off(EM_START_GAP); + TurnReadLFOn(18*8); - // now start writting with bitbanging the antenna. - while(fwd_bit_sz-- > 0) { //prepare next bit modulation - if(((*fwd_write_ptr++) & 1) == 1) { - WaitUS(32*8); - } else { - TurnReadLF_off(23*8); - TurnReadLFOn(18*8); - } - } + // now start writting with bitbanging the antenna. + while(fwd_bit_sz-- > 0) { //prepare next bit modulation + if(((*fwd_write_ptr++) & 1) == 1) { + WaitUS(32*8); + } else { + TurnReadLF_off(23*8); + TurnReadLFOn(18*8); + } + } } void EM4xLogin(uint32_t pwd) { - uint8_t len; - forward_ptr = forwardLink_data; - len = Prepare_Cmd( FWD_CMD_LOGIN ); - len += Prepare_Data( pwd & 0xFFFF, pwd >> 16 ); - SendForward(len); - //WaitUS(20); // no wait for login command. - // should receive - // 0000 1010 ok. - // 0000 0001 fail + uint8_t len; + forward_ptr = forwardLink_data; + len = Prepare_Cmd( FWD_CMD_LOGIN ); + len += Prepare_Data( pwd & 0xFFFF, pwd >> 16 ); + SendForward(len); + //WaitUS(20); // no wait for login command. + // should receive + // 0000 1010 ok. + // 0000 0001 fail } void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd) { - LED_A_ON(); - uint8_t len; + LED_A_ON(); + uint8_t len; - //clear buffer now so it does not interfere with timing later - BigBuf_Clear_ext(false); + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_ext(false); - StartTicks(); - /* should we read answer from Logincommand? - * - * should receive - * 0000 1010 ok. - * 0000 0001 fail - **/ - if (usepwd) EM4xLogin(pwd); + StartTicks(); + /* should we read answer from Logincommand? + * + * should receive + * 0000 1010 ok. + * 0000 0001 fail + **/ + if (usepwd) EM4xLogin(pwd); - forward_ptr = forwardLink_data; - len = Prepare_Cmd( FWD_CMD_READ ); - len += Prepare_Addr( addr ); + forward_ptr = forwardLink_data; + len = Prepare_Cmd( FWD_CMD_READ ); + len += Prepare_Addr( addr ); - SendForward(len); + SendForward(len); - WaitUS(400); + WaitUS(400); - DoPartialAcquisition(20, true, 6000, 1000); + DoPartialAcquisition(20, true, 6000, 1000); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - cmd_send(CMD_ACK,0,0,0,0,0); - LED_A_OFF(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + cmd_send(CMD_ACK,0,0,0,0,0); + LED_A_OFF(); } void EM4xWriteWord(uint32_t flag, uint32_t data, uint32_t pwd) { - LED_A_ON(); + LED_A_ON(); - bool usePwd = (flag & 0xF); - uint8_t addr = (flag >> 8) & 0xFF; - uint8_t len; + bool usePwd = (flag & 0xF); + uint8_t addr = (flag >> 8) & 0xFF; + uint8_t len; - //clear buffer now so it does not interfere with timing later - BigBuf_Clear_ext(false); - StartTicks(); - /* should we read answer from Logincommand? - * - * should receive - * 0000 1010 ok. - * 0000 0001 fail - **/ - if (usePwd) EM4xLogin(pwd); + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_ext(false); + StartTicks(); + /* should we read answer from Logincommand? + * + * should receive + * 0000 1010 ok. + * 0000 0001 fail + **/ + if (usePwd) EM4xLogin(pwd); - forward_ptr = forwardLink_data; - len = Prepare_Cmd( FWD_CMD_WRITE ); - len += Prepare_Addr( addr ); - len += Prepare_Data( data & 0xFFFF, data >> 16 ); + forward_ptr = forwardLink_data; + len = Prepare_Cmd( FWD_CMD_WRITE ); + len += Prepare_Addr( addr ); + len += Prepare_Data( data & 0xFFFF, data >> 16 ); - SendForward(len); + SendForward(len); - //Wait 20ms for write to complete? - WaitMS(7); + //Wait 20ms for write to complete? + WaitMS(7); - DoPartialAcquisition(20, true, 6000, 1000); + DoPartialAcquisition(20, true, 6000, 1000); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - cmd_send(CMD_ACK,0,0,0,0,0); - LED_A_OFF(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + cmd_send(CMD_ACK,0,0,0,0,0); + LED_A_OFF(); } /* @@ -2112,36 +2113,36 @@ This triggers a COTAG tag to response */ void Cotag(uint32_t arg0) { #ifndef OFF -# define OFF(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS((x)); } +# define OFF(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS((x)); } #endif #ifndef ON # define ON(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); } #endif - uint8_t rawsignal = arg0 & 0xF; + uint8_t rawsignal = arg0 & 0xF; - LED_A_ON(); + LED_A_ON(); - LFSetupFPGAForADC(89, true); + LFSetupFPGAForADC(89, true); - //clear buffer now so it does not interfere with timing later - BigBuf_Clear_ext(false); + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_ext(false); - //send COTAG start pulse - ON(740) OFF(2035) - ON(3330) OFF(2035) - ON(740) OFF(2035) - ON(1000) + //send COTAG start pulse + ON(740) OFF(2035) + ON(3330) OFF(2035) + ON(740) OFF(2035) + ON(1000) - switch(rawsignal) { - case 0: doCotagAcquisition(50000); break; - case 1: doCotagAcquisitionManchester(); break; - case 2: DoAcquisition_config(true, 0); break; - } + switch(rawsignal) { + case 0: doCotagAcquisition(50000); break; + case 1: doCotagAcquisitionManchester(); break; + case 2: DoAcquisition_config(true, 0); break; + } - // Turn the field off - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - cmd_send(CMD_ACK,0,0,0,0,0); - LEDsoff(); + // Turn the field off + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + cmd_send(CMD_ACK,0,0,0,0,0); + LEDsoff(); } /* diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 80d95bb4a..93ba535b6 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -10,21 +10,21 @@ /* Default LF config is set to: - decimation = 1 (we keep 1 out of 1 samples) - bits_per_sample = 8 - averaging = YES - divisor = 95 (125khz) - trigger_threshold = 0 - */ + decimation = 1 (we keep 1 out of 1 samples) + bits_per_sample = 8 + averaging = YES + divisor = 95 (125khz) + trigger_threshold = 0 + */ sample_config config = { 1, 8, 1, 95, 0 } ; void printConfig() { - Dbprintf("LF Sampling config"); - Dbprintf(" [q] divisor.............%d (%d KHz)", config.divisor, 12000 / (config.divisor+1)); - Dbprintf(" [b] bps.................%d", config.bits_per_sample); - Dbprintf(" [d] decimation..........%d", config.decimation); - Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No"); - Dbprintf(" [t] trigger threshold...%d", config.trigger_threshold); + Dbprintf("LF Sampling config"); + Dbprintf(" [q] divisor.............%d (%d KHz)", config.divisor, 12000 / (config.divisor+1)); + Dbprintf(" [b] bps.................%d", config.bits_per_sample); + Dbprintf(" [d] decimation..........%d", config.decimation); + Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No"); + Dbprintf(" [t] trigger threshold...%d", config.trigger_threshold); } /** @@ -39,25 +39,25 @@ void printConfig() { * @param sc */ void setSamplingConfig(sample_config *sc) { - if(sc->divisor != 0) config.divisor = sc->divisor; - if(sc->bits_per_sample != 0) config.bits_per_sample = sc->bits_per_sample; - if(sc->trigger_threshold != -1) config.trigger_threshold = sc->trigger_threshold; + if(sc->divisor != 0) config.divisor = sc->divisor; + if(sc->bits_per_sample != 0) config.bits_per_sample = sc->bits_per_sample; + if(sc->trigger_threshold != -1) config.trigger_threshold = sc->trigger_threshold; - config.decimation = (sc->decimation != 0) ? sc->decimation : 1; - config.averaging = sc->averaging; - if(config.bits_per_sample > 8) config.bits_per_sample = 8; + config.decimation = (sc->decimation != 0) ? sc->decimation : 1; + config.averaging = sc->averaging; + if(config.bits_per_sample > 8) config.bits_per_sample = 8; - printConfig(); + printConfig(); } sample_config* getSamplingConfig() { - return &config; + return &config; } struct BitstreamOut { - uint8_t * buffer; - uint32_t numbits; - uint32_t position; + uint8_t * buffer; + uint32_t numbits; + uint32_t position; }; /** @@ -66,39 +66,39 @@ struct BitstreamOut { * @param bit */ void pushBit( BitstreamOut* stream, uint8_t bit) { - int bytepos = stream->position >> 3; // divide by 8 - int bitpos = stream->position & 7; - *(stream->buffer+bytepos) |= (bit > 0) << (7 - bitpos); - stream->position++; - stream->numbits++; + int bytepos = stream->position >> 3; // divide by 8 + int bitpos = stream->position & 7; + *(stream->buffer+bytepos) |= (bit > 0) << (7 - bitpos); + stream->position++; + stream->numbits++; } /** * Setup the FPGA to listen for samples. This method downloads the FPGA bitstream * if not already loaded, sets divisor and starts up the antenna. * @param divisor : 1, 88> 255 or negative ==> 134.8 KHz -* 0 or 95 ==> 125 KHz +* 0 or 95 ==> 125 KHz * **/ 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) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - else - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + if ( (divisor == 1) || (divisor < 0) || (divisor > 255) ) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + else if (divisor == 0) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + else + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); + 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); - // 50ms 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(); - // start a 1.5ticks is 1us - StartTicks(); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // 50ms 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(); + // start a 1.5ticks is 1us + StartTicks(); } /** @@ -118,97 +118,97 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) { */ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold, bool silent, int bufsize, uint32_t cancel_after) { - uint8_t *dest = BigBuf_get_addr(); + uint8_t *dest = BigBuf_get_addr(); bufsize = (bufsize > 0 && bufsize < BigBuf_max_traceLen()) ? bufsize : BigBuf_max_traceLen(); - if (bits_per_sample < 1) bits_per_sample = 1; - if (bits_per_sample > 8) bits_per_sample = 8; + if (bits_per_sample < 1) bits_per_sample = 1; + if (bits_per_sample > 8) bits_per_sample = 8; - if (decimation < 1) decimation = 1; + if (decimation < 1) decimation = 1; - // use a bit stream to handle the output - BitstreamOut data = { dest , 0, 0}; - int sample_counter = 0; - uint8_t sample = 0; + // use a bit stream to handle the output + BitstreamOut data = { dest , 0, 0}; + int sample_counter = 0; + uint8_t sample = 0; - // if we want to do averaging - uint32_t sample_sum =0 ; - uint32_t sample_total_numbers = 0; - uint32_t sample_total_saved = 0; - uint32_t cancel_counter = 0; + // if we want to do averaging + uint32_t sample_sum =0 ; + uint32_t sample_total_numbers = 0; + uint32_t sample_total_saved = 0; + uint32_t cancel_counter = 0; - while (!BUTTON_PRESS() && !usb_poll_validate_length() ) { - WDT_HIT(); + while (!BUTTON_PRESS() && !usb_poll_validate_length() ) { + WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - // Testpoint 8 (TP8) can be used to trigger oscilliscope - LED_D_OFF(); + // Testpoint 8 (TP8) can be used to trigger oscilliscope + LED_D_OFF(); - // threshold either high or low values 128 = center 0. if trigger = 178 - if ((trigger_threshold > 0) && (sample < (trigger_threshold + 128)) && (sample > (128 - trigger_threshold))) { - if (cancel_after > 0) { - cancel_counter++; - if (cancel_after == cancel_counter) - break; - } - continue; - } + // threshold either high or low values 128 = center 0. if trigger = 178 + if ((trigger_threshold > 0) && (sample < (trigger_threshold + 128)) && (sample > (128 - trigger_threshold))) { + if (cancel_after > 0) { + cancel_counter++; + if (cancel_after == cancel_counter) + break; + } + continue; + } - trigger_threshold = 0; - sample_total_numbers++; + trigger_threshold = 0; + sample_total_numbers++; - if (averaging) - sample_sum += sample; + if (averaging) + sample_sum += sample; - // check decimation - if (decimation > 1) { - sample_counter++; - if (sample_counter < decimation) continue; - sample_counter = 0; - } + // check decimation + if (decimation > 1) { + sample_counter++; + if (sample_counter < decimation) continue; + sample_counter = 0; + } - // averaging - if (averaging && decimation > 1) { - sample = sample_sum / decimation; - sample_sum =0; - } + // averaging + if (averaging && decimation > 1) { + sample = sample_sum / decimation; + sample_sum =0; + } - // store the sample - sample_total_saved ++; - if (bits_per_sample == 8) { - dest[sample_total_saved-1] = sample; + // store the sample + sample_total_saved ++; + if (bits_per_sample == 8) { + dest[sample_total_saved-1] = sample; - // Get the return value correct - data.numbits = sample_total_saved << 3; - if (sample_total_saved >= bufsize) break; + // Get the return value correct + data.numbits = sample_total_saved << 3; + if (sample_total_saved >= bufsize) break; - } else { - pushBit(&data, sample & 0x80); - if (bits_per_sample > 1) pushBit(&data, sample & 0x40); - if (bits_per_sample > 2) pushBit(&data, sample & 0x20); - if (bits_per_sample > 3) pushBit(&data, sample & 0x10); - if (bits_per_sample > 4) pushBit(&data, sample & 0x08); - if (bits_per_sample > 5) pushBit(&data, sample & 0x04); - if (bits_per_sample > 6) pushBit(&data, sample & 0x02); + } else { + pushBit(&data, sample & 0x80); + if (bits_per_sample > 1) pushBit(&data, sample & 0x40); + if (bits_per_sample > 2) pushBit(&data, sample & 0x20); + if (bits_per_sample > 3) pushBit(&data, sample & 0x10); + if (bits_per_sample > 4) pushBit(&data, sample & 0x08); + if (bits_per_sample > 5) pushBit(&data, sample & 0x04); + if (bits_per_sample > 6) pushBit(&data, sample & 0x02); - if ((data.numbits >> 3) + 1 >= bufsize) break; - } - } - } + if ((data.numbits >> 3) + 1 >= bufsize) break; + } + } + } - if (!silent) { - Dbprintf("Done, saved %d out of %d seen samples at %d bits/sample", sample_total_saved, sample_total_numbers, bits_per_sample); - 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]); - } + if (!silent) { + Dbprintf("Done, saved %d out of %d seen samples at %d bits/sample", sample_total_saved, sample_total_numbers, bits_per_sample); + 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]); + } - // Ensure that DC offset removal and noise check is performed for any device-side processing - removeSignalOffset(dest, bufsize); - computeSignalProperties(dest, bufsize); + // Ensure that DC offset removal and noise check is performed for any device-side processing + removeSignalOffset(dest, bufsize); + computeSignalProperties(dest, bufsize); - return data.numbits; + return data.numbits; } /** * @brief Does sample acquisition, ignoring the config values set in the sample_config. @@ -219,27 +219,27 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag * @return number of bits sampled */ uint32_t DoAcquisition_default(int trigger_threshold, bool silent) { - return DoAcquisition(1, 8, 0,trigger_threshold, silent, 0, 0); + return DoAcquisition(1, 8, 0,trigger_threshold, silent, 0, 0); } uint32_t DoAcquisition_config( bool silent, int sample_size) { - return DoAcquisition(config.decimation - ,config.bits_per_sample - ,config.averaging - ,config.trigger_threshold - ,silent - ,sample_size - ,0); + return DoAcquisition(config.decimation + ,config.bits_per_sample + ,config.averaging + ,config.trigger_threshold + ,silent + ,sample_size + ,0); } uint32_t DoPartialAcquisition(int trigger_threshold, bool silent, int sample_size, uint32_t cancel_after) { - return DoAcquisition(1, 8, 0, trigger_threshold, silent, sample_size, cancel_after); + return DoAcquisition(1, 8, 0, trigger_threshold, silent, sample_size, cancel_after); } uint32_t ReadLF(bool activeField, bool silent, int sample_size) { - if (!silent) - printConfig(); - LFSetupFPGAForADC(config.divisor, activeField); - return DoAcquisition_config(silent, sample_size); + if (!silent) + printConfig(); + LFSetupFPGAForADC(config.divisor, activeField); + return DoAcquisition_config(silent, sample_size); } /** @@ -247,20 +247,20 @@ uint32_t ReadLF(bool activeField, bool silent, int sample_size) { * @return number of bits sampled **/ uint32_t SampleLF(bool printCfg, int sample_size) { - BigBuf_Clear_ext(false); - uint32_t ret = ReadLF(true, printCfg, sample_size); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - return ret; + BigBuf_Clear_ext(false); + uint32_t ret = ReadLF(true, printCfg, sample_size); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + return ret; } /** * Initializes the FPGA for snoop-mode (field off), and acquires the samples. * @return number of bits sampled **/ uint32_t SnoopLF() { - BigBuf_Clear_ext(false); - uint32_t ret = ReadLF(false, true, 0); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - return ret; + BigBuf_Clear_ext(false); + uint32_t ret = ReadLF(false, true, 0); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + return ret; } /** @@ -269,61 +269,61 @@ uint32_t SnoopLF() { **/ void doT55x7Acquisition(size_t sample_size) { - #define T55xx_READ_UPPER_THRESHOLD 128+60 // 60 grph - #define T55xx_READ_LOWER_THRESHOLD 128-60 // -60 grph - #define T55xx_READ_TOL 5 + #define T55xx_READ_UPPER_THRESHOLD 128+60 // 60 grph + #define T55xx_READ_LOWER_THRESHOLD 128-60 // -60 grph + #define T55xx_READ_TOL 5 - uint8_t *dest = BigBuf_get_addr(); - uint16_t bufsize = BigBuf_max_traceLen(); + uint8_t *dest = BigBuf_get_addr(); + uint16_t bufsize = BigBuf_max_traceLen(); - if ( bufsize > sample_size ) - bufsize = sample_size; + if ( bufsize > sample_size ) + bufsize = sample_size; - uint8_t curSample = 0, lastSample = 0; - uint16_t i = 0, skipCnt = 0; - bool startFound = false; - bool highFound = false; - bool lowFound = false; + uint8_t curSample = 0, lastSample = 0; + uint16_t i = 0, skipCnt = 0; + bool startFound = false; + bool highFound = false; + bool lowFound = false; - while(!BUTTON_PRESS() && !usb_poll_validate_length() && skipCnt < 1000 && (i < bufsize) ) { - WDT_HIT(); + while(!BUTTON_PRESS() && !usb_poll_validate_length() && skipCnt < 1000 && (i < bufsize) ) { + WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - LED_D_OFF(); + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + LED_D_OFF(); - // skip until the first high sample above threshold - if (!startFound && curSample > T55xx_READ_UPPER_THRESHOLD) { - //if (curSample > lastSample) - // lastSample = curSample; - highFound = true; - } else if (!highFound) { - skipCnt++; - continue; - } - // skip until the first low sample below threshold - if (!startFound && curSample < T55xx_READ_LOWER_THRESHOLD) { - //if (curSample > lastSample) - lastSample = curSample; - lowFound = true; - } else if (!lowFound) { - skipCnt++; - continue; - } + // skip until the first high sample above threshold + if (!startFound && curSample > T55xx_READ_UPPER_THRESHOLD) { + //if (curSample > lastSample) + // lastSample = curSample; + highFound = true; + } else if (!highFound) { + skipCnt++; + continue; + } + // skip until the first low sample below threshold + if (!startFound && curSample < T55xx_READ_LOWER_THRESHOLD) { + //if (curSample > lastSample) + lastSample = curSample; + lowFound = true; + } else if (!lowFound) { + skipCnt++; + continue; + } - // skip until first high samples begin to change - if (startFound || curSample > T55xx_READ_LOWER_THRESHOLD + T55xx_READ_TOL){ - // if just found start - recover last sample - if (!startFound) { - dest[i++] = lastSample; - startFound = true; - } - // collect samples - dest[i++] = curSample; - } - } - } + // skip until first high samples begin to change + if (startFound || curSample > T55xx_READ_LOWER_THRESHOLD + T55xx_READ_TOL){ + // if just found start - recover last sample + if (!startFound) { + dest[i++] = lastSample; + startFound = true; + } + // collect samples + dest[i++] = curSample; + } + } + } } /** * acquisition of Cotag LF signal. Similart to other LF, since the Cotag has such long datarate RF/384 @@ -339,117 +339,117 @@ void doT55x7Acquisition(size_t sample_size) { #endif void doCotagAcquisition(size_t sample_size) { - uint8_t *dest = BigBuf_get_addr(); - uint16_t bufsize = BigBuf_max_traceLen(); + uint8_t *dest = BigBuf_get_addr(); + uint16_t bufsize = BigBuf_max_traceLen(); - if ( bufsize > sample_size ) - bufsize = sample_size; + if ( bufsize > sample_size ) + bufsize = sample_size; - dest[0] = 0; - uint8_t sample = 0, firsthigh = 0, firstlow = 0; - uint16_t i = 0; - uint16_t noise_counter = 0; + dest[0] = 0; + uint8_t sample = 0, firsthigh = 0, firstlow = 0; + uint16_t i = 0; + uint16_t noise_counter = 0; - while (!BUTTON_PRESS() && !usb_poll_validate_length() && (i < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) { - WDT_HIT(); + while (!BUTTON_PRESS() && !usb_poll_validate_length() && (i < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) { + WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - LED_D_OFF(); + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + LED_D_OFF(); - // find first peak - if ( !firsthigh ) { - if (sample < COTAG_ONE_THRESHOLD) { - noise_counter++; - continue; - } - noise_counter = 0; - firsthigh = 1; - } - if ( !firstlow ){ - if (sample > COTAG_ZERO_THRESHOLD ) { - noise_counter++; - continue; - } - noise_counter = 0; - firstlow = 1; - } + // find first peak + if ( !firsthigh ) { + if (sample < COTAG_ONE_THRESHOLD) { + noise_counter++; + continue; + } + noise_counter = 0; + firsthigh = 1; + } + if ( !firstlow ){ + if (sample > COTAG_ZERO_THRESHOLD ) { + noise_counter++; + continue; + } + noise_counter = 0; + firstlow = 1; + } - ++i; + ++i; - if ( sample > COTAG_ONE_THRESHOLD) - dest[i] = 255; - else if ( sample < COTAG_ZERO_THRESHOLD) - dest[i] = 0; - else - dest[i] = dest[i-1]; - } - } + if ( sample > COTAG_ONE_THRESHOLD) + dest[i] = 255; + else if ( sample < COTAG_ZERO_THRESHOLD) + dest[i] = 0; + else + dest[i] = dest[i-1]; + } + } } uint32_t doCotagAcquisitionManchester() { - uint8_t *dest = BigBuf_get_addr(); - uint16_t bufsize = BigBuf_max_traceLen(); + uint8_t *dest = BigBuf_get_addr(); + uint16_t bufsize = BigBuf_max_traceLen(); - if ( bufsize > COTAG_BITS ) - bufsize = COTAG_BITS; + if ( bufsize > COTAG_BITS ) + bufsize = COTAG_BITS; - dest[0] = 0; - uint8_t sample = 0, firsthigh = 0, firstlow = 0; - uint16_t sample_counter = 0, period = 0; - uint8_t curr = 0, prev = 0; - uint16_t noise_counter = 0; + dest[0] = 0; + uint8_t sample = 0, firsthigh = 0, firstlow = 0; + uint16_t sample_counter = 0, period = 0; + uint8_t curr = 0, prev = 0; + uint16_t noise_counter = 0; - while (!BUTTON_PRESS() && !usb_poll_validate_length() && (sample_counter < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) { - WDT_HIT(); + while (!BUTTON_PRESS() && !usb_poll_validate_length() && (sample_counter < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) { + WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - LED_D_OFF(); + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + LED_D_OFF(); - // find first peak - if ( !firsthigh ) { - if (sample < COTAG_ONE_THRESHOLD) { - noise_counter++; - continue; - } - noise_counter = 0; - firsthigh = 1; - } + // find first peak + if ( !firsthigh ) { + if (sample < COTAG_ONE_THRESHOLD) { + noise_counter++; + continue; + } + noise_counter = 0; + firsthigh = 1; + } - if ( !firstlow ){ - if (sample > COTAG_ZERO_THRESHOLD ) { - noise_counter++; - continue; - } - noise_counter = 0; - firstlow = 1; - } + if ( !firstlow ){ + if (sample > COTAG_ZERO_THRESHOLD ) { + noise_counter++; + continue; + } + noise_counter = 0; + firstlow = 1; + } - // set sample 255, 0, or previous - if ( sample > COTAG_ONE_THRESHOLD){ - prev = curr; - curr = 1; - } - else if ( sample < COTAG_ZERO_THRESHOLD) { - prev = curr; - curr = 0; - } - else { - curr = prev; - } + // set sample 255, 0, or previous + if ( sample > COTAG_ONE_THRESHOLD){ + prev = curr; + curr = 1; + } + else if ( sample < COTAG_ZERO_THRESHOLD) { + prev = curr; + curr = 0; + } + else { + curr = prev; + } - // full T1 periods, - if ( period > 0 ) { - --period; - continue; - } + // full T1 periods, + if ( period > 0 ) { + --period; + continue; + } - dest[sample_counter] = curr; - ++sample_counter; - period = COTAG_T1; - } - } - return sample_counter; + dest[sample_counter] = curr; + ++sample_counter; + period = COTAG_T1; + } + } + return sample_counter; } diff --git a/armsrc/lfsampling.h b/armsrc/lfsampling.h index aadf0a822..15510198a 100644 --- a/armsrc/lfsampling.h +++ b/armsrc/lfsampling.h @@ -5,8 +5,8 @@ #include "apps.h" #include "util.h" #include "string.h" -#include "usb_cdc.h" // for usb_poll_validate_length -#include "ticks.h" // for StartTicks +#include "usb_cdc.h" // for usb_poll_validate_length +#include "ticks.h" // for StartTicks typedef struct BitstreamOut BitstreamOut; @@ -60,7 +60,7 @@ uint32_t DoAcquisition_config(bool silent, int sample_size); * Setup the FPGA to listen for samples. This method downloads the FPGA bitstream * if not already loaded, sets divisor and starts up the antenna. * @param divisor : 1, 88> 255 or negative ==> 134.8 KHz -* 0 or 95 ==> 125 KHz +* 0 or 95 ==> 125 KHz * **/ void LFSetupFPGAForADC(int divisor, bool lf_field); diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index a10925da7..4889afce0 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -17,18 +17,18 @@ #include #ifndef HARDNESTED_AUTHENTICATION_TIMEOUT -# define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation) +# define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation) #endif #ifndef HARDNESTED_PRE_AUTHENTICATION_LEADTIME -# define HARDNESTED_PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication +# define HARDNESTED_PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication #endif // send an incomplete dummy response in order to trigger the card's authentication failure timeout #ifndef CHK_TIMEOUT # define CHK_TIMEOUT() { \ - ReaderTransmit(&dummy_answer, 1, NULL); \ - uint32_t timeout = GetCountSspClk() + HARDNESTED_AUTHENTICATION_TIMEOUT; \ - while (GetCountSspClk() < timeout) {}; \ + ReaderTransmit(&dummy_answer, 1, NULL); \ + uint32_t timeout = GetCountSspClk() + HARDNESTED_AUTHENTICATION_TIMEOUT; \ + while (GetCountSspClk() < timeout) {}; \ } #endif @@ -41,94 +41,94 @@ static uint8_t dummy_answer = 0; void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) { // params - uint8_t blockNo = arg0; - uint8_t keyType = arg1; - uint64_t ui64Key = 0; - ui64Key = bytes_to_num(datain, 6); + uint8_t blockNo = arg0; + uint8_t keyType = arg1; + uint64_t ui64Key = 0; + ui64Key = bytes_to_num(datain, 6); - // variables - byte_t isOK = 0; - byte_t dataoutbuf[16] = {0x00}; - uint8_t uid[10] = {0x00}; - uint32_t cuid = 0; - struct Crypto1State mpcs = {0, 0}; - struct Crypto1State *pcs; - pcs = &mpcs; + // variables + byte_t isOK = 0; + byte_t dataoutbuf[16] = {0x00}; + uint8_t uid[10] = {0x00}; + uint32_t cuid = 0; + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); + clear_trace(); + set_tracing(true); - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); + LED_A_ON(); + LED_B_OFF(); + LED_C_OFF(); - while (true) { - if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); - break; - }; + while (true) { + if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { + 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"); - break; - }; + if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Auth error"); + break; + }; - if(mifare_classic_readblock(pcs, cuid, blockNo, dataoutbuf)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Read block error"); - break; - }; + if(mifare_classic_readblock(pcs, cuid, blockNo, dataoutbuf)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Read block error"); + break; + }; - if(mifare_classic_halt(pcs, cuid)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); - break; - }; + if(mifare_classic_halt(pcs, cuid)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); + break; + }; - isOK = 1; - break; - } + isOK = 1; + break; + } - crypto1_destroy(pcs); + crypto1_destroy(pcs); - if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED"); + if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED"); - LED_B_ON(); - cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16); - LED_B_OFF(); + LED_B_ON(); + cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16); + LED_B_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); } void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){ - bool turnOffField = (arg0 == 1); + bool turnOffField = (arg0 == 1); - LED_A_ON(); LED_B_OFF(); LED_C_OFF(); + LED_A_ON(); LED_B_OFF(); LED_C_OFF(); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); + clear_trace(); + set_tracing(true); - if(!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card"); - OnError(0); - return; - }; + if(!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card"); + OnError(0); + return; + }; - if(!mifare_ultra_auth(keybytes)){ - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed"); - OnError(1); - return; - } + if(!mifare_ultra_auth(keybytes)){ + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed"); + OnError(1); + return; + } - if (turnOffField) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - } - cmd_send(CMD_ACK,1,0,0,0,0); + if (turnOffField) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + } + cmd_send(CMD_ACK,1,0,0,0,0); } // Arg0 = BlockNo, @@ -136,62 +136,62 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){ // datain = PWD bytes, void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { - uint8_t blockNo = arg0; - byte_t dataout[16] = {0x00}; - bool useKey = (arg1 == 1); //UL_C - bool usePwd = (arg1 == 2); //UL_EV1/NTAG + uint8_t blockNo = arg0; + byte_t dataout[16] = {0x00}; + bool useKey = (arg1 == 1); //UL_C + bool usePwd = (arg1 == 2); //UL_EV1/NTAG - LEDsoff(); - LED_A_ON(); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + LEDsoff(); + LED_A_ON(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); + clear_trace(); + set_tracing(true); - int len = iso14443a_select_card(NULL, NULL, NULL, true, 0, true); - if(!len) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len); - OnError(1); - return; - } + int len = iso14443a_select_card(NULL, NULL, NULL, true, 0, true); + if(!len) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len); + OnError(1); + return; + } - // UL-C authentication - if ( useKey ) { - uint8_t key[16] = {0x00}; - memcpy(key, datain, sizeof(key) ); + // UL-C authentication + if ( useKey ) { + uint8_t key[16] = {0x00}; + memcpy(key, datain, sizeof(key) ); - if ( !mifare_ultra_auth(key) ) { - OnError(1); - return; - } - } + if ( !mifare_ultra_auth(key) ) { + OnError(1); + return; + } + } - // UL-EV1 / NTAG authentication - if ( usePwd ) { - uint8_t pwd[4] = {0x00}; - memcpy(pwd, datain, 4); - uint8_t pack[4] = {0,0,0,0}; - if (!mifare_ul_ev1_auth(pwd, pack)) { - OnError(1); - return; - } - } + // UL-EV1 / NTAG authentication + if ( usePwd ) { + uint8_t pwd[4] = {0x00}; + memcpy(pwd, datain, 4); + uint8_t pack[4] = {0,0,0,0}; + if (!mifare_ul_ev1_auth(pwd, pack)) { + OnError(1); + return; + } + } - if( mifare_ultra_readblock(blockNo, dataout) ) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error"); - OnError(2); - return; - } + if( mifare_ultra_readblock(blockNo, dataout) ) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error"); + OnError(2); + return; + } - if( mifare_ultra_halt() ) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error"); - OnError(3); - return; - } + if( mifare_ultra_halt() ) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error"); + OnError(3); + return; + } cmd_send(CMD_ACK,1,0,0,dataout,16); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); } //----------------------------------------------------------------------------- @@ -201,64 +201,64 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) { // params - uint8_t sectorNo = arg0; - uint8_t keyType = arg1; - uint64_t ui64Key = 0; - ui64Key = bytes_to_num(datain, 6); + uint8_t sectorNo = arg0; + uint8_t keyType = arg1; + uint64_t ui64Key = 0; + ui64Key = bytes_to_num(datain, 6); - // variables - byte_t isOK = 0; - byte_t dataoutbuf[16 * 16]; - uint8_t uid[10] = {0x00}; - uint32_t cuid = 0; - struct Crypto1State mpcs = {0, 0}; - struct Crypto1State *pcs; - pcs = &mpcs; + // variables + byte_t isOK = 0; + byte_t dataoutbuf[16 * 16]; + uint8_t uid[10] = {0x00}; + uint32_t cuid = 0; + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); + clear_trace(); + set_tracing(true); - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); + LED_A_ON(); + LED_B_OFF(); + LED_C_OFF(); - isOK = 1; - if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - isOK = 0; - if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); - } + isOK = 1; + if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { + isOK = 0; + if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); + } - if(isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) { - isOK = 0; - if (MF_DBGLEVEL >= 1) Dbprintf("Auth error"); - } + 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; - } - } + 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"); - } + if(mifare_classic_halt(pcs, cuid)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); + } - if (MF_DBGLEVEL >= 2) DbpString("READ SECTOR FINISHED"); + if (MF_DBGLEVEL >= 2) DbpString("READ SECTOR FINISHED"); - crypto1_destroy(pcs); + crypto1_destroy(pcs); - LED_B_ON(); - cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16*NumBlocksPerSector(sectorNo)); - LED_B_OFF(); + LED_B_ON(); + cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16*NumBlocksPerSector(sectorNo)); + LED_B_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - set_tracing(false); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + set_tracing(false); } // arg0 = blockNo (start) @@ -267,97 +267,97 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) // datain = KEY bytes void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) { - LEDsoff(); - LED_A_ON(); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + LEDsoff(); + LED_A_ON(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - // free eventually allocated BigBuf memory - BigBuf_free(); BigBuf_Clear_ext(false); - clear_trace(); - set_tracing(true); + // free eventually allocated BigBuf memory + BigBuf_free(); BigBuf_Clear_ext(false); + clear_trace(); + set_tracing(true); - // params - uint8_t blockNo = arg0; - uint16_t blocks = arg1; - bool useKey = (arg2 == 1); //UL_C - bool usePwd = (arg2 == 2); //UL_EV1/NTAG - uint32_t countblocks = 0; - uint8_t *dataout = BigBuf_malloc(CARD_MEMORY_SIZE); - if (dataout == NULL){ - Dbprintf("out of memory"); - OnError(1); - return; - } + // params + uint8_t blockNo = arg0; + uint16_t blocks = arg1; + bool useKey = (arg2 == 1); //UL_C + bool usePwd = (arg2 == 2); //UL_EV1/NTAG + uint32_t countblocks = 0; + uint8_t *dataout = BigBuf_malloc(CARD_MEMORY_SIZE); + if (dataout == NULL){ + Dbprintf("out of memory"); + OnError(1); + return; + } - int len = iso14443a_select_card(NULL, NULL, NULL, true, 0, true); - if (!len) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len); - OnError(1); - return; - } + int len = iso14443a_select_card(NULL, NULL, NULL, true, 0, true); + if (!len) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len); + OnError(1); + return; + } - // UL-C authentication - if ( useKey ) { - uint8_t key[16] = {0x00}; - memcpy(key, datain, sizeof(key) ); + // UL-C authentication + if ( useKey ) { + uint8_t key[16] = {0x00}; + memcpy(key, datain, sizeof(key) ); - if ( !mifare_ultra_auth(key) ) { - OnError(1); - return; - } - } + if ( !mifare_ultra_auth(key) ) { + OnError(1); + return; + } + } - // UL-EV1 / NTAG authentication - if (usePwd) { - uint8_t pwd[4] = {0x00}; - memcpy(pwd, datain, sizeof(pwd)); - uint8_t pack[4] = {0,0,0,0}; + // UL-EV1 / NTAG authentication + if (usePwd) { + uint8_t pwd[4] = {0x00}; + memcpy(pwd, datain, sizeof(pwd)); + uint8_t pack[4] = {0,0,0,0}; - if (!mifare_ul_ev1_auth(pwd, pack)){ - OnError(1); - return; - } - } + if (!mifare_ul_ev1_auth(pwd, pack)){ + OnError(1); + return; + } + } - for (int i = 0; i < blocks; i++){ - if ((i*4) + 4 >= CARD_MEMORY_SIZE) { - Dbprintf("Data exceeds buffer!!"); - break; - } + for (int i = 0; i < blocks; i++){ + if ((i*4) + 4 >= CARD_MEMORY_SIZE) { + Dbprintf("Data exceeds buffer!!"); + break; + } - len = mifare_ultra_readblock(blockNo + i, dataout + 4 * i); + len = mifare_ultra_readblock(blockNo + i, dataout + 4 * i); - if (len) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block %d error",i); - // if no blocks read - error out - if (i == 0) { - OnError(2); - return; - } else { - //stop at last successful read block and return what we got - break; - } - } else { - countblocks++; - } - } + if (len) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block %d error",i); + // if no blocks read - error out + if (i == 0) { + OnError(2); + return; + } else { + //stop at last successful read block and return what we got + break; + } + } else { + countblocks++; + } + } - len = mifare_ultra_halt(); - if (len) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error"); - OnError(3); - return; - } + len = mifare_ultra_halt(); + if (len) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error"); + OnError(3); + return; + } - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Blocks read %d", countblocks); + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Blocks read %d", countblocks); - countblocks *= 4; + countblocks *= 4; - cmd_send(CMD_ACK, 1, countblocks, BigBuf_max_traceLen(), 0, 0); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - BigBuf_free(); - set_tracing(false); + cmd_send(CMD_ACK, 1, countblocks, BigBuf_max_traceLen(), 0, 0); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + BigBuf_free(); + set_tracing(false); } //----------------------------------------------------------------------------- @@ -366,106 +366,106 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) //----------------------------------------------------------------------------- void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) { - // params - uint8_t blockNo = arg0; - uint8_t keyType = arg1; - uint64_t ui64Key = 0; - byte_t blockdata[16] = {0x00}; + // params + uint8_t blockNo = arg0; + uint8_t keyType = arg1; + uint64_t ui64Key = 0; + byte_t blockdata[16] = {0x00}; - ui64Key = bytes_to_num(datain, 6); - memcpy(blockdata, datain + 10, 16); + ui64Key = bytes_to_num(datain, 6); + memcpy(blockdata, datain + 10, 16); - // variables - byte_t isOK = 0; - uint8_t uid[10] = {0x00}; - uint32_t cuid = 0; - struct Crypto1State mpcs = {0, 0}; - struct Crypto1State *pcs; - pcs = &mpcs; + // variables + byte_t isOK = 0; + uint8_t uid[10] = {0x00}; + uint32_t cuid = 0; + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); + clear_trace(); + set_tracing(true); - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); + LED_A_ON(); + LED_B_OFF(); + LED_C_OFF(); - while (true) { - if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); - break; - }; + while (true) { + if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { + 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"); - break; - }; + if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Auth error"); + break; + }; - if(mifare_classic_writeblock(pcs, cuid, blockNo, blockdata)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); - break; - }; + if(mifare_classic_writeblock(pcs, cuid, blockNo, blockdata)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); + break; + }; - if(mifare_classic_halt(pcs, cuid)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); - break; - }; + if(mifare_classic_halt(pcs, cuid)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); + break; + }; - isOK = 1; - break; - } + isOK = 1; + break; + } - crypto1_destroy(pcs); + crypto1_destroy(pcs); - if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED"); + if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED"); - cmd_send(CMD_ACK,isOK,0,0,0,0); + cmd_send(CMD_ACK,isOK,0,0,0,0); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - set_tracing(false); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + set_tracing(false); } /* // Command not needed but left for future testing void MifareUWriteBlockCompat(uint8_t arg0, uint8_t *datain) { - uint8_t blockNo = arg0; - byte_t blockdata[16] = {0x00}; + uint8_t blockNo = arg0; + byte_t blockdata[16] = {0x00}; - memcpy(blockdata, datain, 16); + memcpy(blockdata, datain, 16); - uint8_t uid[10] = {0x00}; + uint8_t uid[10] = {0x00}; - LED_A_ON(); LED_B_OFF(); LED_C_OFF(); + LED_A_ON(); LED_B_OFF(); LED_C_OFF(); - clear_trace(); - set_tracing(true); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + set_tracing(true); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - if(!iso14443a_select_card(uid, NULL, NULL, true, 0, true)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); - OnError(0); - return; - }; + if(!iso14443a_select_card(uid, NULL, NULL, true, 0, true)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); + OnError(0); + return; + }; - if(mifare_ultra_writeblock_compat(blockNo, blockdata)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); - OnError(0); - return; }; + if(mifare_ultra_writeblock_compat(blockNo, blockdata)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); + OnError(0); + return; }; - if(mifare_ultra_halt()) { - if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); - OnError(0); - return; - }; + if(mifare_ultra_halt()) { + if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); + OnError(0); + return; + }; - if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED"); + if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED"); - cmd_send(CMD_ACK,1,0,0,0,0); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); + cmd_send(CMD_ACK,1,0,0,0,0); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); } */ @@ -477,238 +477,238 @@ void MifareUWriteBlockCompat(uint8_t arg0, uint8_t *datain) // : 4/16 next bytes is authentication key. void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { - uint8_t blockNo = arg0; - bool useKey = (arg1 == 1); //UL_C - bool usePwd = (arg1 == 2); //UL_EV1/NTAG - byte_t blockdata[4] = {0x00}; + uint8_t blockNo = arg0; + bool useKey = (arg1 == 1); //UL_C + bool usePwd = (arg1 == 2); //UL_EV1/NTAG + byte_t blockdata[4] = {0x00}; - memcpy(blockdata, datain, 4); + memcpy(blockdata, datain, 4); - LEDsoff(); - LED_A_ON(); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + LEDsoff(); + LED_A_ON(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); + clear_trace(); + set_tracing(true); - if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); - OnError(0); - return; - }; + if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); + OnError(0); + return; + }; - // UL-C authentication - if ( useKey ) { - uint8_t key[16] = {0x00}; - memcpy(key, datain+4, sizeof(key) ); + // UL-C authentication + if ( useKey ) { + uint8_t key[16] = {0x00}; + memcpy(key, datain+4, sizeof(key) ); - if ( !mifare_ultra_auth(key) ) { - OnError(1); - return; - } - } + if ( !mifare_ultra_auth(key) ) { + OnError(1); + return; + } + } - // UL-EV1 / NTAG authentication - if (usePwd) { - uint8_t pwd[4] = {0x00}; - memcpy(pwd, datain+4, 4); - uint8_t pack[4] = {0,0,0,0}; - if (!mifare_ul_ev1_auth(pwd, pack)) { - OnError(1); - return; - } - } + // UL-EV1 / NTAG authentication + if (usePwd) { + uint8_t pwd[4] = {0x00}; + memcpy(pwd, datain+4, 4); + uint8_t pack[4] = {0,0,0,0}; + if (!mifare_ul_ev1_auth(pwd, pack)) { + OnError(1); + return; + } + } - if (mifare_ultra_writeblock(blockNo, blockdata)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); - OnError(0); - return; - }; + if (mifare_ultra_writeblock(blockNo, blockdata)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); + OnError(0); + return; + }; - if (mifare_ultra_halt()) { - if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); - OnError(0); - return; - }; + if (mifare_ultra_halt()) { + if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); + OnError(0); + return; + }; - if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED"); + if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED"); - cmd_send(CMD_ACK,1,0,0,0,0); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - set_tracing(false); + cmd_send(CMD_ACK,1,0,0,0,0); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + set_tracing(false); } void MifareUSetPwd(uint8_t arg0, uint8_t *datain){ - uint8_t pwd[16] = {0x00}; - byte_t blockdata[4] = {0x00}; + uint8_t pwd[16] = {0x00}; + byte_t blockdata[4] = {0x00}; - memcpy(pwd, datain, 16); + memcpy(pwd, datain, 16); - LED_A_ON(); LED_B_OFF(); LED_C_OFF(); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + LED_A_ON(); LED_B_OFF(); LED_C_OFF(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); + clear_trace(); + set_tracing(true); - if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); - OnError(0); - return; - }; + if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); + OnError(0); + return; + }; - blockdata[0] = pwd[7]; - blockdata[1] = pwd[6]; - blockdata[2] = pwd[5]; - blockdata[3] = pwd[4]; - if (mifare_ultra_writeblock( 44, blockdata)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); - OnError(44); - return; - }; + blockdata[0] = pwd[7]; + blockdata[1] = pwd[6]; + blockdata[2] = pwd[5]; + blockdata[3] = pwd[4]; + if (mifare_ultra_writeblock( 44, blockdata)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); + OnError(44); + return; + }; - blockdata[0] = pwd[3]; - blockdata[1] = pwd[2]; - blockdata[2] = pwd[1]; - blockdata[3] = pwd[0]; - if (mifare_ultra_writeblock( 45, blockdata)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); - OnError(45); - return; - }; + blockdata[0] = pwd[3]; + blockdata[1] = pwd[2]; + blockdata[2] = pwd[1]; + blockdata[3] = pwd[0]; + if (mifare_ultra_writeblock( 45, blockdata)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); + OnError(45); + return; + }; - blockdata[0] = pwd[15]; - blockdata[1] = pwd[14]; - blockdata[2] = pwd[13]; - blockdata[3] = pwd[12]; - if (mifare_ultra_writeblock( 46, blockdata)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); - OnError(46); - return; - }; + blockdata[0] = pwd[15]; + blockdata[1] = pwd[14]; + blockdata[2] = pwd[13]; + blockdata[3] = pwd[12]; + if (mifare_ultra_writeblock( 46, blockdata)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); + OnError(46); + return; + }; - blockdata[0] = pwd[11]; - blockdata[1] = pwd[10]; - blockdata[2] = pwd[9]; - blockdata[3] = pwd[8]; - if (mifare_ultra_writeblock( 47, blockdata)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); - OnError(47); - return; - }; + blockdata[0] = pwd[11]; + blockdata[1] = pwd[10]; + blockdata[2] = pwd[9]; + blockdata[3] = pwd[8]; + if (mifare_ultra_writeblock( 47, blockdata)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); + OnError(47); + return; + }; - if (mifare_ultra_halt()) { - if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); - OnError(0); - return; - }; + if (mifare_ultra_halt()) { + if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); + OnError(0); + return; + }; - cmd_send(CMD_ACK,1,0,0,0,0); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - set_tracing(false); + cmd_send(CMD_ACK,1,0,0,0,0); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + set_tracing(false); } // Return 1 if the nonce is invalid else return 0 int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) { - return ((oddparity8((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity8((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \ - (oddparity8((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity8((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \ - (oddparity8((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity8((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0; + return ((oddparity8((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity8((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \ + (oddparity8((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity8((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \ + (oddparity8((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity8((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0; } void MifareAcquireNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain) { - uint8_t uid[10] = {0x00}; - uint8_t answer[MAX_MIFARE_FRAME_SIZE] = {0x00}; - uint8_t par[1] = {0x00}; - uint8_t buf[USB_CMD_DATA_SIZE] = {0x00}; - uint32_t cuid = 0; - int16_t isOK = 0; - uint16_t num_nonces = 0; - uint8_t cascade_levels = 0; - uint8_t blockNo = arg0 & 0xff; - uint8_t keyType = (arg0 >> 8) & 0xff; - bool initialize = flags & 0x0001; - bool field_off = flags & 0x0004; - bool have_uid = false; + uint8_t uid[10] = {0x00}; + uint8_t answer[MAX_MIFARE_FRAME_SIZE] = {0x00}; + uint8_t par[1] = {0x00}; + uint8_t buf[USB_CMD_DATA_SIZE] = {0x00}; + uint32_t cuid = 0; + int16_t isOK = 0; + uint16_t num_nonces = 0; + uint8_t cascade_levels = 0; + uint8_t blockNo = arg0 & 0xff; + uint8_t keyType = (arg0 >> 8) & 0xff; + bool initialize = flags & 0x0001; + bool field_off = flags & 0x0004; + bool have_uid = false; - LED_A_ON(); - LED_C_OFF(); + LED_A_ON(); + LED_C_OFF(); - BigBuf_free(); BigBuf_Clear_ext(false); - clear_trace(); - set_tracing(true); + BigBuf_free(); BigBuf_Clear_ext(false); + clear_trace(); + set_tracing(true); - if (initialize) - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + if (initialize) + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - LED_C_ON(); + LED_C_ON(); - for (uint16_t i = 0; i <= USB_CMD_DATA_SIZE-4; i += 4 ) { + for (uint16_t i = 0; i <= USB_CMD_DATA_SIZE-4; i += 4 ) { - // Test if the action was cancelled - if (BUTTON_PRESS()) { - isOK = 2; - field_off = true; - break; - } + // Test if the action was cancelled + if (BUTTON_PRESS()) { + isOK = 2; + field_off = true; + break; + } - if (!have_uid) { // need a full select cycle to get the uid first - iso14a_card_select_t card_info; - if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { - if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (ALL)"); - continue; - } - switch (card_info.uidlen) { - case 4 : cascade_levels = 1; break; - case 7 : cascade_levels = 2; break; - case 10: cascade_levels = 3; break; - default: break; - } - have_uid = true; - } else { // no need for anticollision. We can directly select the card - if (!iso14443a_fast_select_card(uid, cascade_levels)) { - if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (UID)"); - continue; - } - } + if (!have_uid) { // need a full select cycle to get the uid first + iso14a_card_select_t card_info; + if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { + if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (ALL)"); + continue; + } + switch (card_info.uidlen) { + case 4 : cascade_levels = 1; break; + case 7 : cascade_levels = 2; break; + case 10: cascade_levels = 3; break; + default: break; + } + have_uid = true; + } else { // no need for anticollision. We can directly select the card + if (!iso14443a_fast_select_card(uid, cascade_levels)) { + if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (UID)"); + continue; + } + } - // Transmit MIFARE_CLASSIC_AUTH - uint8_t dcmd[4] = {0x60 + (keyType & 0x01), blockNo, 0x00, 0x00}; - AddCrc14A(dcmd, 2); - ReaderTransmit(dcmd, sizeof(dcmd), NULL); - int len = ReaderReceive(answer, par); + // Transmit MIFARE_CLASSIC_AUTH + uint8_t dcmd[4] = {0x60 + (keyType & 0x01), blockNo, 0x00, 0x00}; + AddCrc14A(dcmd, 2); + ReaderTransmit(dcmd, sizeof(dcmd), NULL); + int len = ReaderReceive(answer, par); - // wait for the card to become ready again - CHK_TIMEOUT(); + // wait for the card to become ready again + CHK_TIMEOUT(); - if (len != 4) { - if (MF_DBGLEVEL >= 2) Dbprintf("AcquireNonces: Auth1 error"); - continue; - } + if (len != 4) { + if (MF_DBGLEVEL >= 2) Dbprintf("AcquireNonces: Auth1 error"); + continue; + } - num_nonces++; + num_nonces++; - // Save the tag nonce (nt) - buf[i] = answer[0]; - buf[i+1] = answer[1]; - buf[i+2] = answer[2]; - buf[i+3] = answer[3]; - } + // Save the tag nonce (nt) + buf[i] = answer[0]; + buf[i+1] = answer[1]; + buf[i+2] = answer[2]; + buf[i+3] = answer[3]; + } - LED_C_OFF(); - LED_B_ON(); - cmd_send(CMD_ACK, isOK, cuid, num_nonces-1, buf, sizeof(buf)); - LED_B_OFF(); + LED_C_OFF(); + LED_B_ON(); + cmd_send(CMD_ACK, isOK, cuid, num_nonces-1, buf, sizeof(buf)); + LED_B_OFF(); - if (MF_DBGLEVEL >= 3) DbpString("AcquireNonces finished"); + if (MF_DBGLEVEL >= 3) DbpString("AcquireNonces finished"); - if (field_off) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - set_tracing(false); - } + if (field_off) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + set_tracing(false); + } } //----------------------------------------------------------------------------- @@ -719,116 +719,116 @@ void MifareAcquireNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t * //----------------------------------------------------------------------------- void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain) { - struct Crypto1State mpcs = {0, 0}; - struct Crypto1State *pcs; - pcs = &mpcs; + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; - uint8_t uid[10] = {0x00}; - uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; - uint8_t par_enc[1] = {0x00}; - uint8_t buf[USB_CMD_DATA_SIZE] = {0x00}; + uint8_t uid[10] = {0x00}; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; + uint8_t par_enc[1] = {0x00}; + uint8_t buf[USB_CMD_DATA_SIZE] = {0x00}; - uint64_t ui64Key = bytes_to_num(datain, 6); - uint32_t cuid = 0; - int16_t isOK = 0; - uint16_t num_nonces = 0; - uint8_t nt_par_enc = 0; - uint8_t cascade_levels = 0; - uint8_t blockNo = arg0 & 0xff; - uint8_t keyType = (arg0 >> 8) & 0xff; - uint8_t targetBlockNo = arg1 & 0xff; - uint8_t targetKeyType = (arg1 >> 8) & 0xff; - bool initialize = flags & 0x0001; - bool slow = flags & 0x0002; - bool field_off = flags & 0x0004; - bool have_uid = false; + uint64_t ui64Key = bytes_to_num(datain, 6); + uint32_t cuid = 0; + int16_t isOK = 0; + uint16_t num_nonces = 0; + uint8_t nt_par_enc = 0; + uint8_t cascade_levels = 0; + uint8_t blockNo = arg0 & 0xff; + uint8_t keyType = (arg0 >> 8) & 0xff; + uint8_t targetBlockNo = arg1 & 0xff; + uint8_t targetKeyType = (arg1 >> 8) & 0xff; + bool initialize = flags & 0x0001; + bool slow = flags & 0x0002; + bool field_off = flags & 0x0004; + bool have_uid = false; - LED_A_ON(); - LED_C_OFF(); + LED_A_ON(); + LED_C_OFF(); - BigBuf_free(); BigBuf_Clear_ext(false); - clear_trace(); - set_tracing(false); + BigBuf_free(); BigBuf_Clear_ext(false); + clear_trace(); + set_tracing(false); - if (initialize) - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + if (initialize) + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - LED_C_ON(); + LED_C_ON(); - for (uint16_t i = 0; i <= USB_CMD_DATA_SIZE - 9; ) { + for (uint16_t i = 0; i <= USB_CMD_DATA_SIZE - 9; ) { - // Test if the action was cancelled - if(BUTTON_PRESS()) { - isOK = 2; - field_off = true; - break; - } + // Test if the action was cancelled + if(BUTTON_PRESS()) { + isOK = 2; + field_off = true; + break; + } - if (!have_uid) { // need a full select cycle to get the uid first - iso14a_card_select_t card_info; - if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { - if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (ALL)"); - continue; - } - switch (card_info.uidlen) { - case 4 : cascade_levels = 1; break; - case 7 : cascade_levels = 2; break; - case 10: cascade_levels = 3; break; - default: break; - } - have_uid = true; - } else { // no need for anticollision. We can directly select the card - if (!iso14443a_fast_select_card(uid, cascade_levels)) { - if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (UID)"); - continue; - } - } + if (!have_uid) { // need a full select cycle to get the uid first + iso14a_card_select_t card_info; + if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { + if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (ALL)"); + continue; + } + switch (card_info.uidlen) { + case 4 : cascade_levels = 1; break; + case 7 : cascade_levels = 2; break; + case 10: cascade_levels = 3; break; + default: break; + } + have_uid = true; + } else { // no need for anticollision. We can directly select the card + if (!iso14443a_fast_select_card(uid, cascade_levels)) { + if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (UID)"); + continue; + } + } - if (slow) - SpinDelayUs(HARDNESTED_PRE_AUTHENTICATION_LEADTIME); + if (slow) + SpinDelayUs(HARDNESTED_PRE_AUTHENTICATION_LEADTIME); - uint32_t nt1; - if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, NULL)) { - if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Auth1 error"); - continue; - } + uint32_t nt1; + if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, NULL)) { + if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Auth1 error"); + continue; + } - // nested authentication - uint16_t len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par_enc, NULL); + // nested authentication + uint16_t len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par_enc, NULL); - // wait for the card to become ready again - CHK_TIMEOUT(); + // wait for the card to become ready again + CHK_TIMEOUT(); - if (len != 4) { - if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Auth2 error len=%d", len); - continue; - } + if (len != 4) { + if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Auth2 error len=%d", len); + continue; + } - num_nonces++; - if (num_nonces % 2) { - memcpy(buf+i, receivedAnswer, 4); - nt_par_enc = par_enc[0] & 0xf0; - } else { - nt_par_enc |= par_enc[0] >> 4; - memcpy(buf+i+4, receivedAnswer, 4); - memcpy(buf+i+8, &nt_par_enc, 1); - i += 9; - } - } + num_nonces++; + if (num_nonces % 2) { + memcpy(buf+i, receivedAnswer, 4); + nt_par_enc = par_enc[0] & 0xf0; + } else { + nt_par_enc |= par_enc[0] >> 4; + memcpy(buf+i+4, receivedAnswer, 4); + memcpy(buf+i+8, &nt_par_enc, 1); + i += 9; + } + } - LED_C_OFF(); - crypto1_destroy(pcs); - LED_B_ON(); - cmd_send(CMD_ACK, isOK, cuid, num_nonces, buf, sizeof(buf)); - LED_B_OFF(); + LED_C_OFF(); + crypto1_destroy(pcs); + LED_B_ON(); + cmd_send(CMD_ACK, isOK, cuid, num_nonces, buf, sizeof(buf)); + LED_B_OFF(); - if (MF_DBGLEVEL >= 3) DbpString("AcquireEncryptedNonces finished"); + if (MF_DBGLEVEL >= 3) DbpString("AcquireEncryptedNonces finished"); - if (field_off) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - set_tracing(false); - } + if (field_off) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + set_tracing(false); + } } @@ -838,215 +838,215 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, //----------------------------------------------------------------------------- void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *datain) { - // params - uint8_t blockNo = arg0 & 0xff; - uint8_t keyType = (arg0 >> 8) & 0xff; - uint8_t targetBlockNo = arg1 & 0xff; - uint8_t targetKeyType = (arg1 >> 8) & 0xff; - uint64_t ui64Key = 0; + // params + uint8_t blockNo = arg0 & 0xff; + uint8_t keyType = (arg0 >> 8) & 0xff; + uint8_t targetBlockNo = arg1 & 0xff; + uint8_t targetKeyType = (arg1 >> 8) & 0xff; + uint64_t ui64Key = 0; - ui64Key = bytes_to_num(datain, 6); + ui64Key = bytes_to_num(datain, 6); - // variables - uint16_t rtr, i, j, len; - uint16_t davg = 0; - static uint16_t dmin, dmax; - uint8_t uid[10] = {0x00}; - uint32_t cuid = 0, nt1, nt2, nttmp, nttest, ks1; - uint8_t par[1] = {0x00}; - uint32_t target_nt[2] = {0x00}, target_ks[2] = {0x00}; + // variables + uint16_t rtr, i, j, len; + uint16_t davg = 0; + static uint16_t dmin, dmax; + uint8_t uid[10] = {0x00}; + uint32_t cuid = 0, nt1, nt2, nttmp, nttest, ks1; + uint8_t par[1] = {0x00}; + uint32_t target_nt[2] = {0x00}, target_ks[2] = {0x00}; - uint8_t par_array[4] = {0x00}; - uint16_t ncount = 0; - struct Crypto1State mpcs = {0, 0}; - struct Crypto1State *pcs; - pcs = &mpcs; - uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; + uint8_t par_array[4] = {0x00}; + uint16_t ncount = 0; + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; - uint32_t auth1_time, auth2_time; - static uint16_t delta_time = 0; + uint32_t auth1_time, auth2_time; + static uint16_t delta_time = 0; - LED_A_ON(); - LED_C_OFF(); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + LED_A_ON(); + LED_C_OFF(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - // free eventually allocated BigBuf memory - BigBuf_free(); BigBuf_Clear_ext(false); + // free eventually allocated BigBuf memory + BigBuf_free(); BigBuf_Clear_ext(false); - if (calibrate) clear_trace(); - set_tracing(true); + if (calibrate) clear_trace(); + set_tracing(true); - // statistics on nonce distance - int16_t isOK = 0; - #define NESTED_MAX_TRIES 12 - uint16_t unsuccessfull_tries = 0; - if (calibrate) { // for first call only. Otherwise reuse previous calibration - LED_B_ON(); - WDT_HIT(); + // statistics on nonce distance + int16_t isOK = 0; + #define NESTED_MAX_TRIES 12 + uint16_t unsuccessfull_tries = 0; + if (calibrate) { // for first call only. Otherwise reuse previous calibration + LED_B_ON(); + WDT_HIT(); - davg = dmax = 0; - dmin = 2000; - delta_time = 0; + davg = dmax = 0; + dmin = 2000; + delta_time = 0; - for (rtr = 0; rtr < 17; rtr++) { + for (rtr = 0; rtr < 17; rtr++) { - // Test if the action was cancelled - if(BUTTON_PRESS()) { - isOK = -2; - break; - } + // Test if the action was cancelled + if(BUTTON_PRESS()) { + isOK = -2; + break; + } - // prepare next select. No need to power down the card. - if(mifare_classic_halt(pcs, cuid)) { - if (MF_DBGLEVEL >= 2) Dbprintf("Nested: Halt error"); - rtr--; - continue; - } + // prepare next select. No need to power down the card. + if(mifare_classic_halt(pcs, cuid)) { + if (MF_DBGLEVEL >= 2) Dbprintf("Nested: Halt error"); + rtr--; + continue; + } - if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - if (MF_DBGLEVEL >= 2) Dbprintf("Nested: Can't select card"); - rtr--; - continue; - }; + if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { + if (MF_DBGLEVEL >= 2) Dbprintf("Nested: Can't select card"); + rtr--; + continue; + }; - auth1_time = 0; - if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, &auth1_time)) { - if (MF_DBGLEVEL >= 2) Dbprintf("Nested: Auth1 error"); - rtr--; - continue; - }; - auth2_time = (delta_time) ? auth1_time + delta_time : 0; + auth1_time = 0; + if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, &auth1_time)) { + if (MF_DBGLEVEL >= 2) Dbprintf("Nested: Auth1 error"); + rtr--; + continue; + }; + auth2_time = (delta_time) ? auth1_time + delta_time : 0; - if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_NESTED, &nt2, &auth2_time)) { - if (MF_DBGLEVEL >= 2) Dbprintf("Nested: Auth2 error"); - rtr--; - continue; - }; + if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_NESTED, &nt2, &auth2_time)) { + if (MF_DBGLEVEL >= 2) Dbprintf("Nested: Auth2 error"); + rtr--; + continue; + }; - nttmp = prng_successor(nt1, 100); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160 - for (i = 101; i < 1200; i++) { - nttmp = prng_successor(nttmp, 1); - if (nttmp == nt2) break; - } + nttmp = prng_successor(nt1, 100); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160 + for (i = 101; i < 1200; i++) { + nttmp = prng_successor(nttmp, 1); + if (nttmp == nt2) break; + } - if (i != 1200) { - if (rtr != 0) { - davg += i; - dmin = MIN(dmin, i); - dmax = MAX(dmax, i); - } - else { - delta_time = auth2_time - auth1_time + 32; // allow some slack for proper timing - } - if (MF_DBGLEVEL >= 3) Dbprintf("Nested: calibrating... ntdist=%d", i); - } else { - unsuccessfull_tries++; - if (unsuccessfull_tries > NESTED_MAX_TRIES) { // card isn't vulnerable to nested attack (random numbers are not predictable) - isOK = -3; - } - } - } + if (i != 1200) { + if (rtr != 0) { + davg += i; + dmin = MIN(dmin, i); + dmax = MAX(dmax, i); + } + else { + delta_time = auth2_time - auth1_time + 32; // allow some slack for proper timing + } + if (MF_DBGLEVEL >= 3) Dbprintf("Nested: calibrating... ntdist=%d", i); + } else { + unsuccessfull_tries++; + if (unsuccessfull_tries > NESTED_MAX_TRIES) { // card isn't vulnerable to nested attack (random numbers are not predictable) + isOK = -3; + } + } + } - davg = (davg + (rtr - 1)/2) / (rtr - 1); + davg = (davg + (rtr - 1)/2) / (rtr - 1); - if (MF_DBGLEVEL >= 3) Dbprintf("rtr=%d isOK=%d min=%d max=%d avg=%d, delta_time=%d", rtr, isOK, dmin, dmax, davg, delta_time); + if (MF_DBGLEVEL >= 3) Dbprintf("rtr=%d isOK=%d min=%d max=%d avg=%d, delta_time=%d", rtr, isOK, dmin, dmax, davg, delta_time); - dmin = davg - 2; - dmax = davg + 2; + dmin = davg - 2; + dmax = davg + 2; - LED_B_OFF(); - } + LED_B_OFF(); + } // ------------------------------------------------------------------------------------------------- - LED_C_ON(); + LED_C_ON(); - // get crypted nonces for target sector - for(i=0; i < 2 && !isOK; i++) { // look for exactly two different nonces + // get crypted nonces for target sector + for(i=0; i < 2 && !isOK; i++) { // look for exactly two different nonces - target_nt[i] = 0; - while(target_nt[i] == 0) { // continue until we have an unambiguous nonce + target_nt[i] = 0; + while(target_nt[i] == 0) { // continue until we have an unambiguous nonce - // prepare next select. No need to power down the card. - if(mifare_classic_halt(pcs, cuid)) { - if (MF_DBGLEVEL >= 2) Dbprintf("Nested: Halt error"); - continue; - } + // prepare next select. No need to power down the card. + if(mifare_classic_halt(pcs, cuid)) { + if (MF_DBGLEVEL >= 2) Dbprintf("Nested: Halt error"); + continue; + } - if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - if (MF_DBGLEVEL >= 2) Dbprintf("Nested: Can't select card"); - continue; - }; + if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { + if (MF_DBGLEVEL >= 2) Dbprintf("Nested: Can't select card"); + continue; + }; - auth1_time = 0; - if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, &auth1_time)) { - if (MF_DBGLEVEL >= 2) Dbprintf("Nested: Auth1 error"); - continue; - }; + auth1_time = 0; + if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, &auth1_time)) { + if (MF_DBGLEVEL >= 2) Dbprintf("Nested: Auth1 error"); + continue; + }; - // nested authentication - auth2_time = auth1_time + delta_time; + // nested authentication + auth2_time = auth1_time + delta_time; - len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, &auth2_time); - if (len != 4) { - if (MF_DBGLEVEL >= 2) Dbprintf("Nested: Auth2 error len=%d", len); - continue; - }; + len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, &auth2_time); + if (len != 4) { + if (MF_DBGLEVEL >= 2) Dbprintf("Nested: Auth2 error len=%d", len); + continue; + }; - nt2 = bytes_to_num(receivedAnswer, 4); - if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: Testing nt1=%08x nt2enc=%08x nt2par=%02x", i+1, nt1, nt2, par[0]); + nt2 = bytes_to_num(receivedAnswer, 4); + if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: Testing nt1=%08x nt2enc=%08x nt2par=%02x", i+1, nt1, nt2, par[0]); - // Parity validity check - for (j = 0; j < 4; j++) { - par_array[j] = (oddparity8(receivedAnswer[j]) != ((par[0] >> (7-j)) & 0x01)); - } + // Parity validity check + for (j = 0; j < 4; j++) { + par_array[j] = (oddparity8(receivedAnswer[j]) != ((par[0] >> (7-j)) & 0x01)); + } - ncount = 0; - nttest = prng_successor(nt1, dmin - 1); - for (j = dmin; j < dmax + 1; j++) { - nttest = prng_successor(nttest, 1); - ks1 = nt2 ^ nttest; + ncount = 0; + nttest = prng_successor(nt1, dmin - 1); + for (j = dmin; j < dmax + 1; j++) { + nttest = prng_successor(nttest, 1); + ks1 = nt2 ^ nttest; - if (valid_nonce(nttest, nt2, ks1, par_array)){ - if (ncount > 0) { // we are only interested in disambiguous nonces, try again - if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (ambigous), ntdist=%d", i+1, j); - target_nt[i] = 0; - break; - } - target_nt[i] = nttest; - target_ks[i] = ks1; - ncount++; - if (i == 1 && target_nt[1] == target_nt[0]) { // we need two different nonces - target_nt[i] = 0; - if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#2: dismissed (= nonce#1), ntdist=%d", j); - break; - } - if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: valid, ntdist=%d", i+1, j); - } - } - if (target_nt[i] == 0 && j == dmax+1 && MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (all invalid)", i+1); - } - } + if (valid_nonce(nttest, nt2, ks1, par_array)){ + if (ncount > 0) { // we are only interested in disambiguous nonces, try again + if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (ambigous), ntdist=%d", i+1, j); + target_nt[i] = 0; + break; + } + target_nt[i] = nttest; + target_ks[i] = ks1; + ncount++; + if (i == 1 && target_nt[1] == target_nt[0]) { // we need two different nonces + target_nt[i] = 0; + if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#2: dismissed (= nonce#1), ntdist=%d", j); + break; + } + if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: valid, ntdist=%d", i+1, j); + } + } + if (target_nt[i] == 0 && j == dmax+1 && MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (all invalid)", i+1); + } + } - LED_C_OFF(); + LED_C_OFF(); - crypto1_destroy(pcs); + crypto1_destroy(pcs); - uint8_t buf[4 + 4 * 4] = {0}; - memcpy(buf, &cuid, 4); - memcpy(buf+4, &target_nt[0], 4); - memcpy(buf+8, &target_ks[0], 4); - memcpy(buf+12, &target_nt[1], 4); - memcpy(buf+16, &target_ks[1], 4); + uint8_t buf[4 + 4 * 4] = {0}; + memcpy(buf, &cuid, 4); + memcpy(buf+4, &target_nt[0], 4); + memcpy(buf+8, &target_ks[0], 4); + memcpy(buf+12, &target_nt[1], 4); + memcpy(buf+16, &target_ks[1], 4); - LED_B_ON(); - cmd_send(CMD_ACK, isOK, 0, targetBlockNo + (targetKeyType * 0x100), buf, sizeof(buf)); - LED_B_OFF(); + LED_B_ON(); + cmd_send(CMD_ACK, isOK, 0, targetBlockNo + (targetKeyType * 0x100), buf, sizeof(buf)); + LED_B_OFF(); - if (MF_DBGLEVEL >= 3) DbpString("NESTED FINISHED"); + if (MF_DBGLEVEL >= 3) DbpString("NESTED FINISHED"); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - set_tracing(false); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + set_tracing(false); } //----------------------------------------------------------------------------- @@ -1054,18 +1054,18 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat // //----------------------------------------------------------------------------- typedef struct sector_t { - uint8_t keyA[6]; - uint8_t keyB[6]; + uint8_t keyA[6]; + uint8_t keyB[6]; } sector_t; typedef struct chk_t { - uint64_t key; - uint32_t cuid; - uint8_t cl; - uint8_t block; - uint8_t keyType; - uint8_t *uid; - struct Crypto1State *pcs; + uint64_t key; + uint32_t cuid; + uint8_t cl; + uint8_t block; + uint8_t keyType; + uint8_t *uid; + struct Crypto1State *pcs; } chk_t; // checks one key. @@ -1076,117 +1076,117 @@ typedef struct chk_t { // 1 = wrong key // 0 = correct key uint8_t chkKey( struct chk_t *c ) { - uint8_t i = 0, res = 2; - while( i < 5 ) { - // this part is from Piwi's faster nonce collecting part in Hardnested. - // assume: fast select - if (!iso14443a_fast_select_card(c->uid, c->cl)) { - ++i; - continue; - } - res = mifare_classic_authex(c->pcs, c->cuid, c->block, c->keyType, c->key, AUTH_FIRST, NULL, NULL); + uint8_t i = 0, res = 2; + while( i < 5 ) { + // this part is from Piwi's faster nonce collecting part in Hardnested. + // assume: fast select + if (!iso14443a_fast_select_card(c->uid, c->cl)) { + ++i; + continue; + } + res = mifare_classic_authex(c->pcs, c->cuid, c->block, c->keyType, c->key, AUTH_FIRST, NULL, NULL); - CHK_TIMEOUT(); + CHK_TIMEOUT(); - // if successfull auth, send HALT - // if ( !res ) - // mifare_classic_halt_ex(c->pcs); - break; - } - return res; + // if successfull auth, send HALT + // if ( !res ) + // mifare_classic_halt_ex(c->pcs); + break; + } + return res; } uint8_t chkKey_readb(struct chk_t *c, uint8_t *keyb) { - if (!iso14443a_fast_select_card(c->uid, c->cl)) - return 2; + if (!iso14443a_fast_select_card(c->uid, c->cl)) + return 2; - if ( mifare_classic_authex(c->pcs, c->cuid, c->block, 0, c->key, AUTH_FIRST, NULL, NULL) ) - return 1; + if ( mifare_classic_authex(c->pcs, c->cuid, c->block, 0, c->key, AUTH_FIRST, NULL, NULL) ) + return 1; - uint8_t data[16] = {0x00}; - uint8_t res = mifare_classic_readblock(c->pcs, c->cuid, c->block, data); + uint8_t data[16] = {0x00}; + uint8_t res = mifare_classic_readblock(c->pcs, c->cuid, c->block, data); - // successful read - if ( !res ) { - // data was something else than zeros. - if ( memcmp(data+10, "\x00\x00\x00\x00\x00\x00", 6) != 0) { - memcpy(keyb, data+10, 6); - res = 0; - } else { - res = 3; - } - mifare_classic_halt_ex(c->pcs); - } - return res; + // successful read + if ( !res ) { + // data was something else than zeros. + if ( memcmp(data+10, "\x00\x00\x00\x00\x00\x00", 6) != 0) { + memcpy(keyb, data+10, 6); + res = 0; + } else { + res = 3; + } + mifare_classic_halt_ex(c->pcs); + } + return res; } void chkKey_scanA(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) { - for (uint8_t s = 0; s < *sectorcnt; s++) { + for (uint8_t s = 0; s < *sectorcnt; s++) { - // skip already found A keys - if ( found[(s*2)] ) - continue; + // skip already found A keys + if ( found[(s*2)] ) + continue; - c->block = FirstBlockOfSector( s ); - if ( chkKey( c ) == 0 ) { - num_to_bytes(c->key, 6, k_sector[s].keyA); - found[(s*2)] = 1; - ++*foundkeys; + c->block = FirstBlockOfSector( s ); + if ( chkKey( c ) == 0 ) { + num_to_bytes(c->key, 6, k_sector[s].keyA); + found[(s*2)] = 1; + ++*foundkeys; - if (MF_DBGLEVEL >= 3) Dbprintf("ChkKeys_fast: Scan A found (%d)", c->block); - } - } + if (MF_DBGLEVEL >= 3) Dbprintf("ChkKeys_fast: Scan A found (%d)", c->block); + } + } } void chkKey_scanB(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) { - for (uint8_t s = 0; s < *sectorcnt; s++) { + for (uint8_t s = 0; s < *sectorcnt; s++) { - // skip already found B keys - if ( found[(s*2)+1] ) - continue; + // skip already found B keys + if ( found[(s*2)+1] ) + continue; - c->block = FirstBlockOfSector( s ); - if ( chkKey( c ) == 0 ) { - num_to_bytes(c->key, 6, k_sector[s].keyB); - found[(s*2)+1] = 1; - ++*foundkeys; + c->block = FirstBlockOfSector( s ); + if ( chkKey( c ) == 0 ) { + num_to_bytes(c->key, 6, k_sector[s].keyB); + found[(s*2)+1] = 1; + ++*foundkeys; - if (MF_DBGLEVEL >= 3) Dbprintf("ChkKeys_fast: Scan B found (%d)", c->block); - } - } + if (MF_DBGLEVEL >= 3) Dbprintf("ChkKeys_fast: Scan B found (%d)", c->block); + } + } } // loop all A keys, // when A is found but not B, try to read B. void chkKey_loopBonly(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) { - // read Block B, if A is found. - for (uint8_t s = 0; s < *sectorcnt; ++s) { + // read Block B, if A is found. + for (uint8_t s = 0; s < *sectorcnt; ++s) { - if ( found[(s*2)] && found[(s*2)+1] ) - continue; + if ( found[(s*2)] && found[(s*2)+1] ) + continue; - c->block = (FirstBlockOfSector( s ) + NumBlocksPerSector( s ) - 1); + c->block = (FirstBlockOfSector( s ) + NumBlocksPerSector( s ) - 1); - // A but not B - if ( found[(s*2)] && !found[(s*2)+1] ){ - c->key = bytes_to_num(k_sector[s].keyA, 6); - uint8_t status = chkKey_readb(c, k_sector[s].keyB); - if ( status == 0 ){ - found[(s*2)+1] = 1; - ++*foundkeys; + // A but not B + if ( found[(s*2)] && !found[(s*2)+1] ){ + c->key = bytes_to_num(k_sector[s].keyA, 6); + uint8_t status = chkKey_readb(c, k_sector[s].keyB); + if ( status == 0 ){ + found[(s*2)+1] = 1; + ++*foundkeys; - if (MF_DBGLEVEL >= 3) Dbprintf("ChkKeys_fast: Reading B found (%d)", c->block); + if (MF_DBGLEVEL >= 3) Dbprintf("ChkKeys_fast: Reading B found (%d)", c->block); - // try quick find all B? - // assume: keys comes in groups. Find one B, test against all B. - c->key = bytes_to_num( k_sector[s].keyB, 6); - c->keyType = 1; - chkKey_scanB(c, k_sector, found, sectorcnt, foundkeys); - } - } - } + // try quick find all B? + // assume: keys comes in groups. Find one B, test against all B. + c->key = bytes_to_num( k_sector[s].keyB, 6); + c->keyType = 1; + chkKey_scanB(c, k_sector, found, sectorcnt, foundkeys); + } + } + } } @@ -1199,376 +1199,376 @@ void chkKey_loopBonly(struct chk_t *c, struct sector_t *k_sector, uint8_t *found // datain = keys as array void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) { - // first call or - uint8_t sectorcnt = arg0 & 0xFF; // 16; - uint8_t firstchunk = (arg0 >> 8) & 0xF; - uint8_t lastchunk = (arg0 >> 12) & 0xF; - uint8_t strategy = arg1 & 0xFF; - uint8_t use_flashmem = (arg1 >> 8) & 0xFF; - uint16_t keyCount = arg2 & 0xFF; - uint8_t status = 0; + // first call or + uint8_t sectorcnt = arg0 & 0xFF; // 16; + uint8_t firstchunk = (arg0 >> 8) & 0xF; + uint8_t lastchunk = (arg0 >> 12) & 0xF; + uint8_t strategy = arg1 & 0xFF; + uint8_t use_flashmem = (arg1 >> 8) & 0xFF; + uint16_t keyCount = arg2 & 0xFF; + uint8_t status = 0; - struct Crypto1State mpcs = {0, 0}; - struct Crypto1State *pcs; - pcs = &mpcs; - struct chk_t chk_data; + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; + struct chk_t chk_data; - uint8_t allkeys = sectorcnt << 1; + uint8_t allkeys = sectorcnt << 1; - static uint32_t cuid = 0; - static uint8_t cascade_levels = 0; - static uint8_t foundkeys = 0; - static sector_t k_sector[80]; - static uint8_t found[80]; - static uint8_t *uid; + static uint32_t cuid = 0; + static uint8_t cascade_levels = 0; + static uint8_t foundkeys = 0; + static sector_t k_sector[80]; + static uint8_t found[80]; + static uint8_t *uid; #ifdef WITH_FLASH - if ( use_flashmem ) { - BigBuf_free(); - uint16_t isok = 0; - uint8_t size[2] = {0x00, 0x00}; - isok = Flash_ReadData(DEFAULT_MF_KEYS_OFFSET, size, 2); - if ( isok != 2 ) - goto OUT; + if ( use_flashmem ) { + BigBuf_free(); + uint16_t isok = 0; + uint8_t size[2] = {0x00, 0x00}; + isok = Flash_ReadData(DEFAULT_MF_KEYS_OFFSET, size, 2); + if ( isok != 2 ) + goto OUT; - keyCount = size[1] << 8 | size[0]; + keyCount = size[1] << 8 | size[0]; - if ( keyCount == 0 && keyCount == 0xFFFF) - goto OUT; + if ( keyCount == 0 && keyCount == 0xFFFF) + goto OUT; - datain = BigBuf_malloc( keyCount * 6); - if (datain == NULL ) - goto OUT; + datain = BigBuf_malloc( keyCount * 6); + if (datain == NULL ) + goto OUT; - isok = Flash_ReadData(DEFAULT_MF_KEYS_OFFSET+2, datain, keyCount * 6); - if ( isok != keyCount * 6 ) - goto OUT; + isok = Flash_ReadData(DEFAULT_MF_KEYS_OFFSET+2, datain, keyCount * 6); + if ( isok != keyCount * 6 ) + goto OUT; - } + } #endif - if (uid == NULL || firstchunk) { - uid = BigBuf_malloc(10); - if (uid == NULL ) - goto OUT; - } + if (uid == NULL || firstchunk) { + uid = BigBuf_malloc(10); + if (uid == NULL ) + goto OUT; + } - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - LEDsoff(); - LED_A_ON(); + LEDsoff(); + LED_A_ON(); - if ( firstchunk ) { - clear_trace(); - set_tracing(false); + if ( firstchunk ) { + clear_trace(); + set_tracing(false); - memset(k_sector, 0x00, 480+10); - memset(found, 0x00, sizeof(found)); - foundkeys = 0; + memset(k_sector, 0x00, 480+10); + memset(found, 0x00, sizeof(found)); + foundkeys = 0; - iso14a_card_select_t card_info; - if ( !iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { - if (MF_DBGLEVEL >= 1) Dbprintf("ChkKeys_fast: Can't select card (ALL)"); - goto OUT; - } + iso14a_card_select_t card_info; + if ( !iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { + if (MF_DBGLEVEL >= 1) Dbprintf("ChkKeys_fast: Can't select card (ALL)"); + goto OUT; + } - switch (card_info.uidlen) { - case 4 : cascade_levels = 1; break; - case 7 : cascade_levels = 2; break; - case 10: cascade_levels = 3; break; - default: break; - } + switch (card_info.uidlen) { + case 4 : cascade_levels = 1; break; + case 7 : cascade_levels = 2; break; + case 10: cascade_levels = 3; break; + default: break; + } - CHK_TIMEOUT(); - } + CHK_TIMEOUT(); + } - // set check struct. - chk_data.uid = uid; - chk_data.cuid = cuid; - chk_data.cl = cascade_levels; - chk_data.pcs = pcs; - chk_data.block = 0; + // set check struct. + chk_data.uid = uid; + chk_data.cuid = cuid; + chk_data.cl = cascade_levels; + chk_data.pcs = pcs; + chk_data.block = 0; - // keychunk loop - depth first one sector. - if ( strategy == 1 || use_flashmem) { + // keychunk loop - depth first one sector. + if ( strategy == 1 || use_flashmem) { - uint8_t newfound = foundkeys; + uint8_t newfound = foundkeys; - uint16_t lastpos = 0; - uint16_t s_point = 0; - // Sector main loop - // keep track of how many sectors on card. - for (uint8_t s = 0; s < sectorcnt; ++s) { + uint16_t lastpos = 0; + uint16_t s_point = 0; + // Sector main loop + // keep track of how many sectors on card. + for (uint8_t s = 0; s < sectorcnt; ++s) { - if ( found[(s*2)] && found[(s*2)+1] ) - continue; + if ( found[(s*2)] && found[(s*2)+1] ) + continue; - for (uint16_t i = s_point; i < keyCount; ++i) { + for (uint16_t i = s_point; i < keyCount; ++i) { - //if ( i % 100 == 0) Dbprintf("ChkKeys_fast: sector %d | checking %d | %d found | s_point %d", s, i, foundkeys, s_point); + //if ( i % 100 == 0) Dbprintf("ChkKeys_fast: sector %d | checking %d | %d found | s_point %d", s, i, foundkeys, s_point); - // Allow button press / usb cmd to interrupt device - if (BUTTON_PRESS() && !usb_poll_validate_length()) { - goto OUT; - } + // Allow button press / usb cmd to interrupt device + if (BUTTON_PRESS() && !usb_poll_validate_length()) { + goto OUT; + } - // found all keys? - if ( foundkeys == allkeys ) - goto OUT; + // found all keys? + if ( foundkeys == allkeys ) + goto OUT; - WDT_HIT(); + WDT_HIT(); - // assume: block0,1,2 has more read rights in accessbits than the sectortrailer. authenticating against block0 in each sector - chk_data.block = FirstBlockOfSector( s ); + // assume: block0,1,2 has more read rights in accessbits than the sectortrailer. authenticating against block0 in each sector + chk_data.block = FirstBlockOfSector( s ); - // new key - chk_data.key = bytes_to_num(datain + i * 6, 6); + // new key + chk_data.key = bytes_to_num(datain + i * 6, 6); - // skip already found A keys - if( !found[(s*2)] ) { - chk_data.keyType = 0; - status = chkKey( &chk_data); - if ( status == 0 ) { - memcpy(k_sector[s].keyA, datain + i * 6, 6); - found[(s*2)] = 1; - ++foundkeys; + // skip already found A keys + if( !found[(s*2)] ) { + chk_data.keyType = 0; + status = chkKey( &chk_data); + if ( status == 0 ) { + memcpy(k_sector[s].keyA, datain + i * 6, 6); + found[(s*2)] = 1; + ++foundkeys; - chkKey_scanA(&chk_data, k_sector, found, §orcnt, &foundkeys); + chkKey_scanA(&chk_data, k_sector, found, §orcnt, &foundkeys); - // read Block B, if A is found. - chkKey_loopBonly( &chk_data, k_sector, found, §orcnt, &foundkeys); + // read Block B, if A is found. + chkKey_loopBonly( &chk_data, k_sector, found, §orcnt, &foundkeys); - chk_data.keyType = 1; - chkKey_scanB(&chk_data, k_sector, found, §orcnt, &foundkeys); + chk_data.keyType = 1; + chkKey_scanB(&chk_data, k_sector, found, §orcnt, &foundkeys); - chk_data.keyType = 0; - chk_data.block = FirstBlockOfSector( s ); + chk_data.keyType = 0; + chk_data.block = FirstBlockOfSector( s ); - if ( use_flashmem ) { - if ( lastpos != i && lastpos != 0) { - if ( i - lastpos < 0xF) { - s_point = i & 0xFFF0; - } - } else { - lastpos = i; - } - } - } - } + if ( use_flashmem ) { + if ( lastpos != i && lastpos != 0) { + if ( i - lastpos < 0xF) { + s_point = i & 0xFFF0; + } + } else { + lastpos = i; + } + } + } + } - // skip already found B keys - if( !found[(s*2)+1] ) { - chk_data.keyType = 1; - status = chkKey( &chk_data); - if ( status == 0 ) { - memcpy(k_sector[s].keyB, datain + i * 6, 6); - found[(s*2)+1] = 1; - ++foundkeys; + // skip already found B keys + if( !found[(s*2)+1] ) { + chk_data.keyType = 1; + status = chkKey( &chk_data); + if ( status == 0 ) { + memcpy(k_sector[s].keyB, datain + i * 6, 6); + found[(s*2)+1] = 1; + ++foundkeys; - chkKey_scanB(&chk_data, k_sector, found, §orcnt, &foundkeys); + chkKey_scanB(&chk_data, k_sector, found, §orcnt, &foundkeys); - if ( use_flashmem ) { - if ( lastpos != i && lastpos != 0) { + if ( use_flashmem ) { + if ( lastpos != i && lastpos != 0) { - if ( i - lastpos < 0xF) - s_point = i & 0xFFF0; - } else { - lastpos = i; - } - } - } - } + if ( i - lastpos < 0xF) + s_point = i & 0xFFF0; + } else { + lastpos = i; + } + } + } + } - if ( found[(s*2)] && found[(s*2)+1] ) - break; + if ( found[(s*2)] && found[(s*2)+1] ) + break; - } // end keys test loop - depth first + } // end keys test loop - depth first - // assume1. if no keys found in first sector, get next keychunk from client - if ( !use_flashmem && (newfound-foundkeys == 0) ) - goto OUT; + // assume1. if no keys found in first sector, get next keychunk from client + if ( !use_flashmem && (newfound-foundkeys == 0) ) + goto OUT; - } // end loop - sector - } // end strategy 1 + } // end loop - sector + } // end strategy 1 - if ( foundkeys == allkeys ) - goto OUT; + if ( foundkeys == allkeys ) + goto OUT; - if ( strategy == 2 || use_flashmem ) { + if ( strategy == 2 || use_flashmem ) { - // Keychunk loop - for (uint16_t i = 0; i < keyCount; i++) { + // Keychunk loop + for (uint16_t i = 0; i < keyCount; i++) { - // Allow button press / usb cmd to interrupt device - if (BUTTON_PRESS() && !usb_poll_validate_length()) break; + // Allow button press / usb cmd to interrupt device + if (BUTTON_PRESS() && !usb_poll_validate_length()) break; - // found all keys? - if ( foundkeys == allkeys ) - goto OUT; + // found all keys? + if ( foundkeys == allkeys ) + goto OUT; - WDT_HIT(); + WDT_HIT(); - // new key - chk_data.key = bytes_to_num(datain + i * 6, 6); + // new key + chk_data.key = bytes_to_num(datain + i * 6, 6); - // Sector main loop - // keep track of how many sectors on card. - for (uint8_t s = 0; s < sectorcnt; ++s) { + // Sector main loop + // keep track of how many sectors on card. + for (uint8_t s = 0; s < sectorcnt; ++s) { - if ( found[(s*2)] && found[(s*2)+1] ) continue; + if ( found[(s*2)] && found[(s*2)+1] ) continue; - // found all keys? - if ( foundkeys == allkeys ) - goto OUT; + // found all keys? + if ( foundkeys == allkeys ) + goto OUT; - // assume: block0,1,2 has more read rights in accessbits than the sectortrailer. authenticating against block0 in each sector - chk_data.block = FirstBlockOfSector( s ); + // assume: block0,1,2 has more read rights in accessbits than the sectortrailer. authenticating against block0 in each sector + chk_data.block = FirstBlockOfSector( s ); - // skip already found A keys - if( !found[(s*2)] ) { - chk_data.keyType = 0; - status = chkKey( &chk_data); - if ( status == 0 ) { - memcpy(k_sector[s].keyA, datain + i * 6, 6); - found[(s*2)] = 1; - ++foundkeys; + // skip already found A keys + if( !found[(s*2)] ) { + chk_data.keyType = 0; + status = chkKey( &chk_data); + if ( status == 0 ) { + memcpy(k_sector[s].keyA, datain + i * 6, 6); + found[(s*2)] = 1; + ++foundkeys; - chkKey_scanA( &chk_data, k_sector, found, §orcnt, &foundkeys); + chkKey_scanA( &chk_data, k_sector, found, §orcnt, &foundkeys); - // read Block B, if A is found. - chkKey_loopBonly( &chk_data, k_sector, found, §orcnt, &foundkeys); + // read Block B, if A is found. + chkKey_loopBonly( &chk_data, k_sector, found, §orcnt, &foundkeys); - chk_data.block = FirstBlockOfSector( s ); - } - } + chk_data.block = FirstBlockOfSector( s ); + } + } - // skip already found B keys - if( !found[(s*2)+1] ) { - chk_data.keyType = 1; - status = chkKey( &chk_data); - if ( status == 0 ) { - memcpy(k_sector[s].keyB, datain + i * 6, 6); - found[(s*2)+1] = 1; - ++foundkeys; + // skip already found B keys + if( !found[(s*2)+1] ) { + chk_data.keyType = 1; + status = chkKey( &chk_data); + if ( status == 0 ) { + memcpy(k_sector[s].keyB, datain + i * 6, 6); + found[(s*2)+1] = 1; + ++foundkeys; - chkKey_scanB(&chk_data, k_sector, found, §orcnt, &foundkeys); - } - } - } // end loop sectors - } // end loop keys - } // end loop strategy 2 + chkKey_scanB(&chk_data, k_sector, found, §orcnt, &foundkeys); + } + } + } // end loop sectors + } // end loop keys + } // end loop strategy 2 OUT: - LEDsoff(); + LEDsoff(); - crypto1_destroy(pcs); + crypto1_destroy(pcs); - // All keys found, send to client, or last keychunk from client - if (foundkeys == allkeys || lastchunk ) { + // All keys found, send to client, or last keychunk from client + if (foundkeys == allkeys || lastchunk ) { - uint64_t foo = 0; - for (uint8_t m = 0; m < 64; m++) { - foo |= ((uint64_t)(found[m] & 1) << m); - } + uint64_t foo = 0; + for (uint8_t m = 0; m < 64; m++) { + foo |= ((uint64_t)(found[m] & 1) << m); + } - uint16_t bar = 0; - uint8_t j = 0; - for (uint8_t m=64; m < sizeof(found); m++) { - bar |= ((uint16_t)(found[m] & 1) << j++); - } + uint16_t bar = 0; + uint8_t j = 0; + for (uint8_t m=64; m < sizeof(found); m++) { + bar |= ((uint16_t)(found[m] & 1) << j++); + } - uint8_t *tmp = BigBuf_malloc(480+10); - memcpy(tmp, k_sector, sectorcnt * sizeof(sector_t) ); - num_to_bytes(foo, 8, tmp+480); - tmp[488] = bar & 0xFF; - tmp[489] = bar >> 8 & 0xFF; + uint8_t *tmp = BigBuf_malloc(480+10); + memcpy(tmp, k_sector, sectorcnt * sizeof(sector_t) ); + num_to_bytes(foo, 8, tmp+480); + tmp[488] = bar & 0xFF; + tmp[489] = bar >> 8 & 0xFF; - cmd_send(CMD_ACK, foundkeys, 0, 0, tmp, 480+10); + cmd_send(CMD_ACK, foundkeys, 0, 0, tmp, 480+10); - set_tracing(false); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - BigBuf_free(); BigBuf_Clear_ext(false); - } else { - // partial/none keys found - cmd_send(CMD_ACK, foundkeys, 0, 0, 0, 0); - } + set_tracing(false); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + BigBuf_free(); BigBuf_Clear_ext(false); + } else { + // partial/none keys found + cmd_send(CMD_ACK, foundkeys, 0, 0, 0, 0); + } } void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - struct Crypto1State mpcs = {0, 0}; - struct Crypto1State *pcs; - pcs = &mpcs; + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; - uint8_t uid[10] = {0x00}; + uint8_t uid[10] = {0x00}; - uint64_t key = 0; - uint32_t cuid = 0; - int i, res; - uint8_t blockNo = arg0 & 0xFF; - uint8_t keyType = (arg0 >> 8) & 0xFF; - uint8_t keyCount = arg2; - uint8_t cascade_levels = 0; - uint8_t isOK = 0; - bool have_uid = false; - bool clearTrace = arg1 & 0xFF; + uint64_t key = 0; + uint32_t cuid = 0; + int i, res; + uint8_t blockNo = arg0 & 0xFF; + uint8_t keyType = (arg0 >> 8) & 0xFF; + uint8_t keyCount = arg2; + uint8_t cascade_levels = 0; + uint8_t isOK = 0; + bool have_uid = false; + bool clearTrace = arg1 & 0xFF; - LEDsoff(); - LED_A_ON(); + LEDsoff(); + LED_A_ON(); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - if (clearTrace) - clear_trace(); + if (clearTrace) + clear_trace(); - set_tracing(true); + set_tracing(true); - for (i = 0; i < keyCount; i++) { + for (i = 0; i < keyCount; i++) { - // Iceman: use piwi's faster nonce collecting part in hardnested. - if (!have_uid) { // need a full select cycle to get the uid first - iso14a_card_select_t card_info; - if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { - if (MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card (ALL)"); - --i; // try same key once again - continue; - } - switch (card_info.uidlen) { - case 4 : cascade_levels = 1; break; - case 7 : cascade_levels = 2; break; - case 10: cascade_levels = 3; break; - default: break; - } - have_uid = true; - } else { // no need for anticollision. We can directly select the card - if (!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels, true)) { - if (MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card (UID)"); - --i; // try same key once again - continue; - } - } + // Iceman: use piwi's faster nonce collecting part in hardnested. + if (!have_uid) { // need a full select cycle to get the uid first + iso14a_card_select_t card_info; + if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { + if (MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card (ALL)"); + --i; // try same key once again + continue; + } + switch (card_info.uidlen) { + case 4 : cascade_levels = 1; break; + case 7 : cascade_levels = 2; break; + case 10: cascade_levels = 3; break; + default: break; + } + have_uid = true; + } else { // no need for anticollision. We can directly select the card + if (!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels, true)) { + if (MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card (UID)"); + --i; // try same key once again + continue; + } + } - key = bytes_to_num(datain + i * 6, 6); - res = mifare_classic_auth(pcs, cuid, blockNo, keyType, key, AUTH_FIRST); + key = bytes_to_num(datain + i * 6, 6); + res = mifare_classic_auth(pcs, cuid, blockNo, keyType, key, AUTH_FIRST); - CHK_TIMEOUT(); + CHK_TIMEOUT(); - if (res) - continue; + if (res) + continue; - isOK = 1; - break; - } + isOK = 1; + break; + } - LED_B_ON(); + LED_B_ON(); cmd_send(CMD_ACK, isOK, 0, 0, datain + i * 6, 6); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); - set_tracing(false); - crypto1_destroy(pcs); + set_tracing(false); + crypto1_destroy(pcs); } //----------------------------------------------------------------------------- @@ -1576,8 +1576,8 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) { // //----------------------------------------------------------------------------- void MifareSetDbgLvl(uint16_t arg0){ - MF_DBGLEVEL = arg0; - Dbprintf("Debug level: %d", MF_DBGLEVEL); + MF_DBGLEVEL = arg0; + Dbprintf("Debug level: %d", MF_DBGLEVEL); } //----------------------------------------------------------------------------- @@ -1589,24 +1589,24 @@ void MifareSetDbgLvl(uint16_t arg0){ //----------------------------------------------------------------------------- void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){ - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - emlClearMem(); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + emlClearMem(); } void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){ - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - if (arg2==0) arg2 = 16; // backwards compat... default bytewidth - emlSetMem_xt(datain, arg0, arg1, arg2); // data, block num, blocks count, block byte width + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + if (arg2==0) arg2 = 16; // backwards compat... default bytewidth + emlSetMem_xt(datain, arg0, arg1, arg2); // data, block num, blocks count, block byte width } void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){ - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - byte_t buf[USB_CMD_DATA_SIZE] = {0x00}; - emlGetMem(buf, arg0, arg1); // data, block num, blocks count (max 4) + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + byte_t buf[USB_CMD_DATA_SIZE] = {0x00}; + emlGetMem(buf, arg0, arg1); // data, block num, blocks count (max 4) - LED_B_ON(); - cmd_send(CMD_ACK,arg0,arg1,0,buf,USB_CMD_DATA_SIZE); - LED_B_OFF(); + LED_B_ON(); + cmd_send(CMD_ACK,arg0,arg1,0,buf,USB_CMD_DATA_SIZE); + LED_B_OFF(); } //----------------------------------------------------------------------------- @@ -1614,82 +1614,82 @@ void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) // //----------------------------------------------------------------------------- void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){ - uint8_t numSectors = arg0; - uint8_t keyType = arg1; - uint64_t ui64Key = 0; - uint32_t cuid = 0; - struct Crypto1State mpcs = {0, 0}; - struct Crypto1State *pcs; - pcs = &mpcs; + uint8_t numSectors = arg0; + uint8_t keyType = arg1; + uint64_t ui64Key = 0; + uint32_t cuid = 0; + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; - // variables - byte_t dataoutbuf[16] = {0x00}; - byte_t dataoutbuf2[16] = {0x00}; - uint8_t uid[10] = {0x00}; + // variables + byte_t dataoutbuf[16] = {0x00}; + byte_t dataoutbuf2[16] = {0x00}; + uint8_t uid[10] = {0x00}; - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + LED_A_ON(); + LED_B_OFF(); + LED_C_OFF(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); + clear_trace(); + set_tracing(true); - bool isOK = true; + bool isOK = true; - if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - isOK = false; - if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); - } + if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { + isOK = false; + if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); + } - 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 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); - } - } - } + 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_halt(pcs, cuid)) - if (MF_DBGLEVEL >= 1) - Dbprintf("Halt error"); + if(mifare_classic_halt(pcs, cuid)) + if (MF_DBGLEVEL >= 1) + Dbprintf("Halt error"); - // ----------------------------- crypto1 destroy - crypto1_destroy(pcs); + // ----------------------------- crypto1 destroy + crypto1_destroy(pcs); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); - if (MF_DBGLEVEL >= 2) DbpString("EMUL FILL SECTORS FINISHED"); + if (MF_DBGLEVEL >= 2) DbpString("EMUL FILL SECTORS FINISHED"); - set_tracing(false); + set_tracing(false); } @@ -1712,359 +1712,359 @@ uint8_t wipeC[] = { MIFARE_MAGICWIPEC }; void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){ - // params - uint8_t workFlags = arg0; - uint8_t blockNo = arg1; + // params + uint8_t workFlags = arg0; + uint8_t blockNo = arg1; - // detect 1a/1b - bool is1b = false; + // detect 1a/1b + bool is1b = false; - // variables - bool isOK = false; //assume we will get an error - uint8_t errormsg = 0x00; - uint8_t uid[10] = {0x00}; - uint8_t data[18] = {0x00}; - uint32_t cuid = 0; + // variables + bool isOK = false; //assume we will get an error + uint8_t errormsg = 0x00; + uint8_t uid[10] = {0x00}; + uint8_t data[18] = {0x00}; + uint32_t cuid = 0; - uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; - uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; - if (workFlags & MAGIC_INIT) { - LED_A_ON(); - LED_B_OFF(); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); - } + if (workFlags & MAGIC_INIT) { + LED_A_ON(); + LED_B_OFF(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + set_tracing(true); + } - //loop doesn't loop just breaks out if error - while (true) { - // read UID and return to client with write - if (workFlags & MAGIC_UID) { - if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card"); - errormsg = MAGIC_UID; - } - mifare_classic_halt_ex(NULL); - break; - } + //loop doesn't loop just breaks out if error + while (true) { + // read UID and return to client with write + if (workFlags & MAGIC_UID) { + if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card"); + errormsg = MAGIC_UID; + } + mifare_classic_halt_ex(NULL); + break; + } - // wipe tag, fill it with zeros - if (workFlags & MAGIC_WIPE){ - ReaderTransmitBitsPar(wupC1, 7, NULL, NULL); - if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC1 error"); - errormsg = MAGIC_WIPE; - break; - } + // wipe tag, fill it with zeros + if (workFlags & MAGIC_WIPE){ + ReaderTransmitBitsPar(wupC1, 7, NULL, NULL); + if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC1 error"); + errormsg = MAGIC_WIPE; + break; + } - ReaderTransmit(wipeC, sizeof(wipeC), NULL); - if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wipeC error"); - errormsg = MAGIC_WIPE; - break; - } + ReaderTransmit(wipeC, sizeof(wipeC), NULL); + if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wipeC error"); + errormsg = MAGIC_WIPE; + break; + } - mifare_classic_halt_ex(NULL); - } + mifare_classic_halt_ex(NULL); + } - // write block - if (workFlags & MAGIC_WUPC) { - ReaderTransmitBitsPar(wupC1, 7, NULL, NULL); - if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC1 error"); - errormsg = MAGIC_WUPC; - break; - } + // write block + if (workFlags & MAGIC_WUPC) { + ReaderTransmitBitsPar(wupC1, 7, NULL, NULL); + if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC1 error"); + errormsg = MAGIC_WUPC; + break; + } - if ( !is1b ) { - ReaderTransmit(wupC2, sizeof(wupC2), NULL); - if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { - if (MF_DBGLEVEL >= MF_DBG_ALL) Dbprintf("Assuming Magic Gen 1B tag. [wupC2 failed]"); - is1b = true; - continue; - } - } - } + if ( !is1b ) { + ReaderTransmit(wupC2, sizeof(wupC2), NULL); + if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { + if (MF_DBGLEVEL >= MF_DBG_ALL) Dbprintf("Assuming Magic Gen 1B tag. [wupC2 failed]"); + is1b = true; + continue; + } + } + } - if ((mifare_sendcmd_short(NULL, 0, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("write block send command error"); - errormsg = 4; - break; - } + if ((mifare_sendcmd_short(NULL, 0, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("write block send command error"); + errormsg = 4; + break; + } - memcpy(data, datain, 16); - AddCrc14A(data, 16); + memcpy(data, datain, 16); + AddCrc14A(data, 16); - ReaderTransmit(data, sizeof(data), NULL); - if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("write block send data error"); - errormsg = 0; - break; - } + ReaderTransmit(data, sizeof(data), NULL); + if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("write block send data error"); + errormsg = 0; + break; + } - if (workFlags & MAGIC_HALT) - mifare_classic_halt_ex(NULL); + if (workFlags & MAGIC_HALT) + mifare_classic_halt_ex(NULL); - isOK = true; - break; + isOK = true; + break; - } // end while + } // end while - if (isOK ) - cmd_send(CMD_ACK,1,0,0,uid,sizeof(uid)); - else - OnErrorMagic(errormsg); + if (isOK ) + cmd_send(CMD_ACK,1,0,0,uid,sizeof(uid)); + else + OnErrorMagic(errormsg); - if (workFlags & MAGIC_OFF) - OnSuccessMagic(); + if (workFlags & MAGIC_OFF) + OnSuccessMagic(); } void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){ - uint8_t workFlags = arg0; - uint8_t blockNo = arg1; - uint8_t errormsg = 0x00; - bool isOK = false; //assume we will get an error + uint8_t workFlags = arg0; + uint8_t blockNo = arg1; + uint8_t errormsg = 0x00; + bool isOK = false; //assume we will get an error - // detect 1a/1b - bool is1b = false; + // detect 1a/1b + bool is1b = false; - // variables - uint8_t data[MAX_MIFARE_FRAME_SIZE]; - uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; - uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; + // variables + uint8_t data[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; - memset(data, 0x00, sizeof(data)); + memset(data, 0x00, sizeof(data)); - if (workFlags & MAGIC_INIT) { - LED_A_ON(); - LED_B_OFF(); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); - } + if (workFlags & MAGIC_INIT) { + LED_A_ON(); + LED_B_OFF(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + set_tracing(true); + } - //loop doesn't loop just breaks out if error or done - while (true) { - if (workFlags & MAGIC_WUPC) { - ReaderTransmitBitsPar(wupC1, 7, NULL, NULL); - if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC1 error"); - errormsg = MAGIC_WUPC; - break; - } + //loop doesn't loop just breaks out if error or done + while (true) { + if (workFlags & MAGIC_WUPC) { + ReaderTransmitBitsPar(wupC1, 7, NULL, NULL); + if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC1 error"); + errormsg = MAGIC_WUPC; + break; + } - if ( !is1b ) { - ReaderTransmit(wupC2, sizeof(wupC2), NULL); - if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { - if (MF_DBGLEVEL >= MF_DBG_ALL) Dbprintf("Assuming Magic Gen 1B tag. [wupC2 failed]"); - is1b = true; - continue; - } - } - } + if ( !is1b ) { + ReaderTransmit(wupC2, sizeof(wupC2), NULL); + if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { + if (MF_DBGLEVEL >= MF_DBG_ALL) Dbprintf("Assuming Magic Gen 1B tag. [wupC2 failed]"); + is1b = true; + continue; + } + } + } - // read block - if ((mifare_sendcmd_short(NULL, 0, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("read block send command error"); - errormsg = 0; - break; - } + // read block + if ((mifare_sendcmd_short(NULL, 0, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("read block send command error"); + errormsg = 0; + break; + } - memcpy(data, receivedAnswer, sizeof(data)); + memcpy(data, receivedAnswer, sizeof(data)); - // send HALT - if (workFlags & MAGIC_HALT) - mifare_classic_halt_ex(NULL); + // send HALT + if (workFlags & MAGIC_HALT) + mifare_classic_halt_ex(NULL); - isOK = true; - break; - } - // if MAGIC_DATAIN, the data stays on device side. - if (workFlags & MAGIC_DATAIN) { - if (isOK) - memcpy(datain, data, sizeof(data)); - } else { - if (isOK) - cmd_send(CMD_ACK,1,0,0,data,sizeof(data)); - else - OnErrorMagic(errormsg); - } + isOK = true; + break; + } + // if MAGIC_DATAIN, the data stays on device side. + if (workFlags & MAGIC_DATAIN) { + if (isOK) + memcpy(datain, data, sizeof(data)); + } else { + if (isOK) + cmd_send(CMD_ACK,1,0,0,data,sizeof(data)); + else + OnErrorMagic(errormsg); + } - if (workFlags & MAGIC_OFF) - OnSuccessMagic(); + if (workFlags & MAGIC_OFF) + OnSuccessMagic(); } void MifareCIdent(){ - #define GEN_1A 1 - #define GEN_1B 2 - #define GEN_2 4 - // variables - uint8_t isGen = 0; - uint8_t rec[1] = {0x00}; - uint8_t recpar[1] = {0x00}; + #define GEN_1A 1 + #define GEN_1B 2 + #define GEN_2 4 + // variables + uint8_t isGen = 0; + uint8_t rec[1] = {0x00}; + uint8_t recpar[1] = {0x00}; - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - // Generation 1 test - ReaderTransmitBitsPar(wupC1, 7, NULL, NULL); - if(!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { - goto TEST2; - }; - isGen = GEN_1B; + // Generation 1 test + ReaderTransmitBitsPar(wupC1, 7, NULL, NULL); + if(!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { + goto TEST2; + }; + isGen = GEN_1B; - ReaderTransmit(wupC2, sizeof(wupC2), NULL); - if(!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { - goto OUT; - }; - isGen = GEN_1A; - goto OUT; + ReaderTransmit(wupC2, sizeof(wupC2), NULL); + if(!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { + goto OUT; + }; + isGen = GEN_1A; + goto OUT; TEST2:; /* - // Generation 2 test + // Generation 2 test - // halt previous. - mifare_classic_halt(NULL, 0); + // halt previous. + mifare_classic_halt(NULL, 0); - //select - if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) { - goto OUT; - }; + //select + if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) { + goto OUT; + }; - // MIFARE_CLASSIC_WRITEBLOCK 0xA0 - // ACK 0x0a - uint16_t len = mifare_sendcmd_short(null, 1, 0xA0, 0, rec, recpar, NULL); - if ((len != 1) || (rec[0] != 0x0A)) { - isGen = GEN_2; - }; - */ + // MIFARE_CLASSIC_WRITEBLOCK 0xA0 + // ACK 0x0a + uint16_t len = mifare_sendcmd_short(null, 1, 0xA0, 0, rec, recpar, NULL); + if ((len != 1) || (rec[0] != 0x0A)) { + isGen = GEN_2; + }; + */ OUT:; - // removed the if, since some magic tags misbehavies and send an answer to it. - mifare_classic_halt_ex(NULL); - cmd_send(CMD_ACK, isGen, 0, 0, 0, 0); - // turns off - OnSuccessMagic(); + // removed the if, since some magic tags misbehavies and send an answer to it. + mifare_classic_halt_ex(NULL); + cmd_send(CMD_ACK, isGen, 0, 0, 0, 0); + // turns off + OnSuccessMagic(); } void OnSuccessMagic(){ - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - set_tracing(false); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + set_tracing(false); } void OnErrorMagic(uint8_t reason){ - // ACK, ISOK, reason,0,0,0 - cmd_send(CMD_ACK,0,reason,0,0,0); - OnSuccessMagic(); + // ACK, ISOK, reason,0,0,0 + cmd_send(CMD_ACK,0,reason,0,0,0); + OnSuccessMagic(); } void MifareSetMod(uint8_t mod, uint8_t *key) { - uint64_t ui64Key = bytes_to_num(key, 6); + uint64_t ui64Key = bytes_to_num(key, 6); - // variables - uint8_t isOK = 0; - uint8_t uid[10] = {0}; - uint32_t cuid = 0; - struct Crypto1State mpcs = {0, 0}; - struct Crypto1State *pcs = &mpcs; - int respLen = 0; - uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0}; - uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0}; + // variables + uint8_t isOK = 0; + uint8_t uid[10] = {0}; + uint32_t cuid = 0; + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs = &mpcs; + int respLen = 0; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0}; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0}; - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); + clear_trace(); + set_tracing(true); - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); + LED_A_ON(); + LED_B_OFF(); + LED_C_OFF(); - while (true) { - if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); - break; - } + while (true) { + if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); + break; + } - if(mifare_classic_auth(pcs, cuid, 0, 0, ui64Key, AUTH_FIRST)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Auth error"); - break; - } + if(mifare_classic_auth(pcs, cuid, 0, 0, ui64Key, AUTH_FIRST)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Auth error"); + break; + } - if (((respLen = mifare_sendcmd_short(pcs, 1, 0x43, mod, receivedAnswer, receivedAnswerPar, NULL)) != 1) || (receivedAnswer[0] != 0x0a)) { - if (MF_DBGLEVEL >= 1) Dbprintf("SetMod error; response[0]: %hhX, len: %d", receivedAnswer[0], respLen); - break; - } + if (((respLen = mifare_sendcmd_short(pcs, 1, 0x43, mod, receivedAnswer, receivedAnswerPar, NULL)) != 1) || (receivedAnswer[0] != 0x0a)) { + if (MF_DBGLEVEL >= 1) Dbprintf("SetMod error; response[0]: %hhX, len: %d", receivedAnswer[0], respLen); + break; + } - if(mifare_classic_halt(pcs, cuid)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); - break; - } + if(mifare_classic_halt(pcs, cuid)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); + break; + } - isOK = 1; - break; - } + isOK = 1; + break; + } - crypto1_destroy(pcs); + crypto1_destroy(pcs); - LED_B_ON(); - cmd_send(CMD_ACK, isOK, 0, 0, 0, 0); - LED_B_OFF(); + LED_B_ON(); + cmd_send(CMD_ACK, isOK, 0, 0, 0, 0); + LED_B_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); } // // DESFIRE // void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){ - byte_t dataout[12] = {0x00}; - uint8_t uid[10] = {0x00}; - uint32_t cuid = 0; + byte_t dataout[12] = {0x00}; + uint8_t uid[10] = {0x00}; + uint32_t cuid = 0; - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + set_tracing(true); - int len = iso14443a_select_card(uid, NULL, &cuid, true, 0, false); - if(!len) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card"); - OnError(1); - return; - }; + int len = iso14443a_select_card(uid, NULL, &cuid, true, 0, false); + if(!len) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card"); + OnError(1); + return; + }; - if(mifare_desfire_des_auth1(cuid, dataout)){ - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication part1: Fail."); - OnError(4); - return; - } + if(mifare_desfire_des_auth1(cuid, dataout)){ + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication part1: Fail."); + OnError(4); + return; + } - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 1 FINISHED"); + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 1 FINISHED"); cmd_send(CMD_ACK, 1, cuid, 0, dataout, sizeof(dataout)); } void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){ - uint32_t cuid = arg0; - uint8_t key[16] = {0x00}; - byte_t dataout[12] = {0x00}; - byte_t isOK = 0; + uint32_t cuid = arg0; + uint8_t key[16] = {0x00}; + byte_t dataout[12] = {0x00}; + byte_t isOK = 0; - memcpy(key, datain, 16); + memcpy(key, datain, 16); - isOK = mifare_desfire_des_auth2(cuid, key, dataout); + isOK = mifare_desfire_des_auth2(cuid, key, dataout); - if( isOK) { - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Authentication part2: Failed"); - OnError(4); - return; - } + if( isOK) { + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Authentication part2: Failed"); + OnError(4); + return; + } - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 2 FINISHED"); + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 2 FINISHED"); - cmd_send(CMD_ACK, isOK, 0, 0, dataout, sizeof(dataout)); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - set_tracing(false); + cmd_send(CMD_ACK, isOK, 0, 0, dataout, sizeof(dataout)); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + set_tracing(false); } \ No newline at end of file diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index 4cafca16c..e53ac0f59 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -18,189 +18,189 @@ static uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4}; bool InitDesfireCard(){ - iso14a_card_select_t card; + iso14a_card_select_t card; - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - set_tracing(true); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + set_tracing(true); - if (!iso14443a_select_card(NULL, &card, NULL, true, 0, false)) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) DbpString("Can't select card"); - OnError(1); - return false; - } - return true; + if (!iso14443a_select_card(NULL, &card, NULL, true, 0, false)) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) DbpString("Can't select card"); + OnError(1); + return false; + } + return true; } // ARG0 flag enums enum { - NONE = 0x00, - INIT = 0x01, - DISCONNECT = 0x02, - CLEARTRACE = 0x04, - BAR = 0x08, + NONE = 0x00, + INIT = 0x01, + DISCONNECT = 0x02, + CLEARTRACE = 0x04, + BAR = 0x08, } CmdOptions ; void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){ - /* ARG0 contains flags. - 0x01 = init card. - 0x02 = Disconnect - 0x03 - */ - uint8_t flags = arg0; - size_t datalen = arg1; - uint8_t resp[RECEIVE_SIZE]; - memset(resp,0,sizeof(resp)); + /* ARG0 contains flags. + 0x01 = init card. + 0x02 = Disconnect + 0x03 + */ + uint8_t flags = arg0; + size_t datalen = arg1; + uint8_t resp[RECEIVE_SIZE]; + memset(resp,0,sizeof(resp)); - if (MF_DBGLEVEL >= 4) { - Dbprintf(" flags : %02X", flags); - Dbprintf(" len : %02X", datalen); - print_result(" RX : ", datain, datalen); - } + if (MF_DBGLEVEL >= 4) { + Dbprintf(" flags : %02X", flags); + Dbprintf(" len : %02X", datalen); + print_result(" RX : ", datain, datalen); + } - if ( flags & CLEARTRACE ) - clear_trace(); + if ( flags & CLEARTRACE ) + clear_trace(); - if ( flags & INIT ){ - if ( !InitDesfireCard() ) - return; - } + if ( flags & INIT ){ + if ( !InitDesfireCard() ) + return; + } - int len = DesfireAPDU(datain, datalen, resp); - if (MF_DBGLEVEL >= 4) - print_result("ERR <--: ", resp, len); + int len = DesfireAPDU(datain, datalen, resp); + if (MF_DBGLEVEL >= 4) + print_result("ERR <--: ", resp, len); - if ( !len ) { - OnError(2); - return; - } + if ( !len ) { + OnError(2); + return; + } - // reset the pcb_blocknum, - pcb_blocknum = 0; + // reset the pcb_blocknum, + pcb_blocknum = 0; - if ( flags & DISCONNECT ) - OnSuccess(); + if ( flags & DISCONNECT ) + OnSuccess(); - cmd_send(CMD_ACK,1,len,0,resp,len); + cmd_send(CMD_ACK,1,len,0,resp,len); } void MifareDesfireGetInformation(){ - int len = 0; - iso14a_card_select_t card; - uint8_t resp[USB_CMD_DATA_SIZE] = {0x00}; - uint8_t dataout[USB_CMD_DATA_SIZE] = {0x00}; + int len = 0; + iso14a_card_select_t card; + uint8_t resp[USB_CMD_DATA_SIZE] = {0x00}; + uint8_t dataout[USB_CMD_DATA_SIZE] = {0x00}; - /* - 1 = PCB 1 - 2 = cid 2 - 3 = desfire command 3 - 4-5 = crc 4 key - 5-6 crc - PCB == 0x0A because sending CID byte. - CID == 0x00 first card? - */ - clear_trace(); - set_tracing(true); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + /* + 1 = PCB 1 + 2 = cid 2 + 3 = desfire command 3 + 4-5 = crc 4 key + 5-6 crc + PCB == 0x0A because sending CID byte. + CID == 0x00 first card? + */ + clear_trace(); + set_tracing(true); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - // card select - information - if ( !iso14443a_select_card(NULL, &card, NULL, true, 0, false) ) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) DbpString("Can't select card"); - OnError(1); - return; - } + // card select - information + if ( !iso14443a_select_card(NULL, &card, NULL, true, 0, false) ) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) DbpString("Can't select card"); + OnError(1); + return; + } - if ( card.uidlen != 7 ) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Wrong UID size. Expected 7byte got %d", card.uidlen); - OnError(2); - return; - } + if ( card.uidlen != 7 ) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Wrong UID size. Expected 7byte got %d", card.uidlen); + OnError(2); + return; + } - memcpy(dataout, card.uid, 7); + memcpy(dataout, card.uid, 7); - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); + LED_A_ON(); + LED_B_OFF(); + LED_C_OFF(); - uint8_t cmd[] = {GET_VERSION}; - size_t cmd_len = sizeof(cmd); + uint8_t cmd[] = {GET_VERSION}; + size_t cmd_len = sizeof(cmd); - len = DesfireAPDU(cmd, cmd_len, resp); - if ( !len ) { - print_result("ERROR <--: ", resp, len); - OnError(3); - return; - } + len = DesfireAPDU(cmd, cmd_len, resp); + if ( !len ) { + print_result("ERROR <--: ", resp, len); + OnError(3); + return; + } - LED_A_OFF(); - LED_B_ON(); - memcpy(dataout+7,resp+3,7); + LED_A_OFF(); + LED_B_ON(); + memcpy(dataout+7,resp+3,7); - // ADDITION_FRAME 1 - cmd[0] = ADDITIONAL_FRAME; - len = DesfireAPDU(cmd, cmd_len, resp); - if ( !len ) { - print_result("ERROR <--: ", resp, len); - OnError(3); - return; - } + // ADDITION_FRAME 1 + cmd[0] = ADDITIONAL_FRAME; + len = DesfireAPDU(cmd, cmd_len, resp); + if ( !len ) { + print_result("ERROR <--: ", resp, len); + OnError(3); + return; + } - LED_B_OFF(); - LED_C_ON(); - memcpy(dataout+7+7,resp+3,7); + LED_B_OFF(); + LED_C_ON(); + memcpy(dataout+7+7,resp+3,7); - // ADDITION_FRAME 2 - len = DesfireAPDU(cmd, cmd_len, resp); - if ( !len ) { - print_result("ERROR <--: ", resp, len); - OnError(3); - return; - } + // ADDITION_FRAME 2 + len = DesfireAPDU(cmd, cmd_len, resp); + if ( !len ) { + print_result("ERROR <--: ", resp, len); + OnError(3); + return; + } - memcpy(dataout+7+7+7,resp+3,14); + memcpy(dataout+7+7+7,resp+3,14); - cmd_send(CMD_ACK,1,0,0,dataout,sizeof(dataout)); + cmd_send(CMD_ACK,1,0,0,dataout,sizeof(dataout)); - // reset the pcb_blocknum, - pcb_blocknum = 0; - OnSuccess(); + // reset the pcb_blocknum, + pcb_blocknum = 0; + OnSuccess(); } void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain){ - int len = 0; - //uint8_t PICC_MASTER_KEY8[8] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47}; - uint8_t PICC_MASTER_KEY16[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f }; - uint8_t null_key_data8[8] = {0x00}; - //uint8_t null_key_data16[16] = {0x00}; - //uint8_t new_key_data8[8] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77}; - //uint8_t new_key_data16[16] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}; + int len = 0; + //uint8_t PICC_MASTER_KEY8[8] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47}; + uint8_t PICC_MASTER_KEY16[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f }; + uint8_t null_key_data8[8] = {0x00}; + //uint8_t null_key_data16[16] = {0x00}; + //uint8_t new_key_data8[8] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77}; + //uint8_t new_key_data16[16] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}; - uint8_t resp[256] = {0x00}; - uint8_t IV[16] = {0x00}; + uint8_t resp[256] = {0x00}; + uint8_t IV[16] = {0x00}; - size_t datalen = datain[0]; + size_t datalen = datain[0]; - uint8_t cmd[40] = {0x00}; - uint8_t encRndB[16] = {0x00}; - uint8_t decRndB[16] = {0x00}; - uint8_t nonce[16] = {0x00}; - uint8_t both[32] = {0x00}; - uint8_t encBoth[32] = {0x00}; + uint8_t cmd[40] = {0x00}; + uint8_t encRndB[16] = {0x00}; + uint8_t decRndB[16] = {0x00}; + uint8_t nonce[16] = {0x00}; + uint8_t both[32] = {0x00}; + uint8_t encBoth[32] = {0x00}; - InitDesfireCard(); + InitDesfireCard(); - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); + LED_A_ON(); + LED_B_OFF(); + LED_C_OFF(); - // 3 olika sätt att authenticera. AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32) - // 4 olika crypto algo DES, 3DES, 3K3DES, AES - // 3 olika kommunikations sätt, PLAIN,MAC,CRYPTO + // 3 olika sätt att authenticera. AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32) + // 4 olika crypto algo DES, 3DES, 3K3DES, AES + // 3 olika kommunikations sätt, PLAIN,MAC,CRYPTO - // des, nyckel 0, - switch (mode){ + // des, nyckel 0, + switch (mode){ case 1:{ uint8_t keybytes[16]; uint8_t RndA[8] = {0x00}; @@ -416,83 +416,83 @@ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain return; } } - break; - case 2: - //SendDesfireCommand(AUTHENTICATE_ISO, &keyno, resp); - break; - case 3:{ + break; + case 2: + //SendDesfireCommand(AUTHENTICATE_ISO, &keyno, resp); + break; + case 3:{ - //defaultkey - uint8_t keybytes[16] = {0x00}; - if (datain[1] == 0xff){ - memcpy(keybytes,PICC_MASTER_KEY16,16); - } else{ - memcpy(keybytes, datain+1, datalen); - } + //defaultkey + uint8_t keybytes[16] = {0x00}; + if (datain[1] == 0xff){ + memcpy(keybytes,PICC_MASTER_KEY16,16); + } else{ + memcpy(keybytes, datain+1, datalen); + } - struct desfire_key defaultkey = {0x00}; - desfirekey_t key = &defaultkey; - Desfire_aes_key_new( keybytes, key); + struct desfire_key defaultkey = {0x00}; + desfirekey_t key = &defaultkey; + Desfire_aes_key_new( keybytes, key); - AesCtx ctx; - if ( AesCtxIni(&ctx, IV, key->data, KEY128, CBC) < 0 ){ - if( MF_DBGLEVEL >= 4) { - DbpString("AES context failed to init"); - } - OnError(7); - return; - } + AesCtx ctx; + if ( AesCtxIni(&ctx, IV, key->data, KEY128, CBC) < 0 ){ + if( MF_DBGLEVEL >= 4) { + DbpString("AES context failed to init"); + } + OnError(7); + return; + } - cmd[0] = AUTHENTICATE_AES; - cmd[1] = 0x00; //keynumber - len = DesfireAPDU(cmd, 2, resp); - if ( !len ) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) { - DbpString("Authentication failed. Card timeout."); - } - OnError(3); - return; - } - - memcpy( encRndB, resp+3, 16); - - // dekryptera tagnonce. - AesDecrypt(&ctx, encRndB, decRndB, 16); - rol(decRndB,16); - memcpy(both, nonce,16); - memcpy(both+16, decRndB ,16 ); - AesEncrypt(&ctx, both, encBoth, 32 ); - - cmd[0] = ADDITIONAL_FRAME; - memcpy(cmd+1, encBoth, 32 ); - - len = DesfireAPDU(cmd, 33, resp); // 1 + 32 == 33 - if ( !len ) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) { - DbpString("Authentication failed. Card timeout."); - } + cmd[0] = AUTHENTICATE_AES; + cmd[1] = 0x00; //keynumber + len = DesfireAPDU(cmd, 2, resp); + if ( !len ) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) { + DbpString("Authentication failed. Card timeout."); + } OnError(3); - return; - } + return; + } - if ( resp[2] == 0x00 ){ - // Create AES Session key - struct desfire_key sessionKey = {0}; - desfirekey_t skey = &sessionKey; - Desfire_session_key_new( nonce, decRndB , key, skey ); - print_result("SESSION : ", skey->data, 16); - } else { - DbpString("Authentication failed."); - OnError(7); - return; - } + memcpy( encRndB, resp+3, 16); - break; - } - } + // dekryptera tagnonce. + AesDecrypt(&ctx, encRndB, decRndB, 16); + rol(decRndB,16); + memcpy(both, nonce,16); + memcpy(both+16, decRndB ,16 ); + AesEncrypt(&ctx, both, encBoth, 32 ); - OnSuccess(); - cmd_send(CMD_ACK,1,len,0,resp,len); + cmd[0] = ADDITIONAL_FRAME; + memcpy(cmd+1, encBoth, 32 ); + + len = DesfireAPDU(cmd, 33, resp); // 1 + 32 == 33 + if ( !len ) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) { + DbpString("Authentication failed. Card timeout."); + } + OnError(3); + return; + } + + if ( resp[2] == 0x00 ){ + // Create AES Session key + struct desfire_key sessionKey = {0}; + desfirekey_t skey = &sessionKey; + Desfire_session_key_new( nonce, decRndB , key, skey ); + print_result("SESSION : ", skey->data, 16); + } else { + DbpString("Authentication failed."); + OnError(7); + return; + } + + break; + } + } + + OnSuccess(); + cmd_send(CMD_ACK,1,len,0,resp,len); } // 3 olika ISO sätt att skicka data till DESFIRE (direkt, inkapslat, inkapslat ISO) @@ -501,71 +501,71 @@ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain // dataout = pointer to response data array int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){ - size_t len = 0; - size_t wrappedLen = 0; - uint8_t wCmd[USB_CMD_DATA_SIZE] = {0x00}; - uint8_t resp[MAX_FRAME_SIZE]; + size_t len = 0; + size_t wrappedLen = 0; + uint8_t wCmd[USB_CMD_DATA_SIZE] = {0x00}; + uint8_t resp[MAX_FRAME_SIZE]; uint8_t par[MAX_PARITY_SIZE]; - wrappedLen = CreateAPDU( cmd, cmd_len, wCmd); + wrappedLen = CreateAPDU( cmd, cmd_len, wCmd); - if (MF_DBGLEVEL >= 4) - print_result("WCMD <--: ", wCmd, wrappedLen); + if (MF_DBGLEVEL >= 4) + print_result("WCMD <--: ", wCmd, wrappedLen); - ReaderTransmit( wCmd, wrappedLen, NULL); + ReaderTransmit( wCmd, wrappedLen, NULL); - len = ReaderReceive(resp, par); - if ( !len ) { - if (MF_DBGLEVEL >= 4) Dbprintf("fukked"); - return false; //DATA LINK ERROR - } - // if we received an I- or R(ACK)-Block with a block number equal to the - // current block number, toggle the current block number - else if (len >= 4 // PCB+CID+CRC = 4 bytes - && ((resp[0] & 0xC0) == 0 // I-Block - || (resp[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0 - && (resp[0] & 0x01) == pcb_blocknum) // equal block numbers - { - pcb_blocknum ^= 1; //toggle next block - } + len = ReaderReceive(resp, par); + if ( !len ) { + if (MF_DBGLEVEL >= 4) Dbprintf("fukked"); + return false; //DATA LINK ERROR + } + // if we received an I- or R(ACK)-Block with a block number equal to the + // current block number, toggle the current block number + else if (len >= 4 // PCB+CID+CRC = 4 bytes + && ((resp[0] & 0xC0) == 0 // I-Block + || (resp[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0 + && (resp[0] & 0x01) == pcb_blocknum) // equal block numbers + { + pcb_blocknum ^= 1; //toggle next block + } - memcpy(dataout, resp, len); - return len; + memcpy(dataout, resp, len); + return len; } // CreateAPDU size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout){ - size_t cmdlen = MIN(len+4, USB_CMD_DATA_SIZE-1); + size_t cmdlen = MIN(len+4, USB_CMD_DATA_SIZE-1); - uint8_t cmd[cmdlen]; - memset(cmd, 0, cmdlen); + uint8_t cmd[cmdlen]; + memset(cmd, 0, cmdlen); - cmd[0] = 0x0A; // 0x0A = skicka cid, 0x02 = ingen cid. Särskilda bitar // - cmd[0] |= pcb_blocknum; // OR the block number into the PCB - cmd[1] = 0x00; // CID: 0x00 //TODO: allow multiple selected cards + cmd[0] = 0x0A; // 0x0A = skicka cid, 0x02 = ingen cid. Särskilda bitar // + cmd[0] |= pcb_blocknum; // OR the block number into the PCB + cmd[1] = 0x00; // CID: 0x00 //TODO: allow multiple selected cards - memcpy(cmd+2, datain, len); - AddCrc14A(cmd, len+2); + memcpy(cmd+2, datain, len); + AddCrc14A(cmd, len+2); - memcpy(dataout, cmd, cmdlen); + memcpy(dataout, cmd, cmdlen); - return cmdlen; + return cmdlen; } - // crc_update(&desfire_crc32, 0, 1); /* CMD_WRITE */ - // crc_update(&desfire_crc32, addr, addr_sz); - // crc_update(&desfire_crc32, byte, 8); - // uint32_t crc = crc_finish(&desfire_crc32); + // crc_update(&desfire_crc32, 0, 1); /* CMD_WRITE */ + // crc_update(&desfire_crc32, addr, addr_sz); + // crc_update(&desfire_crc32, byte, 8); + // uint32_t crc = crc_finish(&desfire_crc32); void OnSuccess(){ - pcb_blocknum = 0; - ReaderTransmit(deselect_cmd, 3 , NULL); - mifare_ultra_halt(); - switch_off(); + pcb_blocknum = 0; + ReaderTransmit(deselect_cmd, 3 , NULL); + mifare_ultra_halt(); + switch_off(); } void OnError(uint8_t reason){ - cmd_send(CMD_ACK,0,reason,0,0,0); - OnSuccess(); + cmd_send(CMD_ACK,0,reason,0,0,0); + OnSuccess(); } diff --git a/armsrc/mifaresniff.c b/armsrc/mifaresniff.c index 43e416086..cbdf3a99d 100644 --- a/armsrc/mifaresniff.c +++ b/armsrc/mifaresniff.c @@ -25,300 +25,300 @@ static uint32_t timerData = 0; //----------------------------------------------------------------------------- // "hf mf sniff" void RAMFUNC SniffMifare(uint8_t param) { - // param: - // bit 0 - trigger from first card answer - // bit 1 - trigger from first reader 7-bit request + // param: + // bit 0 - trigger from first card answer + // bit 1 - trigger from first reader 7-bit request - // C(red) A(yellow) B(green) - LEDsoff(); - iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER); + // C(red) A(yellow) B(green) + LEDsoff(); + iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER); - // Allocate memory from BigBuf for some buffers - // free all previous allocations first - BigBuf_free(); BigBuf_Clear_ext(false); - clear_trace(); - set_tracing(true); + // Allocate memory from BigBuf for some buffers + // free all previous allocations first + BigBuf_free(); BigBuf_Clear_ext(false); + clear_trace(); + set_tracing(true); - // The command (reader -> tag) that we're receiving. - uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE] = {0x00}; - uint8_t receivedCmdPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; + // The command (reader -> tag) that we're receiving. + uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE] = {0x00}; + uint8_t receivedCmdPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; - // The response (tag -> reader) that we're receiving. - uint8_t receivedResp[MAX_MIFARE_FRAME_SIZE] = {0x00}; - uint8_t receivedRespPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; + // The response (tag -> reader) that we're receiving. + uint8_t receivedResp[MAX_MIFARE_FRAME_SIZE] = {0x00}; + uint8_t receivedRespPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; - // allocate the DMA buffer, used to stream samples from the FPGA - uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); - uint8_t *data = dmaBuf; - uint8_t previous_data = 0; - int maxDataLen = 0; - int dataLen = 0; - bool ReaderIsActive = false; - bool TagIsActive = false; + // allocate the DMA buffer, used to stream samples from the FPGA + uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); + uint8_t *data = dmaBuf; + uint8_t previous_data = 0; + int maxDataLen = 0; + int dataLen = 0; + bool ReaderIsActive = false; + bool TagIsActive = false; - // 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 - // response from the tag. - // triggered == false -- to wait first for card - //bool triggered = !(param & 0x03); + // 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 + // response from the tag. + // triggered == false -- to wait first for card + //bool triggered = !(param & 0x03); - // Set up the demodulator for tag -> reader responses. - DemodInit(receivedResp, receivedRespPar); + // Set up the demodulator for tag -> reader responses. + DemodInit(receivedResp, receivedRespPar); - // Set up the demodulator for the reader -> tag commands - UartInit(receivedCmd, receivedCmdPar); + // Set up the demodulator for the reader -> tag commands + UartInit(receivedCmd, receivedCmdPar); - // Setup and start DMA. - // set transfer address and number of bytes. Start transfer. - if ( !FpgaSetupSscDma(dmaBuf, DMA_BUFFER_SIZE) ){ - if (MF_DBGLEVEL > 1) Dbprintf("[!] FpgaSetupSscDma failed. Exiting"); - return; - } + // Setup and start DMA. + // set transfer address and number of bytes. Start transfer. + if ( !FpgaSetupSscDma(dmaBuf, DMA_BUFFER_SIZE) ){ + if (MF_DBGLEVEL > 1) Dbprintf("[!] FpgaSetupSscDma failed. Exiting"); + return; + } - tUart* uart = GetUart(); - tDemod* demod = GetDemod(); + tUart* uart = GetUart(); + tDemod* demod = GetDemod(); - MfSniffInit(); + MfSniffInit(); - uint32_t sniffCounter = 0; + uint32_t sniffCounter = 0; // loop and listen - while (!BUTTON_PRESS()) { - WDT_HIT(); - LED_A_ON(); + while (!BUTTON_PRESS()) { + WDT_HIT(); + LED_A_ON(); /* - if ((sniffCounter & 0x0000FFFF) == 0) { // from time to time - // check if a transaction is completed (timeout after 2000ms). - // if yes, stop the DMA transfer and send what we have so far to the client - if (BigBuf_get_traceLen()) { - MfSniffSend(); - // Reset everything - we missed some sniffed data anyway while the DMA was stopped - sniffCounter = 0; - dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); - data = dmaBuf; - maxDataLen = 0; - ReaderIsActive = false; - TagIsActive = false; - FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); // set transfer address and number of bytes. Start transfer. - } - } - */ + if ((sniffCounter & 0x0000FFFF) == 0) { // from time to time + // check if a transaction is completed (timeout after 2000ms). + // if yes, stop the DMA transfer and send what we have so far to the client + if (BigBuf_get_traceLen()) { + MfSniffSend(); + // Reset everything - we missed some sniffed data anyway while the DMA was stopped + sniffCounter = 0; + dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); + data = dmaBuf; + maxDataLen = 0; + ReaderIsActive = false; + TagIsActive = false; + FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); // set transfer address and number of bytes. Start transfer. + } + } + */ - // number of bytes we have processed so far - int register readBufDataP = data - dmaBuf; - // number of bytes already transferred - int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR; - if (readBufDataP <= dmaBufDataP) // we are processing the same block of data which is currently being transferred - dataLen = dmaBufDataP - readBufDataP; // number of bytes still to be processed - else - dataLen = DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP; // number of bytes still to be processed + // number of bytes we have processed so far + int register readBufDataP = data - dmaBuf; + // number of bytes already transferred + int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR; + if (readBufDataP <= dmaBufDataP) // we are processing the same block of data which is currently being transferred + dataLen = dmaBufDataP - readBufDataP; // number of bytes still to be processed + else + dataLen = DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP; // number of bytes still to be processed - // test for length of buffer - if (dataLen > maxDataLen) { // we are more behind than ever... - maxDataLen = dataLen; - if (dataLen > (9 * DMA_BUFFER_SIZE / 10)) { - Dbprintf("[!] blew circular buffer! | datalen %u", dataLen); - break; - } - } - if (dataLen < 1) continue; + // test for length of buffer + if (dataLen > maxDataLen) { // we are more behind than ever... + maxDataLen = dataLen; + if (dataLen > (9 * DMA_BUFFER_SIZE / 10)) { + Dbprintf("[!] blew circular buffer! | datalen %u", dataLen); + break; + } + } + if (dataLen < 1) continue; - // primary buffer was stopped ( <-- we lost data! - 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 | data length %d", dataLen); // temporary - } - // secondary buffer sets as primary, secondary buffer was stopped - if (!AT91C_BASE_PDC_SSC->PDC_RNCR) { - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)dmaBuf; - AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; - } + // primary buffer was stopped ( <-- we lost data! + 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 | data length %d", dataLen); // temporary + } + // secondary buffer sets as primary, secondary buffer was stopped + if (!AT91C_BASE_PDC_SSC->PDC_RNCR) { + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)dmaBuf; + AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; + } - LED_A_OFF(); + LED_A_OFF(); - // Need two samples to feed Miller and Manchester-Decoder - if (sniffCounter & 0x01) { + // Need two samples to feed Miller and Manchester-Decoder + if (sniffCounter & 0x01) { - // no need to try decoding tag data if the reader is sending - if (!TagIsActive) { - uint8_t readerbyte = (previous_data & 0xF0) | (*data >> 4); - if (MillerDecoding(readerbyte, (sniffCounter-1)*4)) { - LogTrace(receivedCmd, uart->len, 0, 0, NULL, true); - DemodReset(); - UartReset(); - } - ReaderIsActive = (uart->state != STATE_UNSYNCD); - } + // no need to try decoding tag data if the reader is sending + if (!TagIsActive) { + uint8_t readerbyte = (previous_data & 0xF0) | (*data >> 4); + if (MillerDecoding(readerbyte, (sniffCounter-1)*4)) { + LogTrace(receivedCmd, uart->len, 0, 0, NULL, true); + DemodReset(); + UartReset(); + } + ReaderIsActive = (uart->state != STATE_UNSYNCD); + } - // no need to try decoding tag data if the reader is sending - if (!ReaderIsActive) { - uint8_t tagbyte = (previous_data << 4) | (*data & 0x0F); - if (ManchesterDecoding(tagbyte, 0, (sniffCounter-1)*4)) { - LogTrace(receivedResp, demod->len, 0, 0, NULL, false); - DemodReset(); - UartReset(); - } - TagIsActive = (demod->state != DEMOD_UNSYNCD); - } - } - previous_data = *data; - sniffCounter++; - data++; + // no need to try decoding tag data if the reader is sending + if (!ReaderIsActive) { + uint8_t tagbyte = (previous_data << 4) | (*data & 0x0F); + if (ManchesterDecoding(tagbyte, 0, (sniffCounter-1)*4)) { + LogTrace(receivedResp, demod->len, 0, 0, NULL, false); + DemodReset(); + UartReset(); + } + TagIsActive = (demod->state != DEMOD_UNSYNCD); + } + } + previous_data = *data; + sniffCounter++; + data++; - if (data == dmaBuf + DMA_BUFFER_SIZE) - data = dmaBuf; + if (data == dmaBuf + DMA_BUFFER_SIZE) + data = dmaBuf; - } // main cycle + } // main cycle - MfSniffEnd(); - switch_off(); + MfSniffEnd(); + switch_off(); } void MfSniffInit(void){ - memset(sniffUID, 0x00, sizeof(sniffUID)); - memset(sniffATQA, 0x00, sizeof(sniffATQA)); - memset(sniffBuf, 0x00, sizeof(sniffBuf)); - sniffSAK = 0; - sniffUIDType = SNF_UID_4; - timerData = 0; + memset(sniffUID, 0x00, sizeof(sniffUID)); + memset(sniffATQA, 0x00, sizeof(sniffATQA)); + memset(sniffBuf, 0x00, sizeof(sniffBuf)); + sniffSAK = 0; + sniffUIDType = SNF_UID_4; + timerData = 0; } void MfSniffEnd(void){ - LED_B_ON(); - cmd_send(CMD_ACK,0,0,0,0,0); - LED_B_OFF(); + LED_B_ON(); + cmd_send(CMD_ACK,0,0,0,0,0); + LED_B_OFF(); } /* bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, uint16_t bitCnt, bool reader) { - // reset on 7-Bit commands from reader - if (reader && (len == 1) && (bitCnt == 7)) { - sniffState = SNF_INIT; - } + // reset on 7-Bit commands from reader + if (reader && (len == 1) && (bitCnt == 7)) { + sniffState = SNF_INIT; + } - switch (sniffState) { - case SNF_INIT:{ - // REQA,WUPA or MAGICWUP from reader - if ((len == 1) && (reader) && (bitCnt == 7) ) { - MfSniffInit(); - sniffState = (data[0] == MIFARE_MAGICWUPC1) ? SNF_MAGIC_WUPC2 : SNF_ATQA; - } - break; - } - case SNF_MAGIC_WUPC2: { - if ((len == 1) && (reader) && (data[0] == MIFARE_MAGICWUPC2) ) { - sniffState = SNF_CARD_IDLE; - } - break; - } - case SNF_ATQA:{ - // ATQA from tag - if ((!reader) && (len == 2)) { - sniffATQA[0] = data[0]; - sniffATQA[1] = data[1]; - sniffState = SNF_UID; - } - break; - } - case SNF_UID: { + switch (sniffState) { + case SNF_INIT:{ + // REQA,WUPA or MAGICWUP from reader + if ((len == 1) && (reader) && (bitCnt == 7) ) { + MfSniffInit(); + sniffState = (data[0] == MIFARE_MAGICWUPC1) ? SNF_MAGIC_WUPC2 : SNF_ATQA; + } + break; + } + case SNF_MAGIC_WUPC2: { + if ((len == 1) && (reader) && (data[0] == MIFARE_MAGICWUPC2) ) { + sniffState = SNF_CARD_IDLE; + } + break; + } + case SNF_ATQA:{ + // ATQA from tag + if ((!reader) && (len == 2)) { + sniffATQA[0] = data[0]; + sniffATQA[1] = data[1]; + sniffState = SNF_UID; + } + break; + } + case SNF_UID: { - if ( !reader ) break; - if ( len != 9 ) break; - if ( !CheckCrc14443(CRC_14443_A, data, 9)) break; - if ( data[1] != 0x70 ) break; + if ( !reader ) break; + if ( len != 9 ) break; + if ( !CheckCrc14443(CRC_14443_A, data, 9)) break; + if ( data[1] != 0x70 ) break; - Dbprintf("[!] UID | %x", data[0]); + Dbprintf("[!] UID | %x", data[0]); - if ((data[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT)) { - // UID_4 - select 4 Byte UID from reader - memcpy(sniffUID, data+2, 4); - sniffUIDType = SNF_UID_4; - sniffState = SNF_SAK; - } else if ((data[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2)) { - // UID_7 - Select 2nd part of 7 Byte UID + if ((data[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT)) { + // UID_4 - select 4 Byte UID from reader + memcpy(sniffUID, data+2, 4); + sniffUIDType = SNF_UID_4; + sniffState = SNF_SAK; + } else if ((data[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2)) { + // UID_7 - Select 2nd part of 7 Byte UID - // get rid of 0x88 - sniffUID[0] = sniffUID[1]; - sniffUID[1] = sniffUID[2]; - sniffUID[2] = sniffUID[3]; - //new uid bytes - memcpy(sniffUID+3, data+2, 4); - sniffUIDType = SNF_UID_7; - sniffState = SNF_SAK; - } else if ((data[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3)) { - // UID_10 - Select 3nd part of 10 Byte UID - // 3+3+4 = 10. - // get ride of previous 0x88 - sniffUID[3] = sniffUID[4]; - sniffUID[4] = sniffUID[5]; - sniffUID[5] = sniffUID[6]; - // new uid bytes - memcpy(sniffUID+6, data+2, 4); - sniffUIDType = SNF_UID_10; - sniffState = SNF_SAK; - } - break; - } - case SNF_SAK:{ - // SAK from card? - if ((!reader) && (len == 3) && (CheckCrc14443(CRC_14443_A, data, 3))) { - sniffSAK = data[0]; - // CL2 UID part to be expected - if (( sniffSAK == 0x04) && (sniffUIDType == SNF_UID_4)) { - sniffState = SNF_UID; - // CL3 UID part to be expected - } else if ((sniffSAK == 0x04) && (sniffUIDType == SNF_UID_7)) { - sniffState = SNF_UID; - } else { - // select completed - sniffState = SNF_CARD_IDLE; - } - } - break; - } - case SNF_CARD_IDLE:{ // trace the card select sequence - sniffBuf[0] = 0xFF; - sniffBuf[1] = 0xFF; - memcpy(sniffBuf + 2, sniffUID, sizeof(sniffUID)); - memcpy(sniffBuf + 12, sniffATQA, sizeof(sniffATQA)); - sniffBuf[14] = sniffSAK; - sniffBuf[15] = 0xFF; - sniffBuf[16] = 0xFF; - LogTrace(sniffBuf, sizeof(sniffBuf), 0, 0, NULL, true); - sniffState = SNF_CARD_CMD; - } // intentionally no break; - case SNF_CARD_CMD:{ - LogTrace(data, len, 0, 0, NULL, reader); - timerData = GetTickCount(); - break; - } - default: - sniffState = SNF_INIT; - break; - } - return false; + // get rid of 0x88 + sniffUID[0] = sniffUID[1]; + sniffUID[1] = sniffUID[2]; + sniffUID[2] = sniffUID[3]; + //new uid bytes + memcpy(sniffUID+3, data+2, 4); + sniffUIDType = SNF_UID_7; + sniffState = SNF_SAK; + } else if ((data[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3)) { + // UID_10 - Select 3nd part of 10 Byte UID + // 3+3+4 = 10. + // get ride of previous 0x88 + sniffUID[3] = sniffUID[4]; + sniffUID[4] = sniffUID[5]; + sniffUID[5] = sniffUID[6]; + // new uid bytes + memcpy(sniffUID+6, data+2, 4); + sniffUIDType = SNF_UID_10; + sniffState = SNF_SAK; + } + break; + } + case SNF_SAK:{ + // SAK from card? + if ((!reader) && (len == 3) && (CheckCrc14443(CRC_14443_A, data, 3))) { + sniffSAK = data[0]; + // CL2 UID part to be expected + if (( sniffSAK == 0x04) && (sniffUIDType == SNF_UID_4)) { + sniffState = SNF_UID; + // CL3 UID part to be expected + } else if ((sniffSAK == 0x04) && (sniffUIDType == SNF_UID_7)) { + sniffState = SNF_UID; + } else { + // select completed + sniffState = SNF_CARD_IDLE; + } + } + break; + } + case SNF_CARD_IDLE:{ // trace the card select sequence + sniffBuf[0] = 0xFF; + sniffBuf[1] = 0xFF; + memcpy(sniffBuf + 2, sniffUID, sizeof(sniffUID)); + memcpy(sniffBuf + 12, sniffATQA, sizeof(sniffATQA)); + sniffBuf[14] = sniffSAK; + sniffBuf[15] = 0xFF; + sniffBuf[16] = 0xFF; + LogTrace(sniffBuf, sizeof(sniffBuf), 0, 0, NULL, true); + sniffState = SNF_CARD_CMD; + } // intentionally no break; + case SNF_CARD_CMD:{ + LogTrace(data, len, 0, 0, NULL, reader); + timerData = GetTickCount(); + break; + } + default: + sniffState = SNF_INIT; + break; + } + return false; } */ void RAMFUNC MfSniffSend() { - uint16_t tracelen = BigBuf_get_traceLen(); - uint16_t chunksize = 0; - int packlen = tracelen; // total number of bytes to send - uint8_t *data = BigBuf_get_addr(); + uint16_t tracelen = BigBuf_get_traceLen(); + uint16_t chunksize = 0; + int packlen = tracelen; // total number of bytes to send + uint8_t *data = BigBuf_get_addr(); - while (packlen > 0) { - LED_B_ON(); - chunksize = MIN(USB_CMD_DATA_SIZE, packlen); // chunk size 512 - cmd_send(CMD_ACK, 1, tracelen, chunksize, data + tracelen - packlen, chunksize); - packlen -= chunksize; - LED_B_OFF(); - } + while (packlen > 0) { + LED_B_ON(); + chunksize = MIN(USB_CMD_DATA_SIZE, packlen); // chunk size 512 + cmd_send(CMD_ACK, 1, tracelen, chunksize, data + tracelen - packlen, chunksize); + packlen -= chunksize; + LED_B_OFF(); + } - LED_B_ON(); - cmd_send(CMD_ACK, 2, 0, 0, 0, 0); // 2 == data transfer finished. - LED_B_OFF(); + LED_B_ON(); + cmd_send(CMD_ACK, 2, 0, 0, 0, 0); // 2 == data transfer finished. + LED_B_OFF(); } \ No newline at end of file diff --git a/armsrc/mifaresniff.h b/armsrc/mifaresniff.h index efd34fdeb..debfd5a09 100644 --- a/armsrc/mifaresniff.h +++ b/armsrc/mifaresniff.h @@ -21,18 +21,18 @@ #include "mifareutil.h" #include "common.h" -#define SNF_INIT 0 -#define SNF_NO_FIELD 1 -#define SNF_ATQA 2 -#define SNF_UID 3 -#define SNF_SAK 4 -#define SNF_CARD_IDLE 5 -#define SNF_CARD_CMD 6 -#define SNF_MAGIC_WUPC2 7 +#define SNF_INIT 0 +#define SNF_NO_FIELD 1 +#define SNF_ATQA 2 +#define SNF_UID 3 +#define SNF_SAK 4 +#define SNF_CARD_IDLE 5 +#define SNF_CARD_CMD 6 +#define SNF_MAGIC_WUPC2 7 -#define SNF_UID_4 0 -#define SNF_UID_7 0 -#define SNF_UID_10 0 +#define SNF_UID_4 0 +#define SNF_UID_7 0 +#define SNF_UID_10 0 void MfSniffInit(void); bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, uint16_t bitCnt, bool reader); diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 86048ae88..f15d13dec 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -14,676 +14,676 @@ int MF_DBGLEVEL = MF_DBG_ERROR; // crypto1 helpers void mf_crypto1_decryptEx(struct Crypto1State *pcs, uint8_t *data_in, int len, uint8_t *data_out){ - uint8_t bt = 0; - int i; + uint8_t bt = 0; + int i; - if (len != 1) { - for (i = 0; i < len; i++) - data_out[i] = crypto1_byte(pcs, 0x00, 0) ^ data_in[i]; - } else { - bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data_in[0], 0)) << 0; - bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data_in[0], 1)) << 1; - bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data_in[0], 2)) << 2; - bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data_in[0], 3)) << 3; - data_out[0] = bt; - } - return; + if (len != 1) { + for (i = 0; i < len; i++) + data_out[i] = crypto1_byte(pcs, 0x00, 0) ^ data_in[i]; + } else { + bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data_in[0], 0)) << 0; + bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data_in[0], 1)) << 1; + bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data_in[0], 2)) << 2; + bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data_in[0], 3)) << 3; + data_out[0] = bt; + } + return; } void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len){ - mf_crypto1_decryptEx(pcs, data, len, data); + mf_crypto1_decryptEx(pcs, data, len, data); } void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par) { - uint8_t bt = 0; - int i; - par[0] = 0; + uint8_t bt = 0; + int i; + par[0] = 0; - for (i = 0; i < len; i++) { - bt = data[i]; - data[i] = crypto1_byte(pcs, 0x00, 0) ^ data[i]; - if ( ( i & 0x0007 ) == 0) - par[ i >> 3 ] = 0; - par[ i >> 3 ] |= (((filter(pcs->odd) ^ oddparity8(bt)) & 0x01)<<(7-(i&0x0007))); - } + for (i = 0; i < len; i++) { + bt = data[i]; + data[i] = crypto1_byte(pcs, 0x00, 0) ^ data[i]; + if ( ( i & 0x0007 ) == 0) + par[ i >> 3 ] = 0; + par[ i >> 3 ] |= (((filter(pcs->odd) ^ oddparity8(bt)) & 0x01)<<(7-(i&0x0007))); + } } uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data) { - uint8_t bt = 0; - bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data, 0)) << 0; - bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data, 1)) << 1; - bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data, 2)) << 2; - bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data, 3)) << 3; - return bt; + uint8_t bt = 0; + bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data, 0)) << 0; + bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data, 1)) << 1; + bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data, 2)) << 2; + bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data, 3)) << 3; + return bt; } // send X byte basic commands int mifare_sendcmd(uint8_t cmd, uint8_t* data, uint8_t data_size, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing) { - uint8_t dcmd[data_size+3]; + uint8_t dcmd[data_size+3]; dcmd[0] = cmd; - memcpy(dcmd+1, data, data_size); - AddCrc14A(dcmd, data_size+1); - ReaderTransmit(dcmd, sizeof(dcmd), timing); - int len = ReaderReceive(answer, answer_parity); - if(!len) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("%02X Cmd failed. Card timeout.", cmd); - len = ReaderReceive(answer,answer_parity); + memcpy(dcmd+1, data, data_size); + AddCrc14A(dcmd, data_size+1); + ReaderTransmit(dcmd, sizeof(dcmd), timing); + int len = ReaderReceive(answer, answer_parity); + if(!len) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("%02X Cmd failed. Card timeout.", cmd); + len = ReaderReceive(answer,answer_parity); } - return len; + return len; } // send 2 byte commands int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) { - uint16_t pos, res; - uint8_t dcmd[4] = {cmd, data, 0x00, 0x00}; - uint8_t ecmd[4] = {0x00, 0x00, 0x00, 0x00}; - uint8_t par[1] = {0x00}; // 1 Byte parity is enough here - AddCrc14A(dcmd, 2); - memcpy(ecmd, dcmd, sizeof(dcmd)); + uint16_t pos, res; + uint8_t dcmd[4] = {cmd, data, 0x00, 0x00}; + uint8_t ecmd[4] = {0x00, 0x00, 0x00, 0x00}; + uint8_t par[1] = {0x00}; // 1 Byte parity is enough here + AddCrc14A(dcmd, 2); + memcpy(ecmd, dcmd, sizeof(dcmd)); - if (crypted) { - par[0] = 0; - for (pos = 0; pos < 4; pos++) { - ecmd[pos] = crypto1_byte(pcs, 0x00, 0) ^ dcmd[pos]; - par[0] |= (((filter(pcs->odd) ^ oddparity8(dcmd[pos])) & 0x01) << (7-pos)); - } - ReaderTransmitPar(ecmd, sizeof(ecmd), par, timing); - } else { - ReaderTransmit(dcmd, sizeof(dcmd), timing); - } + if (crypted) { + par[0] = 0; + for (pos = 0; pos < 4; pos++) { + ecmd[pos] = crypto1_byte(pcs, 0x00, 0) ^ dcmd[pos]; + par[0] |= (((filter(pcs->odd) ^ oddparity8(dcmd[pos])) & 0x01) << (7-pos)); + } + ReaderTransmitPar(ecmd, sizeof(ecmd), par, timing); + } else { + ReaderTransmit(dcmd, sizeof(dcmd), timing); + } - int len = ReaderReceive(answer, par); + int len = ReaderReceive(answer, par); - if (answer_parity) *answer_parity = par[0]; + if (answer_parity) *answer_parity = par[0]; - if (crypted == CRYPT_ALL) { - if (len == 1) { - res = 0; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(answer[0], 0)) << 0; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(answer[0], 1)) << 1; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(answer[0], 2)) << 2; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(answer[0], 3)) << 3; - answer[0] = res; - } else { - for (pos = 0; pos < len; pos++) - answer[pos] = crypto1_byte(pcs, 0x00, 0) ^ answer[pos]; - } - } - return len; + if (crypted == CRYPT_ALL) { + if (len == 1) { + res = 0; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(answer[0], 0)) << 0; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(answer[0], 1)) << 1; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(answer[0], 2)) << 2; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(answer[0], 3)) << 3; + answer[0] = res; + } else { + for (pos = 0; pos < len; pos++) + answer[pos] = crypto1_byte(pcs, 0x00, 0) ^ answer[pos]; + } + } + return len; } // mifare classic commands int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested) { - return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL); + return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL); } int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing) { - int len; - uint32_t pos, nt, ntpp; // Supplied tag nonce - uint8_t par[1] = {0x00}; - uint8_t nr[4]; - uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; - uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; + int len; + uint32_t pos, nt, ntpp; // Supplied tag nonce + uint8_t par[1] = {0x00}; + uint8_t nr[4]; + uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; - // "random" reader nonce: - num_to_bytes( prng_successor( GetTickCount(), 32), 4, nr); + // "random" reader nonce: + num_to_bytes( prng_successor( GetTickCount(), 32), 4, nr); - // Transmit MIFARE_CLASSIC_AUTH - len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, receivedAnswerPar, timing); - if (len != 4) return 1; + // Transmit MIFARE_CLASSIC_AUTH + len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, receivedAnswerPar, timing); + if (len != 4) return 1; - // Save the tag nonce (nt) - nt = bytes_to_num(receivedAnswer, 4); + // Save the tag nonce (nt) + nt = bytes_to_num(receivedAnswer, 4); - // ----------------------------- crypto1 create - if (isNested) - crypto1_destroy(pcs); + // ----------------------------- crypto1 create + if (isNested) + crypto1_destroy(pcs); - // Init cipher with key - crypto1_create(pcs, ui64Key); + // Init cipher with key + crypto1_create(pcs, ui64Key); - if (isNested == AUTH_NESTED) { - // decrypt nt with help of new key - nt = crypto1_word(pcs, nt ^ uid, 1) ^ nt; - } else { - // Load (plain) uid^nt into the cipher - crypto1_word(pcs, nt ^ uid, 0); - } + if (isNested == AUTH_NESTED) { + // decrypt nt with help of new key + nt = crypto1_word(pcs, nt ^ uid, 1) ^ nt; + } else { + // Load (plain) uid^nt into the cipher + crypto1_word(pcs, nt ^ uid, 0); + } - // some statistic - if (!ntptr && (MF_DBGLEVEL >= MF_DBG_EXTENDED)) - Dbprintf("auth uid: %08x | nr: %08x | nt: %08x", uid, nr, nt); + // some statistic + if (!ntptr && (MF_DBGLEVEL >= MF_DBG_EXTENDED)) + Dbprintf("auth uid: %08x | nr: %08x | nt: %08x", uid, nr, nt); - // save Nt - if (ntptr) - *ntptr = nt; + // save Nt + if (ntptr) + *ntptr = nt; - // Generate (encrypted) nr+parity by loading it into the cipher (Nr) - par[0] = 0; - for (pos = 0; pos < 4; pos++) { - mf_nr_ar[pos] = crypto1_byte(pcs, nr[pos], 0) ^ nr[pos]; - par[0] |= (((filter(pcs->odd) ^ oddparity8(nr[pos])) & 0x01) << (7-pos)); - } + // Generate (encrypted) nr+parity by loading it into the cipher (Nr) + par[0] = 0; + for (pos = 0; pos < 4; pos++) { + mf_nr_ar[pos] = crypto1_byte(pcs, nr[pos], 0) ^ nr[pos]; + par[0] |= (((filter(pcs->odd) ^ oddparity8(nr[pos])) & 0x01) << (7-pos)); + } - // Skip 32 bits in pseudo random generator - nt = prng_successor(nt, 32); + // Skip 32 bits in pseudo random generator + nt = prng_successor(nt, 32); - // ar+parity - for (pos = 4; pos < 8; pos++) { - nt = prng_successor(nt,8); - mf_nr_ar[pos] = crypto1_byte(pcs,0x00,0) ^ (nt & 0xff); - par[0] |= (((filter(pcs->odd) ^ oddparity8(nt & 0xff)) & 0x01) << (7-pos)); - } + // ar+parity + for (pos = 4; pos < 8; pos++) { + nt = prng_successor(nt,8); + mf_nr_ar[pos] = crypto1_byte(pcs,0x00,0) ^ (nt & 0xff); + par[0] |= (((filter(pcs->odd) ^ oddparity8(nt & 0xff)) & 0x01) << (7-pos)); + } - // Transmit reader nonce and reader answer - ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL); + // Transmit reader nonce and reader answer + ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL); - // Receive 4 byte tag answer - len = ReaderReceive(receivedAnswer, receivedAnswerPar); - if (!len) { - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Authentication failed. Card timeout."); - return 2; - } + // Receive 4 byte tag answer + len = ReaderReceive(receivedAnswer, receivedAnswerPar); + if (!len) { + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Authentication failed. Card timeout."); + return 2; + } - ntpp = prng_successor(nt, 32) ^ crypto1_word(pcs, 0,0); + ntpp = prng_successor(nt, 32) ^ crypto1_word(pcs, 0,0); - if (ntpp != bytes_to_num(receivedAnswer, 4)) { - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Authentication failed. Error card response."); - return 3; - } - return 0; + if (ntpp != bytes_to_num(receivedAnswer, 4)) { + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Authentication failed. Error card response."); + return 3; + } + return 0; } int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) { - int len; - uint8_t bt[2] = {0x00, 0x00}; - uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; - uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; + int len; + uint8_t bt[2] = {0x00, 0x00}; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; - len = mifare_sendcmd_short(pcs, 1, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); - if (len == 1) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); - return 1; - } - if (len != 18) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: wrong response len: %x (expected 18)", len); - return 2; - } + len = mifare_sendcmd_short(pcs, 1, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); + if (len == 1) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); + return 1; + } + if (len != 18) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: wrong response len: %x (expected 18)", len); + return 2; + } - memcpy(bt, receivedAnswer + 16, 2); - AddCrc14A(receivedAnswer, 16); - if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) { - if (MF_DBGLEVEL >= MF_DBG_ALL) Dbprintf("Cmd CRC response error."); - return 3; - } + memcpy(bt, receivedAnswer + 16, 2); + AddCrc14A(receivedAnswer, 16); + if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) { + if (MF_DBGLEVEL >= MF_DBG_ALL) Dbprintf("Cmd CRC response error."); + return 3; + } - memcpy(blockData, receivedAnswer, 16); - return 0; + memcpy(blockData, receivedAnswer, 16); + return 0; } // mifare ultralight commands int mifare_ul_ev1_auth(uint8_t *keybytes, uint8_t *pack){ - uint16_t len = 0; - uint8_t resp[4] = {0x00, 0x00, 0x00, 0x00}; - uint8_t respPar[1] = {0x00}; - uint8_t key[4] = {0x00, 0x00, 0x00, 0x00}; - memcpy(key, keybytes, 4); + uint16_t len = 0; + uint8_t resp[4] = {0x00, 0x00, 0x00, 0x00}; + uint8_t respPar[1] = {0x00}; + uint8_t key[4] = {0x00, 0x00, 0x00, 0x00}; + memcpy(key, keybytes, 4); - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) - Dbprintf("EV1 Auth : %02x%02x%02x%02x", key[0], key[1], key[2], key[3]); + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) + Dbprintf("EV1 Auth : %02x%02x%02x%02x", key[0], key[1], key[2], key[3]); - len = mifare_sendcmd(MIFARE_ULEV1_AUTH, key, sizeof(key), resp, respPar, NULL); + len = mifare_sendcmd(MIFARE_ULEV1_AUTH, key, sizeof(key), resp, respPar, NULL); - if (len != 4) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x %u", resp[0], len); - return 0; - } + if (len != 4) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x %u", resp[0], len); + return 0; + } - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) - Dbprintf("Auth Resp: %02x%02x%02x%02x", resp[0],resp[1],resp[2],resp[3]); + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) + Dbprintf("Auth Resp: %02x%02x%02x%02x", resp[0],resp[1],resp[2],resp[3]); - memcpy(pack, resp, 4); - return 1; + memcpy(pack, resp, 4); + return 1; } int mifare_ultra_auth(uint8_t *keybytes){ - /// 3des2k - uint8_t random_a[8] = {1,1,1,1,1,1,1,1}; - uint8_t random_b[8] = {0x00}; - uint8_t enc_random_b[8] = {0x00}; - uint8_t rnd_ab[16] = {0x00}; - uint8_t IV[8] = {0x00}; - uint8_t key[16] = {0x00}; - memcpy(key, keybytes, 16); + /// 3des2k + uint8_t random_a[8] = {1,1,1,1,1,1,1,1}; + uint8_t random_b[8] = {0x00}; + uint8_t enc_random_b[8] = {0x00}; + uint8_t rnd_ab[16] = {0x00}; + uint8_t IV[8] = {0x00}; + uint8_t key[16] = {0x00}; + memcpy(key, keybytes, 16); - uint16_t len = 0; - uint8_t resp[19] = {0x00}; - uint8_t respPar[3] = {0,0,0}; + uint16_t len = 0; + uint8_t resp[19] = {0x00}; + uint8_t respPar[3] = {0,0,0}; - // REQUEST AUTHENTICATION - len = mifare_sendcmd_short(NULL, 1, MIFARE_ULC_AUTH_1, 0x00, resp, respPar ,NULL); - if (len != 11) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]); - return 0; - } + // REQUEST AUTHENTICATION + len = mifare_sendcmd_short(NULL, 1, MIFARE_ULC_AUTH_1, 0x00, resp, respPar ,NULL); + if (len != 11) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]); + return 0; + } - // tag nonce. - memcpy(enc_random_b,resp+1,8); + // tag nonce. + memcpy(enc_random_b,resp+1,8); - // decrypt nonce. - tdes_2key_dec((void*)random_b, (void*)enc_random_b, sizeof(random_b), (const void*)key, IV ); - rol(random_b,8); - memcpy(rnd_ab ,random_a,8); - memcpy(rnd_ab+8,random_b,8); + // decrypt nonce. + tdes_2key_dec((void*)random_b, (void*)enc_random_b, sizeof(random_b), (const void*)key, IV ); + rol(random_b,8); + memcpy(rnd_ab ,random_a,8); + memcpy(rnd_ab+8,random_b,8); - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { - Dbprintf("enc_B: %02x %02x %02x %02x %02x %02x %02x %02x", - enc_random_b[0],enc_random_b[1],enc_random_b[2],enc_random_b[3],enc_random_b[4],enc_random_b[5],enc_random_b[6],enc_random_b[7]); + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { + Dbprintf("enc_B: %02x %02x %02x %02x %02x %02x %02x %02x", + enc_random_b[0],enc_random_b[1],enc_random_b[2],enc_random_b[3],enc_random_b[4],enc_random_b[5],enc_random_b[6],enc_random_b[7]); - Dbprintf(" B: %02x %02x %02x %02x %02x %02x %02x %02x", - random_b[0],random_b[1],random_b[2],random_b[3],random_b[4],random_b[5],random_b[6],random_b[7]); + Dbprintf(" B: %02x %02x %02x %02x %02x %02x %02x %02x", + random_b[0],random_b[1],random_b[2],random_b[3],random_b[4],random_b[5],random_b[6],random_b[7]); - Dbprintf("rnd_ab: %02x %02x %02x %02x %02x %02x %02x %02x", - rnd_ab[0],rnd_ab[1],rnd_ab[2],rnd_ab[3],rnd_ab[4],rnd_ab[5],rnd_ab[6],rnd_ab[7]); + Dbprintf("rnd_ab: %02x %02x %02x %02x %02x %02x %02x %02x", + rnd_ab[0],rnd_ab[1],rnd_ab[2],rnd_ab[3],rnd_ab[4],rnd_ab[5],rnd_ab[6],rnd_ab[7]); - Dbprintf("rnd_ab: %02x %02x %02x %02x %02x %02x %02x %02x", - rnd_ab[8],rnd_ab[9],rnd_ab[10],rnd_ab[11],rnd_ab[12],rnd_ab[13],rnd_ab[14],rnd_ab[15] ); - } + Dbprintf("rnd_ab: %02x %02x %02x %02x %02x %02x %02x %02x", + rnd_ab[8],rnd_ab[9],rnd_ab[10],rnd_ab[11],rnd_ab[12],rnd_ab[13],rnd_ab[14],rnd_ab[15] ); + } - // encrypt out, in, length, key, iv - tdes_2key_enc(rnd_ab, rnd_ab, sizeof(rnd_ab), key, enc_random_b); + // encrypt out, in, length, key, iv + tdes_2key_enc(rnd_ab, rnd_ab, sizeof(rnd_ab), key, enc_random_b); - len = mifare_sendcmd(MIFARE_ULC_AUTH_2, rnd_ab, sizeof(rnd_ab), resp, respPar, NULL); - if (len != 11) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]); - return 0; - } + len = mifare_sendcmd(MIFARE_ULC_AUTH_2, rnd_ab, sizeof(rnd_ab), resp, respPar, NULL); + if (len != 11) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]); + return 0; + } - uint8_t enc_resp[8] = { 0,0,0,0,0,0,0,0 }; - uint8_t resp_random_a[8] = { 0,0,0,0,0,0,0,0 }; - memcpy(enc_resp, resp+1, 8); + uint8_t enc_resp[8] = { 0,0,0,0,0,0,0,0 }; + uint8_t resp_random_a[8] = { 0,0,0,0,0,0,0,0 }; + memcpy(enc_resp, resp+1, 8); - // decrypt out, in, length, key, iv - tdes_2key_dec(resp_random_a, enc_resp, 8, key, enc_random_b); - if ( memcmp(resp_random_a, random_a, 8) != 0 ) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("failed authentication"); - return 0; - } + // decrypt out, in, length, key, iv + tdes_2key_dec(resp_random_a, enc_resp, 8, key, enc_random_b); + if ( memcmp(resp_random_a, random_a, 8) != 0 ) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("failed authentication"); + return 0; + } - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { - Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", - rnd_ab[0],rnd_ab[1],rnd_ab[2],rnd_ab[3], - rnd_ab[4],rnd_ab[5],rnd_ab[6],rnd_ab[7]); + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { + Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", + rnd_ab[0],rnd_ab[1],rnd_ab[2],rnd_ab[3], + rnd_ab[4],rnd_ab[5],rnd_ab[6],rnd_ab[7]); - Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", - rnd_ab[8],rnd_ab[9],rnd_ab[10],rnd_ab[11], - rnd_ab[12],rnd_ab[13],rnd_ab[14],rnd_ab[15]); + Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", + rnd_ab[8],rnd_ab[9],rnd_ab[10],rnd_ab[11], + rnd_ab[12],rnd_ab[13],rnd_ab[14],rnd_ab[15]); - Dbprintf("a: %02x %02x %02x %02x %02x %02x %02x %02x", - random_a[0],random_a[1],random_a[2],random_a[3], - random_a[4],random_a[5],random_a[6],random_a[7]); + Dbprintf("a: %02x %02x %02x %02x %02x %02x %02x %02x", + random_a[0],random_a[1],random_a[2],random_a[3], + random_a[4],random_a[5],random_a[6],random_a[7]); - Dbprintf("b: %02x %02x %02x %02x %02x %02x %02x %02x", - resp_random_a[0],resp_random_a[1],resp_random_a[2],resp_random_a[3], - resp_random_a[4],resp_random_a[5],resp_random_a[6],resp_random_a[7]); - } - return 1; + Dbprintf("b: %02x %02x %02x %02x %02x %02x %02x %02x", + resp_random_a[0],resp_random_a[1],resp_random_a[2],resp_random_a[3], + resp_random_a[4],resp_random_a[5],resp_random_a[6],resp_random_a[7]); + } + return 1; } int mifare_ultra_readblockEx(uint8_t blockNo, uint8_t *blockData) { - uint16_t len = 0; - uint8_t bt[2] = {0x00, 0x00}; - uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00}; - uint8_t receivedAnswerPar[MAX_PARITY_SIZE] = {0x00}; + uint16_t len = 0; + uint8_t bt[2] = {0x00, 0x00}; + uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00}; + uint8_t receivedAnswerPar[MAX_PARITY_SIZE] = {0x00}; - len = mifare_sendcmd_short(NULL, 1, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); - if (len == 1) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); - return 1; - } - if (len != 18) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: card timeout. len: %x", len); - return 2; - } + len = mifare_sendcmd_short(NULL, 1, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); + if (len == 1) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); + return 1; + } + if (len != 18) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: card timeout. len: %x", len); + return 2; + } - memcpy(bt, receivedAnswer + 16, 2); - AddCrc14A(receivedAnswer, 16); - if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd CRC response error."); - return 3; - } + memcpy(bt, receivedAnswer + 16, 2); + AddCrc14A(receivedAnswer, 16); + if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd CRC response error."); + return 3; + } - memcpy(blockData, receivedAnswer, 14); - return 0; + memcpy(blockData, receivedAnswer, 14); + return 0; } int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData) { - #define MFU_MAX_RETRIES 5 - uint8_t res; + #define MFU_MAX_RETRIES 5 + uint8_t res; - for (uint8_t retries = 0; retries < MFU_MAX_RETRIES; ++retries) { - res = mifare_ultra_readblockEx(blockNo, blockData); + for (uint8_t retries = 0; retries < MFU_MAX_RETRIES; ++retries) { + res = mifare_ultra_readblockEx(blockNo, blockData); - // break if OK, or NACK. - switch ( res ) { - case 0: - case 1: - return res; - default: - continue; - } - } - return res; + // break if OK, or NACK. + switch ( res ) { + case 0: + case 1: + return res; + default: + continue; + } + } + return res; } int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) { - // variables - uint16_t len = 0; - uint32_t pos = 0; - uint8_t par[3] = {0x00, 0x00, 0x00}; // enough for 18 Bytes to send - byte_t res = 0; + // variables + uint16_t len = 0; + uint32_t pos = 0; + uint8_t par[3] = {0x00, 0x00, 0x00}; // enough for 18 Bytes to send + byte_t res = 0; - uint8_t d_block[18], d_block_enc[18]; - uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; - uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; + uint8_t d_block[18], d_block_enc[18]; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; - // command MIFARE_CLASSIC_WRITEBLOCK - len = mifare_sendcmd_short(pcs, 1, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); + // command MIFARE_CLASSIC_WRITEBLOCK + len = mifare_sendcmd_short(pcs, 1, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); - if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); - return 1; - } + if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); + return 1; + } - memcpy(d_block, blockData, 16); - AddCrc14A(d_block, 16); + memcpy(d_block, blockData, 16); + AddCrc14A(d_block, 16); - // crypto - for (pos = 0; pos < 18; pos++) { - d_block_enc[pos] = crypto1_byte(pcs, 0x00, 0) ^ d_block[pos]; - par[pos>>3] |= (((filter(pcs->odd) ^ oddparity8(d_block[pos])) & 0x01) << (7 - (pos&0x0007))); - } + // crypto + for (pos = 0; pos < 18; pos++) { + d_block_enc[pos] = crypto1_byte(pcs, 0x00, 0) ^ d_block[pos]; + par[pos>>3] |= (((filter(pcs->odd) ^ oddparity8(d_block[pos])) & 0x01) << (7 - (pos&0x0007))); + } - ReaderTransmitPar(d_block_enc, sizeof(d_block_enc), par, NULL); + ReaderTransmitPar(d_block_enc, sizeof(d_block_enc), par, NULL); - // Receive the response - len = ReaderReceive(receivedAnswer, receivedAnswerPar); + // Receive the response + len = ReaderReceive(receivedAnswer, receivedAnswerPar); - res = 0; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 0)) << 0; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 1)) << 1; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 2)) << 2; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 3)) << 3; + res = 0; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 0)) << 0; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 1)) << 1; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 2)) << 2; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 3)) << 3; - if ((len != 1) || (res != 0x0A)) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd send data2 Error: %02x", res); - return 2; - } - return 0; + if ((len != 1) || (res != 0x0A)) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd send data2 Error: %02x", res); + return 2; + } + return 0; } /* // command not needed, but left for future testing int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData) { - uint16_t len; + uint16_t len; uint8_t par[3] = {0}; // enough for 18 parity bits - uint8_t d_block[18] = {0x00}; - uint8_t receivedAnswer[MAX_FRAME_SIZE]; - uint8_t receivedAnswerPar[MAX_PARITY_SIZE]; + uint8_t d_block[18] = {0x00}; + uint8_t receivedAnswer[MAX_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_PARITY_SIZE]; len = mifare_sendcmd_short(NULL, true, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK - if (MF_DBGLEVEL >= MF_DBG_ERROR) - Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]); + if (MF_DBGLEVEL >= MF_DBG_ERROR) + Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]); return 1; } - memcpy(d_block, blockData, 16); + memcpy(d_block, blockData, 16); AddCrc14A(d_block, 16); - ReaderTransmitPar(d_block, sizeof(d_block), par, NULL); + ReaderTransmitPar(d_block, sizeof(d_block), par, NULL); - len = ReaderReceive(receivedAnswer, receivedAnswerPar); + len = ReaderReceive(receivedAnswer, receivedAnswerPar); - if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK - if (MF_DBGLEVEL >= MF_DBG_ERROR) - Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len); + if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK + if (MF_DBGLEVEL >= MF_DBG_ERROR) + Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len); return 2; - } + } return 0; } */ int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) { uint16_t len = 0; - uint8_t block[5] = {blockNo, 0x00, 0x00, 0x00, 0x00 }; - uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; - uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; + uint8_t block[5] = {blockNo, 0x00, 0x00, 0x00, 0x00 }; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; // command MIFARE_CLASSIC_WRITEBLOCK - memcpy(block+1, blockData, 4); + memcpy(block+1, blockData, 4); - len = mifare_sendcmd( MIFARE_ULC_WRITE, block, sizeof(block), receivedAnswer, receivedAnswerPar, NULL); + len = mifare_sendcmd( MIFARE_ULC_WRITE, block, sizeof(block), receivedAnswer, receivedAnswerPar, NULL); if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK - if (MF_DBGLEVEL >= MF_DBG_ERROR) - Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len); + if (MF_DBGLEVEL >= MF_DBG_ERROR) + Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len); return 1; } return 0; } int mifare_classic_halt_ex(struct Crypto1State *pcs) { - uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00}; - uint16_t len = mifare_sendcmd_short(pcs, (pcs == NULL) ? CRYPT_NONE : CRYPT_ALL, ISO14443A_CMD_HALT, 0x00, receivedAnswer, NULL, NULL); - if (len != 0) { - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("halt warning. response len: %x", len); - return 1; - } - return 0; + uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00}; + uint16_t len = mifare_sendcmd_short(pcs, (pcs == NULL) ? CRYPT_NONE : CRYPT_ALL, ISO14443A_CMD_HALT, 0x00, receivedAnswer, NULL, NULL); + if (len != 0) { + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("halt warning. response len: %x", len); + return 1; + } + return 0; } int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) { - return mifare_classic_halt_ex(pcs); + return mifare_classic_halt_ex(pcs); } int mifare_ultra_halt() { - uint16_t len = 0; - uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00}; - len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_HALT, 0x00, receivedAnswer, NULL, NULL); - if (len != 0) { - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("halt warning. response len: %x", len); - return 1; - } - return 0; + uint16_t len = 0; + uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00}; + len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_HALT, 0x00, receivedAnswer, NULL, NULL); + if (len != 0) { + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("halt warning. response len: %x", len); + return 1; + } + 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) { - return (sectorNo < 32) ? 4 : 16; + return (sectorNo < 32) ? 4 : 16; } uint8_t FirstBlockOfSector(uint8_t sectorNo) { - if (sectorNo < 32) - return sectorNo * 4; - else - return 32*4 + (sectorNo - 32) * 16; + 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) { - emlSetMem_xt(data, blockNum, blocksCount, 16); + emlSetMem_xt(data, blockNum, blocksCount, 16); } void emlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidth) { - uint8_t* emCARD = BigBuf_get_EM_addr(); - memcpy(emCARD + blockNum * blockBtWidth, data, blocksCount * blockBtWidth); + uint8_t* emCARD = BigBuf_get_EM_addr(); + memcpy(emCARD + blockNum * blockBtWidth, data, blocksCount * blockBtWidth); } void emlGetMem(uint8_t *data, int blockNum, int blocksCount) { - uint8_t* emCARD = BigBuf_get_EM_addr(); - memcpy(data, emCARD + blockNum * 16, blocksCount * 16); + uint8_t* emCARD = BigBuf_get_EM_addr(); + memcpy(data, emCARD + blockNum * 16, blocksCount * 16); } void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount) { - uint8_t* emCARD = BigBuf_get_EM_addr(); - memcpy(data, emCARD + bytePtr, byteCount); + uint8_t* emCARD = BigBuf_get_EM_addr(); + memcpy(data, emCARD + bytePtr, byteCount); } int emlCheckValBl(int blockNum) { - uint8_t* emCARD = BigBuf_get_EM_addr(); - uint8_t* data = emCARD + blockNum * 16; + uint8_t* emCARD = BigBuf_get_EM_addr(); + uint8_t* data = emCARD + blockNum * 16; - if ((data[0] != (data[4] ^ 0xff)) || (data[0] != data[8]) || - (data[1] != (data[5] ^ 0xff)) || (data[1] != data[9]) || - (data[2] != (data[6] ^ 0xff)) || (data[2] != data[10]) || - (data[3] != (data[7] ^ 0xff)) || (data[3] != data[11]) || - (data[12] != (data[13] ^ 0xff)) || (data[12] != data[14]) || - (data[12] != (data[15] ^ 0xff)) - ) - return 1; - return 0; + if ((data[0] != (data[4] ^ 0xff)) || (data[0] != data[8]) || + (data[1] != (data[5] ^ 0xff)) || (data[1] != data[9]) || + (data[2] != (data[6] ^ 0xff)) || (data[2] != data[10]) || + (data[3] != (data[7] ^ 0xff)) || (data[3] != data[11]) || + (data[12] != (data[13] ^ 0xff)) || (data[12] != data[14]) || + (data[12] != (data[15] ^ 0xff)) + ) + return 1; + return 0; } int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) { - uint8_t* emCARD = BigBuf_get_EM_addr(); - uint8_t* data = emCARD + blockNum * 16; + uint8_t* emCARD = BigBuf_get_EM_addr(); + uint8_t* data = emCARD + blockNum * 16; - if (emlCheckValBl(blockNum)) - return 1; + if (emlCheckValBl(blockNum)) + return 1; - memcpy(blReg, data, 4); - *blBlock = data[12]; - return 0; + memcpy(blReg, data, 4); + *blBlock = data[12]; + return 0; } int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) { - uint8_t* emCARD = BigBuf_get_EM_addr(); - uint8_t* data = emCARD + blockNum * 16; + uint8_t* emCARD = BigBuf_get_EM_addr(); + uint8_t* data = emCARD + blockNum * 16; - memcpy(data + 0, &blReg, 4); - memcpy(data + 8, &blReg, 4); - blReg = blReg ^ 0xffffffff; - memcpy(data + 4, &blReg, 4); + memcpy(data + 0, &blReg, 4); + memcpy(data + 8, &blReg, 4); + blReg = blReg ^ 0xffffffff; + memcpy(data + 4, &blReg, 4); - data[12] = blBlock; - data[13] = blBlock ^ 0xff; - data[14] = blBlock; - data[15] = blBlock ^ 0xff; + data[12] = blBlock; + data[13] = blBlock ^ 0xff; + data[14] = blBlock; + data[15] = blBlock ^ 0xff; - return 0; + return 0; } uint64_t emlGetKey(int sectorNum, int keyType) { - uint8_t key[6] = {0x00}; - uint8_t* emCARD = BigBuf_get_EM_addr(); - memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6); - return bytes_to_num(key, 6); + uint8_t key[6] = {0x00}; + uint8_t* emCARD = BigBuf_get_EM_addr(); + memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6); + return bytes_to_num(key, 6); } void emlClearMem(void) { - const uint8_t trailer[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x69, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - const uint8_t uid[] = {0xe6, 0x84, 0x87, 0xf3, 0x16, 0x88, 0x04, 0x00, 0x46, 0x8e, 0x45, 0x55, 0x4d, 0x70, 0x41, 0x04}; - uint8_t* emCARD = BigBuf_get_EM_addr(); - memset(emCARD, 0, CARD_MEMORY_SIZE); + const uint8_t trailer[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x69, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + const uint8_t uid[] = {0xe6, 0x84, 0x87, 0xf3, 0x16, 0x88, 0x04, 0x00, 0x46, 0x8e, 0x45, 0x55, 0x4d, 0x70, 0x41, 0x04}; + uint8_t* emCARD = BigBuf_get_EM_addr(); + memset(emCARD, 0, CARD_MEMORY_SIZE); - // fill sectors trailer data - for(uint16_t b = 3; b < 256; ((b < 127) ? (b += 4) : (b += 16))) - emlSetMem((uint8_t *)trailer, b, 1); + // fill sectors trailer data + for(uint16_t b = 3; b < 256; ((b < 127) ? (b += 4) : (b += 16))) + emlSetMem((uint8_t *)trailer, b, 1); - // uid - emlSetMem((uint8_t *)uid, 0, 1); - return; + // uid + emlSetMem((uint8_t *)uid, 0, 1); + return; } // Mifare desfire commands int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing) { uint8_t dcmd[5] = {cmd, data[0], data[1], 0x00, 0x00}; - AddCrc14A(dcmd, 3); + AddCrc14A(dcmd, 3); - ReaderTransmit(dcmd, sizeof(dcmd), NULL); - int len = ReaderReceive(answer, answer_parity); - if(!len) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed. Card timeout."); - return 1; + ReaderTransmit(dcmd, sizeof(dcmd), NULL); + int len = ReaderReceive(answer, answer_parity); + if(!len) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed. Card timeout."); + return 1; } - return len; + return len; } int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer,uint8_t *answer_parity, uint32_t *timing) { uint8_t dcmd[20] = {0x00}; dcmd[0] = cmd; memcpy(dcmd+1,data,17); - AddCrc14A(dcmd, 18); + AddCrc14A(dcmd, 18); - ReaderTransmit(dcmd, sizeof(dcmd), NULL); - int len = ReaderReceive(answer, answer_parity); - if(!len){ + ReaderTransmit(dcmd, sizeof(dcmd), NULL); + int len = ReaderReceive(answer, answer_parity); + if(!len){ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed. Card timeout."); - return 1; + return 1; } - return len; + return len; } int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData){ - int len; - // load key, keynumber - uint8_t data[2]={MFDES_AUTHENTICATE, 0x00}; - uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00}; - uint8_t receivedAnswerPar[MAX_PARITY_SIZE] = {0x00}; + int len; + // load key, keynumber + uint8_t data[2]={MFDES_AUTHENTICATE, 0x00}; + uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00}; + uint8_t receivedAnswerPar[MAX_PARITY_SIZE] = {0x00}; - len = mifare_sendcmd_special(NULL, 1, 0x02, data, receivedAnswer,receivedAnswerPar,NULL); - if (len == 1) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) - Dbprintf("Cmd Error: %02x", receivedAnswer[0]); - return 1; - } + len = mifare_sendcmd_special(NULL, 1, 0x02, data, receivedAnswer,receivedAnswerPar,NULL); + if (len == 1) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) + Dbprintf("Cmd Error: %02x", receivedAnswer[0]); + return 1; + } - if (len == 12) { - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { - Dbprintf("Auth1 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4], - receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9], - receivedAnswer[10],receivedAnswer[11]); - } - memcpy(blockData, receivedAnswer, 12); - return 0; - } - return 1; + if (len == 12) { + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { + Dbprintf("Auth1 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4], + receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9], + receivedAnswer[10],receivedAnswer[11]); + } + memcpy(blockData, receivedAnswer, 12); + return 0; + } + return 1; } int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){ - int len; - uint8_t data[17] = {MFDES_AUTHENTICATION_FRAME}; - memcpy(data+1,key,16); + int len; + uint8_t data[17] = {MFDES_AUTHENTICATION_FRAME}; + memcpy(data+1,key,16); - uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00}; - uint8_t receivedAnswerPar[MAX_PARITY_SIZE] = {0x00}; + uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00}; + uint8_t receivedAnswerPar[MAX_PARITY_SIZE] = {0x00}; - len = mifare_sendcmd_special2(NULL, 1, 0x03, data, receivedAnswer, receivedAnswerPar ,NULL); + len = mifare_sendcmd_special2(NULL, 1, 0x03, data, receivedAnswer, receivedAnswerPar ,NULL); - if ((receivedAnswer[0] == 0x03) && (receivedAnswer[1] == 0xae)) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) - Dbprintf("Auth Error: %02x %02x", receivedAnswer[0], receivedAnswer[1]); - return 1; - } + if ((receivedAnswer[0] == 0x03) && (receivedAnswer[1] == 0xae)) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) + Dbprintf("Auth Error: %02x %02x", receivedAnswer[0], receivedAnswer[1]); + return 1; + } - if (len == 12){ - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { - Dbprintf("Auth2 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4], - receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9], - receivedAnswer[10],receivedAnswer[11]); - } - memcpy(blockData, receivedAnswer, 12); - return 0; - } - return 1; + if (len == 12){ + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) { + Dbprintf("Auth2 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4], + receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9], + receivedAnswer[10],receivedAnswer[11]); + } + memcpy(blockData, receivedAnswer, 12); + return 0; + } + return 1; } diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index 594b7ca80..ad01a7078 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -21,7 +21,7 @@ #include "iso14443a.h" #include "crapto1/crapto1.h" #include "des.h" -#include "random.h" // fast_prand, prand +#include "random.h" // fast_prand, prand // mifare authentication #define CRYPT_NONE 0 @@ -30,8 +30,8 @@ #define AUTH_FIRST 0 #define AUTH_NESTED 2 -#define AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation) -#define PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication +#define AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation) +#define PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication // mifare 4bit card answers #define CARD_ACK 0x0A // 1010 - ACK @@ -48,7 +48,7 @@ #define MFEMUL_SELECT3 4 #define MFEMUL_AUTH1 5 #define MFEMUL_AUTH2 6 -#define MFEMUL_WORK 7 +#define MFEMUL_WORK 7 #define MFEMUL_WRITEBL2 8 #define MFEMUL_INTREG_INC 9 #define MFEMUL_INTREG_DEC 10 diff --git a/armsrc/optimized_cipher.c b/armsrc/optimized_cipher.c index 98ab88041..f8ddc19d2 100644 --- a/armsrc/optimized_cipher.c +++ b/armsrc/optimized_cipher.c @@ -41,8 +41,8 @@ This file contains an optimized version of the MAC-calculation algorithm. Some measurements on a std laptop showed it runs in about 1/3 of the time: - Std: 0.428962 - Opt: 0.151609 + Std: 0.428962 + Opt: 0.151609 Additionally, it is self-reliant, not requiring e.g. bitstreams from the cipherutils, thus can be easily dropped into a code base. @@ -67,162 +67,162 @@ #define opt_B(s) (((s->b >> 6) ^ (s->b >> 5) ^ (s->b >> 4) ^ (s->b)) & 0x1) #define opt__select(x,y,r) (4 & (((r & (r << 2)) >> 5) ^ ((r & ~(r << 2)) >> 4) ^ ( (r | r << 2) >> 3)))\ - |(2 & (((r | r << 2) >> 6) ^ ( (r | r << 2) >> 1) ^ (r >> 5) ^ r ^ ((x^y) << 1)))\ - |(1 & (((r & ~(r << 2)) >> 4) ^ ((r & (r << 2)) >> 3) ^ r ^ x)) + |(2 & (((r | r << 2) >> 6) ^ ( (r | r << 2) >> 1) ^ (r >> 5) ^ r ^ ((x^y) << 1)))\ + |(1 & (((r & ~(r << 2)) >> 4) ^ ((r & (r << 2)) >> 3) ^ r ^ x)) /* * Some background on the expression above can be found here... uint8_t xopt__select(bool x, bool y, uint8_t r) { - uint8_t r_ls2 = r << 2; - uint8_t r_and_ls2 = r & r_ls2; - uint8_t r_or_ls2 = r | r_ls2; + uint8_t r_ls2 = r << 2; + uint8_t r_and_ls2 = r & r_ls2; + uint8_t r_or_ls2 = r | r_ls2; - //r: r0 r1 r2 r3 r4 r5 r6 r7 - //r_ls2: r2 r3 r4 r5 r6 r7 0 0 - // z0 - // z1 + //r: r0 r1 r2 r3 r4 r5 r6 r7 + //r_ls2: r2 r3 r4 r5 r6 r7 0 0 + // z0 + // z1 -// uint8_t z0 = (r0 & r2) ^ (r1 & ~r3) ^ (r2 | r4); // <-- original - uint8_t z0 = (r_and_ls2 >> 5) ^ ((r & ~r_ls2) >> 4) ^ ( r_or_ls2 >> 3); +// uint8_t z0 = (r0 & r2) ^ (r1 & ~r3) ^ (r2 | r4); // <-- original + uint8_t z0 = (r_and_ls2 >> 5) ^ ((r & ~r_ls2) >> 4) ^ ( r_or_ls2 >> 3); -// uint8_t z1 = (r0 | r2) ^ ( r5 | r7) ^ r1 ^ r6 ^ x ^ y; // <-- original - uint8_t z1 = (r_or_ls2 >> 6) ^ ( r_or_ls2 >> 1) ^ (r >> 5) ^ r ^ ((x^y) << 1); +// uint8_t z1 = (r0 | r2) ^ ( r5 | r7) ^ r1 ^ r6 ^ x ^ y; // <-- original + uint8_t z1 = (r_or_ls2 >> 6) ^ ( r_or_ls2 >> 1) ^ (r >> 5) ^ r ^ ((x^y) << 1); -// uint8_t z2 = (r3 & ~r5) ^ (r4 & r6 ) ^ r7 ^ x; // <-- original - uint8_t z2 = ((r & ~r_ls2) >> 4) ^ (r_and_ls2 >> 3) ^ r ^ x; +// uint8_t z2 = (r3 & ~r5) ^ (r4 & r6 ) ^ r7 ^ x; // <-- original + uint8_t z2 = ((r & ~r_ls2) >> 4) ^ (r_and_ls2 >> 3) ^ r ^ x; - return (z0 & 4) | (z1 & 2) | (z2 & 1); + return (z0 & 4) | (z1 & 2) | (z2 & 1); } */ void opt_successor(const uint8_t* k, State *s, bool y, State* successor) { - uint8_t Tt = 1 & opt_T(s); + uint8_t Tt = 1 & opt_T(s); - successor->t = (s->t >> 1); - successor->t |= (Tt ^ (s->r >> 7 & 0x1) ^ (s->r >> 3 & 0x1)) << 15; + successor->t = (s->t >> 1); + successor->t |= (Tt ^ (s->r >> 7 & 0x1) ^ (s->r >> 3 & 0x1)) << 15; - successor->b = s->b >> 1; - successor->b |= (opt_B(s) ^ (s->r & 0x1)) << 7; + successor->b = s->b >> 1; + successor->b |= (opt_B(s) ^ (s->r & 0x1)) << 7; - successor->r = (k[opt__select(Tt,y,s->r)] ^ successor->b) + s->l ; - successor->l = successor->r+s->r; + successor->r = (k[opt__select(Tt,y,s->r)] ^ successor->b) + s->l ; + successor->l = successor->r+s->r; } void opt_suc(const uint8_t* k,State* s, uint8_t *in, uint8_t length, bool add32Zeroes) { - State x2; - int i; - uint8_t head = 0; - for (i = 0; i < length; i++) { - head = 1 & (in[i] >> 7); - opt_successor(k, s, head, &x2); + State x2; + int i; + uint8_t head = 0; + for (i = 0; i < length; i++) { + head = 1 & (in[i] >> 7); + opt_successor(k, s, head, &x2); - head = 1 & (in[i] >> 6); - opt_successor(k, &x2, head, s); + head = 1 & (in[i] >> 6); + opt_successor(k, &x2, head, s); - head = 1 & (in[i] >> 5); - opt_successor(k, s, head, &x2); + head = 1 & (in[i] >> 5); + opt_successor(k, s, head, &x2); - head = 1 & (in[i] >> 4); - opt_successor(k, &x2, head, s); + head = 1 & (in[i] >> 4); + opt_successor(k, &x2, head, s); - head = 1 & (in[i] >> 3); - opt_successor(k, s, head, &x2); + head = 1 & (in[i] >> 3); + opt_successor(k, s, head, &x2); - head = 1 & (in[i] >> 2); - opt_successor(k, &x2, head, s); + head = 1 & (in[i] >> 2); + opt_successor(k, &x2, head, s); - head = 1 & (in[i] >> 1); - opt_successor(k, s, head, &x2); + head = 1 & (in[i] >> 1); + opt_successor(k, s, head, &x2); - head = 1 & in[i]; - opt_successor(k, &x2, head, s); - } + head = 1 & in[i]; + opt_successor(k, &x2, head, s); + } - //For tag MAC, an additional 32 zeroes - if (add32Zeroes) { - for (i = 0; i < 16; i++) { - opt_successor(k, s, 0, &x2); - opt_successor(k, &x2, 0, s); - } - } + //For tag MAC, an additional 32 zeroes + if (add32Zeroes) { + for (i = 0; i < 16; i++) { + opt_successor(k, s, 0, &x2); + opt_successor(k, &x2, 0, s); + } + } } void opt_output(const uint8_t* k,State* s, uint8_t *buffer) { - uint8_t times = 0; - uint8_t bout = 0; - State temp = {0,0,0,0}; - for ( ; times < 4; times++) { - bout =0; - bout |= (s->r & 0x4) << 5; - opt_successor(k, s, 0, &temp); - bout |= (temp.r & 0x4) << 4; - opt_successor(k, &temp, 0, s); - bout |= (s->r & 0x4) << 3; - opt_successor(k, s, 0, &temp); - bout |= (temp.r & 0x4) << 2; - opt_successor(k, &temp, 0, s); - bout |= (s->r & 0x4) << 1; - opt_successor(k, s, 0, &temp); - bout |= (temp.r & 0x4) ; - opt_successor(k, &temp, 0, s); - bout |= (s->r & 0x4) >> 1; - opt_successor(k, s, 0, &temp); - bout |= (temp.r & 0x4) >> 2; - opt_successor(k, &temp, 0, s); - buffer[times] = bout; - } + uint8_t times = 0; + uint8_t bout = 0; + State temp = {0,0,0,0}; + for ( ; times < 4; times++) { + bout =0; + bout |= (s->r & 0x4) << 5; + opt_successor(k, s, 0, &temp); + bout |= (temp.r & 0x4) << 4; + opt_successor(k, &temp, 0, s); + bout |= (s->r & 0x4) << 3; + opt_successor(k, s, 0, &temp); + bout |= (temp.r & 0x4) << 2; + opt_successor(k, &temp, 0, s); + bout |= (s->r & 0x4) << 1; + opt_successor(k, s, 0, &temp); + bout |= (temp.r & 0x4) ; + opt_successor(k, &temp, 0, s); + bout |= (s->r & 0x4) >> 1; + opt_successor(k, s, 0, &temp); + bout |= (temp.r & 0x4) >> 2; + opt_successor(k, &temp, 0, s); + buffer[times] = bout; + } } void opt_MAC(uint8_t* k, uint8_t* input, uint8_t* out) { - State _init = { - ((k[0] ^ 0x4c) + 0xEC) & 0xFF,// l - ((k[0] ^ 0x4c) + 0x21) & 0xFF,// r - 0x4c, // b - 0xE012 // t - }; + State _init = { + ((k[0] ^ 0x4c) + 0xEC) & 0xFF,// l + ((k[0] ^ 0x4c) + 0x21) & 0xFF,// r + 0x4c, // b + 0xE012 // t + }; - opt_suc(k,&_init,input,12, false); - opt_output(k,&_init, out); + opt_suc(k,&_init,input,12, false); + opt_output(k,&_init, out); } uint8_t rev_byte(uint8_t b) { - b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; - b = (b & 0xCC) >> 2 | (b & 0x33) << 2; - b = (b & 0xAA) >> 1 | (b & 0x55) << 1; + b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; + b = (b & 0xCC) >> 2 | (b & 0x33) << 2; + b = (b & 0xAA) >> 1 | (b & 0x55) << 1; return b; } void opt_reverse_arraybytecpy(uint8_t* dest, uint8_t *src, size_t len) { - uint8_t i; - for ( i =0; i< len ; i++) - dest[i] = rev_byte(src[i]); + uint8_t i; + for ( i =0; i< len ; i++) + dest[i] = rev_byte(src[i]); } void opt_doReaderMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) { - static uint8_t cc_nr[12]; - opt_reverse_arraybytecpy(cc_nr, cc_nr_p, 12); - uint8_t dest [] = {0,0,0,0,0,0,0,0}; - opt_MAC(div_key_p, cc_nr, dest); - //The output MAC must also be reversed - opt_reverse_arraybytecpy(mac, dest, 4); - return; + static uint8_t cc_nr[12]; + opt_reverse_arraybytecpy(cc_nr, cc_nr_p, 12); + uint8_t dest [] = {0,0,0,0,0,0,0,0}; + opt_MAC(div_key_p, cc_nr, dest); + //The output MAC must also be reversed + opt_reverse_arraybytecpy(mac, dest, 4); + return; } void opt_doTagMAC(uint8_t *cc_p, const uint8_t *div_key_p, uint8_t mac[4]) { - static uint8_t cc_nr[8+4+4]; - opt_reverse_arraybytecpy(cc_nr, cc_p, 12); - State _init = { - ((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l - ((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r - 0x4c, // b - 0xE012 // t - }; - opt_suc(div_key_p, &_init, cc_nr, 12, true); - uint8_t dest [] = {0,0,0,0}; - opt_output(div_key_p, &_init, dest); - //The output MAC must also be reversed - opt_reverse_arraybytecpy(mac, dest,4); - return; + static uint8_t cc_nr[8+4+4]; + opt_reverse_arraybytecpy(cc_nr, cc_p, 12); + State _init = { + ((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l + ((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r + 0x4c, // b + 0xE012 // t + }; + opt_suc(div_key_p, &_init, cc_nr, 12, true); + uint8_t dest [] = {0,0,0,0}; + opt_output(div_key_p, &_init, dest); + //The output MAC must also be reversed + opt_reverse_arraybytecpy(mac, dest,4); + return; } /** @@ -234,16 +234,16 @@ void opt_doTagMAC(uint8_t *cc_p, const uint8_t *div_key_p, uint8_t mac[4]) { * @return the cipher state */ State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) { - static uint8_t cc_nr[8]; - opt_reverse_arraybytecpy(cc_nr, cc_p, 8); - State _init = { - ((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l - ((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r - 0x4c, // b - 0xE012 // t - }; - opt_suc(div_key_p, &_init, cc_nr, 8, false); - return _init; + static uint8_t cc_nr[8]; + opt_reverse_arraybytecpy(cc_nr, cc_p, 8); + State _init = { + ((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l + ((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r + 0x4c, // b + 0xE012 // t + }; + opt_suc(div_key_p, &_init, cc_nr, 8, false); + return _init; } /** * The second part of the tag MAC calculation, since the CC is already calculated into the state, @@ -255,13 +255,13 @@ State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) { * @param div_key_p - the key to use */ void opt_doTagMAC_2(State _init, uint8_t* nr, uint8_t mac[4], const uint8_t* div_key_p) { - static uint8_t _nr[4]; - opt_reverse_arraybytecpy(_nr, nr, 4); - opt_suc(div_key_p, &_init,_nr, 4, true); + static uint8_t _nr[4]; + opt_reverse_arraybytecpy(_nr, nr, 4); + opt_suc(div_key_p, &_init,_nr, 4, true); - uint8_t dest [] = {0,0,0,0}; - opt_output(div_key_p, &_init, dest); - //The output MAC must also be reversed - opt_reverse_arraybytecpy(mac, dest,4); - return; + uint8_t dest [] = {0,0,0,0}; + opt_output(div_key_p, &_init, dest); + //The output MAC must also be reversed + opt_reverse_arraybytecpy(mac, dest,4); + return; } diff --git a/armsrc/optimized_cipher.h b/armsrc/optimized_cipher.h index 7398069f0..ad4649d3f 100644 --- a/armsrc/optimized_cipher.h +++ b/armsrc/optimized_cipher.h @@ -8,16 +8,16 @@ /** * Definition 1 (Cipher state). A cipher state of iClass s is an element of F 40/2 * consisting of the following four components: -* 1. the left register l = (l 0 . . . l 7 ) ∈ F 8/2 ; -* 2. the right register r = (r 0 . . . r 7 ) ∈ F 8/2 ; -* 3. the top register t = (t 0 . . . t 15 ) ∈ F 16/2 . -* 4. the bottom register b = (b 0 . . . b 7 ) ∈ F 8/2 . +* 1. the left register l = (l 0 . . . l 7 ) ∈ F 8/2 ; +* 2. the right register r = (r 0 . . . r 7 ) ∈ F 8/2 ; +* 3. the top register t = (t 0 . . . t 15 ) ∈ F 16/2 . +* 4. the bottom register b = (b 0 . . . b 7 ) ∈ F 8/2 . **/ typedef struct { - uint8_t l; - uint8_t r; - uint8_t b; - uint16_t t; + uint8_t l; + uint8_t r; + uint8_t b; + uint16_t t; } State; /** The reader MAC is MAC(key, CC * NR ) diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 4c8259ea5..be56bc37f 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -5,384 +5,384 @@ size_t DemodPCF7931(uint8_t **outBlocks) { uint8_t bits[256] = {0x00}; - uint8_t blocks[8][16]; + uint8_t blocks[8][16]; uint8_t *dest = BigBuf_get_addr(); - int GraphTraceLen = BigBuf_max_traceLen(); - if ( GraphTraceLen > 18000 ) - GraphTraceLen = 18000; + int GraphTraceLen = BigBuf_max_traceLen(); + if ( GraphTraceLen > 18000 ) + GraphTraceLen = 18000; - int i, j, lastval, bitidx, half_switch; - int clock = 64; - int tolerance = clock / 8; - int pmc, block_done; - int lc, warnings = 0; - size_t num_blocks = 0; - int lmin=128, lmax=128; - uint8_t dir; - //clear read buffer - BigBuf_Clear_keep_EM(); + int i, j, lastval, bitidx, half_switch; + int clock = 64; + int tolerance = clock / 8; + int pmc, block_done; + int lc, warnings = 0; + size_t num_blocks = 0; + int lmin=128, lmax=128; + uint8_t dir; + //clear read buffer + BigBuf_Clear_keep_EM(); - LFSetupFPGAForADC(95, true); - DoAcquisition_default(0, true); + LFSetupFPGAForADC(95, true); + DoAcquisition_default(0, true); - lmin = 64; - lmax = 192; + lmin = 64; + lmax = 192; - i = 2; + i = 2; - /* Find first local max/min */ + /* Find first local max/min */ if(dest[1] > dest[0]) { - while(i < GraphTraceLen) { + while(i < GraphTraceLen) { if( !(dest[i] > dest[i-1]) && dest[i] > lmax) - break; - i++; - } - dir = 0; - } else { - while(i < GraphTraceLen) { + break; + i++; + } + dir = 0; + } else { + while(i < GraphTraceLen) { if( !(dest[i] < dest[i-1]) && dest[i] < lmin) - break; - i++; - } - dir = 1; - } + break; + i++; + } + dir = 1; + } - lastval = i++; - half_switch = 0; - pmc = 0; - block_done = 0; + lastval = i++; + half_switch = 0; + pmc = 0; + block_done = 0; - for (bitidx = 0; i < GraphTraceLen; i++) { - if ((dest[i-1] > dest[i] && dir == 1 && dest[i] > lmax) || (dest[i-1] < dest[i] && dir == 0 && dest[i] < lmin)) { - lc = i - lastval; - lastval = i; + for (bitidx = 0; i < GraphTraceLen; i++) { + if ((dest[i-1] > dest[i] && dir == 1 && dest[i] > lmax) || (dest[i-1] < dest[i] && dir == 0 && dest[i] < lmin)) { + lc = i - lastval; + lastval = i; - // Switch depending on lc length: - // Tolerance is 1/8 of clock rate (arbitrary) - if (ABS(lc-clock/4) < tolerance) { - // 16T0 - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33+16)-1; - lastval = i; - pmc = 0; - block_done = 1; - } else { - pmc = i; - } - } else if (ABS(lc-clock/2) < tolerance) { - // 32TO - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33)-1; - lastval = i; - pmc = 0; - block_done = 1; - } else if(half_switch == 1) { + // Switch depending on lc length: + // Tolerance is 1/8 of clock rate (arbitrary) + if (ABS(lc-clock/4) < tolerance) { + // 16T0 + if((i - pmc) == lc) { /* 16T0 was previous one */ + /* It's a PMC ! */ + i += (128+127+16+32+33+16)-1; + lastval = i; + pmc = 0; + block_done = 1; + } else { + pmc = i; + } + } else if (ABS(lc-clock/2) < tolerance) { + // 32TO + if((i - pmc) == lc) { /* 16T0 was previous one */ + /* It's a PMC ! */ + i += (128+127+16+32+33)-1; + lastval = i; + pmc = 0; + block_done = 1; + } else if(half_switch == 1) { bits[bitidx++] = 0; - half_switch = 0; - } - else - half_switch++; - } else if (ABS(lc-clock) < tolerance) { - // 64TO + half_switch = 0; + } + else + half_switch++; + } else if (ABS(lc-clock) < tolerance) { + // 64TO bits[bitidx++] = 1; - } else { - // Error - if (++warnings > 10) { - Dbprintf("Error: too many detection errors, aborting."); - return 0; - } - } + } else { + // Error + if (++warnings > 10) { + Dbprintf("Error: too many detection errors, aborting."); + return 0; + } + } - if(block_done == 1) { - if(bitidx == 128) { - for(j = 0; j < 16; ++j) { - blocks[num_blocks][j] = - 128 * bits[j*8 + 7]+ + if(block_done == 1) { + if(bitidx == 128) { + for(j = 0; j < 16; ++j) { + blocks[num_blocks][j] = + 128 * bits[j*8 + 7]+ 64*bits[j*8+6]+ 32*bits[j*8+5]+ 16*bits[j*8+4]+ 8*bits[j*8+3]+ 4*bits[j*8+2]+ 2*bits[j*8+1]+ - bits[j*8] - ; - } - num_blocks++; - } - bitidx = 0; - block_done = 0; - half_switch = 0; - } - if(i < GraphTraceLen) + bits[j*8] + ; + } + num_blocks++; + } + bitidx = 0; + block_done = 0; + half_switch = 0; + } + if(i < GraphTraceLen) dir =(dest[i-1] > dest[i]) ? 0 : 1; - } - if(bitidx==255) - bitidx=0; - warnings = 0; - if(num_blocks == 4) break; - } + } + if(bitidx==255) + bitidx=0; + warnings = 0; + if(num_blocks == 4) break; + } memcpy(outBlocks, blocks, 16*num_blocks); - return num_blocks; + return num_blocks; } bool IsBlock0PCF7931(uint8_t *block) { - // assuming all RFU bits are set to 0 - // if PAC is enabled password is set to 0 - if (block[7] == 0x01) - { - if (!memcmp(block, "\x00\x00\x00\x00\x00\x00\x00", 7) && !memcmp(block+9, "\x00\x00\x00\x00\x00\x00\x00", 7)) - return true; - } - else if (block[7] == 0x00) - { - if (!memcmp(block+9, "\x00\x00\x00\x00\x00\x00\x00", 7)) - return true; - } - return false; + // assuming all RFU bits are set to 0 + // if PAC is enabled password is set to 0 + if (block[7] == 0x01) + { + if (!memcmp(block, "\x00\x00\x00\x00\x00\x00\x00", 7) && !memcmp(block+9, "\x00\x00\x00\x00\x00\x00\x00", 7)) + return true; + } + else if (block[7] == 0x00) + { + if (!memcmp(block+9, "\x00\x00\x00\x00\x00\x00\x00", 7)) + return true; + } + return false; } bool IsBlock1PCF7931(uint8_t *block) { - // assuming all RFU bits are set to 0 - if (block[10] == 0 && block[11] == 0 && block[12] == 0 && block[13] == 0) - if((block[14] & 0x7f) <= 9 && block[15] <= 9) - return true; + // assuming all RFU bits are set to 0 + if (block[10] == 0 && block[11] == 0 && block[12] == 0 && block[13] == 0) + if((block[14] & 0x7f) <= 9 && block[15] <= 9) + return true; - return false; + return false; } void ReadPCF7931() { - int found_blocks = 0; // successfully read blocks - int max_blocks = 8; // readable blocks - uint8_t memory_blocks[8][17]; // PCF content + int found_blocks = 0; // successfully read blocks + int max_blocks = 8; // readable blocks + uint8_t memory_blocks[8][17]; // PCF content - uint8_t single_blocks[8][17]; // PFC blocks with unknown position - int single_blocks_cnt = 0; + uint8_t single_blocks[8][17]; // PFC blocks with unknown position + int single_blocks_cnt = 0; - size_t n = 0; // transmitted blocks - uint8_t tmp_blocks[4][16]; // temporary read buffer + size_t n = 0; // transmitted blocks + uint8_t tmp_blocks[4][16]; // temporary read buffer - uint8_t found_0_1 = 0; // flag: blocks 0 and 1 were found - int errors = 0; // error counter - int tries = 0; // tries counter + uint8_t found_0_1 = 0; // flag: blocks 0 and 1 were found + int errors = 0; // error counter + int tries = 0; // tries counter - memset(memory_blocks, 0, 8*17*sizeof(uint8_t)); - memset(single_blocks, 0, 8*17*sizeof(uint8_t)); + memset(memory_blocks, 0, 8*17*sizeof(uint8_t)); + memset(single_blocks, 0, 8*17*sizeof(uint8_t)); - int i = 0, j = 0; + int i = 0, j = 0; - do { - i = 0; + do { + i = 0; - memset(tmp_blocks, 0, 4*16*sizeof(uint8_t)); - n = DemodPCF7931((uint8_t**)tmp_blocks); - if(!n) - ++errors; + memset(tmp_blocks, 0, 4*16*sizeof(uint8_t)); + n = DemodPCF7931((uint8_t**)tmp_blocks); + if(!n) + ++errors; - // exit if no block is received - if (errors >= 10 && found_blocks == 0 && single_blocks_cnt == 0) { - Dbprintf("Error, no tag or bad tag"); - return; - } - // exit if too many errors during reading - if (tries > 50 && (2*errors > tries)) { - Dbprintf("Error reading the tag"); - Dbprintf("Here is the partial content"); - goto end; - } + // exit if no block is received + if (errors >= 10 && found_blocks == 0 && single_blocks_cnt == 0) { + Dbprintf("Error, no tag or bad tag"); + return; + } + // exit if too many errors during reading + if (tries > 50 && (2*errors > tries)) { + Dbprintf("Error reading the tag"); + Dbprintf("Here is the partial content"); + goto end; + } - // our logic breaks if we don't get at least two blocks - if (n < 2) { - if (n == 0 || !memcmp(tmp_blocks[0], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) - continue; + // our logic breaks if we don't get at least two blocks + if (n < 2) { + if (n == 0 || !memcmp(tmp_blocks[0], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) + continue; - if (single_blocks_cnt < max_blocks) { - for (i = 0; i < single_blocks_cnt; ++i) { - if (!memcmp(single_blocks[i], tmp_blocks[0], 16)) { - j = 1; - break; - } - } - if (j != 1) { - memcpy(single_blocks[single_blocks_cnt], tmp_blocks[0], 16); - single_blocks_cnt++; - } - j = 0; - } - ++tries; - continue; - } + if (single_blocks_cnt < max_blocks) { + for (i = 0; i < single_blocks_cnt; ++i) { + if (!memcmp(single_blocks[i], tmp_blocks[0], 16)) { + j = 1; + break; + } + } + if (j != 1) { + memcpy(single_blocks[single_blocks_cnt], tmp_blocks[0], 16); + single_blocks_cnt++; + } + j = 0; + } + ++tries; + continue; + } - Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors); + Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors); - i = 0; - if(!found_0_1) { - while (i < n - 1) { - if (IsBlock0PCF7931(tmp_blocks[i]) && IsBlock1PCF7931(tmp_blocks[i+1])) { - found_0_1 = 1; - memcpy(memory_blocks[0], tmp_blocks[i], 16); - memcpy(memory_blocks[1], tmp_blocks[i+1], 16); - memory_blocks[0][ALLOC] = memory_blocks[1][ALLOC] = 1; - // block 1 tells how many blocks are going to be sent - max_blocks = MAX((memory_blocks[1][14] & 0x7f), memory_blocks[1][15]) + 1; - found_blocks = 2; + i = 0; + if(!found_0_1) { + while (i < n - 1) { + if (IsBlock0PCF7931(tmp_blocks[i]) && IsBlock1PCF7931(tmp_blocks[i+1])) { + found_0_1 = 1; + memcpy(memory_blocks[0], tmp_blocks[i], 16); + memcpy(memory_blocks[1], tmp_blocks[i+1], 16); + memory_blocks[0][ALLOC] = memory_blocks[1][ALLOC] = 1; + // block 1 tells how many blocks are going to be sent + max_blocks = MAX((memory_blocks[1][14] & 0x7f), memory_blocks[1][15]) + 1; + found_blocks = 2; - Dbprintf("Found blocks 0 and 1. PCF is transmitting %d blocks.", max_blocks); + Dbprintf("Found blocks 0 and 1. PCF is transmitting %d blocks.", max_blocks); - // handle the following blocks - for (j = i + 2; j < n; ++j) { - memcpy(memory_blocks[found_blocks], tmp_blocks[j], 16); - memory_blocks[found_blocks][ALLOC] = 1; - ++found_blocks; - } - break; - } - ++i; - } - } else { - // Trying to re-order blocks - // Look for identical block in memory blocks - while (i < n-1) { - // skip all zeroes blocks - if (memcmp(tmp_blocks[i], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { - for (j = 1; j < max_blocks - 1; ++j) { - if (!memcmp(tmp_blocks[i], memory_blocks[j], 16) && !memory_blocks[j+1][ALLOC]) { - memcpy(memory_blocks[j+1], tmp_blocks[i+1], 16); - memory_blocks[j+1][ALLOC] = 1; - if (++found_blocks >= max_blocks) goto end; - } - } - } - if (memcmp(tmp_blocks[i+1], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { - for (j = 0; j < max_blocks; ++j) { - if (!memcmp(tmp_blocks[i+1], memory_blocks[j], 16) && !memory_blocks[(j == 0 ? max_blocks : j) -1][ALLOC]) { - if (j == 0) { - memcpy(memory_blocks[max_blocks - 1], tmp_blocks[i], 16); - memory_blocks[max_blocks - 1][ALLOC] = 1; - } else { - memcpy(memory_blocks[j-1], tmp_blocks[i], 16); - memory_blocks[j-1][ALLOC] = 1; - } - if (++found_blocks >= max_blocks) goto end; - } - } - } - ++i; - } - } - ++tries; - if (BUTTON_PRESS()) { - Dbprintf("Button pressed, stopping."); - goto end; - } - } - while (found_blocks != max_blocks); + // handle the following blocks + for (j = i + 2; j < n; ++j) { + memcpy(memory_blocks[found_blocks], tmp_blocks[j], 16); + memory_blocks[found_blocks][ALLOC] = 1; + ++found_blocks; + } + break; + } + ++i; + } + } else { + // Trying to re-order blocks + // Look for identical block in memory blocks + while (i < n-1) { + // skip all zeroes blocks + if (memcmp(tmp_blocks[i], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { + for (j = 1; j < max_blocks - 1; ++j) { + if (!memcmp(tmp_blocks[i], memory_blocks[j], 16) && !memory_blocks[j+1][ALLOC]) { + memcpy(memory_blocks[j+1], tmp_blocks[i+1], 16); + memory_blocks[j+1][ALLOC] = 1; + if (++found_blocks >= max_blocks) goto end; + } + } + } + if (memcmp(tmp_blocks[i+1], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { + for (j = 0; j < max_blocks; ++j) { + if (!memcmp(tmp_blocks[i+1], memory_blocks[j], 16) && !memory_blocks[(j == 0 ? max_blocks : j) -1][ALLOC]) { + if (j == 0) { + memcpy(memory_blocks[max_blocks - 1], tmp_blocks[i], 16); + memory_blocks[max_blocks - 1][ALLOC] = 1; + } else { + memcpy(memory_blocks[j-1], tmp_blocks[i], 16); + memory_blocks[j-1][ALLOC] = 1; + } + if (++found_blocks >= max_blocks) goto end; + } + } + } + ++i; + } + } + ++tries; + if (BUTTON_PRESS()) { + Dbprintf("Button pressed, stopping."); + goto end; + } + } + while (found_blocks != max_blocks); end: - Dbprintf("-----------------------------------------"); - Dbprintf("Memory content:"); - Dbprintf("-----------------------------------------"); - for (i = 0; i < max_blocks; ++i) { - if (memory_blocks[i][ALLOC]) - print_result("Block", memory_blocks[i], 16); - else - Dbprintf("", i); - } - Dbprintf("-----------------------------------------"); + Dbprintf("-----------------------------------------"); + Dbprintf("Memory content:"); + Dbprintf("-----------------------------------------"); + for (i = 0; i < max_blocks; ++i) { + if (memory_blocks[i][ALLOC]) + print_result("Block", memory_blocks[i], 16); + else + Dbprintf("", i); + } + Dbprintf("-----------------------------------------"); - if (found_blocks < max_blocks) { - Dbprintf("-----------------------------------------"); - Dbprintf("Blocks with unknown position:"); - Dbprintf("-----------------------------------------"); - for (i = 0; i < single_blocks_cnt; ++i) - print_result("Block", single_blocks[i], 16); + if (found_blocks < max_blocks) { + Dbprintf("-----------------------------------------"); + Dbprintf("Blocks with unknown position:"); + Dbprintf("-----------------------------------------"); + for (i = 0; i < single_blocks_cnt; ++i) + print_result("Block", single_blocks[i], 16); - Dbprintf("-----------------------------------------"); - } - cmd_send(CMD_ACK,0,0,0,0,0); + Dbprintf("-----------------------------------------"); + } + cmd_send(CMD_ACK,0,0,0,0,0); } static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) { - uint32_t tab[1024] = {0}; // data times frame - uint32_t u = 0; - uint8_t parity = 0; - bool comp = 0; + uint32_t tab[1024] = {0}; // data times frame + uint32_t u = 0; + uint8_t parity = 0; + bool comp = 0; - //BUILD OF THE DATA FRAME - //alimentation of the tag (time for initializing) - AddPatternPCF7931(init_delay, 0, 8192/2*T0_PCF, tab); - AddPatternPCF7931(8192/2*T0_PCF + 319*T0_PCF+70, 3*T0_PCF, 29*T0_PCF, tab); - //password indication bit - AddBitPCF7931(1, tab, l, p); - //password (on 56 bits) - AddBytePCF7931(pass[0], tab, l, p); - AddBytePCF7931(pass[1], tab, l, p); - AddBytePCF7931(pass[2], tab, l, p); - AddBytePCF7931(pass[3], tab, l, p); - AddBytePCF7931(pass[4], tab, l, p); - AddBytePCF7931(pass[5], tab, l, p); - AddBytePCF7931(pass[6], tab, l, p); - //programming mode (0 or 1) - AddBitPCF7931(0, tab, l, p); + //BUILD OF THE DATA FRAME + //alimentation of the tag (time for initializing) + AddPatternPCF7931(init_delay, 0, 8192/2*T0_PCF, tab); + AddPatternPCF7931(8192/2*T0_PCF + 319*T0_PCF+70, 3*T0_PCF, 29*T0_PCF, tab); + //password indication bit + AddBitPCF7931(1, tab, l, p); + //password (on 56 bits) + AddBytePCF7931(pass[0], tab, l, p); + AddBytePCF7931(pass[1], tab, l, p); + AddBytePCF7931(pass[2], tab, l, p); + AddBytePCF7931(pass[3], tab, l, p); + AddBytePCF7931(pass[4], tab, l, p); + AddBytePCF7931(pass[5], tab, l, p); + AddBytePCF7931(pass[6], tab, l, p); + //programming mode (0 or 1) + AddBitPCF7931(0, tab, l, p); - //block adress on 6 bits - for (u = 0; u < 6; ++u) { - if (address&(1< 0xFFFF){ - tab[u] -= 0xFFFF; - comp = 0; - } - } + //compensation of the counter reload + while (!comp){ + comp = 1; + for (u = 0; tab[u] != 0; ++u) + if(tab[u] > 0xFFFF){ + tab[u] -= 0xFFFF; + comp = 0; + } + } - SendCmdPCF7931(tab); + SendCmdPCF7931(tab); } /* Write on a byte of a PCF7931 tag @@ -391,16 +391,16 @@ static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int3 @param data : data to write */ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) { - Dbprintf("Initialization delay : %d us", init_delay); - Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p); - Dbprintf("Password (LSB first on each byte): %02x %02x %02x %02x %02x %02x %02x", pass1, pass2, pass3, pass4, pass5, pass6, pass7); - Dbprintf("Block address : %02x", address); - Dbprintf("Byte address : %02x", byte); - Dbprintf("Data : %02x", data); + Dbprintf("Initialization delay : %d us", init_delay); + Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p); + Dbprintf("Password (LSB first on each byte): %02x %02x %02x %02x %02x %02x %02x", pass1, pass2, pass3, pass4, pass5, pass6, pass7); + Dbprintf("Block address : %02x", address); + Dbprintf("Byte address : %02x", byte); + Dbprintf("Data : %02x", data); - uint8_t password[7] = {pass1, pass2, pass3, pass4, pass5, pass6, pass7}; + uint8_t password[7] = {pass1, pass2, pass3, pass4, pass5, pass6, pass7}; - RealWritePCF7931 (password, init_delay, l, p, address, byte, data); + RealWritePCF7931 (password, init_delay, l, p, address, byte, data); } @@ -409,52 +409,52 @@ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, ui */ void SendCmdPCF7931(uint32_t * tab){ - uint16_t u=0, tempo=0; + uint16_t u=0, tempo=0; - Dbprintf("Sending data frame..."); + Dbprintf("Sending data frame..."); - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU ); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU ); - LED_A_ON(); + LED_A_ON(); - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + // steal this pin from the SSP and use it to control the modulation + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - //initialization of the timer - AT91C_BASE_PMC->PMC_PCER |= (0x1 << AT91C_ID_TC0); - AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable - AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; //clock at 48/32 MHz - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN; - AT91C_BASE_TCB->TCB_BCR = 1; + //initialization of the timer + AT91C_BASE_PMC->PMC_PCER |= (0x1 << AT91C_ID_TC0); + AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable + AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; //clock at 48/32 MHz + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN; + AT91C_BASE_TCB->TCB_BCR = 1; - tempo = AT91C_BASE_TC0->TC_CV; - for( u = 0; tab[u] != 0; u += 3){ - // modulate antenna - HIGH(GPIO_SSC_DOUT); - while (tempo != tab[u]) - tempo = AT91C_BASE_TC0->TC_CV; + tempo = AT91C_BASE_TC0->TC_CV; + for( u = 0; tab[u] != 0; u += 3){ + // modulate antenna + HIGH(GPIO_SSC_DOUT); + while (tempo != tab[u]) + tempo = AT91C_BASE_TC0->TC_CV; - // stop modulating antenna - LOW(GPIO_SSC_DOUT); - while (tempo != tab[u+1]) - tempo = AT91C_BASE_TC0->TC_CV; + // stop modulating antenna + LOW(GPIO_SSC_DOUT); + while (tempo != tab[u+1]) + tempo = AT91C_BASE_TC0->TC_CV; - // modulate antenna - HIGH(GPIO_SSC_DOUT); - while (tempo != tab[u+2]) - tempo = AT91C_BASE_TC0->TC_CV; - } + // modulate antenna + HIGH(GPIO_SSC_DOUT); + while (tempo != tab[u+2]) + tempo = AT91C_BASE_TC0->TC_CV; + } - LED_A_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(200); + LED_A_OFF(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(200); - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable - LED(0xFFFF, 1000); + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable + LED(0xFFFF, 1000); } @@ -465,16 +465,16 @@ void SendCmdPCF7931(uint32_t * tab){ * @param p : offset on low pulse positioning */ bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p){ - uint32_t u; - for (u = 0; u < 8; ++u) { - if (byte & (1 << u)) { //bit is 1 - if( AddBitPCF7931(1, tab, l, p)==1) return 1; - } else { //bit is 0 - if (AddBitPCF7931(0, tab, l, p)==1) return 1; - } - } + uint32_t u; + for (u = 0; u < 8; ++u) { + if (byte & (1 << u)) { //bit is 1 + if( AddBitPCF7931(1, tab, l, p)==1) return 1; + } else { //bit is 0 + if (AddBitPCF7931(0, tab, l, p)==1) return 1; + } + } - return 0; + return 0; } /* Add a bits for building the data frame of PCF7931 tags @@ -484,32 +484,32 @@ bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p){ * @param p : offset on low pulse positioning */ bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p){ - uint8_t u = 0; + uint8_t u = 0; - //we put the cursor at the last value of the array - for ( u = 0; tab[u] != 0; u += 3 ) { } + //we put the cursor at the last value of the array + for ( u = 0; tab[u] != 0; u += 3 ) { } - if ( b == 1 ) { //add a bit 1 - if ( u == 0 ) - tab[u] = 34 * T0_PCF + p; - else - tab[u] = 34 * T0_PCF + tab[u-1] + p; + if ( b == 1 ) { //add a bit 1 + if ( u == 0 ) + tab[u] = 34 * T0_PCF + p; + else + tab[u] = 34 * T0_PCF + tab[u-1] + p; - tab[u+1] = 6 * T0_PCF + tab[u] + l; - tab[u+2] = 88 * T0_PCF + tab[u+1] - l - p; - return 0; - } else { //add a bit 0 + tab[u+1] = 6 * T0_PCF + tab[u] + l; + tab[u+2] = 88 * T0_PCF + tab[u+1] - l - p; + return 0; + } else { //add a bit 0 - if ( u == 0 ) - tab[u] = 98 * T0_PCF + p; - else - tab[u] = 98 * T0_PCF + tab[u-1] + p; + if ( u == 0 ) + tab[u] = 98 * T0_PCF + p; + else + tab[u] = 98 * T0_PCF + tab[u-1] + p; - tab[u+1] = 6 * T0_PCF + tab[u] + l; - tab[u+2] = 24 * T0_PCF + tab[u+1] - l - p; - return 0; - } - return 1; + tab[u+1] = 6 * T0_PCF + tab[u] + l; + tab[u+2] = 24 * T0_PCF + tab[u+1] - l - p; + return 0; + } + return 1; } /* Add a custom pattern in the data frame @@ -519,12 +519,12 @@ bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p){ * @param tab : array of the data frame */ bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t * tab){ - uint32_t u = 0; - for(u = 0; tab[u] != 0; u += 3){} //we put the cursor at the last value of the array + uint32_t u = 0; + for(u = 0; tab[u] != 0; u += 3){} //we put the cursor at the last value of the array - tab[u] = (u == 0) ? a : a + tab[u-1]; - tab[u+1] = b + tab[u]; - tab[u+2] = c + tab[u+1]; + tab[u] = (u == 0) ? a : a + tab[u-1]; + tab[u+1] = b + tab[u]; + tab[u+2] = c + tab[u+1]; - return 0; + return 0; } \ No newline at end of file diff --git a/armsrc/printf.c b/armsrc/printf.c index c148bc9fd..ff48dec1c 100644 --- a/armsrc/printf.c +++ b/armsrc/printf.c @@ -1,6 +1,6 @@ /*- * Copyright (c) 1986, 1988, 1991, 1993 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph @@ -31,7 +31,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94 + * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94 */ #include "printf.h" @@ -50,7 +50,7 @@ char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz"; #define toupper(c) ((c) - 0x20 * (((c) >= 'a') && ((c) <= 'z'))) /* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */ -#define MAXNBUF (sizeof(intmax_t) * NBBY + 1) +#define MAXNBUF (sizeof(intmax_t) * NBBY + 1) /* * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse @@ -61,17 +61,17 @@ char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz"; static char * ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper) { - char *p, c; + char *p, c; - p = nbuf; - *p = '\0'; - do { - c = hex2ascii(num % base); - *++p = upper ? toupper(c) : c; - } while (num /= base); - if (lenp) - *lenp = p - nbuf; - return (p); + p = nbuf; + *p = '\0'; + do { + c = hex2ascii(num % base); + *++p = upper ? toupper(c) : c; + } while (num /= base); + if (lenp) + *lenp = p - nbuf; + return (p); } /* @@ -82,7 +82,7 @@ ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper) * The format %b is supported to decode error registers. * Its usage is: * - * printf("reg=%b\n", regval, "*"); + * printf("reg=%b\n", regval, "*"); * * where is the output base expressed as a control character, e.g. * \10 gives octal; \20 gives hex. Each arg is a sequence of characters, @@ -90,340 +90,340 @@ ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper) * the next characters (up to a control character, i.e. a character <= 32), * give the name of the register. Thus: * - * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); + * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); * * would produce output: * - * reg=3 + * reg=3 * * XXX: %D -- Hexdump, takes pointer and separator string: - * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX - * ("%*D", len, ptr, " " -> XX XX XX XX ... + * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX + * ("%*D", len, ptr, " " -> XX XX XX XX ... */ int kvsprintf(char const *fmt, void *arg, int radix, va_list ap) { #define PCHAR(c) {int cc=(c); *d++ = cc; retval++; } - char nbuf[MAXNBUF]; - char *d; - const char *p, *percent, *q; - u_char *up; - int ch, n; - uintmax_t num; - int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot; - int cflag, hflag, jflag, tflag, zflag; - int dwidth, upper; - char padc; - int stop = 0, retval = 0; + char nbuf[MAXNBUF]; + char *d; + const char *p, *percent, *q; + u_char *up; + int ch, n; + uintmax_t num; + int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot; + int cflag, hflag, jflag, tflag, zflag; + int dwidth, upper; + char padc; + int stop = 0, retval = 0; - num = 0; - d = (char *) arg; + num = 0; + d = (char *) arg; - if (fmt == NULL) - fmt = "(fmt null)\n"; + if (fmt == NULL) + fmt = "(fmt null)\n"; - if (radix < 2 || radix > 36) - radix = 10; + if (radix < 2 || radix > 36) + radix = 10; - for (;;) { - padc = ' '; - width = 0; - while ((ch = (u_char)*fmt++) != '%' || stop) { - PCHAR(ch); - if (ch == '\0') - return (retval); - } - percent = fmt - 1; - qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0; - sign = 0; dot = 0; dwidth = 0; upper = 0; - cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0; -reswitch: switch (ch = (u_char)*fmt++) { - case '.': - dot = 1; - goto reswitch; - case '#': - sharpflag = 1; - goto reswitch; - case '+': - sign = 1; - goto reswitch; - case '-': - ladjust = 1; - goto reswitch; - case '%': - PCHAR(ch); - break; - case '*': - if (!dot) { - width = va_arg(ap, int); - if (width < 0) { - ladjust = !ladjust; - width = -width; - } - } else { - dwidth = va_arg(ap, int); - } - goto reswitch; - case '0': - if (!dot) { - padc = '0'; - goto reswitch; - } - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - for (n = 0;; ++fmt) { - n = n * 10 + ch - '0'; - ch = *fmt; - if (ch < '0' || ch > '9') - break; - } - if (dot) - dwidth = n; - else - width = n; - goto reswitch; - case 'b': - num = (u_int)va_arg(ap, int); - p = va_arg(ap, char *); - for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;) - PCHAR(*q--); + for (;;) { + padc = ' '; + width = 0; + while ((ch = (u_char)*fmt++) != '%' || stop) { + PCHAR(ch); + if (ch == '\0') + return (retval); + } + percent = fmt - 1; + qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0; + sign = 0; dot = 0; dwidth = 0; upper = 0; + cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0; +reswitch: switch (ch = (u_char)*fmt++) { + case '.': + dot = 1; + goto reswitch; + case '#': + sharpflag = 1; + goto reswitch; + case '+': + sign = 1; + goto reswitch; + case '-': + ladjust = 1; + goto reswitch; + case '%': + PCHAR(ch); + break; + case '*': + if (!dot) { + width = va_arg(ap, int); + if (width < 0) { + ladjust = !ladjust; + width = -width; + } + } else { + dwidth = va_arg(ap, int); + } + goto reswitch; + case '0': + if (!dot) { + padc = '0'; + goto reswitch; + } + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + for (n = 0;; ++fmt) { + n = n * 10 + ch - '0'; + ch = *fmt; + if (ch < '0' || ch > '9') + break; + } + if (dot) + dwidth = n; + else + width = n; + goto reswitch; + case 'b': + num = (u_int)va_arg(ap, int); + p = va_arg(ap, char *); + for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;) + PCHAR(*q--); - if (num == 0) - break; + if (num == 0) + break; - for (tmp = 0; *p;) { - n = *p++; - if (num & (1 << (n - 1))) { - PCHAR(tmp ? ',' : '<'); - for (; (n = *p) > ' '; ++p) - PCHAR(n); - tmp = 1; - } else - for (; *p > ' '; ++p) - continue; - } - if (tmp) - PCHAR('>'); - break; - case 'c': - PCHAR(va_arg(ap, int)); - break; - case 'D': - up = va_arg(ap, u_char *); - p = va_arg(ap, char *); - if (!width) - width = 16; - while(width--) { - PCHAR(hex2ascii(*up >> 4)); - PCHAR(hex2ascii(*up & 0x0f)); - up++; - if (width) - for (q=p;*q;q++) - PCHAR(*q); - } - break; - case 'd': - case 'i': - base = 10; - sign = 1; - goto handle_sign; - case 'h': - if (hflag) { - hflag = 0; - cflag = 1; - } else - hflag = 1; - goto reswitch; - case 'j': - jflag = 1; - goto reswitch; - case 'l': - if (lflag) { - lflag = 0; - qflag = 1; - } else - lflag = 1; - goto reswitch; - case 'n': - if (jflag) - *(va_arg(ap, intmax_t *)) = retval; - else if (qflag) - *(va_arg(ap, quad_t *)) = retval; - else if (lflag) - *(va_arg(ap, long *)) = retval; - else if (zflag) - *(va_arg(ap, size_t *)) = retval; - else if (hflag) - *(va_arg(ap, short *)) = retval; - else if (cflag) - *(va_arg(ap, char *)) = retval; - else - *(va_arg(ap, int *)) = retval; - break; - case 'o': - base = 8; - goto handle_nosign; - case 'p': - base = 16; - sharpflag = (width == 0); - sign = 0; - num = (uintptr_t)va_arg(ap, void *); - goto number; - case 'q': - qflag = 1; - goto reswitch; - case 'r': - base = radix; - if (sign) - goto handle_sign; - goto handle_nosign; - case 's': - p = va_arg(ap, char *); - if (p == NULL) - p = "(null)"; - if (!dot) - n = strlen (p); - else - for (n = 0; n < dwidth && p[n]; n++) - continue; + for (tmp = 0; *p;) { + n = *p++; + if (num & (1 << (n - 1))) { + PCHAR(tmp ? ',' : '<'); + for (; (n = *p) > ' '; ++p) + PCHAR(n); + tmp = 1; + } else + for (; *p > ' '; ++p) + continue; + } + if (tmp) + PCHAR('>'); + break; + case 'c': + PCHAR(va_arg(ap, int)); + break; + case 'D': + up = va_arg(ap, u_char *); + p = va_arg(ap, char *); + if (!width) + width = 16; + while(width--) { + PCHAR(hex2ascii(*up >> 4)); + PCHAR(hex2ascii(*up & 0x0f)); + up++; + if (width) + for (q=p;*q;q++) + PCHAR(*q); + } + break; + case 'd': + case 'i': + base = 10; + sign = 1; + goto handle_sign; + case 'h': + if (hflag) { + hflag = 0; + cflag = 1; + } else + hflag = 1; + goto reswitch; + case 'j': + jflag = 1; + goto reswitch; + case 'l': + if (lflag) { + lflag = 0; + qflag = 1; + } else + lflag = 1; + goto reswitch; + case 'n': + if (jflag) + *(va_arg(ap, intmax_t *)) = retval; + else if (qflag) + *(va_arg(ap, quad_t *)) = retval; + else if (lflag) + *(va_arg(ap, long *)) = retval; + else if (zflag) + *(va_arg(ap, size_t *)) = retval; + else if (hflag) + *(va_arg(ap, short *)) = retval; + else if (cflag) + *(va_arg(ap, char *)) = retval; + else + *(va_arg(ap, int *)) = retval; + break; + case 'o': + base = 8; + goto handle_nosign; + case 'p': + base = 16; + sharpflag = (width == 0); + sign = 0; + num = (uintptr_t)va_arg(ap, void *); + goto number; + case 'q': + qflag = 1; + goto reswitch; + case 'r': + base = radix; + if (sign) + goto handle_sign; + goto handle_nosign; + case 's': + p = va_arg(ap, char *); + if (p == NULL) + p = "(null)"; + if (!dot) + n = strlen (p); + else + for (n = 0; n < dwidth && p[n]; n++) + continue; - width -= n; + width -= n; - if (!ladjust && width > 0) - while (width--) - PCHAR(padc); - while (n--) - PCHAR(*p++); - if (ladjust && width > 0) - while (width--) - PCHAR(padc); - break; - case 't': - tflag = 1; - goto reswitch; - case 'u': - base = 10; - goto handle_nosign; - case 'X': - upper = 1; - case 'x': - base = 16; - goto handle_nosign; - case 'y': - base = 16; - sign = 1; - goto handle_sign; - case 'z': - zflag = 1; - goto reswitch; + if (!ladjust && width > 0) + while (width--) + PCHAR(padc); + while (n--) + PCHAR(*p++); + if (ladjust && width > 0) + while (width--) + PCHAR(padc); + break; + case 't': + tflag = 1; + goto reswitch; + case 'u': + base = 10; + goto handle_nosign; + case 'X': + upper = 1; + case 'x': + base = 16; + goto handle_nosign; + case 'y': + base = 16; + sign = 1; + goto handle_sign; + case 'z': + zflag = 1; + goto reswitch; handle_nosign: - sign = 0; - if (jflag) - num = va_arg(ap, uintmax_t); - else if (qflag) - num = va_arg(ap, u_quad_t); - else if (tflag) - num = va_arg(ap, ptrdiff_t); - else if (lflag) - num = va_arg(ap, u_long); - else if (zflag) - num = va_arg(ap, size_t); - else if (hflag) - num = (u_short)va_arg(ap, int); - else if (cflag) - num = (u_char)va_arg(ap, int); - else - num = va_arg(ap, u_int); - goto number; + sign = 0; + if (jflag) + num = va_arg(ap, uintmax_t); + else if (qflag) + num = va_arg(ap, u_quad_t); + else if (tflag) + num = va_arg(ap, ptrdiff_t); + else if (lflag) + num = va_arg(ap, u_long); + else if (zflag) + num = va_arg(ap, size_t); + else if (hflag) + num = (u_short)va_arg(ap, int); + else if (cflag) + num = (u_char)va_arg(ap, int); + else + num = va_arg(ap, u_int); + goto number; handle_sign: - if (jflag) - num = va_arg(ap, intmax_t); - else if (qflag) - num = va_arg(ap, quad_t); - else if (tflag) - num = va_arg(ap, ptrdiff_t); - else if (lflag) - num = va_arg(ap, long); - else if (zflag) - num = va_arg(ap, ssize_t); - else if (hflag) - num = (short)va_arg(ap, int); - else if (cflag) - num = (char)va_arg(ap, int); - else - num = va_arg(ap, int); + if (jflag) + num = va_arg(ap, intmax_t); + else if (qflag) + num = va_arg(ap, quad_t); + else if (tflag) + num = va_arg(ap, ptrdiff_t); + else if (lflag) + num = va_arg(ap, long); + else if (zflag) + num = va_arg(ap, ssize_t); + else if (hflag) + num = (short)va_arg(ap, int); + else if (cflag) + num = (char)va_arg(ap, int); + else + num = va_arg(ap, int); number: - if (sign && (intmax_t)num < 0) { - neg = 1; - num = -(intmax_t)num; - } - p = ksprintn(nbuf, num, base, &tmp, upper); - if (sharpflag && num != 0) { - if (base == 8) - tmp++; - else if (base == 16) - tmp += 2; - } - if (neg) - tmp++; + if (sign && (intmax_t)num < 0) { + neg = 1; + num = -(intmax_t)num; + } + p = ksprintn(nbuf, num, base, &tmp, upper); + if (sharpflag && num != 0) { + if (base == 8) + tmp++; + else if (base == 16) + tmp += 2; + } + if (neg) + tmp++; - if (!ladjust && padc != '0' && width - && (width -= tmp) > 0) - while (width--) - PCHAR(padc); - if (neg) - PCHAR('-'); - if (sharpflag && num != 0) { - if (base == 8) { - PCHAR('0'); - } else if (base == 16) { - PCHAR('0'); - PCHAR('x'); - } - } - if (!ladjust && width && (width -= tmp) > 0) - while (width--) - PCHAR(padc); + if (!ladjust && padc != '0' && width + && (width -= tmp) > 0) + while (width--) + PCHAR(padc); + if (neg) + PCHAR('-'); + if (sharpflag && num != 0) { + if (base == 8) { + PCHAR('0'); + } else if (base == 16) { + PCHAR('0'); + PCHAR('x'); + } + } + if (!ladjust && width && (width -= tmp) > 0) + while (width--) + PCHAR(padc); - while (*p) - PCHAR(*p--); + while (*p) + PCHAR(*p--); - if (ladjust && width && (width -= tmp) > 0) - while (width--) - PCHAR(padc); + if (ladjust && width && (width -= tmp) > 0) + while (width--) + PCHAR(padc); - break; - default: - while (percent < fmt) - PCHAR(*percent++); - /* - * Since we ignore an formatting argument it is no - * longer safe to obey the remaining formatting - * arguments as the arguments will no longer match - * the format specs. - */ - stop = 1; - break; - } - } - PCHAR(0); - return retval; + break; + default: + while (percent < fmt) + PCHAR(*percent++); + /* + * Since we ignore an formatting argument it is no + * longer safe to obey the remaining formatting + * arguments as the arguments will no longer match + * the format specs. + */ + stop = 1; + break; + } + } + PCHAR(0); + return retval; #undef PCHAR } int vsprintf(char *dest, const char *fmt, va_list ap) { - return kvsprintf(fmt, dest, 10, ap); + return kvsprintf(fmt, dest, 10, ap); } int sprintf(char *dest, const char *fmt, ...) { - /* http://www.pagetable.com/?p=298 */ - int retval; - va_list ap; - va_start(ap, fmt); - retval = kvsprintf(fmt, dest, 10, ap); - va_end(ap); - return retval; + /* http://www.pagetable.com/?p=298 */ + int retval; + va_list ap; + va_start(ap, fmt); + retval = kvsprintf(fmt, dest, 10, ap); + va_end(ap); + return retval; } diff --git a/armsrc/start.c b/armsrc/start.c index 5d55f24e0..dcec6f59a 100644 --- a/armsrc/start.c +++ b/armsrc/start.c @@ -23,62 +23,62 @@ extern char __data_src_start__, __data_start__, __data_end__, __bss_start__, __b static voidpf inflate_malloc(voidpf opaque, uInt items, uInt size) { - uint8_t *allocated_memory; + uint8_t *allocated_memory; - allocated_memory = next_free_memory; - next_free_memory += items*size; - return allocated_memory; + allocated_memory = next_free_memory; + next_free_memory += items*size; + return allocated_memory; } static void inflate_free(voidpf opaque, voidpf address) { - // nothing to do + // nothing to do } static void uncompress_data_section(void) { - z_stream data_section; + z_stream data_section; - next_free_memory = BigBuf_get_addr(); + next_free_memory = BigBuf_get_addr(); - // initialize zstream structure - data_section.next_in = (uint8_t *) &__data_src_start__; - data_section.avail_in = &__data_end__ - &__data_start__; // uncompressed size. Wrong but doesn't matter. - data_section.next_out = (uint8_t *) &__data_start__; - data_section.avail_out = &__data_end__ - &__data_start__; // uncompressed size. Correct. - data_section.zalloc = &inflate_malloc; - data_section.zfree = &inflate_free; - data_section.opaque = NULL; + // initialize zstream structure + data_section.next_in = (uint8_t *) &__data_src_start__; + data_section.avail_in = &__data_end__ - &__data_start__; // uncompressed size. Wrong but doesn't matter. + data_section.next_out = (uint8_t *) &__data_start__; + data_section.avail_out = &__data_end__ - &__data_start__; // uncompressed size. Correct. + data_section.zalloc = &inflate_malloc; + data_section.zfree = &inflate_free; + data_section.opaque = NULL; - // initialize zlib for inflate - inflateInit2(&data_section, 15); + // initialize zlib for inflate + inflateInit2(&data_section, 15); - // uncompress data segment to RAM - inflate(&data_section, Z_FINISH); + // uncompress data segment to RAM + inflate(&data_section, Z_FINISH); - // save the size of the compressed data section - common_area.arg1 = data_section.total_in; + // save the size of the compressed data section + common_area.arg1 = data_section.total_in; } void __attribute__((section(".startos"))) Vector(void) { - /* Stack should have been set up by the bootloader */ - // char *src; - char *dst, *end; + /* Stack should have been set up by the bootloader */ + // char *src; + char *dst, *end; - uncompress_data_section(); + uncompress_data_section(); - /* Set up (that is: clear) BSS. */ - dst = &__bss_start__; - end = &__bss_end__; - while(dst < end) *dst++ = 0; + /* Set up (that is: clear) BSS. */ + dst = &__bss_start__; + end = &__bss_end__; + while(dst < end) *dst++ = 0; - // Set up data segment: Copy from flash to ram - // src = &__data_src_start__; - // dst = &__data_start__; - // end = &__data_end__; - // while(dst < end) *dst++ = *src++; + // Set up data segment: Copy from flash to ram + // src = &__data_src_start__; + // dst = &__data_start__; + // end = &__data_end__; + // while(dst < end) *dst++ = *src++; - AppMain(); + AppMain(); } #endif \ No newline at end of file diff --git a/armsrc/string.c b/armsrc/string.c index 6552ce1c9..e63ba4b05 100644 --- a/armsrc/string.c +++ b/armsrc/string.c @@ -11,39 +11,39 @@ void *memcpy(void *dest, const void *src, int len) { - uint8_t *d = dest; - const uint8_t *s = src; - while((len--) > 0) { - *d = *s; - d++; - s++; - } - return dest; + uint8_t *d = dest; + const uint8_t *s = src; + while((len--) > 0) { + *d = *s; + d++; + s++; + } + return dest; } void *memset(void *dest, int c, int len) { - uint8_t *d = dest; - while((len--) > 0) { - *d = c; - d++; - } - return dest; + uint8_t *d = dest; + while((len--) > 0) { + *d = c; + d++; + } + return dest; } int memcmp(const void *av, const void *bv, int len) { - const uint8_t *a = av; - const uint8_t *b = bv; + const uint8_t *a = av; + const uint8_t *b = bv; - while((len--) > 0) { - if(*a != *b) { - return *a - *b; - } - a++; - b++; - } - return 0; + while((len--) > 0) { + if(*a != *b) { + return *a - *b; + } + a++; + b++; + } + return 0; } void memxor(uint8_t * dest, uint8_t * src, size_t len) { @@ -53,36 +53,36 @@ void memxor(uint8_t * dest, uint8_t * src, size_t len) { int strlen(const char *str) { - int l = 0; - while(*str) { - l++; - str++; - } - return l; + int l = 0; + while(*str) { + l++; + str++; + } + return l; } char* strncat(char *dest, const char *src, unsigned int n) { - unsigned int dest_len = strlen(dest); - unsigned int i; + unsigned int dest_len = strlen(dest); + unsigned int i; - for (i = 0 ; i < n && src[i] != '\0' ; i++) - dest[dest_len + i] = src[i]; - dest[dest_len + i] = '\0'; + for (i = 0 ; i < n && src[i] != '\0' ; i++) + dest[dest_len + i] = src[i]; + dest[dest_len + i] = '\0'; - return dest; + return dest; } char* strcat(char *dest, const char *src) { - unsigned int dest_len = strlen(dest); - unsigned int i; + unsigned int dest_len = strlen(dest); + unsigned int i; - for (i = 0 ; src[i] != '\0' ; i++) - dest[dest_len + i] = src[i]; - dest[dest_len + i] = '\0'; + for (i = 0 ; src[i] != '\0' ; i++) + dest[dest_len + i] = src[i]; + dest[dest_len + i] = '\0'; - return dest; + return dest; } ////////////////////////////////////////// code to do 'itoa' diff --git a/armsrc/ticks.c b/armsrc/ticks.c index cfa36d12f..7445781bf 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -12,160 +12,160 @@ // attempt at high resolution microsecond timer // beware: timer counts in 21.3uS increments (1024/48Mhz) void SpinDelayUs(int us) { - int ticks = (48 * us) >> 10; + int ticks = (48 * us) >> 10; - // Borrow a PWM unit for my real-time clock - AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); + // Borrow a PWM unit for my real-time clock + AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); - // 48 MHz / 1024 gives 46.875 kHz - AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10); // Channel Mode Register - AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; // Channel Duty Cycle Register - AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff; // Channel Period Register + // 48 MHz / 1024 gives 46.875 kHz + AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10); // Channel Mode Register + AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; // Channel Duty Cycle Register + AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff; // Channel Period Register - uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; + uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; - for(;;) { - uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; - if (now == (uint16_t)(start + ticks)) - return; + for(;;) { + uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; + if (now == (uint16_t)(start + ticks)) + return; - WDT_HIT(); - } + WDT_HIT(); + } } void SpinDelay(int ms) { // convert to uS and call microsecond delay function - SpinDelayUs(ms*1000); + SpinDelayUs(ms*1000); } // ------------------------------------------------------------------------- // timer lib // ------------------------------------------------------------------------- // test procedure: // -// ti = GetTickCount(); -// SpinDelay(1000); -// ti = GetTickCount() - ti; -// Dbprintf("timer(1s): %d t=%d", ti, GetTickCount()); +// ti = GetTickCount(); +// SpinDelay(1000); +// ti = GetTickCount() - ti; +// Dbprintf("timer(1s): %d t=%d", ti, GetTickCount()); void StartTickCount(void) { - // This timer is based on the slow clock. The slow clock frequency is between 22kHz and 40kHz. - // We can determine the actual slow clock frequency by looking at the Main Clock Frequency Register. - uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & 0xffff; // = 16 * main clock frequency (16MHz) / slow clock frequency - // set RealTimeCounter divider to count at 1kHz: - AT91C_BASE_RTTC->RTTC_RTMR = AT91C_RTTC_RTTRST | ((256000 + (mainf/2)) / mainf); - // note: worst case precision is approx 2.5% + // This timer is based on the slow clock. The slow clock frequency is between 22kHz and 40kHz. + // We can determine the actual slow clock frequency by looking at the Main Clock Frequency Register. + uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & 0xffff; // = 16 * main clock frequency (16MHz) / slow clock frequency + // set RealTimeCounter divider to count at 1kHz: + AT91C_BASE_RTTC->RTTC_RTMR = AT91C_RTTC_RTTRST | ((256000 + (mainf/2)) / mainf); + // note: worst case precision is approx 2.5% } /* * Get the current count. */ uint32_t RAMFUNC GetTickCount(void){ - return AT91C_BASE_RTTC->RTTC_RTVR;// was * 2; + return AT91C_BASE_RTTC->RTTC_RTVR;// was * 2; } // ------------------------------------------------------------------------- // microseconds timer // ------------------------------------------------------------------------- void StartCountUS(void) { - AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1); - AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE; + AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1); + AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE; - // fast clock - // tick=1.5mks - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable - AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK(48MHz) / 32 - AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_ACPA_CLEAR | - AT91C_TC_ACPC_SET | AT91C_TC_ASWTRG_SET; - AT91C_BASE_TC0->TC_RA = 1; - AT91C_BASE_TC0->TC_RC = 0xBFFF + 1; // 0xC000 + // fast clock + // tick=1.5mks + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable + AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK(48MHz) / 32 + AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_ACPA_CLEAR | + AT91C_TC_ACPC_SET | AT91C_TC_ASWTRG_SET; + AT91C_BASE_TC0->TC_RA = 1; + AT91C_BASE_TC0->TC_RC = 0xBFFF + 1; // 0xC000 - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // timer disable - AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_XC1; // from timer 0 + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // timer disable + AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_XC1; // from timer 0 - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - AT91C_BASE_TCB->TCB_BCR = 1; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + AT91C_BASE_TCB->TCB_BCR = 1; - while (AT91C_BASE_TC1->TC_CV > 0); + while (AT91C_BASE_TC1->TC_CV > 0); } uint32_t RAMFUNC GetCountUS(void){ - //return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV / 15) * 10); - // By suggestion from PwPiwi, http://www.proxmark.org/forum/viewtopic.php?pid=17548#p17548 - return ((uint32_t)AT91C_BASE_TC1->TC_CV) * 0x8000 + (((uint32_t)AT91C_BASE_TC0->TC_CV) * 2) / 3; + //return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV / 15) * 10); + // By suggestion from PwPiwi, http://www.proxmark.org/forum/viewtopic.php?pid=17548#p17548 + return ((uint32_t)AT91C_BASE_TC1->TC_CV) * 0x8000 + (((uint32_t)AT91C_BASE_TC0->TC_CV) * 2) / 3; } // ------------------------------------------------------------------------- // Timer for iso14443 commands. Uses ssp_clk from FPGA // ------------------------------------------------------------------------- void StartCountSspClk(void) { - AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1) | (1 << AT91C_ID_TC2); // Enable Clock to all timers - AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_TIOA1 // XC0 Clock = TIOA1 - | AT91C_TCB_TC1XC1S_NONE // XC1 Clock = none - | AT91C_TCB_TC2XC2S_TIOA0; // XC2 Clock = TIOA0 + AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1) | (1 << AT91C_ID_TC2); // Enable Clock to all timers + AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_TIOA1 // XC0 Clock = TIOA1 + | AT91C_TCB_TC1XC1S_NONE // XC1 Clock = none + | AT91C_TCB_TC2XC2S_TIOA0; // XC2 Clock = TIOA0 - // configure TC1 to create a short pulse on TIOA1 when a rising edge on TIOB1 (= ssp_clk from FPGA) occurs: - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // disable TC1 - AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK // TC1 Clock = MCK(48MHz)/2 = 24MHz - | AT91C_TC_CPCSTOP // Stop clock on RC compare - | AT91C_TC_EEVTEDG_RISING // Trigger on rising edge of Event - | AT91C_TC_EEVT_TIOB // Event-Source: TIOB1 (= ssp_clk from FPGA = 13,56MHz/16) - | AT91C_TC_ENETRG // Enable external trigger event - | AT91C_TC_WAVESEL_UP // Upmode without automatic trigger on RC compare - | AT91C_TC_WAVE // Waveform Mode - | AT91C_TC_AEEVT_SET // Set TIOA1 on external event - | AT91C_TC_ACPC_CLEAR; // Clear TIOA1 on RC Compare - AT91C_BASE_TC1->TC_RC = 0x04; // RC Compare value = 0x04 + // configure TC1 to create a short pulse on TIOA1 when a rising edge on TIOB1 (= ssp_clk from FPGA) occurs: + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // disable TC1 + AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK // TC1 Clock = MCK(48MHz)/2 = 24MHz + | AT91C_TC_CPCSTOP // Stop clock on RC compare + | AT91C_TC_EEVTEDG_RISING // Trigger on rising edge of Event + | AT91C_TC_EEVT_TIOB // Event-Source: TIOB1 (= ssp_clk from FPGA = 13,56MHz/16) + | AT91C_TC_ENETRG // Enable external trigger event + | AT91C_TC_WAVESEL_UP // Upmode without automatic trigger on RC compare + | AT91C_TC_WAVE // Waveform Mode + | AT91C_TC_AEEVT_SET // Set TIOA1 on external event + | AT91C_TC_ACPC_CLEAR; // Clear TIOA1 on RC Compare + AT91C_BASE_TC1->TC_RC = 0x04; // RC Compare value = 0x04 - // use TC0 to count TIOA1 pulses - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // disable TC0 - AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_XC0 // TC0 clock = XC0 clock = TIOA1 - | AT91C_TC_WAVE // Waveform Mode - | AT91C_TC_WAVESEL_UP // just count - | AT91C_TC_ACPA_CLEAR // Clear TIOA0 on RA Compare - | AT91C_TC_ACPC_SET; // Set TIOA0 on RC Compare - AT91C_BASE_TC0->TC_RA = 1; // RA Compare value = 1; pulse width to TC2 - AT91C_BASE_TC0->TC_RC = 0; // RC Compare value = 0; increment TC2 on overflow + // use TC0 to count TIOA1 pulses + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // disable TC0 + AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_XC0 // TC0 clock = XC0 clock = TIOA1 + | AT91C_TC_WAVE // Waveform Mode + | AT91C_TC_WAVESEL_UP // just count + | AT91C_TC_ACPA_CLEAR // Clear TIOA0 on RA Compare + | AT91C_TC_ACPC_SET; // Set TIOA0 on RC Compare + AT91C_BASE_TC0->TC_RA = 1; // RA Compare value = 1; pulse width to TC2 + AT91C_BASE_TC0->TC_RC = 0; // RC Compare value = 0; increment TC2 on overflow - // use TC2 to count TIOA0 pulses (giving us a 32bit counter (TC0/TC2) clocked by ssp_clk) - AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKDIS; // disable TC2 - AT91C_BASE_TC2->TC_CMR = AT91C_TC_CLKS_XC2 // TC2 clock = XC2 clock = TIOA0 - | AT91C_TC_WAVE // Waveform Mode - | AT91C_TC_WAVESEL_UP; // just count + // use TC2 to count TIOA0 pulses (giving us a 32bit counter (TC0/TC2) clocked by ssp_clk) + AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKDIS; // disable TC2 + AT91C_BASE_TC2->TC_CMR = AT91C_TC_CLKS_XC2 // TC2 clock = XC2 clock = TIOA0 + | AT91C_TC_WAVE // Waveform Mode + | AT91C_TC_WAVESEL_UP; // just count - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // enable and reset TC0 - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // enable and reset TC1 - AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // enable and reset TC2 + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // enable and reset TC0 + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // enable and reset TC1 + AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // enable and reset TC2 - // synchronize the counter with the ssp_frame signal. - // Note: FPGA must be in any iso14443 mode, otherwise the frame signal would not be present - while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_FRAME)); // wait for ssp_frame to go high (start of frame) - while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_FRAME); // wait for ssp_frame to be low - while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)); // wait for ssp_clk to go high + // synchronize the counter with the ssp_frame signal. + // Note: FPGA must be in any iso14443 mode, otherwise the frame signal would not be present + while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_FRAME)); // wait for ssp_frame to go high (start of frame) + while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_FRAME); // wait for ssp_frame to be low + while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)); // wait for ssp_clk to go high - // note: up to now two ssp_clk rising edges have passed since the rising edge of ssp_frame - // it is now safe to assert a sync signal. This sets all timers to 0 on next active clock edge - AT91C_BASE_TCB->TCB_BCR = 1; // assert Sync (set all timers to 0 on next active clock edge) - // at the next (3rd) ssp_clk rising edge, TC1 will be reset (and not generate a clock signal to TC0) - // at the next (4th) ssp_clk rising edge, TC0 (the low word of our counter) will be reset. From now on, - // whenever the last three bits of our counter go 0, we can be sure to be in the middle of a frame transfer. - // (just started with the transfer of the 4th Bit). + // note: up to now two ssp_clk rising edges have passed since the rising edge of ssp_frame + // it is now safe to assert a sync signal. This sets all timers to 0 on next active clock edge + AT91C_BASE_TCB->TCB_BCR = 1; // assert Sync (set all timers to 0 on next active clock edge) + // at the next (3rd) ssp_clk rising edge, TC1 will be reset (and not generate a clock signal to TC0) + // at the next (4th) ssp_clk rising edge, TC0 (the low word of our counter) will be reset. From now on, + // whenever the last three bits of our counter go 0, we can be sure to be in the middle of a frame transfer. + // (just started with the transfer of the 4th Bit). - // The high word of the counter (TC2) will not reset until the low word (TC0) overflows. - // Therefore need to wait quite some time before we can use the counter. - while (AT91C_BASE_TC2->TC_CV > 0); + // The high word of the counter (TC2) will not reset until the low word (TC0) overflows. + // Therefore need to wait quite some time before we can use the counter. + while (AT91C_BASE_TC2->TC_CV > 0); } void ResetSspClk(void) { - //enable clock of timer and software trigger - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - while (AT91C_BASE_TC2->TC_CV > 0); + //enable clock of timer and software trigger + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + while (AT91C_BASE_TC2->TC_CV > 0); } uint32_t RAMFUNC GetCountSspClk(void) { - uint32_t tmp_count = (AT91C_BASE_TC2->TC_CV << 16) | AT91C_BASE_TC0->TC_CV; - if ((tmp_count & 0x0000ffff) == 0) //small chance that we may have missed an increment in TC2 - return (AT91C_BASE_TC2->TC_CV << 16); - return tmp_count; + uint32_t tmp_count = (AT91C_BASE_TC2->TC_CV << 16) | AT91C_BASE_TC0->TC_CV; + if ((tmp_count & 0x0000ffff) == 0) //small chance that we may have missed an increment in TC2 + return (AT91C_BASE_TC2->TC_CV << 16); + return tmp_count; } // ------------------------------------------------------------------------- @@ -173,68 +173,68 @@ uint32_t RAMFUNC GetCountSspClk(void) { // 1us = 1.5ticks // ------------------------------------------------------------------------- void StartTicks(void){ - // initialization of the timer - AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1); - AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE; + // initialization of the timer + AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1); + AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE; - // disable TC0 and TC1 for re-configuration - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + // disable TC0 and TC1 for re-configuration + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - // first configure TC1 (higher, 0xFFFF0000) 16 bit counter - AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_XC1; // just connect to TIOA0 from TC0 - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // re-enable timer and wait for TC0 + // first configure TC1 (higher, 0xFFFF0000) 16 bit counter + AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_XC1; // just connect to TIOA0 from TC0 + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // re-enable timer and wait for TC0 - // second configure TC0 (lower, 0x0000FFFF) 16 bit counter - AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK(48MHz) / 32 - AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | - AT91C_TC_ACPA_CLEAR | // RA comperator clears TIOA (carry bit) - AT91C_TC_ACPC_SET | // RC comperator sets TIOA (carry bit) - AT91C_TC_ASWTRG_SET; // SWTriger sets TIOA (carry bit) - AT91C_BASE_TC0->TC_RC = 0; // set TIOA (carry bit) on overflow, return to zero - AT91C_BASE_TC0->TC_RA = 1; // clear carry bit on next clock cycle - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // reset and re-enable timer + // second configure TC0 (lower, 0x0000FFFF) 16 bit counter + AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK(48MHz) / 32 + AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | + AT91C_TC_ACPA_CLEAR | // RA comperator clears TIOA (carry bit) + AT91C_TC_ACPC_SET | // RC comperator sets TIOA (carry bit) + AT91C_TC_ASWTRG_SET; // SWTriger sets TIOA (carry bit) + AT91C_BASE_TC0->TC_RC = 0; // set TIOA (carry bit) on overflow, return to zero + AT91C_BASE_TC0->TC_RA = 1; // clear carry bit on next clock cycle + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // reset and re-enable timer - // synchronized startup procedure - while (AT91C_BASE_TC0->TC_CV > 0); // wait until TC0 returned to zero - while (AT91C_BASE_TC0->TC_CV < 2); // and has started (TC_CV > TC_RA, now TC1 is cleared) + // synchronized startup procedure + while (AT91C_BASE_TC0->TC_CV > 0); // wait until TC0 returned to zero + while (AT91C_BASE_TC0->TC_CV < 2); // and has started (TC_CV > TC_RA, now TC1 is cleared) - // return to zero - AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - while (AT91C_BASE_TC0->TC_CV > 0); + // return to zero + AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + while (AT91C_BASE_TC0->TC_CV > 0); } uint32_t GetTicks(void) { - uint32_t hi, lo; + uint32_t hi, lo; - do { - hi = AT91C_BASE_TC1->TC_CV; - lo = AT91C_BASE_TC0->TC_CV; - } while(hi != AT91C_BASE_TC1->TC_CV); + do { + hi = AT91C_BASE_TC1->TC_CV; + lo = AT91C_BASE_TC0->TC_CV; + } while(hi != AT91C_BASE_TC1->TC_CV); - return (hi << 16) | lo; + return (hi << 16) | lo; } // Wait - Spindelay in ticks. // if called with a high number, this will trigger the WDT... void WaitTicks(uint32_t ticks){ - if ( ticks == 0 ) return; - ticks += GetTicks(); - while (GetTicks() < ticks); + if ( ticks == 0 ) return; + ticks += GetTicks(); + while (GetTicks() < ticks); } // Wait / Spindelay in us (microseconds) // 1us = 1.5ticks. void WaitUS(uint16_t us){ - WaitTicks( (uint32_t)us * 3/2 ); + WaitTicks( (uint32_t)us * 3/2 ); } void WaitMS(uint16_t ms){ - WaitTicks( (uint32_t)ms * 1500 ); + WaitTicks( (uint32_t)ms * 1500 ); } // stop clock void StopTicks(void){ - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; } diff --git a/armsrc/util.c b/armsrc/util.c index 04cf1fc33..e3027c997 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -10,7 +10,7 @@ #include "util.h" size_t nbytes(size_t nbits) { - return (nbits >> 3)+((nbits % 8) > 0); + return (nbits >> 3)+((nbits % 8) > 0); } /* @@ -19,19 +19,19 @@ size_t nbytes(size_t nbits) { Example: reflect(0x3e23L,3) == 0x3e26 */ uint32_t reflect(uint32_t v, int b) { - uint32_t t = v; - for ( int i = 0; i < b; ++i) { - if (t & 1) - v |= BITMASK((b-1)-i); - else - v &= ~BITMASK((b-1)-i); - t>>=1; - } - return v; + uint32_t t = v; + for ( int i = 0; i < b; ++i) { + if (t & 1) + v |= BITMASK((b-1)-i); + else + v &= ~BITMASK((b-1)-i); + t>>=1; + } + return v; } uint8_t reflect8(uint8_t b) { - return ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32; + return ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32; } uint16_t reflect16(uint16_t b) { uint16_t v = 0; @@ -56,19 +56,19 @@ uint16_t reflect16(uint16_t b) { } void num_to_bytes(uint64_t n, size_t len, uint8_t* dest) { - while (len--) { - dest[len] = (uint8_t) n; - n >>= 8; - } + while (len--) { + dest[len] = (uint8_t) n; + n >>= 8; + } } uint64_t bytes_to_num(uint8_t* src, size_t len) { - uint64_t num = 0; - while (len--) { - num = (num << 8) | (*src); - src++; - } - return num; + uint64_t num = 0; + while (len--) { + num = (num << 8) | (*src); + src++; + } + return num; } // RotateLeft - Ultralight, Desfire @@ -107,11 +107,11 @@ uint8_t hex2int(char hexchar){ case 'a': case 'A': return 10; break; case 'b': - case 'B': return 11; break; + case 'B': return 11; break; case 'c': case 'C': return 12; break; case 'd': - case 'D': return 13; break; + case 'D': return 13; break; case 'e': case 'E': return 14; break; case 'f': @@ -122,36 +122,36 @@ uint8_t hex2int(char hexchar){ } void LEDsoff() { - LED_A_OFF(); - LED_B_OFF(); - LED_C_OFF(); - LED_D_OFF(); + LED_A_OFF(); + LED_B_OFF(); + LED_C_OFF(); + LED_D_OFF(); } // LEDs: R(C) O(A) G(B) -- R(D) [1, 2, 4 and 8] void LED(int led, int ms) { - if (led & LED_RED) - LED_C_ON(); - if (led & LED_ORANGE) - LED_A_ON(); - if (led & LED_GREEN) - LED_B_ON(); - if (led & LED_RED2) - LED_D_ON(); + if (led & LED_RED) + LED_C_ON(); + if (led & LED_ORANGE) + LED_A_ON(); + if (led & LED_GREEN) + LED_B_ON(); + if (led & LED_RED2) + LED_D_ON(); - if (!ms) - return; + if (!ms) + return; - SpinDelay(ms); + SpinDelay(ms); - if (led & LED_RED) - LED_C_OFF(); - if (led & LED_ORANGE) - LED_A_OFF(); - if (led & LED_GREEN) - LED_B_OFF(); - if (led & LED_RED2) - LED_D_OFF(); + if (led & LED_RED) + LED_C_OFF(); + if (led & LED_ORANGE) + LED_A_OFF(); + if (led & LED_GREEN) + LED_B_OFF(); + if (led & LED_RED2) + LED_D_OFF(); } void SpinOff(uint32_t pause) { @@ -166,7 +166,7 @@ void SpinOff(uint32_t pause) { void SpinErr(uint8_t led, uint32_t speed, uint8_t times) { SpinOff(speed); NTIME(times) - { + { switch (led) { case 0: LED_A_INV(); @@ -223,102 +223,102 @@ void SpinUp(uint32_t speed) { // In general, don't use this function unless you expect a // double click, otherwise it will waste 500ms -- use BUTTON_HELD instead int BUTTON_CLICKED(int ms) { - // Up to 500ms in between clicks to mean a double click - int ticks = (48000 * (ms ? ms : 1000)) >> 10; + // Up to 500ms in between clicks to mean a double click + int ticks = (48000 * (ms ? ms : 1000)) >> 10; - // If we're not even pressed, forget about it! - if (!BUTTON_PRESS()) - return BUTTON_NO_CLICK; + // If we're not even pressed, forget about it! + if (!BUTTON_PRESS()) + return BUTTON_NO_CLICK; - // Borrow a PWM unit for my real-time clock - AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); - // 48 MHz / 1024 gives 46.875 kHz - AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10); - AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; - AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff; + // Borrow a PWM unit for my real-time clock + AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); + // 48 MHz / 1024 gives 46.875 kHz + AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10); + AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; + AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff; - uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; + uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; - int letoff = 0; - for(;;) - { - uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; + int letoff = 0; + for(;;) + { + uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; - // We haven't let off the button yet - if (!letoff) - { - // We just let it off! - if (!BUTTON_PRESS()) - { - letoff = 1; + // We haven't let off the button yet + if (!letoff) + { + // We just let it off! + if (!BUTTON_PRESS()) + { + letoff = 1; - // reset our timer for 500ms - start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; - ticks = (48000 * (500)) >> 10; - } + // reset our timer for 500ms + start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; + ticks = (48000 * (500)) >> 10; + } - // Still haven't let it off - else - // Have we held down a full second? - if (now == (uint16_t)(start + ticks)) - return BUTTON_HOLD; - } + // Still haven't let it off + else + // Have we held down a full second? + if (now == (uint16_t)(start + ticks)) + return BUTTON_HOLD; + } - // We already let off, did we click again? - else - // Sweet, double click! - if (BUTTON_PRESS()) - return BUTTON_DOUBLE_CLICK; + // We already let off, did we click again? + else + // Sweet, double click! + if (BUTTON_PRESS()) + return BUTTON_DOUBLE_CLICK; - // Have we ran out of time to double click? - else - if (now == (uint16_t)(start + ticks)) - // At least we did a single click - return BUTTON_SINGLE_CLICK; + // Have we ran out of time to double click? + else + if (now == (uint16_t)(start + ticks)) + // At least we did a single click + return BUTTON_SINGLE_CLICK; - WDT_HIT(); - } + WDT_HIT(); + } - // We should never get here - return BUTTON_ERROR; + // We should never get here + return BUTTON_ERROR; } // Determine if a button is held down int BUTTON_HELD(int ms) { - // If button is held for one second - int ticks = (48000 * (ms ? ms : 1000)) >> 10; + // If button is held for one second + int ticks = (48000 * (ms ? ms : 1000)) >> 10; - // If we're not even pressed, forget about it! - if (!BUTTON_PRESS()) - return BUTTON_NO_CLICK; + // If we're not even pressed, forget about it! + if (!BUTTON_PRESS()) + return BUTTON_NO_CLICK; - // Borrow a PWM unit for my real-time clock - AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); - // 48 MHz / 1024 gives 46.875 kHz - AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10); - AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; - AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff; + // Borrow a PWM unit for my real-time clock + AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); + // 48 MHz / 1024 gives 46.875 kHz + AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10); + AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; + AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff; - uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; + uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; - for(;;) - { - uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; + for(;;) + { + uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; - // As soon as our button let go, we didn't hold long enough - if (!BUTTON_PRESS()) - return BUTTON_SINGLE_CLICK; + // As soon as our button let go, we didn't hold long enough + if (!BUTTON_PRESS()) + return BUTTON_SINGLE_CLICK; - // Have we waited the full second? - else - if (now == (uint16_t)(start + ticks)) - return BUTTON_HOLD; + // Have we waited the full second? + else + if (now == (uint16_t)(start + ticks)) + return BUTTON_HOLD; - WDT_HIT(); - } + WDT_HIT(); + } - // We should never get here - return BUTTON_ERROR; + // We should never get here + return BUTTON_ERROR; } /* Similar to FpgaGatherVersion this formats stored version information @@ -327,30 +327,30 @@ int BUTTON_HELD(int ms) { * prefix in dst. */ void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information) { - struct version_information *v = (struct version_information*)version_information; - dst[0] = 0; - strncat(dst, prefix, len-1); - if (v->magic != VERSION_INFORMATION_MAGIC) { - strncat(dst, "Missing/Invalid version information\n", len - strlen(dst) - 1); - return; - } - if (v->versionversion != 1) { - strncat(dst, "Version information not understood\n", len - strlen(dst) - 1); - return; - } - if (!v->present) { - strncat(dst, "Version information not available\n", len - strlen(dst) - 1); - return; - } + struct version_information *v = (struct version_information*)version_information; + dst[0] = 0; + strncat(dst, prefix, len-1); + if (v->magic != VERSION_INFORMATION_MAGIC) { + strncat(dst, "Missing/Invalid version information\n", len - strlen(dst) - 1); + return; + } + if (v->versionversion != 1) { + strncat(dst, "Version information not understood\n", len - strlen(dst) - 1); + return; + } + if (!v->present) { + strncat(dst, "Version information not available\n", len - strlen(dst) - 1); + return; + } - strncat(dst, v->gitversion, len - strlen(dst) - 1); - if (v->clean == 0) { - strncat(dst, "-unclean", len - strlen(dst) - 1); - } else if (v->clean == 2) { - strncat(dst, "-suspect", len - strlen(dst) - 1); - } + strncat(dst, v->gitversion, len - strlen(dst) - 1); + if (v->clean == 0) { + strncat(dst, "-unclean", len - strlen(dst) - 1); + } else if (v->clean == 2) { + strncat(dst, "-suspect", len - strlen(dst) - 1); + } - strncat(dst, " ", len - strlen(dst) - 1); - strncat(dst, v->buildtime, len - strlen(dst) - 1); - strncat(dst, "\n", len - strlen(dst) - 1); + strncat(dst, " ", len - strlen(dst) - 1); + strncat(dst, v->buildtime, len - strlen(dst) - 1); + strncat(dst, "\n", len - strlen(dst) - 1); } diff --git a/armsrc/util.h b/armsrc/util.h index cc613b273..bca073273 100644 --- a/armsrc/util.h +++ b/armsrc/util.h @@ -46,8 +46,8 @@ size_t nbytes(size_t nbits); extern uint32_t reflect(uint32_t v, int b); // used in crc.c ... -extern uint8_t reflect8(uint8_t b); // dedicated 8bit reversal -extern uint16_t reflect16(uint16_t b); // dedicated 16bit reversal +extern uint8_t reflect8(uint8_t b); // dedicated 8bit reversal +extern uint16_t reflect16(uint16_t b); // dedicated 16bit reversal void num_to_bytes(uint64_t n, size_t len, uint8_t* dest); uint64_t bytes_to_num(uint8_t* src, size_t len);