]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Merge branch 'master' into topaz
authorpwpiwi <pwpiwi@users.noreply.github.com>
Tue, 25 Aug 2015 05:53:00 +0000 (07:53 +0200)
committerpwpiwi <pwpiwi@users.noreply.github.com>
Tue, 25 Aug 2015 05:53:00 +0000 (07:53 +0200)
43 files changed:
CHANGELOG.md
armsrc/BigBuf.c
armsrc/BigBuf.h
armsrc/Makefile
armsrc/appmain.c
armsrc/apps.h
armsrc/epa.c
armsrc/epa.h
armsrc/fpgaloader.c
armsrc/fpgaloader.h
armsrc/iso14443a.c
armsrc/iso14443b.c
armsrc/iso14443b.h [new file with mode: 0644]
armsrc/lfops.c
armsrc/lfsampling.c
armsrc/lfsampling.h
armsrc/mifarecmd.c
armsrc/mifareutil.h
armsrc/util.c
client/Makefile
client/cmddata.c
client/cmdhf.c
client/cmdhf14b.c
client/cmdhfmf.c
client/cmdhw.c
client/cmdlf.c
client/cmdlfawid.c [new file with mode: 0644]
client/cmdlfawid.h [new file with mode: 0644]
client/cmdlft55xx.c
client/cmdmain.c
client/hid-flasher/usb_cmd.h
client/lualibs/commands.lua
client/mifarehost.c
client/mifarehost.h
client/nonce2key/nonce2key.c
client/scripts/mifare_autopwn.lua
client/util.h
common/lfdemod.c
common/usb_cdc.c
common/usb_cdc.h
doc/RFID_Antenna-Basic-Form.stl [new file with mode: 0755]
doc/RFID_Antenna-With-Lanyard-Hook.stl [new file with mode: 0755]
include/usb_cmd.h

index 3f9546d9856277428b89f0caa355f205e9ac1093..e2196a39afb8ed1c1d54fdf2311d4bb813cae4db 100644 (file)
@@ -2,11 +2,28 @@
 All notable changes to this project will be documented in this file.
 This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
 
-## [Unreleased][unreleased]
+## [unreleased][unreleased]
+
+### Added
+- ISO14443a stand-alone operation with ARM CFLAG="WITH_ISO14443a_StandAlone". This code can read & emulate two banks of 14a tag UIDs and write to "magic" cards  (Craig Young) 
+- AWID26 command context added as 'lf awid' containing realtime demodulation as well as cloning/simulation based on tag numbers (Craig Young)
+- Added 'hw status'. This command makes the ARM print out some runtime information. (holiman) 
+- Added 'hw ping'. This command just sends a usb packets and checks if the pm3 is responsive. Can be used to abort certain operations which supports abort over usb. (holiman)
+- Added `data hex2bin` and `data bin2hex` for command line conversion between binary and hexadecimal (holiman)
+
+### Changed
+- Revised workflow for StandAloneMode14a (Craig Young)
+- EPA functions (`hf epa`) now support both ISO 14443-A and 14443-B cards (frederikmoellers)
+- 'hw version' only talks to ARM at startup, after that the info is cached. (pwpiwi)
+
+## [2.2.0][2015-07-12]
 
 ### Changed
+- Added `hf 14b raw -s` option to auto select a 14b std tag before raw command 
 - Changed `hf 14b write` to `hf 14b sriwrite` as it only applied to sri tags (marshmellow)
 - Added `hf 14b info` to `hf search` (marshmellow)
+- Added compression of fpga config and data, *BOOTROM REFLASH REQUIRED* (piwi)
+- Implemented better detection of mifare-tags that are not vulnerable to classic attacks (`hf mf mifare`, `hf mf nested`) (piwi)
 
 ### Added
 - Add `hf 14b info` to find and print info about std 14b tags and sri tags (using 14b raw commands in the client)  (marshmellow)
index a22c0cb0e499692054b66413c1af5214b290f063..6b52a5894545beaa352273aeea608945a6ada7b0 100644 (file)
@@ -88,6 +88,16 @@ void BigBuf_free_keep_EM(void)
        }
 }
 
+void BigBuf_print_status(void)
+{
+       Dbprintf("Memory");
+       Dbprintf("  BIGBUF_SIZE.............%d", BIGBUF_SIZE);
+       Dbprintf("  BigBuf_hi  .............%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)
index b44a12630ec52b60cd86b4d0faada7d0de020222..05b4180e4b21c77b1604734035b5478216b7918d 100644 (file)
 extern uint8_t *BigBuf_get_addr(void);
 extern uint8_t *BigBuf_get_EM_addr(void);
 extern uint16_t BigBuf_max_traceLen(void);
-void BigBuf_Clear(void);
+extern void BigBuf_Clear(void);
 extern uint8_t *BigBuf_malloc(uint16_t);
 extern void BigBuf_free(void);
 extern void BigBuf_free_keep_EM(void);
-
-uint16_t BigBuf_get_traceLen(void);
-void clear_trace();
-void set_tracing(bool enable);
-bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
-int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader);
-uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length);
+extern void BigBuf_print_status(void);
+extern uint16_t BigBuf_get_traceLen(void);
+extern void clear_trace();
+extern void set_tracing(bool enable);
+extern bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
+extern int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader);
+extern uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length);
 #endif /* __BIGBUF_H */
index 1214c949f3755c54833b8969753f8914042367c8..a59fa07358ae01f53f1c7622e059329cf0c14c48 100644 (file)
@@ -9,17 +9,17 @@
 APP_INCLUDES = apps.h
 
 #remove one of the following defines and comment out the relevant line
-#in the next section to remove that particular feature from compilation  
-APP_CFLAGS     = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG  -DWITH_CRC -DON_DEVICE \
+#in the next section to remove that particular feature from compilation
+APP_CFLAGS     = -DWITH_ISO14443a_StandAlone -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG  -DWITH_CRC -DON_DEVICE \
                                -fno-strict-aliasing -ffunction-sections -fdata-sections
-#-DWITH_LCD 
+#-DWITH_LCD
 
 #SRC_LCD = fonts.c LCD.c
 SRC_LF = lfops.c hitag2.c lfsampling.c
 SRC_ISO15693 = iso15693.c iso15693tools.c
 SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c
 SRC_ISO14443b = iso14443b.c
-SRC_CRAPTO1 = crapto1.c crypto1.c des.c aes.c 
+SRC_CRAPTO1 = crapto1.c crypto1.c des.c aes.c
 SRC_CRC = iso14443crc.c crc.c crc16.c crc32.c
 
 #the FPGA bitstream files. Note: order matters!
@@ -65,7 +65,7 @@ ARMSRC = fpgaloader.c \
 # Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC
 include ../common/Makefile.common
 
-OBJS = $(OBJDIR)/fullimage.s19 
+OBJS = $(OBJDIR)/fullimage.s19
 FPGA_COMPRESSOR = ../client/fpga_compress
 
 all: $(OBJS)
@@ -80,13 +80,13 @@ $(OBJDIR)/fpga_all.bit.z: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR)
 
 $(FPGA_COMPRESSOR):
                make -C ../client $(notdir $(FPGA_COMPRESSOR))
-               
+
 $(OBJDIR)/fullimage.stage1.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ)
        $(CC) $(LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS)
 
 $(OBJDIR)/fullimage.nodata.bin: $(OBJDIR)/fullimage.stage1.elf
        $(OBJCOPY) -O binary -I elf32-littlearm --remove-section .data $^ $@
-       
+
 $(OBJDIR)/fullimage.nodata.o: $(OBJDIR)/fullimage.nodata.bin
        $(OBJCOPY) -O elf32-littlearm -I binary -B arm --rename-section .data=stage1_image $^ $@
 
@@ -94,14 +94,14 @@ $(OBJDIR)/fullimage.data.bin: $(OBJDIR)/fullimage.stage1.elf
        $(OBJCOPY) -O binary -I elf32-littlearm --only-section .data $^ $@
 
 $(OBJDIR)/fullimage.data.bin.z: $(OBJDIR)/fullimage.data.bin $(FPGA_COMPRESSOR)
-       $(FPGA_COMPRESSOR) $(filter %.bin,$^) $@  
-       
+       $(FPGA_COMPRESSOR) $(filter %.bin,$^) $@
+
 $(OBJDIR)/fullimage.data.o: $(OBJDIR)/fullimage.data.bin.z
        $(OBJCOPY) -O elf32-littlearm -I binary -B arm --rename-section .data=compressed_data $^ $@
 
 $(OBJDIR)/fullimage.elf: $(OBJDIR)/fullimage.nodata.o $(OBJDIR)/fullimage.data.o
        $(CC) $(LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^
-       
+
 tarbin: $(OBJS)
        $(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(OBJS:%=armsrc/%) $(OBJS:%.s19=armsrc/%.elf)
 
index 0cbfa2498e6ca7349f23766af663cd57ab70ac47..38afd85d1bfc59cb7c8e0236e56512e26deee182 100644 (file)
 #include <hitag2.h>
 #include "lfsampling.h"
 #include "BigBuf.h"
+#include "mifareutil.h"
 #ifdef WITH_LCD
  #include "LCD.h"
 #endif
 
+// Craig Young - 14a stand-alone code
+#ifdef WITH_ISO14443a_StandAlone
+ #include "iso14443a.h"
+#endif
+
 #define abs(x) ( ((x)<0) ? -(x) : (x) )
 
 //=============================================================================
@@ -293,18 +299,59 @@ void SendVersion(void)
        cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, 0, VersionString, strlen(VersionString));
 }
 
-#ifdef WITH_LF
-// samy's sniff and repeat routine
-void SamyRun()
+// 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) 
 {
-       DbpString("Stand-alone mode! No PC necessary.");
-       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+       Dbprintf("USB Speed:");
+       Dbprintf("  Sending USB packets to client...");
 
-       // 3 possible options? no just 2 for now
-#define OPTS 2
+       #define USB_SPEED_TEST_MIN_TIME 1500    // in milliseconds
+       uint8_t *test_data = BigBuf_get_addr();
+       uint32_t end_time;
 
-       int high[OPTS], low[OPTS];
+       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();
+
+       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));
 
+}
+       
+/**
+  * Prints runtime information about the PM3.
+**/
+void SendStatus(void)
+{
+       BigBuf_print_status();
+       Fpga_print_status();
+       printConfig(); //LF Sampling config
+       printUSBSpeed();
+       Dbprintf("Various");
+       Dbprintf("  MF_DBGLEVEL......%d", MF_DBGLEVEL);
+       Dbprintf("  ToSendMax........%d",ToSendMax);
+       Dbprintf("  ToSendBit........%d",ToSendBit);
+
+       cmd_send(CMD_ACK,1,0,0,0,0);
+}
+
+#if defined(WITH_ISO14443a_StandAlone) || defined(WITH_LF)
+
+#define OPTS 2
+
+void StandAloneMode()
+{
+       DbpString("Stand-alone mode! No PC necessary.");
        // Oooh pretty -- notify user we're in elite samy mode now
        LED(LED_RED,    200);
        LED(LED_ORANGE, 200);
@@ -316,6 +363,270 @@ void SamyRun()
        LED(LED_ORANGE, 200);
        LED(LED_RED,    200);
 
+}
+
+#endif
+
+
+
+#ifdef WITH_ISO14443a_StandAlone
+void StandAloneMode14a()
+{
+       StandAloneMode();
+       FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+
+       int selected = 0;
+       int playing = 0, iGotoRecord = 0, iGotoClone = 0;
+       int cardRead[OPTS] = {0};
+       uint8_t readUID[10] = {0};
+       uint32_t uid_1st[OPTS]={0};
+       uint32_t uid_2nd[OPTS]={0};
+       uint32_t uid_tmp1 = 0;
+       uint32_t uid_tmp2 = 0;
+       iso14a_card_select_t hi14a_card[OPTS];
+
+       LED(selected + 1, 0);
+
+       for (;;)
+       {
+               usb_poll();
+               WDT_HIT();
+               SpinDelay(300);
+
+               if (iGotoRecord == 1 || cardRead[selected] == 0)
+               {
+                       iGotoRecord = 0;
+                       LEDsoff();
+                       LED(selected + 1, 0);
+                       LED(LED_RED2, 0);
+
+                       // record
+                       Dbprintf("Enabling iso14443a reader mode for [Bank: %u]...", selected);
+                       /* need this delay to prevent catching some weird data */
+                       SpinDelay(500);
+                       /* Code for reading from 14a tag */
+                       uint8_t uid[10]  ={0};
+                       uint32_t cuid;
+                       iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
+
+                       for ( ; ; )
+                       {
+                               WDT_HIT();
+                               if (BUTTON_PRESS()) {
+                                       if (cardRead[selected]) {
+                                               Dbprintf("Button press detected -- replaying card in bank[%d]", selected);
+                                               break;
+                                       }
+                                       else if (cardRead[(selected+1)%OPTS]) {
+                                               Dbprintf("Button press detected but no card in bank[%d] so playing from bank[%d]", selected, (selected+1)%OPTS);
+                                               selected = (selected+1)%OPTS;
+                                               break; // playing = 1;
+                                       }
+                                       else {
+                                               Dbprintf("Button press detected but no stored tag to play. (Ignoring button)");
+                                               SpinDelay(300);
+                                       }
+                               }
+                               if (!iso14443a_select_card(uid, &hi14a_card[selected], &cuid))
+                                       continue;
+                               else
+                               {
+                                       Dbprintf("Read UID:"); Dbhexdump(10,uid,0);
+                                       memcpy(readUID,uid,10*sizeof(uint8_t));
+                                       uint8_t *dst = (uint8_t *)&uid_tmp1;
+                                       // Set UID byte order
+                                       for (int i=0; i<4; i++)
+                                               dst[i] = uid[3-i];
+                                       dst = (uint8_t *)&uid_tmp2;
+                                       for (int i=0; i<4; i++)
+                                               dst[i] = uid[7-i];
+                                       if (uid_1st[(selected+1)%OPTS] == uid_tmp1 && uid_2nd[(selected+1)%OPTS] == uid_tmp2) {
+                                               Dbprintf("Card selected has same UID as what is stored in the other bank. Skipping.");
+                                       }
+                                       else {
+                                               if (uid_tmp2) {
+                                                       Dbprintf("Bank[%d] received a 7-byte UID",selected);
+                                                       uid_1st[selected] = (uid_tmp1)>>8;
+                                                       uid_2nd[selected] = (uid_tmp1<<24) + (uid_tmp2>>8);
+                                               }
+                                               else {
+                                                       Dbprintf("Bank[%d] received a 4-byte UID",selected);
+                                                       uid_1st[selected] = uid_tmp1;
+                                                       uid_2nd[selected] = uid_tmp2;
+                                               }
+                                               break;
+                                       }
+                               }
+                       }
+                       Dbprintf("ATQA = %02X%02X",hi14a_card[selected].atqa[0],hi14a_card[selected].atqa[1]);
+                       Dbprintf("SAK = %02X",hi14a_card[selected].sak);
+                       LEDsoff();
+                       LED(LED_GREEN,  200);
+                       LED(LED_ORANGE, 200);
+                       LED(LED_GREEN,  200);
+                       LED(LED_ORANGE, 200);
+
+                       LEDsoff();
+                       LED(selected + 1, 0);
+
+                       // Next state is replay:
+                       playing = 1;
+
+                       cardRead[selected] = 1;
+               }
+               /* MF Classic UID clone */
+               else if (iGotoClone==1)
+               {
+                       iGotoClone=0;
+                       LEDsoff();
+                       LED(selected + 1, 0);
+                       LED(LED_ORANGE, 250);
+
+
+                       // record
+                       Dbprintf("Preparing to Clone card [Bank: %x]; uid: %08x", selected, uid_1st[selected]);
+
+                       // wait for button to be released
+                       while(BUTTON_PRESS())
+                       {
+                               // Delay cloning until card is in place
+                               WDT_HIT();
+                       }
+                       Dbprintf("Starting clone. [Bank: %u]", selected);
+                       // need this delay to prevent catching some weird data
+                       SpinDelay(500);
+                       // Begin clone function here:
+                       /* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards:
+                                       UsbCommand c = {CMD_MIFARE_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};
+                                       memcpy(c.d.asBytes, data, 16);
+                                       SendCommand(&c);
+
+                                       Block read is similar:
+                                       UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, 0, blockNo}};
+                                       We need to imitate that call with blockNo 0 to set a uid.
+
+                                       The get and set commands are handled in this file:
+                                       // Work with "magic Chinese" card
+                                       case CMD_MIFARE_CSETBLOCK:
+                                               MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
+                                               break;
+                                       case CMD_MIFARE_CGETBLOCK:
+                                               MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
+                                               break;
+
+                               mfCSetUID provides example logic for UID set workflow:
+                                       -Read block0 from card in field with MifareCGetBlock()
+                                       -Configure new values without replacing reserved bytes
+                                                       memcpy(block0, uid, 4); // Copy UID bytes from byte array
+                                                       // Mifare UID BCC
+                                                       block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // BCC on byte 5
+                                                       Bytes 5-7 are reserved SAK and ATQA for mifare classic
+                                       -Use mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER) to write it
+                       */
+                       uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0}, testBlock0[16] = {0};
+                       // arg0 = Flags == CSETBLOCK_SINGLE_OPER=0x1F, arg1=returnSlot, arg2=blockNo
+                       MifareCGetBlock(0x3F, 1, 0, oldBlock0);
+                       if (oldBlock0[0] == 0 && oldBlock0[0] == oldBlock0[1]  && oldBlock0[1] == oldBlock0[2] && oldBlock0[2] == oldBlock0[3]) {
+                               Dbprintf("No changeable tag detected. Returning to replay mode for bank[%d]", selected);
+                               playing = 1;
+                       }
+                       else {
+                               Dbprintf("UID from target tag: %02X%02X%02X%02X", oldBlock0[0],oldBlock0[1],oldBlock0[2],oldBlock0[3]);
+                               memcpy(newBlock0,oldBlock0,16);
+                               // Copy uid_1st for bank (2nd is for longer UIDs not supported if classic)
+
+                               newBlock0[0] = uid_1st[selected]>>24;
+                               newBlock0[1] = 0xFF & (uid_1st[selected]>>16);
+                               newBlock0[2] = 0xFF & (uid_1st[selected]>>8);
+                               newBlock0[3] = 0xFF & (uid_1st[selected]);
+                               newBlock0[4] = newBlock0[0]^newBlock0[1]^newBlock0[2]^newBlock0[3];
+                               // arg0 = needWipe, arg1 = workFlags, arg2 = blockNo, datain
+                               MifareCSetBlock(0, 0xFF,0, newBlock0);
+                               MifareCGetBlock(0x3F, 1, 0, testBlock0);
+                               if (memcmp(testBlock0,newBlock0,16)==0)
+                               {
+                                       DbpString("Cloned successfull!");
+                                       cardRead[selected] = 0; // Only if the card was cloned successfully should we clear it
+                                       playing = 0;
+                                       iGotoRecord = 1;
+                                       selected = (selected+1) % OPTS;
+                               }
+                               else {
+                                       Dbprintf("Clone failed. Back to replay mode on bank[%d]", selected);
+                                       playing = 1;
+                               }
+                       }
+                       LEDsoff();
+                       LED(selected + 1, 0);
+
+               }
+               // Change where to record (or begin playing)
+               else if (playing==1) // button_pressed == BUTTON_SINGLE_CLICK && cardRead[selected])
+               {
+                       LEDsoff();
+                       LED(selected + 1, 0);
+
+                       // Begin transmitting
+                       if (playing)
+                       {
+                               LED(LED_GREEN, 0);
+                               DbpString("Playing");
+                               for ( ; ; ) {
+                                       WDT_HIT();
+                                       int button_action = BUTTON_HELD(1000);
+                                       if (button_action == 0) { // No button action, proceed with sim
+                                               uint8_t data[512] = {0}; // in case there is a read command received we shouldn't break
+                                               Dbprintf("Simulating ISO14443a tag with uid[0]: %08x, uid[1]: %08x [Bank: %u]", uid_1st[selected],uid_2nd[selected],selected);
+                                               if (hi14a_card[selected].sak == 8 && hi14a_card[selected].atqa[0] == 4 && hi14a_card[selected].atqa[1] == 0) {
+                                                       DbpString("Mifare Classic");
+                                                       SimulateIso14443aTag(1,uid_1st[selected], uid_2nd[selected], data); // Mifare Classic
+                                               }
+                                               else if (hi14a_card[selected].sak == 0 && hi14a_card[selected].atqa[0] == 0x44 && hi14a_card[selected].atqa[1] == 0) {
+                                                       DbpString("Mifare Ultralight");
+                                                       SimulateIso14443aTag(2,uid_1st[selected],uid_2nd[selected],data); // Mifare Ultralight
+                                               }
+                                               else if (hi14a_card[selected].sak == 20 && hi14a_card[selected].atqa[0] == 0x44 && hi14a_card[selected].atqa[1] == 3) {
+                                                       DbpString("Mifare DESFire");
+                                                       SimulateIso14443aTag(3,uid_1st[selected],uid_2nd[selected],data); // Mifare DESFire
+                                               }
+                                               else {
+                                                       Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation");
+                                                       SimulateIso14443aTag(1,uid_1st[selected], uid_2nd[selected], data);
+                                               }
+                                       }
+                                       else if (button_action == BUTTON_SINGLE_CLICK) {
+                                               selected = (selected + 1) % OPTS;
+                                               Dbprintf("Done playing. Switching to record mode on bank %d",selected);
+                                               iGotoRecord = 1;
+                                               break;
+                                       }
+                                       else if (button_action == BUTTON_HOLD) {
+                                               Dbprintf("Playtime over. Begin cloning...");
+                                               iGotoClone = 1;
+                                               break;
+                                       }
+                                       WDT_HIT();
+                               }
+
+                               /* We pressed a button so ignore it here with a delay */
+                               SpinDelay(300);
+                               LEDsoff();
+                               LED(selected + 1, 0);
+                       }
+                       else
+                               while(BUTTON_PRESS())
+                                       WDT_HIT();
+               }
+       }
+}
+#elif WITH_LF
+// samy's sniff and repeat routine
+void SamyRun()
+{
+       StandAloneMode();
+       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+
+       int high[OPTS], low[OPTS];
        int selected = 0;
        int playing = 0;
        int cardRead = 0;
@@ -326,7 +637,7 @@ void SamyRun()
        for (;;)
        {
                usb_poll();
-    WDT_HIT();
+               WDT_HIT();
 
                // Was our button held down or pressed?
                int button_pressed = BUTTON_HELD(1000);
@@ -439,8 +750,8 @@ void SamyRun()
                }
        }
 }
-#endif
 
+#endif
 /*
 OBJECTIVE
 Listen and detect an external reader. Determine the best location
@@ -667,6 +978,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        break;
                case CMD_T55XX_WRITE_BLOCK:
                        T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
+                       cmd_send(CMD_ACK,0,0,0,0,0);
                        break;
                case CMD_T55XX_READ_TRACE:
                        T55xxReadTrace();
@@ -681,6 +993,9 @@ void UsbPacketReceived(uint8_t *packet, int len)
                case CMD_EM4X_WRITE_WORD:
                        EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
                        break;
+               case CMD_AWID_DEMOD_FSK: // Set realtime AWID demodulation
+                       CmdAWIDdemodFSK(c->arg[0], 0, 0, 1);
+                        break;
 #endif
 
 #ifdef WITH_HITAG
@@ -929,7 +1244,12 @@ void UsbPacketReceived(uint8_t *packet, int len)
                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();
@@ -1028,8 +1348,16 @@ void  __attribute__((noreturn)) AppMain(void)
                WDT_HIT();
 
 #ifdef WITH_LF
+#ifndef WITH_ISO14443a_StandAlone
                if (BUTTON_HELD(1000) > 0)
                        SamyRun();
+#endif
+#endif
+#ifdef WITH_ISO14443a
+#ifdef WITH_ISO14443a_StandAlone
+               if (BUTTON_HELD(1000) > 0)
+                       StandAloneMode14a();
+#endif
 #endif
        }
 }
index bb094b330521b08efbe4b57ff9fa8ee70fd8c250..b5638ee188b15b3b180521313cbb36b8b9198757 100644 (file)
@@ -69,6 +69,7 @@ void CmdFSKsimTAG(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
 void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream);
 void CmdPSKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream);
 void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol);
+void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol); // Realtime demodulation mode for AWID26
 void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol);
 void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol);
 void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an ioProx card to T5557/T5567
@@ -121,7 +122,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 //void MifareUWriteBlockCompat(uint8_t arg0,uint8_t *datain);
 void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
 void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
-void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
+void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
 void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
 void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
 void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
index 6bd8692ecaa52d53c7c18ea3364acac26fdb670a..50c7d87804dbcd2fc9bc846387ef46ec613bdf05 100644 (file)
 //-----------------------------------------------------------------------------
 
 #include "iso14443a.h"
+#include "iso14443b.h"
 #include "epa.h"
 #include "cmd.h"
 
-// Protocol and Parameter Selection Request
+// Protocol and Parameter Selection Request for ISO 14443 type A cards
 // use regular (1x) speed in both directions
 // CRC is already included
 static const uint8_t pps[] = {0xD0, 0x11, 0x00, 0x52, 0xA6};
@@ -100,6 +101,28 @@ static struct {
 // lengths of the replay APDUs
 static uint8_t apdu_lengths_replay[5];
 
+// type of card (ISO 14443 A or B)
+static char iso_type = 0;
+
+//-----------------------------------------------------------------------------
+// Wrapper for sending APDUs to type A and B cards
+//-----------------------------------------------------------------------------
+int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response)
+{
+       switch(iso_type)
+       {
+               case 'a':
+                       return iso14_apdu(apdu, (uint16_t) length, response);
+                       break;
+               case 'b':
+                       return iso14443b_apdu(apdu, length, response);
+                       break;
+               default:
+                       return 0;
+                       break;
+       }
+}
+
 //-----------------------------------------------------------------------------
 // Closes the communication channel and turns off the field
 //-----------------------------------------------------------------------------
@@ -107,6 +130,7 @@ void EPA_Finish()
 {
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
        LEDsoff();
+       iso_type = 0;
 }
 
 //-----------------------------------------------------------------------------
@@ -204,26 +228,26 @@ int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length)
        int rapdu_length = 0;
 
        // select the file EF.CardAccess
-       rapdu_length = iso14_apdu((uint8_t *)apdu_select_binary_cardaccess,
+       rapdu_length = EPA_APDU((uint8_t *)apdu_select_binary_cardaccess,
                                  sizeof(apdu_select_binary_cardaccess),
                                  response_apdu);
-       if (rapdu_length != 6
+       if (rapdu_length < 6
            || response_apdu[rapdu_length - 4] != 0x90
            || response_apdu[rapdu_length - 3] != 0x00)
        {
-               Dbprintf("epa - no select cardaccess");
+               DbpString("Failed to select EF.CardAccess!");
                return -1;
        }
 
        // read the file
-       rapdu_length = iso14_apdu((uint8_t *)apdu_read_binary,
+       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("epa - no read cardaccess");
+               Dbprintf("Failed to read EF.CardAccess!");
                return -1;
        }
 
@@ -338,7 +362,7 @@ int EPA_PACE_Get_Nonce(uint8_t requested_length, uint8_t *nonce)
 
        // send it
        uint8_t response_apdu[262];
-       int send_return = iso14_apdu(apdu,
+       int send_return = EPA_APDU(apdu,
                                     sizeof(apdu),
                                     response_apdu);
        // check if the command succeeded
@@ -409,7 +433,7 @@ int EPA_PACE_MSE_Set_AT(pace_version_info_t pace_version_info, uint8_t password)
        apdu[4] = apdu_length - 5;
        // send it
        uint8_t response_apdu[6];
-       int send_return = iso14_apdu(apdu,
+       int send_return = EPA_APDU(apdu,
                                     apdu_length,
                                     response_apdu);
        // check if the command succeeded
@@ -460,16 +484,13 @@ void EPA_PACE_Replay(UsbCommand *c)
                return;
        }
 
-       // increase the timeout (at least some cards really do need this!)/////////////
-       // iso14a_set_timeout(0x0003FFFF);
-
        // 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 = iso14_apdu(apdus_replay[i].data,
+               func_return = EPA_APDU(apdus_replay[i].data,
                                         apdu_lengths_replay[i],
                                         response_apdu);
                timings[i] = GetCountUS();
@@ -501,18 +522,33 @@ int EPA_Setup()
        uint8_t pps_response_par[1];
        iso14a_card_select_t card_select_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_select_info, NULL);
-       if (return_code != 1) {
-               return 1;
+       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;
        }
-       // 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;
+
+       // 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();
+       if (return_code == 1) {
+               Dbprintf("ISO 14443 Type B");
+               iso_type = 'b';
+               return 0;
        }
-       return 0;
+       Dbprintf("No card found.");
+       return 1;
 }
index 0c580205da938c80d952a853af16c98cc140614d..d2ebed57a4e75381a5aa25d6c041d1a97cee090b 100644 (file)
@@ -19,7 +19,7 @@ typedef struct {
        uint8_t parameter_id;
 } pace_version_info_t;
 
-// note: EPA_PACE_Collect_Nonce is declared in apps.h
+// note: EPA_PACE_Collect_Nonce and EPA_PACE_Replay are declared in apps.h
 
 // general functions
 void EPA_Finish();
index 16fed7c52469b857437a3d58474a1dd4d892f4b4..308dda8c09e6ebf8fd0a691df91ccb0c0c3189d2 100644 (file)
@@ -558,3 +558,11 @@ void SetAdcMuxFor(uint32_t whichGpio)
 
        HIGH(whichGpio);
 }
+
+void Fpga_print_status(void)
+{
+       Dbprintf("Fgpa");
+       if(downloaded_bitstream == FPGA_BITSTREAM_HF) Dbprintf("  mode.............HF");
+       else if(downloaded_bitstream == FPGA_BITSTREAM_LF) Dbprintf("  mode.............LF");
+       else Dbprintf("  mode.............%d", downloaded_bitstream);
+}
index 0bad38094b62d355dc6cd13fb427b8c3c9310876..52d6c67780388ab6f94b1893c337139af9f729de 100644 (file)
@@ -17,6 +17,7 @@ void FpgaGatherVersion(int bitstream_version, char *dst, int len);
 void FpgaSetupSsc(void);
 void SetupSpi(int mode);
 bool FpgaSetupSscDma(uint8_t *buf, int len);
+void Fpga_print_status();
 #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);
index a4e5ceaf1ece9ea5bc57eeade9c2ed77aa1ccc5e..9fa9fe4ff61d8724036feeebeaa182a98b84a341 100644 (file)
@@ -1070,7 +1070,6 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
        LED_A_ON();
        for(;;) {
                // Clean receive command buffer
-               
                if(!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) {
                        DbpString("Button press");
                        break;
index 33c047d8113c84aa2408c5d2eb01bf5cd1563499..82e5dd6a1c1bba44a33814b62b06be2d1e047093 100644 (file)
@@ -19,6 +19,9 @@
 #define RECEIVE_SAMPLES_TIMEOUT 2000
 #define ISO14443B_DMA_BUFFER_SIZE 256
 
+// PCB Block number for APDUs
+static uint8_t pcb_blocknum = 0;
+
 //=============================================================================
 // An ISO 14443 Type B tag. We listen for commands from the reader, using
 // a UART kind of thing that's implemented in software. When we get a
@@ -311,7 +314,7 @@ static int GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len)
                        }
                }
        }
-       
+
        return FALSE;
 }
 
@@ -321,10 +324,14 @@ static int GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len)
 //-----------------------------------------------------------------------------
 void SimulateIso14443bTag(void)
 {
-       // the only commands we understand is REQB, AFI=0, Select All, N=0:
-       static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };
-       // ... and REQB, AFI=0, Normal Request, N=0:
-       static const uint8_t cmd2[] = { 0x05, 0x00, 0x00, 0x71, 0xFF };
+       // the only commands we understand is WUPB, AFI=0, Select All, N=1:
+       static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; // WUPB
+       // ... and REQB, AFI=0, Normal Request, N=1:
+       static const uint8_t cmd2[] = { 0x05, 0x00, 0x00, 0x71, 0xFF }; // REQB
+       // ... and HLTB
+       static const uint8_t cmd3[] = { 0x50, 0xff, 0xff, 0xff, 0xff }; // HLTB
+       // ... and ATTRIB
+       static const uint8_t cmd4[] = { 0x1D, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; // ATTRIB
 
        // ... and we always respond with ATQB, PUPI = 820de174, Application Data = 0x20381922,
        // supports only 106kBit/s in both directions, max frame size = 32Bytes,
@@ -333,6 +340,9 @@ void SimulateIso14443bTag(void)
                0x50, 0x82, 0x0d, 0xe1, 0x74, 0x20, 0x38, 0x19, 0x22,
                0x00, 0x21, 0x85, 0x5e, 0xd7
        };
+       // response to HLTB and ATTRIB
+       static const uint8_t response2[] = {0x00, 0x78, 0xF0};
+
 
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 
@@ -353,9 +363,15 @@ void SimulateIso14443bTag(void)
        // prepare the (only one) tag answer:
        CodeIso14443bAsTag(response1, sizeof(response1));
        uint8_t *resp1Code = BigBuf_malloc(ToSendMax);
-       memcpy(resp1Code, ToSend, ToSendMax); 
+       memcpy(resp1Code, ToSend, ToSendMax);
        uint16_t resp1CodeLen = ToSendMax;
 
+       // prepare the (other) tag answer:
+       CodeIso14443bAsTag(response2, sizeof(response2));
+       uint8_t *resp2Code = BigBuf_malloc(ToSendMax);
+       memcpy(resp2Code, ToSend, ToSendMax);
+       uint16_t resp2CodeLen = ToSendMax;
+
        // We need to listen to the high-frequency, peak-detected path.
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
        FpgaSetupSsc();
@@ -377,22 +393,37 @@ void SimulateIso14443bTag(void)
                // Good, look at the command now.
                if ( (len == sizeof(cmd1) && memcmp(receivedCmd, cmd1, len) == 0)
                        || (len == sizeof(cmd2) && memcmp(receivedCmd, cmd2, len) == 0) ) {
-                       resp = response1; 
+                       resp = response1;
                        respLen = sizeof(response1);
-                       respCode = resp1Code; 
+                       respCode = resp1Code;
                        respCodeLen = resp1CodeLen;
+               } else if ( (len == sizeof(cmd3) && receivedCmd[0] == cmd3[0])
+                       || (len == sizeof(cmd4) && receivedCmd[0] == cmd4[0]) ) {
+                       resp = response2;
+                       respLen = sizeof(response2);
+                       respCode = resp2Code;
+                       respCodeLen = resp2CodeLen;
                } else {
                        Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsRecvd);
                        // And print whether the CRC fails, just for good measure
                        uint8_t b1, b2;
-                       ComputeCrc14443(CRC_14443_B, receivedCmd, len-2, &b1, &b2);
-                       if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) {
-                               // Not so good, try again.
-                               DbpString("+++CRC fail");
-                       } else {
-                               DbpString("CRC passes");
+                       if (len >= 3){ // if crc exists
+                               ComputeCrc14443(CRC_14443_B, receivedCmd, len-2, &b1, &b2);
+                               if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) {
+                                       // Not so good, try again.
+                                       DbpString("+++CRC fail");
+               
+                               } else {
+                                       DbpString("CRC passes");
+                               }
                        }
-                       break;
+                       //get rid of compiler warning
+                       respCodeLen = 0;
+                       resp = response1;
+                       respLen = 0;
+                       respCode = resp1Code;
+                       //don't crash at new command just wait and see if reader will send other new cmds.
+                       //break;
                }
 
                cmdsRecvd++;
@@ -429,13 +460,13 @@ void SimulateIso14443bTag(void)
                                (void)b;
                        }
                }
-               
+
                // trace the response:
                if (tracing) {
                        uint8_t parity[MAX_PARITY_SIZE];
                        LogTrace(resp, respLen, 0, 0, parity, FALSE);
                }
-                       
+
        }
 }
 
@@ -513,7 +544,7 @@ static RAMFUNC int Handle14443bSamplesDemod(int ci, int cq)
                } else { \
                        v -= 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() { \
@@ -547,7 +578,7 @@ static RAMFUNC int Handle14443bSamplesDemod(int ci, int cq)
                        } \
                } \
        }
-       
+
        switch(Demod.state) {
                case DEMOD_UNSYNCD:
                        CHECK_FOR_SUBCARRIER();
@@ -645,7 +676,7 @@ static RAMFUNC int Handle14443bSamplesDemod(int ci, int cq)
                                        Demod.metric -= Demod.thisBit;
                                }
                                (Demod.metricN)++;
-*/                             
+*/
 
                                Demod.shiftReg >>= 1;
                                if(Demod.thisBit > 0) { // logic '1'
@@ -713,10 +744,10 @@ static void GetSamplesFor14443bDemod(int n, bool quiet)
        // Allocate memory from BigBuf for some buffers
        // free all previous allocations first
        BigBuf_free();
-       
+
        // The response (tag -> reader) that we're receiving.
        uint8_t *receivedResponse = 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);
 
@@ -896,6 +927,98 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len)
        }
 }
 
+/* Sends an APDU to the tag
+ * TODO: check CRC and preamble
+ */
+int 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)
+       ComputeCrc14443(CRC_14443_B, message_frame, message_length + 2, &message_frame[message_length + 2], &message_frame[message_length + 3]);
+       // send
+       CodeAndTransmit14443bAsReader(message_frame, message_length + 4);
+       // get response
+       GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT*100, TRUE);
+       if(Demod.len < 3)
+       {
+               return 0;
+       }
+       // TODO: Check CRC
+       // copy response contents
+       if(response != NULL)
+       {
+               memcpy(response, Demod.output, Demod.len);
+       }
+       return Demod.len;
+}
+
+/* Perform the ISO 14443 B Card Selection procedure
+ * Currently does NOT do any collision handling.
+ * It expects 0-1 cards in the device's range.
+ * TODO: Support multiple cards (perform anticollision)
+ * TODO: Verify CRC checksums
+ */
+int iso14443b_select_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[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };
+       // ATTRIB command (with space for CRC)
+       uint8_t attrib[] = { 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00};
+
+       // first, wake up the tag
+       CodeAndTransmit14443bAsReader(wupb, sizeof(wupb));
+       GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
+       // ATQB too short?
+       if (Demod.len < 14)
+       {
+               return 2;
+       }
+
+    // select the tag
+    // copy the PUPI to ATTRIB
+    memcpy(attrib + 1, Demod.output + 1, 4);
+    /* copy the protocol info from ATQB (Protocol Info -> Protocol_Type) into
+    ATTRIB (Param 3) */
+    attrib[7] = Demod.output[10] & 0x0F;
+    ComputeCrc14443(CRC_14443_B, attrib, 9, attrib + 9, attrib + 10);
+    CodeAndTransmit14443bAsReader(attrib, sizeof(attrib));
+    GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
+    // Answer to ATTRIB too short?
+    if(Demod.len < 3)
+       {
+               return 2;
+       }
+       // reset PCB block number
+       pcb_blocknum = 0;
+       return 1;
+}
+
+// Set up ISO 14443 Type B communication (similar to iso14443a_setup)
+void iso14443b_setup() {
+       FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+       // Set up the synchronous serial port
+       FpgaSetupSsc();
+       // connect Demodulated Signal to ADC:
+       SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
+
+       // Signal field is on with the appropriate LED
+    LED_D_ON();
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
+
+       // Start the timer
+       StartCountSspClk();
+
+       DemodReset();
+       UartReset();
+}
 
 //-----------------------------------------------------------------------------
 // Read a SRI512 ISO 14443B tag.
@@ -1090,7 +1213,7 @@ void RAMFUNC SnoopIso14443b(void)
 
        bool TagIsActive = FALSE;
        bool ReaderIsActive = FALSE;
-       
+
        // And now we loop, receiving samples.
        for(;;) {
                int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
@@ -1200,16 +1323,18 @@ void SendRawCommand14443B(uint32_t datalen, uint32_t recv, uint8_t powerfield, u
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
        FpgaSetupSsc();
 
-       set_tracing(TRUE);
-       
-       CodeAndTransmit14443bAsReader(data, datalen);
+       if (datalen){
+               set_tracing(TRUE);
+               
+               CodeAndTransmit14443bAsReader(data, datalen);
 
-       if(recv) {
-               GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
-               uint16_t iLen = MIN(Demod.len, USB_CMD_DATA_SIZE);
-               cmd_send(CMD_ACK, iLen, 0, 0, Demod.output, iLen);
+               if(recv) {
+                       GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, TRUE);
+                       uint16_t iLen = MIN(Demod.len, USB_CMD_DATA_SIZE);
+                       cmd_send(CMD_ACK, iLen, 0, 0, Demod.output, iLen);
+               }
        }
-       
+
        if(!powerfield) {
                FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
                LED_D_OFF();
diff --git a/armsrc/iso14443b.h b/armsrc/iso14443b.h
new file mode 100644 (file)
index 0000000..f90c54f
--- /dev/null
@@ -0,0 +1,21 @@
+//-----------------------------------------------------------------------------
+// Merlok - June 2011
+// Gerhard de Koning Gans - May 2008
+// Hagen Fritsch - June 2010
+//
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// Routines to support ISO 14443 type A.
+//-----------------------------------------------------------------------------
+
+#ifndef __ISO14443B_H
+#define __ISO14443B_H
+#include "common.h"
+
+int iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response);
+void iso14443b_setup();
+int iso14443b_select_card();
+
+#endif /* __ISO14443B_H */
index 7e53d4a566173d97301f9e56ee1e5ad01a1ca15e..733bc953ed04a8dd85129c87f9af6d027f8bfcd4 100644 (file)
@@ -402,7 +402,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
        for(;;) {
                //wait until SSC_CLK goes HIGH
                while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
-                       if(BUTTON_PRESS() || usb_poll()) {
+                       if(BUTTON_PRESS() || (usb_poll_validate_length() )) {
                                DbpString("Stopped");
                                return;
                        }
@@ -841,6 +841,96 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
        if (ledcontrol) LED_A_OFF();
 }
 
+// loop to get raw HID waveform then FSK demodulate the TAG ID from it
+void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
+{
+       uint8_t *dest = BigBuf_get_addr();
+       //const size_t sizeOfBigBuff = BigBuf_max_traceLen();
+       size_t size; 
+       int idx=0;
+       // Configure to go in 125Khz listen mode
+       LFSetupFPGAForADC(95, true);
+
+       while(!BUTTON_PRESS()) {
+
+               WDT_HIT();
+               if (ledcontrol) LED_A_ON();
+
+               DoAcquisition_default(-1,true);
+               // FSK demodulator
+               //size = sizeOfBigBuff;  //variable size will change after demod so re initialize it before use
+               size = 50*128*2; //big enough to catch 2 sequences of largest format
+               idx = AWIDdemodFSK(dest, &size);
+               
+               if (idx>0 && size==96){
+               // 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);
+
+               size = removeParity(dest, idx+8, 4, 1, 88);
+               // 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)
+
+               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();
+                               return;
+                       }
+                       // reset
+               }
+               idx = 0;
+               WDT_HIT();
+       }
+       DbpString("Stopped");
+       if (ledcontrol) LED_A_OFF();
+}
+
 void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
 {
        uint8_t *dest = BigBuf_get_addr();
index 120c0801de6ccecc3e7e558e10c078e3b187c980..6e78376986daa167079608c83b2189d4c528ea42 100644 (file)
@@ -17,7 +17,7 @@ sample_config config = { 1, 8, 1, 95, 0 } ;
 
 void printConfig()
 {
-       Dbprintf("Sampling config: ");
+       Dbprintf("LF Sampling config: ");
        Dbprintf("  [q] divisor:           %d ", config.divisor);
        Dbprintf("  [b] bps:               %d ", config.bits_per_sample);
        Dbprintf("  [d] decimation:        %d ", config.decimation);
@@ -119,8 +119,7 @@ void LFSetupFPGAForADC(int divisor, bool lf_field)
  * @param silent - is true, now outputs are made. If false, dbprints the status
  * @return the number of bits occupied by the samples.
  */
-
-uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold,bool silent)
+uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold, bool silent)
 {
        //.
        uint8_t *dest = BigBuf_get_addr();
@@ -151,8 +150,12 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
                if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
                        sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
                        LED_D_OFF();
-                       if (trigger_threshold > 0 && sample < trigger_threshold)
+                       // threshold either high or low values 128 = center 0.  if trigger = 178 
+                       if ((trigger_threshold > 0) && (sample < (trigger_threshold+128)) && (sample > (128-trigger_threshold))) // 
                                continue;
+               
+                       //if (trigger_threshold > 0 && sample < trigger_threshold) // 
+                               //continue;
 
                        trigger_threshold = 0;
                        sample_total_numbers++;
index 6c671ec8ca7a295b49a2d9200401a3ca69d49753..7d3925cddfff0d70e7032da25b3284276abd3e0d 100644 (file)
@@ -56,4 +56,8 @@ void LFSetupFPGAForADC(int divisor, bool lf_field);
 void setSamplingConfig(sample_config *sc);
 
 sample_config * getSamplingConfig();
+
+void printConfig();
+
+
 #endif // LFSAMPLING_H
index c2d85abb496f50a00b27dd0281c2b54541b3ec41..a3d6609db3413a136b6d5415e3296e103f90a28a 100644 (file)
@@ -642,8 +642,8 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
        // free eventually allocated BigBuf memory\r
        BigBuf_free();\r
 \r
-       clear_trace();\r
-       set_tracing(false);\r
+       if (calibrate) clear_trace();\r
+       set_tracing(true);\r
        \r
        // statistics on nonce distance\r
        int16_t isOK = 0;\r
@@ -820,18 +820,18 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
 \r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
-       set_tracing(TRUE);\r
 }\r
 \r
 //-----------------------------------------------------------------------------\r
 // MIFARE check keys. key count up to 85. \r
 // \r
 //-----------------------------------------------------------------------------\r
-void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
+void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
 {\r
   // params\r
-       uint8_t blockNo = arg0;\r
-       uint8_t keyType = arg1;\r
+       uint8_t blockNo = arg0 & 0xff;\r
+       uint8_t keyType = (arg0 >> 8) & 0xff;\r
+       bool clearTrace = arg1;\r
        uint8_t keyCount = arg2;\r
        uint64_t ui64Key = 0;\r
        \r
@@ -853,7 +853,7 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        LED_C_OFF();\r
        iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
 \r
-       clear_trace();\r
+       if (clearTrace) clear_trace();\r
        set_tracing(TRUE);\r
 \r
        for (i = 0; i < keyCount; i++) {\r
@@ -1143,6 +1143,7 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
        // bit 2 - need HALT after sequence\r
        // bit 3 - need init FPGA and field before sequence\r
        // bit 4 - need reset FPGA and LED\r
+       // bit 5 - need to set datain instead of issuing USB reply (called via ARM for StandAloneMode14a)\r
        uint8_t workFlags = arg0;\r
        uint8_t blockNo = arg2;\r
        \r
@@ -1202,7 +1203,12 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
        }\r
        \r
        LED_B_ON();\r
-       cmd_send(CMD_ACK,isOK,0,0,data,18);\r
+       if (workFlags & 0x20) {\r
+               if (isOK)\r
+                       memcpy(datain, data, 18);\r
+       }\r
+       else\r
+               cmd_send(CMD_ACK,isOK,0,0,data,18);\r
        LED_B_OFF();\r
 \r
        if ((workFlags & 0x10) || (!isOK)) {\r
index 85a34ef62104fa2445503eac3517436d43fa8438..7a09ce64cdac33707a13abdef1de3294d778cd58 100644 (file)
@@ -8,6 +8,7 @@
 //-----------------------------------------------------------------------------\r
 // code for work with mifare cards.\r
 //-----------------------------------------------------------------------------\r
+#include "crapto1.h"\r
 \r
 #ifndef __MIFAREUTIL_H\r
 #define __MIFAREUTIL_H\r
index 8576ddce5fcb7c641236d214bb224ca3221769b1..1dd8dc7544fe1cb2989548692f8449f19b6ca621 100644 (file)
@@ -304,11 +304,12 @@ void FormatVersionInformation(char *dst, int len, const char *prefix, void *vers
 
 void StartTickCount()
 {
-//  must be 0x40, but on my cpu - included divider is optimal
-//  0x20 - 1 ms / bit 
-//  0x40 - 2 ms / bit
-
-       AT91C_BASE_RTTC->RTTC_RTMR = AT91C_RTTC_RTTRST + 0x001D; // was 0x003B
+       // 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%
 }
 
 /*
index f768f3d8ef1e3e6328472151a8433a5b72fcb437..903cbf9ef35fa315a3a2f82ee5331d3a636c6cf6 100644 (file)
@@ -90,6 +90,7 @@ CMDSRCS =     nonce2key/crapto1.c\
                        cmdlf.c \
                        cmdlfio.c \
                        cmdlfhid.c \
+                       cmdlfawid.c \
                        cmdlfem4x.c \
                        cmdlfhitag.c \
                        cmdlfti.c \
index bec1b5aa3f4d4394f011394fa61edca5b9a06767..22da18053c4f80b35e899dbf029c67454e43111a 100644 (file)
 #include "usb_cmd.h"
 #include "crc.h"
 #include "crc16.h"
+#include "loclass/cipherutils.h"
 
 uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
-uint8_t g_debugMode;
-size_t DemodBufferLen;
+uint8_t g_debugMode=0;
+size_t DemodBufferLen=0;
 static int CmdHelp(const char *Cmd);
 
 //set the demod buffer with given array of binary (one bit per byte)
@@ -1491,9 +1492,9 @@ int CmdFDXBdemodBI(const char *Cmd){
 
        setDemodBuf(BitStream, 128, preambleIndex);
 
-       // remove but don't verify parity. (pType = 2)
+       // remove marker bits (1's every 9th digit after preamble) (pType = 2)
        size = removeParity(BitStream, preambleIndex + 11, 9, 2, 117);
-       if ( size <= 103 ) {
+       if ( size != 104 ) {
                if (g_debugMode) PrintAndLog("Error removeParity:: %d", size);
                return 0;
        }
@@ -1943,26 +1944,14 @@ int CmdHpf(const char *Cmd)
        RepaintGraphWindow();
        return 0;
 }
-typedef struct {
-       uint8_t * buffer;
-       uint32_t numbits;
-       uint32_t position;
-}BitstreamOut;
 
-bool _headBit( BitstreamOut *stream)
-{
-       int bytepos = stream->position >> 3; // divide by 8
-       int bitpos = (stream->position++) & 7; // mask out 00000111
-       return (*(stream->buffer + bytepos) >> (7-bitpos)) & 1;
-}
-
-uint8_t getByte(uint8_t bits_per_sample, BitstreamOut* b)
+uint8_t getByte(uint8_t bits_per_sample, BitstreamIn* b)
 {
        int i;
        uint8_t val = 0;
        for(i =0 ; i < bits_per_sample; i++)
        {
-               val |= (_headBit(b) << (7-i));
+               val |= (headBit(b) << (7-i));
        }
        return val;
 }
@@ -2002,7 +1991,7 @@ int getSamples(const char *Cmd, bool silent)
        if(bits_per_sample < 8)
        {
                PrintAndLog("Unpacking...");
-               BitstreamOut bout = { got, bits_per_sample * n,  0};
+               BitstreamIn bout = { got, bits_per_sample * n,  0};
                int j =0;
                for (j = 0; j * bits_per_sample < n * 8 && j < n; j++) {
                        uint8_t sample = getByte(bits_per_sample, &bout);
@@ -2265,6 +2254,99 @@ int CmdZerocrossings(const char *Cmd)
        return 0;
 }
 
+int usage_data_bin2hex(){
+               PrintAndLog("Usage: data bin2hex <binary_digits>");
+               PrintAndLog("       This function will ignore all characters not 1 or 0 (but stop reading on whitespace)");
+               return 0;
+}
+
+/**
+ * @brief Utility for conversion via cmdline.
+ * @param Cmd
+ * @return
+ */
+int Cmdbin2hex(const char *Cmd)
+{
+       int bg =0, en =0;
+       if(param_getptr(Cmd, &bg, &en, 0))
+       {
+               return usage_data_bin2hex();
+       }
+       //Number of digits supplied as argument
+       size_t length = en  - bg +1;
+       size_t bytelen = (length+7) / 8;
+       uint8_t* arr = (uint8_t *) malloc(bytelen);
+       memset(arr, 0, bytelen);
+       BitstreamOut bout = { arr, 0, 0 };
+
+       for(; bg <= en ;bg++)
+       {
+               char c = Cmd[bg];
+               if( c == '1')   pushBit(&bout, 1);
+               else if( c == '0')      pushBit(&bout, 0);
+               else PrintAndLog("Ignoring '%c'", c);
+       }
+
+       if(bout.numbits % 8 != 0)
+       {
+               printf("[padded with %d zeroes]\n", 8-(bout.numbits % 8));
+       }
+
+       //Uses printf instead of PrintAndLog since the latter
+       // adds linebreaks to each printout - this way was more convenient since we don't have to
+       // allocate a string and write to that first...
+       for(size_t x = 0; x  < bytelen ; x++)
+       {
+               printf("%02X", arr[x]);
+       }
+       printf("\n");
+       free(arr);
+       return 0;
+}
+
+int usage_data_hex2bin(){
+
+       PrintAndLog("Usage: data bin2hex <binary_digits>");
+       PrintAndLog("       This function will ignore all non-hexadecimal characters (but stop reading on whitespace)");
+       return 0;
+
+}
+
+int Cmdhex2bin(const char *Cmd)
+{
+       int bg =0, en =0;
+       if(param_getptr(Cmd, &bg, &en, 0))
+       {
+               return usage_data_hex2bin();
+       }
+
+
+       while(bg <= en )
+       {
+               char x = Cmd[bg++];
+               // capitalize
+               if (x >= 'a' && x <= 'f')
+                       x -= 32;
+               // convert to numeric value
+               if (x >= '0' && x <= '9')
+                       x -= '0';
+               else if (x >= 'A' && x <= 'F')
+                       x -= 'A' - 10;
+               else
+                       continue;
+
+               //Uses printf instead of PrintAndLog since the latter
+               // adds linebreaks to each printout - this way was more convenient since we don't have to
+               // allocate a string and write to that first...
+
+               for(int i= 0 ; i < 4 ; ++i)
+                       printf("%d",(x >> (3 - i)) & 1);
+       }
+       printf("\n");
+
+       return 0;
+}
+
 static command_t CommandTable[] =
 {
        {"help",            CmdHelp,            1, "This help"},
@@ -2273,6 +2355,7 @@ static command_t CommandTable[] =
        {"askgproxiidemod", CmdG_Prox_II_Demod, 1, "Demodulate a G Prox II tag from GraphBuffer"},
        {"autocorr",        CmdAutoCorr,        1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"},
        {"biphaserawdecode",CmdBiphaseDecodeRaw,1, "[offset] [invert<0|1>] [maxErr] -- Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"},
+       {"bin2hex",         Cmdbin2hex,         1, "bin2hex <digits>     -- Converts binary to hexadecimal"},
        {"bitsamples",      CmdBitsamples,      0, "Get raw samples as bitstring"},
        {"buffclear",       CmdBuffClear,       1, "Clear sample buffer and graph window"},
        {"dec",             CmdDec,             1, "Decimate samples"},
@@ -2287,6 +2370,7 @@ static command_t CommandTable[] =
        {"getbitstream",    CmdGetBitStream,    1, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"},
        {"grid",            CmdGrid,            1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
        {"hexsamples",      CmdHexsamples,      0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
+       {"hex2bin",         Cmdhex2bin,         1, "hex2bin <hexadecimal> -- Converts hexadecimal to binary"},
        {"hide",            CmdHide,            1, "Hide graph window"},
        {"hpf",             CmdHpf,             1, "Remove DC offset from trace"},
        {"load",            CmdLoad,            1, "<filename> -- Load trace (to graph window"},
index 4777a0f40295b40408e03a3a505eeb73560f041c..ee0b4fd8c1855f83da631df3476ad46b6de83bbd 100644 (file)
@@ -484,7 +484,7 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
                        oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
                }
                uint8_t parityBits = parityBytes[j>>3];
-               if (protocol != ISO_14443B && isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
+               if (protocol != ISO_14443B && (isResponse || protocol == ISO_14443A) && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
                        snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]);
                } else {
                        snprintf(line[j/16]+(( j % 16) * 4), 110, " %02x ", frame[j]);
index d1d668e9e28fcf1fffa9c40a4c64df5db2796096..36932cbd31d887f252afc29852a883706ef2e9c7 100644 (file)
@@ -132,17 +132,21 @@ int CmdHF14BCmdRaw (const char *Cmd) {
        bool reply = true;
        bool crc = false;
        bool power = false;
+       bool select = false;
+       bool SRx = false;
        char buf[5] = "";
        uint8_t data[100] = {0x00};
        uint8_t datalen = 0;
        unsigned int temp;
        int i = 0;
        if (strlen(Cmd)<3) {
-                       PrintAndLog("Usage: hf 14b raw [-r] [-c] [-p] <0A 0B 0C ... hex>");
+                       PrintAndLog("Usage: hf 14b raw [-r] [-c] [-p] [-s || -ss] <0A 0B 0C ... hex>");
                        PrintAndLog("       -r    do not read response");
                        PrintAndLog("       -c    calculate and append CRC");
                        PrintAndLog("       -p    leave the field on after receive");
-                       return 0;    
+                       PrintAndLog("       -s    active signal field ON with select");
+                       PrintAndLog("       -ss   active signal field ON with select for SRx ST Microelectronics tags");
+                       return 0;
        }
 
        // strip
@@ -164,6 +168,14 @@ int CmdHF14BCmdRaw (const char *Cmd) {
                                case 'P': 
                                        power = true;
                                        break;
+                               case 's':
+                               case 'S':
+                                       select = true;
+                                       if (Cmd[i+2]=='s' || Cmd[i+2]=='S') {
+                                               SRx = true;
+                                               i++;
+                                       }
+                                       break;
                                default:
                                        PrintAndLog("Invalid option");
                                        return 0;
@@ -186,7 +198,7 @@ int CmdHF14BCmdRaw (const char *Cmd) {
                        continue;
                }
                PrintAndLog("Invalid char on input");
-               return 1;
+               return 0;
        }
        if (datalen == 0)
        {
@@ -194,11 +206,58 @@ int CmdHF14BCmdRaw (const char *Cmd) {
                return 0;
        }
 
+       if (select){ //auto select 14b tag
+               uint8_t cmd2[16];
+               bool crc2 = true;
+               uint8_t cmdLen;
+
+               if (SRx) {
+                       // REQ SRx
+                       cmdLen = 2;
+                       cmd2[0] = 0x06;
+                       cmd2[1] = 0x00;
+               } else {
+                       cmdLen = 3;
+                       // REQB
+                       cmd2[0] = 0x05;
+                       cmd2[1] = 0x00;
+                       cmd2[2] = 0x08;
+               }
+
+               if (HF14BCmdRaw(true, &crc2, true, cmd2, &cmdLen, false)==0) return rawClose();
+
+               if ( SRx && (cmdLen != 3 || !crc2) ) return rawClose();
+               else if (cmd2[0] != 0x50 || cmdLen != 14 || !crc2) return rawClose();
+               
+               uint8_t chipID = 0;
+               if (SRx) {
+                       // select
+                       chipID = cmd2[0];
+                       cmd2[0] = 0x0E;
+                       cmd2[1] = chipID;
+                       cmdLen = 2;
+               } else {
+                       // attrib
+                       cmd2[0] = 0x1D; 
+                       // UID from cmd2[1 - 4]
+                       cmd2[5] = 0x00;
+                       cmd2[6] = 0x08;
+                       cmd2[7] = 0x01;
+                       cmd2[8] = 0x00;
+                       cmdLen = 9;
+               }
+
+               if (HF14BCmdRaw(true, &crc2, true, cmd2, &cmdLen, false)==0) return rawClose();
+
+               if (cmdLen != 3 || !crc2) return rawClose();
+               if (SRx && cmd2[0] != chipID) return rawClose();
+       }
        return HF14BCmdRaw(reply, &crc, power, data, &datalen, true);
 }
 
+// print full atqb info
 static void print_atqb_resp(uint8_t *data){
-       PrintAndLog ("           UID: %s", sprint_hex(data+1,4));
+       //PrintAndLog ("           UID: %s", sprint_hex(data+1,4));
        PrintAndLog ("      App Data: %s", sprint_hex(data+5,4));
        PrintAndLog ("      Protocol: %s", sprint_hex(data+9,3));
        uint8_t BitRate = data[9];
@@ -233,18 +292,20 @@ static void print_atqb_resp(uint8_t *data){
        else
                maxFrame = 257;
 
-       PrintAndLog ("Max Frame Size: %d%s",maxFrame, (maxFrame == 257) ? "+ RFU" : "");
+       PrintAndLog ("Max Frame Size: %u%s",maxFrame, (maxFrame == 257) ? "+ RFU" : "");
 
        uint8_t protocolT = data[10] & 0xF;
        PrintAndLog (" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT) ? "" : "not " );
-       PrintAndLog ("Frame Wait Int: %d", data[11]>>4);
+       PrintAndLog ("Frame Wait Int: %u", data[11]>>4);
        PrintAndLog (" App Data Code: Application is %s",(data[11]&4) ? "Standard" : "Proprietary");
        PrintAndLog (" Frame Options: NAD is %ssupported",(data[11]&2) ? "" : "not ");
        PrintAndLog (" Frame Options: CID is %ssupported",(data[11]&1) ? "" : "not ");
+       PrintAndLog ("Max Buf Length: %u (MBLI) %s",data[14]>>4, (data[14] & 0xF0) ? "" : "not supported");
        
        return;
 }
 
+// get SRx chip model (from UID) // from ST Microelectronics
 char *get_ST_Chip_Model(uint8_t data){
        static char model[20];
        char *retStr = model;
@@ -263,20 +324,86 @@ char *get_ST_Chip_Model(uint8_t data){
        return retStr;
 }
 
-static void print_st_info(uint8_t *data){
+int print_ST_Lock_info(uint8_t model){
+       //assume connection open and tag selected...
+       uint8_t data[16] = {0x00};
+       uint8_t datalen = 2;
+       bool crc = true;
+       uint8_t resplen;
+       uint8_t blk1;
+       data[0] = 0x08;
+
+       if (model == 0x2) { //SR176 has special command:
+               data[1] = 0xf;
+               resplen = 4;                    
+       } else {
+               data[1] = 0xff;
+               resplen = 6;
+       }
+
+       //std read cmd
+       if (HF14BCmdRaw(true, &crc, true, data, &datalen, false)==0) return rawClose();
+
+       if (datalen != resplen || !crc) return rawClose();
+
+       PrintAndLog("Chip Write Protection Bits:");
+       // now interpret the data
+       switch (model){
+               case 0x0: //fall through (SRIX4K special)
+               case 0x3: //fall through (SRIx4K)
+               case 0x7: //             (SRI4K)
+                       //only need data[3]
+                       blk1 = 9;
+                       PrintAndLog("   raw: %s",printBits(1,data+3));
+                       PrintAndLog(" 07/08:%slocked", (data[3] & 1) ? " not " : " " );
+                       for (uint8_t i = 1; i<8; i++){
+                               PrintAndLog("    %02u:%slocked", blk1, (data[3] & (1 << i)) ? " not " : " " );
+                               blk1++;
+                       }
+                       break;
+               case 0x4: //fall through (SRIX512)
+               case 0x6: //fall through (SRI512)
+               case 0xC: //             (SRT512)
+                       //need data[2] and data[3]
+                       blk1 = 0;
+                       PrintAndLog("   raw: %s",printBits(2,data+2));
+                       for (uint8_t b=2; b<4; b++){
+                               for (uint8_t i=0; i<8; i++){
+                                       PrintAndLog("    %02u:%slocked", blk1, (data[b] & (1 << i)) ? " not " : " " );
+                                       blk1++;
+                               }
+                       }
+                       break;
+               case 0x2: //             (SR176)
+                       //need data[2]
+                       blk1 = 0;
+                       PrintAndLog("   raw: %s",printBits(1,data+2));
+                       for (uint8_t i = 0; i<8; i++){
+                               PrintAndLog(" %02u/%02u:%slocked", blk1, blk1+1, (data[2] & (1 << i)) ? " " : " not " );
+                               blk1+=2;
+                       }
+                       break;
+               default:
+                       return rawClose();
+       }
+       return 1;
+}
+
+// print UID info from SRx chips (ST Microelectronics)
+static void print_st_general_info(uint8_t *data){
        //uid = first 8 bytes in data
-       PrintAndLog(" UID: %s", sprint_hex(SwapEndian64(data,8,8),8));
-       PrintAndLog(" MFG: %02X, %s", data[6], getTagInfo(data[6]));
-       PrintAndLog("Chip: %02X, %s", data[5]>>2, get_ST_Chip_Model(data[5]>>2));
+       PrintAndLog("   UID: %s", sprint_hex(SwapEndian64(data,8,8),8));
+       PrintAndLog("   MFG: %02X, %s", data[6], getTagInfo(data[6]));
+       PrintAndLog("  Chip: %02X, %s", data[5]>>2, get_ST_Chip_Model(data[5]>>2));
        return;
 }
 
-int HF14BStdInfo(uint8_t *data, uint8_t *datalen){
-
+// 14b get and print UID only (general info)
+int HF14BStdReader(uint8_t *data, uint8_t *datalen){
        //05 00 00 = find one tag in field
-       //1d xx xx xx xx 20 00 08 01 00 = attrib xx=crc
-       //a3 = ?  (resp 03 e2 c2)
-       //02 = ?  (resp 02 6a d3)
+       //1d xx xx xx xx 00 08 01 00 = attrib xx=UID (resp 10 [f9 e0])
+       //a3 = ?  (resp 03 [e2 c2])
+       //02 = ?  (resp 02 [6a d3])
        // 022b (resp 02 67 00 [29  5b])
        // 0200a40400 (resp 02 67 00 [29 5b])
        // 0200a4040c07a0000002480300 (resp 02 67 00 [29 5b])
@@ -289,24 +416,60 @@ int HF14BStdInfo(uint8_t *data, uint8_t *datalen){
        //03 = ?  (resp 03 [e3 c2])
        //c2 = ?  (resp c2 [66 15])
        //b2 = ?  (resp a3 [e9 67])
+       //a2 = ?  (resp 02 [6a d3])
        bool crc = true;
        *datalen = 3;
        //std read cmd
        data[0] = 0x05;
        data[1] = 0x00;
-       data[2] = 0x00;
+       data[2] = 0x08;
 
-       if (HF14BCmdRaw(true, &crc, false, data, datalen, false)==0) return 0;
+       if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return rawClose();
 
-       if (data[0] != 0x50  || *datalen != 14 || !crc) return 0;
+       if (data[0] != 0x50 || *datalen != 14 || !crc) return rawClose();
 
        PrintAndLog ("\n14443-3b tag found:");
+       PrintAndLog ("           UID: %s", sprint_hex(data+1,4));
+
+       uint8_t cmd2[16];
+       uint8_t cmdLen = 3;
+       bool crc2 = true;
+
+       cmd2[0] = 0x1D; 
+       // UID from data[1 - 4]
+       cmd2[1] = data[1];
+       cmd2[2] = data[2];
+       cmd2[3] = data[3];
+       cmd2[4] = data[4];
+       cmd2[5] = 0x00;
+       cmd2[6] = 0x08;
+       cmd2[7] = 0x01;
+       cmd2[8] = 0x00;
+       cmdLen = 9;
+
+       // attrib
+       if (HF14BCmdRaw(true, &crc2, true, cmd2, &cmdLen, false)==0) return rawClose();
+
+       if (cmdLen != 3 || !crc2) return rawClose();
+       // add attrib responce to data
+       data[14] = cmd2[0];
+       rawClose();
+       return 1;
+}
+
+// 14b get and print Full Info (as much as we know)
+int HF14BStdInfo(uint8_t *data, uint8_t *datalen){
+       if (!HF14BStdReader(data,datalen)) return 0;
+
+       //add more info here
        print_atqb_resp(data);
 
+
        return 1;
 }
 
-int HF14B_ST_Info(uint8_t *data, uint8_t *datalen){
+// SRx get and print general info about SRx chip from UID
+int HF14B_ST_Reader(uint8_t *data, uint8_t *datalen, bool closeCon){
        bool crc = true;
        *datalen = 2;
        //wake cmd
@@ -326,7 +489,6 @@ int HF14B_ST_Info(uint8_t *data, uint8_t *datalen){
        *datalen = 2;
 
        //leave power on
-       // verbose on for now for testing - turn off when functional
        if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return rawClose();
 
        if (*datalen != 3 || !crc || data[0] != chipID) return rawClose();
@@ -335,19 +497,32 @@ int HF14B_ST_Info(uint8_t *data, uint8_t *datalen){
        data[0] = 0x0B;
        *datalen = 1;
 
-       //power off
-       // verbose on for now for testing - turn off when functional
-       if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return 0;
-       rawClose();
-       if (*datalen != 10 || !crc) return 0;
+       //leave power on
+       if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return rawClose();
+
+       if (*datalen != 10 || !crc) return rawClose();
+
+       //power off ?
+       if (closeCon) rawClose();
 
        PrintAndLog("\n14443-3b ST tag found:");
-       print_st_info(data);
+       print_st_general_info(data);
+       return 1;
+}
+
+// SRx get and print full info (needs more info...)
+int HF14B_ST_Info(uint8_t *data, uint8_t *datalen){
+       if (!HF14B_ST_Reader(data, datalen, false)) return 0;
+       
+       //add locking bit information here.
+       if (print_ST_Lock_info(data[5]>>2)) 
+               rawClose();
+
        return 1;
 }
 
 // test for other 14b type tags (mimic another reader - don't have tags to identify)
-int HF14B_Other_Info(uint8_t *data, uint8_t *datalen){
+int HF14B_Other_Reader(uint8_t *data, uint8_t *datalen){
        bool crc = true;
        *datalen = 4;
        //std read cmd
@@ -356,11 +531,12 @@ int HF14B_Other_Info(uint8_t *data, uint8_t *datalen){
        data[2] = 0x3f;
        data[3] = 0x80;
 
-       if (HF14BCmdRaw(true, &crc, false, data, datalen, false)!=0) {
+       if (HF14BCmdRaw(true, &crc, true, data, datalen, false)!=0) {
                if (*datalen > 2 || !crc) {
                        PrintAndLog ("\n14443-3b tag found:");
                        PrintAndLog ("Unknown tag type answered to a 0x000b3f80 command ans:");
                        PrintAndLog ("%s",sprint_hex(data,*datalen));
+                       rawClose();
                        return 1;
                }
        }
@@ -369,11 +545,12 @@ int HF14B_Other_Info(uint8_t *data, uint8_t *datalen){
        *datalen = 1;
        data[0] = 0x0a;
 
-       if (HF14BCmdRaw(true, &crc, false, data, datalen, false)!=0) {
+       if (HF14BCmdRaw(true, &crc, true, data, datalen, false)!=0) {
                if (*datalen > 0) {
                        PrintAndLog ("\n14443-3b tag found:");
                        PrintAndLog ("Unknown tag type answered to a 0x0A command ans:");
                        PrintAndLog ("%s",sprint_hex(data,*datalen));
+                       rawClose();
                        return 1;
                }
        }
@@ -382,19 +559,20 @@ int HF14B_Other_Info(uint8_t *data, uint8_t *datalen){
        *datalen = 1;
        data[0] = 0x0c;
 
-       if (HF14BCmdRaw(true, &crc, false, data, datalen, false)!=0) {
+       if (HF14BCmdRaw(true, &crc, true, data, datalen, false)!=0) {
                if (*datalen > 0) {
                        PrintAndLog ("\n14443-3b tag found:");
                        PrintAndLog ("Unknown tag type answered to a 0x0C command ans:");
                        PrintAndLog ("%s",sprint_hex(data,*datalen));
+                       rawClose();
                        return 1;
                }
        }
-
+       rawClose();
        return 0;
-
 }
 
+// get and print all info known about any known 14b tag
 int HF14BInfo(bool verbose){
        uint8_t data[100];
        uint8_t datalen = 5;
@@ -407,16 +585,41 @@ int HF14BInfo(bool verbose){
 
        // try unknown 14b read commands (to be identified later)
        //   could be read of calypso, CEPAS, moneo, or pico pass.
-       if (HF14B_Other_Info(data, &datalen)) return 1;
+       if (HF14B_Other_Reader(data, &datalen)) return 1;
 
        if (verbose) PrintAndLog("no 14443B tag found");
        return 0;
 }
 
+// menu command to get and print all info known about any known 14b tag
 int CmdHF14Binfo(const char *Cmd){
        return HF14BInfo(true);
 }
 
+// get and print general info about all known 14b chips
+int HF14BReader(bool verbose){
+       uint8_t data[100];
+       uint8_t datalen = 5;
+       
+       // try std 14b (atqb)
+       if (HF14BStdReader(data, &datalen)) return 1;
+
+       // try st 14b
+       if (HF14B_ST_Reader(data, &datalen, true)) return 1;
+
+       // try unknown 14b read commands (to be identified later)
+       //   could be read of calypso, CEPAS, moneo, or pico pass.
+       if (HF14B_Other_Reader(data, &datalen)) return 1;
+
+       if (verbose) PrintAndLog("no 14443B tag found");
+       return 0;
+}
+
+// menu command to get and print general info about all known 14b chips
+int CmdHF14BReader(const char *Cmd){
+       return HF14BReader(true);
+}
+
 int CmdSriWrite( const char *Cmd){
 /*
  * For SRIX4K  blocks 00 - 7F
@@ -487,8 +690,9 @@ int CmdSriWrite( const char *Cmd){
 static command_t CommandTable[] = 
 {
   {"help",        CmdHelp,        1, "This help"},
-       {"info",        CmdHF14Binfo,   0, "Find and print info about a 14b type tag (HF ISO 14443b)"},
-  {"list",        CmdHF14BList,   0, "[Deprecated] List ISO 14443b history"},
+  {"info",        CmdHF14Binfo,   0, "Find and print details about a 14443B tag"},
+  {"list",        CmdHF14BList,   0, "[Deprecated] List ISO 14443B history"},
+  {"reader",      CmdHF14BReader, 0, "Act as a 14443B reader to identify a tag"},
   {"sim",         CmdHF14BSim,    0, "Fake ISO 14443B tag"},
   {"snoop",       CmdHF14BSnoop,  0, "Eavesdrop ISO 14443B"},
   {"sri512read",  CmdSri512Read,  0, "Read contents of a SRI512 tag"},
index 5ef5273a4013aa759905c16ded2df9c57dcbfc20..16612cba3b86e7f07d0360085f0fa773c8dfb33f 100644 (file)
@@ -18,7 +18,6 @@ int CmdHF14AMifare(const char *Cmd)
        uint32_t nt = 0, nr = 0;\r
        uint64_t par_list = 0, ks_list = 0, r_key = 0;\r
        int16_t isOK = 0;\r
-       uint8_t keyBlock[8] = {0};\r
 \r
        UsbCommand c = {CMD_READER_MIFARE, {true, 0, 0}};\r
 \r
@@ -74,22 +73,13 @@ start:
        if (nonce2key(uid, nt, nr, par_list, ks_list, &r_key)) {\r
                isOK = 2;\r
                PrintAndLog("Key not found (lfsr_common_prefix list is null). Nt=%08x", nt);    \r
-       } else {\r
-               printf("------------------------------------------------------------------\n");\r
-               PrintAndLog("Key found:%012"llx" \n", r_key);\r
-\r
-               num_to_bytes(r_key, 6, keyBlock);\r
-               isOK = mfCheckKeys(0, 0, 1, keyBlock, &r_key);\r
-       }\r
-       \r
-       if (!isOK) \r
-               PrintAndLog("Found valid key:%012"llx, r_key);\r
-       else\r
-       {\r
-               if (isOK != 2) PrintAndLog("Found invalid key. ");      \r
                PrintAndLog("Failing is expected to happen in 25%% of all cases. Trying again with a different reader nonce...");\r
                c.arg[0] = false;\r
                goto start;\r
+       } else {\r
+               isOK = 0;\r
+               printf("------------------------------------------------------------------\n");\r
+               PrintAndLog("Found valid key:%012"llx" \n", r_key);\r
        }\r
        \r
        PrintAndLog("");\r
@@ -689,7 +679,7 @@ int CmdHF14AMfNested(const char *Cmd)
                        for (j = 0; j < 2; j++) {\r
                                if (e_sector[i].foundKey[j]) continue;\r
                                \r
-                               res = mfCheckKeys(FirstBlockOfSector(i), j, 6, keyBlock, &key64);\r
+                               res = mfCheckKeys(FirstBlockOfSector(i), j, true, 6, keyBlock, &key64);\r
                                \r
                                if (!res) {\r
                                        e_sector[i].Key[j] = key64;\r
@@ -973,7 +963,7 @@ int CmdHF14AMfChk(const char *Cmd)
                        uint32_t max_keys = keycnt>USB_CMD_DATA_SIZE/6?USB_CMD_DATA_SIZE/6:keycnt;\r
                        for (uint32_t c = 0; c < keycnt; c+=max_keys) {\r
                                uint32_t size = keycnt-c>max_keys?max_keys:keycnt-c;\r
-                               res = mfCheckKeys(b, t, size, &keyBlock[6*c], &key64);\r
+                               res = mfCheckKeys(b, t, true, size, &keyBlock[6*c], &key64);\r
                                if (res != 1) {\r
                                        if (!res) {\r
                                                PrintAndLog("Found valid key:[%012"llx"]",key64);\r
index 05ad0c9f482f5072616cfdb07357a3b6a9fe52b8..33dc78aeb523c5731ec297e9432159336d774580 100644 (file)
@@ -18,6 +18,7 @@
 #include "cmdhw.h"
 #include "cmdmain.h"
 #include "cmddata.h"
+#include "data.h"
 
 /* low-level hardware control */
 
@@ -405,39 +406,72 @@ int CmdTune(const char *Cmd)
 int CmdVersion(const char *Cmd)
 {
 
+       clearCommandBuffer();
        UsbCommand c = {CMD_VERSION};
        static UsbCommand resp = {0, {0, 0, 0}};
-       
+
        if (resp.arg[0] == 0 && resp.arg[1] == 0) { // no cached information available
                SendCommand(&c);
-               if (WaitForResponseTimeout(CMD_ACK,&resp,1000) && Cmd != NULL) {
+               if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
                        PrintAndLog("Prox/RFID mark3 RFID instrument");
                        PrintAndLog((char*)resp.d.asBytes);
                        lookupChipID(resp.arg[0], resp.arg[1]);
                }
-       } else if (Cmd != NULL) {
+       } else {
+               PrintAndLog("[[[ Cached information ]]]\n");
                PrintAndLog("Prox/RFID mark3 RFID instrument");
                PrintAndLog((char*)resp.d.asBytes);
                lookupChipID(resp.arg[0], resp.arg[1]);
+               PrintAndLog("");
+       }
+       return 0;
+}
+
+int CmdStatus(const char *Cmd)
+{
+       uint8_t speed_test_buffer[USB_CMD_DATA_SIZE];
+       sample_buf = speed_test_buffer;
+
+       clearCommandBuffer();
+       UsbCommand c = {CMD_STATUS};
+       SendCommand(&c);
+       if (!WaitForResponseTimeout(CMD_ACK,&c,1900)) {
+               PrintAndLog("Status command failed. USB Speed Test timed out");
+       }
+       return 0;
+}
+
+
+int CmdPing(const char *Cmd)
+{
+       clearCommandBuffer();
+       UsbCommand resp;
+       UsbCommand c = {CMD_PING};
+       SendCommand(&c);
+       if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
+               PrintAndLog("Ping successfull");
+       }else{
+               PrintAndLog("Ping failed");
        }
-       
        return 0;
 }
 
 static command_t CommandTable[] = 
 {
-  {"help",          CmdHelp,        1, "This help"},
-  {"detectreader",  CmdDetectReader,0, "['l'|'h'] -- Detect external reader field (option 'l' or 'h' to limit to LF or HF)"},
-  {"fpgaoff",       CmdFPGAOff,     0, "Set FPGA off"},
-  {"lcd",           CmdLCD,         0, "<HEX command> <count> -- Send command/data to LCD"},
-  {"lcdreset",      CmdLCDReset,    0, "Hardware reset LCD"},
-  {"readmem",       CmdReadmem,     0, "[address] -- Read memory at decimal address from flash"},
-  {"reset",         CmdReset,       0, "Reset the Proxmark3"},
-  {"setlfdivisor",  CmdSetDivisor,  0, "<19 - 255> -- Drive LF antenna at 12Mhz/(divisor+1)"},
-  {"setmux",        CmdSetMux,      0, "<loraw|hiraw|lopkd|hipkd> -- Set the ADC mux to a specific value"},
-  {"tune",          CmdTune,        0, "Measure antenna tuning"},
-  {"version",       CmdVersion,     0, "Show version information about the connected Proxmark"},
-  {NULL, NULL, 0, NULL}
+       {"help",          CmdHelp,        1, "This help"},
+       {"detectreader",  CmdDetectReader,0, "['l'|'h'] -- Detect external reader field (option 'l' or 'h' to limit to LF or HF)"},
+       {"fpgaoff",       CmdFPGAOff,     0, "Set FPGA off"},
+       {"lcd",           CmdLCD,         0, "<HEX command> <count> -- Send command/data to LCD"},
+       {"lcdreset",      CmdLCDReset,    0, "Hardware reset LCD"},
+       {"readmem",       CmdReadmem,     0, "[address] -- Read memory at decimal address from flash"},
+       {"reset",         CmdReset,       0, "Reset the Proxmark3"},
+       {"setlfdivisor",  CmdSetDivisor,  0, "<19 - 255> -- Drive LF antenna at 12Mhz/(divisor+1)"},
+       {"setmux",        CmdSetMux,      0, "<loraw|hiraw|lopkd|hipkd> -- Set the ADC mux to a specific value"},
+       {"tune",          CmdTune,        0, "Measure antenna tuning"},
+       {"version",       CmdVersion,     0, "Show version information about the connected Proxmark"},
+       {"status",        CmdStatus,      0, "Show runtime status information about the connected Proxmark"},
+       {"ping",          CmdPing,        0, "Test if the pm3 is responsive"},
+       {NULL, NULL, 0, NULL}
 };
 
 int CmdHW(const char *Cmd)
index edf029325ddbe8e353197cdbc667681e14acadc2..4c682a76f1b71cccfa682e6ed7ade580356975e7 100644 (file)
@@ -22,6 +22,7 @@
 #include "util.h"
 #include "cmdlf.h"
 #include "cmdlfhid.h"
+#include "cmdlfawid.h"
 #include "cmdlfti.h"
 #include "cmdlfem4x.h"
 #include "cmdlfhitag.h"
@@ -388,7 +389,7 @@ int usage_lf_config()
        PrintAndLog("       b <bps>       Sets resolution of bits per sample. Default (max): 8");
        PrintAndLog("       d <decim>     Sets decimation. A value of N saves only 1 in N samples. Default: 1");
        PrintAndLog("       a [0|1]       Averaging - if set, will average the stored sample value when decimating. Default: 1");
-       PrintAndLog("       t <threshold> Sets trigger threshold. 0 means no threshold");
+       PrintAndLog("       t <threshold> Sets trigger threshold. 0 means no threshold (range: 0-128)");
        PrintAndLog("Examples:");
        PrintAndLog("      lf config b 8 L");
        PrintAndLog("                    Samples at 125KHz, 8bps.");
@@ -1130,6 +1131,7 @@ static command_t CommandTable[] =
        {"config",      CmdLFSetConfig,     0, "Set config for LF sampling, bit/sample, decimation, frequency"},
        {"flexdemod",   CmdFlexdemod,       1, "Demodulate samples for FlexPass"},
        {"hid",         CmdLFHID,           1, "{ HID RFIDs... }"},
+       {"awid",                CmdLFAWID,                  1, "{ AWID RFIDs... }"},
        {"io",            CmdLFIO,                1, "{ ioProx tags... }"},
        {"indalademod", CmdIndalaDemod,     1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
        {"indalaclone", CmdIndalaClone,     0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"},
diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c
new file mode 100644 (file)
index 0000000..06397e7
--- /dev/null
@@ -0,0 +1,237 @@
+//-----------------------------------------------------------------------------
+// Authored by Craig Young <cyoung@tripwire.com> based on cmdlfhid.c structure
+//
+// cmdlfhid.c is Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
+//
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// Low frequency AWID26 commands
+//-----------------------------------------------------------------------------
+
+#include <stdio.h>      // sscanf
+#include "proxmark3.h"  // Definitions, USB controls, etc
+#include "ui.h"         // PrintAndLog
+#include "cmdparser.h"  // CmdsParse, CmdsHelp
+#include "cmdlfawid.h"  // AWID function declarations
+#include "lfdemod.h"    // parityTest
+#include "cmdmain.h"
+static int CmdHelp(const char *Cmd);
+
+
+int usage_lf_awid_fskdemod(void) {
+       PrintAndLog("Enables AWID26 compatible reader mode printing details of scanned AWID26 tags.");
+       PrintAndLog("By default, values are printed and logged until the button is pressed or another USB command is issued.");
+       PrintAndLog("If the ['1'] option is provided, reader mode is exited after reading a single AWID26 card.");
+       PrintAndLog("");
+       PrintAndLog("Usage:  lf awid fskdemod ['1']");
+       PrintAndLog("  Options : ");
+       PrintAndLog("  1 : (optional) stop after reading a single card");
+       PrintAndLog("");
+       PrintAndLog("   sample : lf awid fskdemod");
+       PrintAndLog("          : lf awid fskdemod 1");
+       return 0;
+}
+
+int usage_lf_awid_sim(void) {
+       PrintAndLog("Enables simulation of AWID26 card with specified facility-code and card number.");
+       PrintAndLog("Simulation runs until the button is pressed or another USB command is issued.");
+       PrintAndLog("Per AWID26 format, the facility-code is 8-bit and the card number is 16-bit.  Larger values are truncated.");
+       PrintAndLog("");
+       PrintAndLog("Usage:  lf awid sim <Facility-Code> <Card-Number>");
+       PrintAndLog("  Options : ");
+       PrintAndLog("  <Facility-Code> : 8-bit value representing the AWID facility code");
+       PrintAndLog("  <Card Number>   : 16-bit value representing the AWID card number");
+       PrintAndLog("");
+       PrintAndLog("   sample : lf awid sim 224 1337");
+       return 0;
+}
+
+int usage_lf_awid_clone(void) {
+       PrintAndLog("Enables cloning of AWID26 card with specified facility-code and card number onto T55x7.");
+       PrintAndLog("The T55x7 must be on the antenna when issuing this command.  T55x7 blocks are calculated and printed in the process.");
+       PrintAndLog("Per AWID26 format, the facility-code is 8-bit and the card number is 16-bit.  Larger values are truncated.");
+       PrintAndLog("");
+       PrintAndLog("Usage:  lf awid clone <Facility-Code> <Card-Number>");
+       PrintAndLog("  Options : ");
+       PrintAndLog("  <Facility-Code> : 8-bit value representing the AWID facility code");
+       PrintAndLog("  <Card Number>   : 16-bit value representing the AWID card number");
+       PrintAndLog("");
+       PrintAndLog("   sample : lf awid clone 224 1337");
+       return 0;
+}
+
+int CmdAWIDDemodFSK(const char *Cmd)
+{
+       int findone=0;
+       if(Cmd[0]=='1') findone=1;
+       if (Cmd[0]=='h' || Cmd[0] == 'H') return usage_lf_awid_fskdemod();
+       UsbCommand c={CMD_AWID_DEMOD_FSK};
+       c.arg[0]=findone;
+       SendCommand(&c);
+       return 0;   
+}
+
+int getAWIDBits(unsigned int fc, unsigned int cn, uint8_t *AWIDBits)
+{
+       int i;
+       uint32_t fcode=(fc & 0x000000FF), cnum=(cn & 0x0000FFFF), uBits=0;
+       if (fcode != fc)
+               PrintAndLog("NOTE: Facility code truncated for AWID26 format (8-bit facility code)");
+       if (cnum!=cn)
+               PrintAndLog("NOTE: Card number was truncated for AWID26 format (16-bit card number)");
+
+       AWIDBits[0] = 0x01; // 6-bit Preamble with 2 parity bits
+       AWIDBits[1] = 0x1D; // First byte from card format (26-bit) plus parity bits
+       AWIDBits[2] = 0x80; // Set the next two bits as 0b10 to finish card format
+       uBits = (fcode<<4) + (cnum>>12);
+       if (!parityTest(uBits,12,0))
+               AWIDBits[2] |= (1<<5); // If not already even parity, set bit to make even
+       uBits = AWIDBits[2]>>5;
+       if (!parityTest(uBits, 3, 1))
+               AWIDBits[2] |= (1<<4);
+       uBits = fcode>>5; // first 3 bits of facility-code
+       AWIDBits[2] += (uBits<<1);
+       if (!parityTest(uBits, 3, 1))
+               AWIDBits[2]++; // Set parity bit to make odd parity
+       uBits = (fcode & 0x1C)>>2;
+       AWIDBits[3] = 0;
+       if (!parityTest(uBits,3,1))
+               AWIDBits[3] |= (1<<4);
+       AWIDBits[3] += (uBits<<5);
+       uBits = ((fcode & 0x3)<<1) + ((cnum & 0x8000)>>15); // Grab/shift 2 LSBs from facility code and add shifted MSB from cardnum
+       if (!parityTest(uBits,3,1))
+               AWIDBits[3]++; // Set LSB for parity
+       AWIDBits[3]+= (uBits<<1);
+       uBits = (cnum & 0x7000)>>12;
+       AWIDBits[4] = uBits<<5;
+       if (!parityTest(uBits,3,1))
+               AWIDBits[4] |= (1<<4);
+       uBits = (cnum & 0x0E00)>>9;
+       AWIDBits[4] += (uBits<<1);
+       if (!parityTest(uBits,3,1))
+               AWIDBits[4]++; // Set LSB for parity
+       uBits = (cnum & 0x1C0)>>6; // Next bits from card number
+       AWIDBits[5]=(uBits<<5);
+       if (!parityTest(uBits,3,1))
+               AWIDBits[5] |= (1<<4); // Set odd parity bit as needed
+       uBits = (cnum & 0x38)>>3;
+       AWIDBits[5]+= (uBits<<1);
+       if (!parityTest(uBits,3,1))
+               AWIDBits[5]++; // Set odd parity bit as needed
+       uBits = (cnum & 0x7); // Last three bits from card number!
+       AWIDBits[6] = (uBits<<5);
+       if (!parityTest(uBits,3,1))
+               AWIDBits[6] |= (1<<4);
+       uBits = (cnum & 0x0FFF);
+       if (!parityTest(uBits,12,1))
+               AWIDBits[6] |= (1<<3);
+       else
+               AWIDBits[6]++;
+       for (i = 7; i<12; i++)
+               AWIDBits[i]=0x11;
+       return 1;
+}
+
+int CmdAWIDSim(const char *Cmd)
+{
+       uint32_t fcode = 0, cnum = 0, fc=0, cn=0, i=0;
+       uint8_t *BS, BitStream[12];
+       uint64_t arg1 = (10<<8) + 8; // fcHigh = 10, fcLow = 8
+       uint64_t arg2 = 50; // clk RF/50 invert=0
+       BS = BitStream;
+       if (sscanf(Cmd, "%u %u", &fc, &cn ) != 2) {
+               return usage_lf_awid_sim();
+       }
+
+       fcode=(fc & 0x000000FF);
+       cnum=(cn & 0x0000FFFF);
+       if (fc!=fcode)
+               PrintAndLog("Facility-Code (%u) truncated to 8-bits: %u",fc,fcode);
+       if (cn!=cnum)
+               PrintAndLog("Card number (%u) truncated to 16-bits: %u",cn,cnum);
+       PrintAndLog("Emulating AWID26 -- FC: %u; CN: %u\n",fcode,cnum);
+       PrintAndLog("Press pm3-button to abort simulation or run another command");
+       // AWID uses: fcHigh: 10, fcLow: 8, clk: 50, invert: 0
+       if (getAWIDBits(fc, cn, BS)) {
+                       PrintAndLog("Running 'lf simfsk c 50 H 10 L 8 d %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x'", 
+                                                                                                                                                               BS[0],BS[1],BS[2],BS[3],BS[4],BS[5],BS[6],
+                                                                                                                                                               BS[7],BS[8],BS[9],BS[10],BS[11]);
+               } else
+                       PrintAndLog("Error with tag bitstream generation.");
+       UsbCommand c;
+       c.cmd = CMD_FSK_SIM_TAG;
+       c.arg[0] = arg1; // fcHigh<<8 + fcLow
+       c.arg[1] = arg2; // Inversion and clk setting
+       c.arg[2] = 96; // Bitstream length: 96-bits == 12 bytes
+       for (i=0; i < 96; i++)
+               c.d.asBytes[i] = (BS[i/8] & (1<<(7-(i%8))))?1:0;
+       SendCommand(&c);
+       return 0;
+}
+
+int CmdAWIDClone(const char *Cmd)
+{
+       uint32_t fc=0,cn=0,blocks[4] = {0x00107060, 0, 0, 0x11111111}, i=0;
+       uint8_t BitStream[12];
+       uint8_t *BS=BitStream;
+       UsbCommand c, resp;
+
+       if (sscanf(Cmd, "%u %u", &fc, &cn ) != 2) {
+               return usage_lf_awid_clone();
+       }
+
+       if ((fc & 0xFF) != fc) {
+               fc &= 0xFF;
+               PrintAndLog("Facility-Code Truncated to 8-bits (AWID26): %u", fc);
+       }
+       if ((cn & 0xFFFF) != cn) {
+               cn &= 0xFFFF;
+               PrintAndLog("Card Number Truncated to 16-bits (AWID26): %u", cn);
+       }
+       if (getAWIDBits(fc,cn,BS)) {
+               PrintAndLog("Preparing to clone AWID26 to T55x7 with FC: %u, CN: %u (Raw: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x)", 
+                                                                       fc,cn, BS[0],BS[1],BS[2],BS[3],BS[4],BS[5],BS[6],BS[7],BS[8],BS[9],BS[10],BS[11]);
+               blocks[1] = (BS[0]<<24) + (BS[1]<<16) + (BS[2]<<8) + (BS[3]);
+               blocks[2] = (BS[4]<<24) + (BS[5]<<16) + (BS[6]<<8) + (BS[7]);
+               PrintAndLog("Block 0: 0x%08x", blocks[0]);
+               PrintAndLog("Block 1: 0x%08x", blocks[1]);
+               PrintAndLog("Block 2: 0x%08x", blocks[2]);
+               PrintAndLog("Block 3: 0x%08x", blocks[3]);
+               for (i=0; i<4; i++) {
+                       c.cmd = CMD_T55XX_WRITE_BLOCK;
+                       c.arg[0] = blocks[i];
+                       c.arg[1] = i;
+                       c.arg[2] = 0;
+                       SendCommand(&c);
+                       if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){
+                               PrintAndLog("Error occurred, device did not respond during write operation.");
+                               return -1;
+                       }
+
+               }
+       }
+       return 0;
+}
+
+static command_t CommandTable[] = 
+{
+       {"help",      CmdHelp,        1, "This help"},
+       {"fskdemod",  CmdAWIDDemodFSK, 0, "['1'] Realtime AWID FSK demodulator (option '1' for one tag only)"},
+       {"sim",       CmdAWIDSim,      0, "<Facility-Code> <Card Number> -- AWID tag simulator"},
+       {"clone",     CmdAWIDClone,    0, "<Facility-Code> <Card Number> -- Clone AWID to T55x7 (tag must be in range of antenna)"},
+       {NULL, NULL, 0, NULL}
+};
+
+int CmdLFAWID(const char *Cmd)
+{
+       CmdsParse(CommandTable, Cmd);
+       return 0;
+}
+
+int CmdHelp(const char *Cmd)
+{
+       CmdsHelp(CommandTable);
+       return 0;
+}
diff --git a/client/cmdlfawid.h b/client/cmdlfawid.h
new file mode 100644 (file)
index 0000000..0062292
--- /dev/null
@@ -0,0 +1,24 @@
+//-----------------------------------------------------------------------------
+// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
+//
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// Low frequency AWID commands
+//-----------------------------------------------------------------------------
+
+#ifndef CMDLFAWID_H__
+#define CMDLFAWID_H__
+
+int CmdLFAWID(const char *Cmd);
+//int CmdAWIDDemod(const char *Cmd);
+int CmdAWIDDemodFSK(const char *Cmd);
+int CmdAWIDSim(const char *Cmd);
+int CmdAWIDClone(const char *Cmd);
+int getAWIDBits(unsigned int fc, unsigned int cn, uint8_t *AWIDBits);
+int usage_lf_awid_fskdemod(void);
+int usage_lf_awid_clone(void);
+int usage_lf_awid_sim(void);
+
+#endif
index b357e71c30c50e327f42cbe346475614685da428..2291735cb8ecd46cd74986eb628cbc978b170f59 100644 (file)
@@ -242,6 +242,7 @@ int CmdT55xxReadBlock(const char *Cmd) {
                c.d.asBytes[0] = 0x1; \r
        }\r
 \r
+       clearCommandBuffer();\r
        SendCommand(&c);\r
        if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {\r
                PrintAndLog("command execution time out");\r
@@ -670,6 +671,7 @@ int CmdT55xxWriteBlock(const char *Cmd)
        }\r
        \r
        UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}};\r
+       UsbCommand resp;\r
        c.d.asBytes[0] = 0x0; \r
 \r
        PrintAndLog("Writing to block: %d  data  : 0x%08X", block, data);\r
@@ -680,7 +682,12 @@ int CmdT55xxWriteBlock(const char *Cmd)
                c.d.asBytes[0] = 0x1; \r
                PrintAndLog("pwd   : 0x%08X", password);\r
        }\r
+       clearCommandBuffer();\r
        SendCommand(&c);\r
+       if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){\r
+               PrintAndLog("Error occurred, device did not ACK write operation. (May be due to old firmware)");\r
+               return -1;\r
+       }\r
        return 0;\r
 }\r
 \r
@@ -878,6 +885,7 @@ int AquireData( uint8_t block ){
                // c.d.asBytes[0] = 0x1; \r
        // }\r
 \r
+       clearCommandBuffer();\r
        SendCommand(&c);\r
        if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {\r
                PrintAndLog("command execution time out");\r
index 512aa13cc91d7e6e950de83346e9342900aef9a1..deced5585c6dc343ebe2d74a8e7f6e6068ba25c1 100644 (file)
@@ -97,8 +97,9 @@ void storeCommand(UsbCommand *command)
     memcpy(destination, command, sizeof(UsbCommand));
 
     cmd_head = (cmd_head +1) % CMD_BUFFER_SIZE; //increment head and wrap
-
 }
+
+
 /**
  * @brief getCommand gets a command from an internal circular buffer.
  * @param response location to write command
@@ -117,9 +118,9 @@ int getCommand(UsbCommand* response)
     cmd_tail = (cmd_tail +1 ) % CMD_BUFFER_SIZE;
 
     return 1;
-
 }
 
+
 /**
  * Waits for a certain response type. This method waits for a maximum of
  * ms_timeout milliseconds for a specified response command.
@@ -131,33 +132,34 @@ int getCommand(UsbCommand* response)
  */
 bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout) {
   
-  UsbCommand resp;
+       UsbCommand resp;
        
-       if (response == NULL)
-    response = &resp;
-
-
-  // Wait until the command is received
-  for(size_t dm_seconds=0; dm_seconds < ms_timeout/10; dm_seconds++) {
+       if (response == NULL) {
+               response = &resp;
+       }
 
+       // Wait until the command is received
+       for(size_t dm_seconds=0; dm_seconds < ms_timeout/10; dm_seconds++) {
                while(getCommand(response)) {
-          if(response->cmd == cmd){
-          return true;
-          }
-      }
-        msleep(10); // XXX ugh
-        if (dm_seconds == 200) { // Two seconds elapsed
-          PrintAndLog("Waiting for a response from the proxmark...");
-          PrintAndLog("Don't forget to cancel its operation first by pressing on the button");
-        }
+                       if(response->cmd == cmd){
+                               return true;
+                       }
+               }
+               msleep(10); // XXX ugh
+               if (dm_seconds == 200) { // Two seconds elapsed
+                       PrintAndLog("Waiting for a response from the proxmark...");
+                       PrintAndLog("Don't forget to cancel its operation first by pressing on the button");
+               }
        }
-    return false;
+       return false;
 }
 
+
 bool WaitForResponse(uint32_t cmd, UsbCommand* response) {
        return WaitForResponseTimeout(cmd,response,-1);
 }
 
+
 //-----------------------------------------------------------------------------
 // Entry point into our code: called whenever the user types a command and
 // then presses Enter, which the full command line that they typed.
@@ -166,6 +168,7 @@ void CommandReceived(char *Cmd) {
   CmdsParse(CommandTable, Cmd);
 }
 
+
 //-----------------------------------------------------------------------------
 // Entry point into our code: called whenever we received a packet over USB
 // that we weren't necessarily expecting, for example a debug print.
@@ -189,12 +192,13 @@ void UsbCommandReceived(UsbCommand *UC)
 
                case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: {
                        memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]);
+                       return;
                } break;
 
                default:
+                       storeCommand(UC);
                        break;
        }
 
-       storeCommand(UC);
 }
 
index b3a7f4ec94c3e3663fc3db40fb9de301dbb1d065..f4013bab5102e42e149ff2b66a9af6d642651642 100644 (file)
@@ -84,6 +84,7 @@ typedef struct {
 #define CMD_FSK_SIM_TAG                                                   0x021E
 #define CMD_ASK_SIM_TAG                                                   0x021F
 #define CMD_PSK_SIM_TAG                                                   0x0220
+#define CMD_AWID_DEMOD_FSK                                                0x0221
 
 /* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
 
index 4c7bc638319d39066227f769c4ee662720a58707..64f16e4491ab95769e358b9f685d727242ef789c 100644 (file)
@@ -20,7 +20,8 @@ local _commands = {
        CMD_BUFF_CLEAR =                                                     0x0105,
        CMD_READ_MEM =                                                       0x0106,
        CMD_VERSION =                                                        0x0107,
-
+       CMD_STATUS =                                                         0x0108,
+       CMD_PING =                                                           0x0109,
        --// For low-frequency tags
        CMD_READ_TI_TYPE =                                                   0x0202,
        CMD_WRITE_TI_TYPE =                                                  0x0203,
@@ -54,6 +55,7 @@ local _commands = {
        CMD_FSK_SIM_TAG =                                                    0x021E,
        CMD_ASK_SIM_TAG =                                                    0x021F,
        CMD_PSK_SIM_TAG =                                                    0x0220,
+       CMD_AWID_DEMOD_FSK =                                                 0x0221,
 
        --/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
 
index 95453ebfd9b5e6ab270df7696985a32232ce7e40..eb145123801d7f227ef150be27fb576303991336 100644 (file)
@@ -181,7 +181,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
                crypto1_get_lfsr(statelists[0].head.slhead + i, &key64);\r
                num_to_bytes(key64, 6, keyBlock);\r
                key64 = 0;\r
-               if (!mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, 1, keyBlock, &key64)) {\r
+               if (!mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, false, 1, keyBlock, &key64)) {\r
                        num_to_bytes(key64, 6, resultKey);\r
                        break;\r
                }\r
@@ -193,11 +193,11 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
        return 0;\r
 }\r
 \r
-int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key){\r
+int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key){\r
 \r
        *key = 0;\r
 \r
-       UsbCommand c = {CMD_MIFARE_CHKKEYS, {blockNo, keyType, keycnt}};\r
+       UsbCommand c = {CMD_MIFARE_CHKKEYS, {((blockNo & 0xff) | ((keyType&0xff)<<8)), clear_trace, keycnt}};\r
        memcpy(c.d.asBytes, keyBlock, 6 * keycnt);\r
        SendCommand(&c);\r
 \r
index a11f11d5068465597b0528ed188736a6bd31752e..f6ffab3f219896c93aaa9ca1e4f6162fd475bdad 100644 (file)
@@ -50,7 +50,7 @@ typedef struct {
 extern char logHexFileName[FILE_PATH_SIZE];\r
 \r
 int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * ResultKeys, bool calibrate);\r
-int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key);\r
+int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key);\r
 \r
 int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);\r
 int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);\r
index 111f58cd6b07a8d21ddff7e006e5de485bf4830b..70d874fe88600c2a8a60014306e480b3f04a42a2 100644 (file)
@@ -133,7 +133,7 @@ int nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint64_t par_info, uint64_
                key64 = *(last_keylist + i);
                num_to_bytes(key64, 6, keyBlock);
                key64 = 0;
-               if (!mfCheckKeys(0, 0, 1, keyBlock, &key64)) {
+               if (!mfCheckKeys(0, 0, false, 1, keyBlock, &key64)) {
                        *key = key64;
                        free(last_keylist);
                        last_keylist = NULL;
index eb98ffbf753809d64188a47448286e5760735498..9cc865f0172f41ab099bf8ebd7836c72cb72a7cc 100644 (file)
@@ -88,10 +88,33 @@ function mfcrack_inner()
        while not core.ukbhit() do              
                local result = core.WaitForResponseTimeout(cmds.CMD_ACK,1000)
                if result then
-                       -- Unpacking the three arg-parameters
-                       local count,cmd,isOK = bin.unpack('LL',result)
 
-                       if isOK ~= 1 then return nil, "Error occurred" end
+                       --[[
+                       I don't understand, they cmd and args are defined as uint32_t, however, 
+                       looking at the returned data, they all look like 64-bit things: 
+
+                       print("result", bin.unpack("HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH", result))
+
+                       FF      00      00      00      00      00      00      00      <-- 64 bits of data
+                       FE      FF      FF      FF      00      00      00      00      <-- 64 bits of data
+                       00      00      00      00      00      00      00      00      <-- 64 bits of data
+                       00      00      00      00      00      00      00      00      <-- 64 bits of data
+                       04      7F      12      E2      00             <-- this is where 'data' starts
+
+                       So below I use LI to pick out the "FEFF FFFF", don't know why it works.. 
+                       --]]
+                       -- Unpacking the arg-parameters
+                       local count,cmd,isOK = bin.unpack('LI',result)
+                       --print("response", isOK)--FF FF FF FF
+                       if isOK == 0xFFFFFFFF then
+                               return nil, "Button pressed. Aborted."
+                       elseif isOK == 0xFFFFFFFE then
+                               return nil, "Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests). You can try 'script run mfkeys' or 'hf mf chk' to test various known keys."
+                       elseif isOK == 0xFFFFFFFD then
+                               return nil, "Card is not vulnerable to Darkside attack (its random number generator is not predictable). You can try 'script run mfkeys' or 'hf mf chk' to test various known keys."
+                       elseif isOK ~= 1 then 
+                               return nil, "Error occurred" 
+                       end
 
 
                        -- The data-part is left
index 2d2beaf42cd12169babe5b12c603ef7680a4c3b4..94021c2c78fe3c409c428a0e6fb4e3410a4c680c 100644 (file)
@@ -47,6 +47,7 @@ char * printBits(size_t const size, void const * const ptr);
 uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize);
 
 char param_getchar(const char *line, int paramnum);
+int param_getptr(const char *line, int *bg, int *en, int paramnum);
 uint8_t param_get8(const char *line, int paramnum);
 uint8_t param_get8ex(const char *line, int paramnum, int deflt, int base);
 uint32_t param_get32ex(const char *line, int paramnum, int deflt, int base);
index f13a567c6fe8cda87b1cf70248cd201603fe023f..a3a7a50087727fc1f85a7a5a8df881537e21e04e 100644 (file)
@@ -580,7 +580,7 @@ int IOdemodFSK(uint8_t *dest, size_t size)
 
 // by marshmellow
 // takes a array of binary values, start position, length of bits per parity (includes parity bit),
-//   Parity Type (1 for odd; 0 for even; 2 for just drop it), and binary Length (length to run) 
+//   Parity Type (1 for odd; 0 for even; 2 Always 1's), and binary Length (length to run) 
 size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen)
 {
        uint32_t parityWd = 0;
@@ -590,10 +590,12 @@ size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t p
                        parityWd = (parityWd << 1) | BitStream[startIdx+word+bit];
                        BitStream[j++] = (BitStream[startIdx+word+bit]);
                }
-               j--;
+               j--; // overwrite parity with next data
                // if parity fails then return 0
-               if (pType != 2) {
-                       if (parityTest(parityWd, pLen, pType) == 0) return -1;
+               if (pType == 2) { // then marker bit which should be a 1
+                       if (!BitStream[j]) return 0;
+               } else {
+                       if (parityTest(parityWd, pLen, pType) == 0) return 0;                   
                }
                bitCnt+=(pLen-1);
                parityWd = 0;
index ccbb3c50e91389a4d733e25f75c7f94e50e77ef5..e13ddbe227e2ea81275cdce764cd24cd0bc95f81 100644 (file)
@@ -293,31 +293,47 @@ bool usb_poll()
   return (pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank);\r
 }\r
 \r
+/**\r
+       In github PR #129, some users appears to get a false positive from\r
+       usb_poll, which returns true, but the usb_read operation\r
+       still returns 0.\r
+       This check is basically the same as above, but also checks\r
+       that the length available to read is non-zero, thus hopefully fixes the\r
+       bug.\r
+**/\r
+bool usb_poll_validate_length()\r
+{\r
+\r
+       if (!usb_check()) return false;\r
+       if (!(pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank)) return false;\r
+       return (pUdp->UDP_CSR[AT91C_EP_OUT] >> 16) >  0;\r
+}\r
+\r
 //*----------------------------------------------------------------------------\r
 //* \fn    usb_read\r
 //* \brief Read available data from Endpoint OUT\r
 //*----------------------------------------------------------------------------\r
 uint32_t usb_read(byte_t* data, size_t len) {\r
-  byte_t bank = btReceiveBank;\r
+       byte_t bank = btReceiveBank;\r
        uint32_t packetSize, nbBytesRcv = 0;\r
-  uint32_t time_out = 0;\r
+       uint32_t time_out = 0;\r
   \r
        while (len)  {\r
                if (!usb_check()) break;\r
 \r
                if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) {\r
                        packetSize = MIN(pUdp->UDP_CSR[AT91C_EP_OUT] >> 16, len);\r
-      len -= packetSize;\r
+                       len -= packetSize;\r
                        while(packetSize--)\r
                                data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT];\r
                        pUdp->UDP_CSR[AT91C_EP_OUT] &= ~(bank);\r
                        if (bank == AT91C_UDP_RX_DATA_BK0) {\r
                                bank = AT91C_UDP_RX_DATA_BK1;\r
-      } else {\r
+                       } else {\r
                                bank = AT91C_UDP_RX_DATA_BK0;\r
-      }\r
+                       }\r
                }\r
-    if (time_out++ == 0x1fff) break;\r
+               if (time_out++ == 0x1fff) break;\r
        }\r
 \r
        btReceiveBank = bank;\r
index 59e73a478f6f37334c681068ed5b22b7bb258b9d..c42da8db90d1717c7c0188c84c29cb652c753d66 100644 (file)
@@ -41,6 +41,7 @@ void usb_disable();
 void usb_enable();\r
 bool usb_check();\r
 bool usb_poll();\r
+bool usb_poll_validate_length();\r
 uint32_t usb_read(byte_t* data, size_t len);\r
 uint32_t usb_write(const byte_t* data, const size_t len);\r
 \r
diff --git a/doc/RFID_Antenna-Basic-Form.stl b/doc/RFID_Antenna-Basic-Form.stl
new file mode 100755 (executable)
index 0000000..6679ae8
Binary files /dev/null and b/doc/RFID_Antenna-Basic-Form.stl differ
diff --git a/doc/RFID_Antenna-With-Lanyard-Hook.stl b/doc/RFID_Antenna-With-Lanyard-Hook.stl
new file mode 100755 (executable)
index 0000000..62f5397
Binary files /dev/null and b/doc/RFID_Antenna-With-Lanyard-Hook.stl differ
index 524554e9384b1db9c715a182df6bddf08431c3b2..f443e970ce02a8a792b80018dee3d87920e24302 100644 (file)
@@ -60,6 +60,8 @@ typedef struct{
 #define CMD_BUFF_CLEAR                                                    0x0105
 #define CMD_READ_MEM                                                      0x0106
 #define CMD_VERSION                                                       0x0107
+#define CMD_STATUS                                                                                                               0x0108
+#define CMD_PING                                                                                                                 0x0109
 
 // For low-frequency tags
 #define CMD_READ_TI_TYPE                                                  0x0202
@@ -95,6 +97,7 @@ typedef struct{
 #define CMD_FSK_SIM_TAG                                                   0x021E
 #define CMD_ASK_SIM_TAG                                                   0x021F
 #define CMD_PSK_SIM_TAG                                                   0x0220
+#define CMD_AWID_DEMOD_FSK                                                0x0221
 
 /* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
 
Impressum, Datenschutz