From 05ddb52c43f932db852e18fe6836bee71e91f74e Mon Sep 17 00:00:00 2001 From: pwpiwi Date: Wed, 18 Mar 2015 17:12:09 +0100 Subject: [PATCH] fix: introduced a stupid error when refactoring the start bit detector in MillerDecoding() chg: use -O2 instead of -Os when compiling ARM sources chg: don't clear the Miller decoders input buffer on reset chg: be more specific for the Miller decoders start bit pattern add: new option c in hf list: mark CRC bytes (default is off) --- armsrc/Makefile | 2 +- armsrc/iso14443a.c | 49 ++++++++++++++++------------ client/Makefile | 71 +++++++++++++++++++++-------------------- client/cmdhf.c | 72 +++++++++++++++++++++++++----------------- client/cmdhftopaz.c | 71 +++++++++++++++++++++++++++++++++++++++++ client/cmdhftopaz.h | 16 ++++++++++ common/Makefile.common | 2 +- 7 files changed, 197 insertions(+), 86 deletions(-) create mode 100644 client/cmdhftopaz.c create mode 100644 client/cmdhftopaz.h diff --git a/armsrc/Makefile b/armsrc/Makefile index 75ccdece..03541d61 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -10,7 +10,7 @@ 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 -fno-strict-aliasing +APP_CFLAGS = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG -DWITH_CRC -DON_DEVICE -fno-strict-aliasing -O2 #-DWITH_LCD #SRC_LCD = fonts.c LCD.c diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 06a134f6..0bd681d9 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -232,13 +232,19 @@ void AppendCrc14443a(uint8_t* data, int len) static tUart Uart; // Lookup-Table to decide if 4 raw bits are a modulation. -// We accept two or three consecutive "0" in any position with the rest "1" +// We accept the following: +// 0001 - a 3 tick wide pause +// 0011 - a 2 tick wide pause, or a three tick wide pause shifted left +// 0111 - a 2 tick wide pause shifted left +// 1001 - a 2 tick wide pause shifted right const bool Mod_Miller_LUT[] = { - TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, - TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE +// TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, +// TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE + FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, + FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }; -#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x00F0) >> 4]) -#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x000F)]) +#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4]) +#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)]) void UartReset() { @@ -248,7 +254,6 @@ void UartReset() Uart.parityLen = 0; // number of decoded parity bytes Uart.shiftReg = 0; // shiftreg to hold decoded data bits Uart.parityBits = 0; // holds 8 parity bits - Uart.fourBits = 0x00000000; // buffer for 4 Bits Uart.startTime = 0; Uart.endTime = 0; } @@ -257,6 +262,7 @@ void UartInit(uint8_t *data, uint8_t *parity) { Uart.output = data; Uart.parity = parity; + Uart.fourBits = 0x00000000; // clear the buffer for 4 Bits UartReset(); } @@ -269,18 +275,21 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) if (Uart.state == STATE_UNSYNCD) { // not yet synced Uart.syncBit = 9999; // not set - // we look for a ...xxxx1111111100x11111xxxxxx pattern - // (unmodulated, followed by the start bit = 8 '1's followed by 2 '0's, eventually followed by another '0', followed by 5 '1's) -#define ISO14443A_STARTBIT_MASK 0x007FEF80 // mask is 00000000 01111111 11101111 10000000 -#define ISO14443A_STARTBIT_PATTERN 0x007F8F80 // pattern is 00000000 01111111 10001111 10000000 - if ((Uart.fourBits & ISO14443A_STARTBIT_MASK) >> 0 == ISO14443A_STARTBIT_PATTERN >> 0) Uart.syncBit = 7; - else if ((Uart.fourBits & ISO14443A_STARTBIT_MASK) >> 1 == ISO14443A_STARTBIT_PATTERN >> 1) Uart.syncBit = 6; - else if ((Uart.fourBits & ISO14443A_STARTBIT_MASK) >> 2 == ISO14443A_STARTBIT_PATTERN >> 2) Uart.syncBit = 5; - else if ((Uart.fourBits & ISO14443A_STARTBIT_MASK) >> 3 == ISO14443A_STARTBIT_PATTERN >> 3) Uart.syncBit = 4; - else if ((Uart.fourBits & ISO14443A_STARTBIT_MASK) >> 4 == ISO14443A_STARTBIT_PATTERN >> 4) Uart.syncBit = 3; - else if ((Uart.fourBits & ISO14443A_STARTBIT_MASK) >> 5 == ISO14443A_STARTBIT_PATTERN >> 5) Uart.syncBit = 2; - else if ((Uart.fourBits & ISO14443A_STARTBIT_MASK) >> 6 == ISO14443A_STARTBIT_PATTERN >> 6) Uart.syncBit = 1; - else if ((Uart.fourBits & ISO14443A_STARTBIT_MASK) >> 7 == ISO14443A_STARTBIT_PATTERN >> 7) Uart.syncBit = 0; + // The start bit is one ore more Sequence Y followed by a Sequence Z (... 11111111 00x11111). We need to distinguish from + // Sequence X followed by Sequence Y followed by Sequence Z (111100x1 11111111 00x11111) + // we therefore look for a ...xx11111111111100x11111xxxxxx... pattern + // (12 '1's followed by 2 '0's, eventually followed by another '0', followed by 5 '1's) +#define ISO14443A_STARTBIT_MASK 0x07FFEF80 // mask is 00000111 11111111 11101111 10000000 +#define ISO14443A_STARTBIT_PATTERN 0x07FF8F80 // pattern is 00000111 11111111 10001111 10000000 + if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 0)) == ISO14443A_STARTBIT_PATTERN >> 0) Uart.syncBit = 7; + else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 1)) == ISO14443A_STARTBIT_PATTERN >> 1) Uart.syncBit = 6; + else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 2)) == ISO14443A_STARTBIT_PATTERN >> 2) Uart.syncBit = 5; + else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 3)) == ISO14443A_STARTBIT_PATTERN >> 3) Uart.syncBit = 4; + else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 4)) == ISO14443A_STARTBIT_PATTERN >> 4) Uart.syncBit = 3; + else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 5)) == ISO14443A_STARTBIT_PATTERN >> 5) Uart.syncBit = 2; + else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 6)) == ISO14443A_STARTBIT_PATTERN >> 6) Uart.syncBit = 1; + else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 7)) == ISO14443A_STARTBIT_PATTERN >> 7) Uart.syncBit = 0; + if (Uart.syncBit != 9999) { // found a sync bit Uart.startTime = non_real_time?non_real_time:(GetCountSspClk() & 0xfffffff8); Uart.startTime -= Uart.syncBit; @@ -646,7 +655,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { TRUE)) break; } /* And ready to receive another command. */ - UartReset(); + UartInit(receivedCmd, receivedCmdPar); /* And also reset the demod code, which might have been */ /* false-triggered by the commands from the reader. */ DemodReset(); @@ -2798,7 +2807,7 @@ void RAMFUNC SniffMifare(uint8_t param) { if (MfSniffLogic(receivedCmd, Uart.len, Uart.parity, Uart.bitCount, TRUE)) break; /* And ready to receive another command. */ - UartReset(); + UartInit(receivedCmd, receivedCmdPar); /* And also reset the demod code */ DemodReset(); diff --git a/client/Makefile b/client/Makefile index 6ec34469..2e1c2092 100644 --- a/client/Makefile +++ b/client/Makefile @@ -65,41 +65,42 @@ CMDSRCS = nonce2key/crapto1.c\ loclass/ikeys.c \ loclass/elite_crack.c\ loclass/fileutils.c\ - mifarehost.c\ - crc16.c \ - iso14443crc.c \ - iso15693tools.c \ - data.c \ - graph.c \ - ui.c \ - cmddata.c \ - lfdemod.c \ - cmdhf.c \ - cmdhf14a.c \ - cmdhf14b.c \ - cmdhf15.c \ - cmdhfepa.c \ - cmdhflegic.c \ - cmdhficlass.c \ - cmdhfmf.c \ - cmdhfmfu.c \ - cmdhw.c \ - cmdlf.c \ - cmdlfio.c \ - cmdlfhid.c \ - cmdlfem4x.c \ - cmdlfhitag.c \ - cmdlfti.c \ - cmdparser.c \ - cmdmain.c \ - cmdlft55xx.c \ - cmdlfpcf7931.c\ - pm3_binlib.c\ - scripting.c\ - cmdscript.c\ - pm3_bitlib.c\ - aes.c\ - protocols.c\ + mifarehost.c\ + crc16.c \ + iso14443crc.c \ + iso15693tools.c \ + data.c \ + graph.c \ + ui.c \ + cmddata.c \ + lfdemod.c \ + cmdhf.c \ + cmdhf14a.c \ + cmdhf14b.c \ + cmdhf15.c \ + cmdhfepa.c \ + cmdhflegic.c \ + cmdhficlass.c \ + cmdhfmf.c \ + cmdhfmfu.c \ + cmdhftopaz.c \ + cmdhw.c \ + cmdlf.c \ + cmdlfio.c \ + cmdlfhid.c \ + cmdlfem4x.c \ + cmdlfhitag.c \ + cmdlfti.c \ + cmdparser.c \ + cmdmain.c \ + cmdlft55xx.c \ + cmdlfpcf7931.c\ + pm3_binlib.c\ + scripting.c\ + cmdscript.c\ + pm3_bitlib.c\ + aes.c\ + protocols.c\ COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o) diff --git a/client/cmdhf.c b/client/cmdhf.c index 960dcf7f..0d678ab6 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -23,6 +23,7 @@ #include "cmdhficlass.h" #include "cmdhfmf.h" #include "cmdhfmfu.h" +#include "cmdhftopaz.h" #include "protocols.h" static int CmdHelp(const char *Cmd); @@ -354,7 +355,7 @@ bool merge_topaz_reader_frames(uint32_t timestamp, uint32_t *duration, uint16_t } -uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles) +uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles, bool markCRCBytes) { bool isResponse; uint16_t data_len, parity_len; @@ -441,13 +442,17 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui } } - if(crcStatus == 0 || crcStatus == 1) - {//CRC-command - char *pos1 = line[(data_len-2)/16]+(((data_len-2) % 16) * 4); - (*pos1) = '['; - char *pos2 = line[(data_len)/16]+(((data_len) % 16) * 4); - sprintf(pos2, "%c", ']'); + + if (markCRCBytes) { + if(crcStatus == 0 || crcStatus == 1) + {//CRC-command + char *pos1 = line[(data_len-2)/16]+(((data_len-2) % 16) * 4); + (*pos1) = '['; + char *pos2 = line[(data_len)/16]+(((data_len) % 16) * 4); + sprintf(pos2, "%c", ']'); + } } + if(data_len == 0) { if(data_len == 0){ @@ -507,22 +512,26 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui int CmdHFList(const char *Cmd) { bool showWaitCycles = false; + bool markCRCBytes = false; char type[40] = {0}; int tlen = param_getstr(Cmd,0,type); - char param = param_getchar(Cmd, 1); + char param1 = param_getchar(Cmd, 1); + char param2 = param_getchar(Cmd, 2); bool errors = false; uint8_t protocol = 0; //Validate params - if(tlen == 0) - { + + if(tlen == 0) { errors = true; } - if(param == 'h' || (param !=0 && param != 'f')) - { + + if(param1 == 'h' + || (param1 != 0 && param1 != 'f' && param1 != 'c') + || (param2 != 0 && param2 != 'f' && param2 != 'c')) { errors = true; } - if(!errors) - { + + if(!errors) { if(strcmp(type, "iclass") == 0) { protocol = ICLASS; } else if(strcmp(type, "14a") == 0) { @@ -540,8 +549,9 @@ int CmdHFList(const char *Cmd) if (errors) { PrintAndLog("List protocol data in trace buffer."); - PrintAndLog("Usage: hf list [f]"); + PrintAndLog("Usage: hf list [f][c]"); PrintAndLog(" f - show frame delay times as well"); + PrintAndLog(" c - mark CRC bytes"); PrintAndLog("Supported values:"); PrintAndLog(" raw - just show raw data without annotations"); PrintAndLog(" 14a - interpret data as iso14443a communications"); @@ -555,10 +565,13 @@ int CmdHFList(const char *Cmd) } - if (param == 'f') { + if (param1 == 'f' || param2 == 'f') { showWaitCycles = true; } + if (param1 == 'c' || param2 == 'c') { + markCRCBytes = true; + } uint8_t *trace; uint16_t tracepos = 0; @@ -592,7 +605,7 @@ int CmdHFList(const char *Cmd) while(tracepos < traceLen) { - tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles); + tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles, markCRCBytes); } free(trace); @@ -602,18 +615,19 @@ int CmdHFList(const char *Cmd) static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, - {"14a", CmdHF14A, 1, "{ ISO14443A RFIDs... }"}, - {"14b", CmdHF14B, 1, "{ ISO14443B RFIDs... }"}, - {"15", CmdHF15, 1, "{ ISO15693 RFIDs... }"}, - {"epa", CmdHFEPA, 1, "{ German Identification Card... }"}, - {"legic", CmdHFLegic, 0, "{ LEGIC RFIDs... }"}, - {"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"}, - {"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"}, - {"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"}, - {"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"}, - {"list", CmdHFList, 1, "List protocol data in trace buffer"}, - {NULL, NULL, 0, NULL} + {"help", CmdHelp, 1, "This help"}, + {"14a", CmdHF14A, 1, "{ ISO14443A RFIDs... }"}, + {"14b", CmdHF14B, 1, "{ ISO14443B RFIDs... }"}, + {"15", CmdHF15, 1, "{ ISO15693 RFIDs... }"}, + {"epa", CmdHFEPA, 1, "{ German Identification Card... }"}, + {"legic", CmdHFLegic, 0, "{ LEGIC RFIDs... }"}, + {"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"}, + {"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"}, + {"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"}, + {"topaz", CmdHFTopaz, 1, "{ TOPAZ (NFC Type 1) RFIDs... }"}, + {"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"}, + {"list", CmdHFList, 1, "List protocol data in trace buffer"}, + {NULL, NULL, 0, NULL} }; int CmdHF(const char *Cmd) diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c new file mode 100644 index 00000000..d747ed05 --- /dev/null +++ b/client/cmdhftopaz.c @@ -0,0 +1,71 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2015 Piwi +// +// 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. +//----------------------------------------------------------------------------- +// High frequency Topaz (NFC Type 1) commands +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include "cmdmain.h" +#include "cmdparser.h" +#include "cmdhftopaz.h" +#include "cmdhf14a.h" +#include "ui.h" + +int CmdHFTopazReader(const char *Cmd) +{ + PrintAndLog("not yet implemented"); + return 0; +} + + +int CmdHFTopazSim(const char *Cmd) +{ + PrintAndLog("not yet implemented"); + return 0; +} + + +int CmdHFTopazCmdRaw(const char *Cmd) +{ + PrintAndLog("not yet implemented"); + return 0; +} + + +static int CmdHelp(const char *Cmd); + + +static command_t CommandTable[] = +{ + {"help", CmdHelp, 1, "This help"}, + {"reader", CmdHFTopazReader, 0, "Act like a Topaz reader"}, + {"sim", CmdHFTopazSim, 0, " -- Simulate Topaz tag"}, + {"snoop", CmdHF14ASnoop, 0, "Eavesdrop a Topaz reader-tag communication"}, + {"raw", CmdHFTopazCmdRaw, 0, "Send raw hex data to tag"}, + {NULL, NULL, 0, NULL} +}; + + +int CmdHFTopaz(const char *Cmd) { + // flush + WaitForResponseTimeout(CMD_ACK,NULL,100); + + // parse + CmdsParse(CommandTable, Cmd); + return 0; +} + +static int CmdHelp(const char *Cmd) +{ + CmdsHelp(CommandTable); + return 0; +} + + diff --git a/client/cmdhftopaz.h b/client/cmdhftopaz.h new file mode 100644 index 00000000..8d5428dd --- /dev/null +++ b/client/cmdhftopaz.h @@ -0,0 +1,16 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2015 Piwi +// +// 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. +//----------------------------------------------------------------------------- +// High frequency Topaz (NFC Type 1) commands +//----------------------------------------------------------------------------- + +#ifndef CMDHFTOPAZ_H__ +#define CMDHFTOPAZ_H__ + +int CmdHFTopaz(const char *Cmd); + +#endif diff --git a/common/Makefile.common b/common/Makefile.common index 2b2bb2fb..7e264d28 100644 --- a/common/Makefile.common +++ b/common/Makefile.common @@ -66,7 +66,7 @@ VPATH = . ../common/ ../fpga/ INCLUDES = ../include/proxmark3.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/usb_cmd.h $(APP_INCLUDES) -CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -std=c99 $(APP_CFLAGS) -Os +CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -std=c99 -Os $(APP_CFLAGS) LDFLAGS = -nostartfiles -nodefaultlibs -Wl,-gc-sections -n LIBS = -lgcc -- 2.39.2