diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index ae1a22a15..0f8d61888 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1140,6 +1140,24 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { AddCrc14A(emdata, len); EmSendCmd(emdata, len + 2); p_response = NULL; + } else if ((receivedCmd[0] == MIFARE_ULC_WRITE || receivedCmd[0] == MIFARE_ULC_COMP_WRITE) && (tagType == 2 || tagType == 7)) { // Received a WRITE + // cmd + block + 4/16 bytes data + 2 bytes crc + if (len == 8 || len == 20) { + bool isCrcCorrect = CheckCrc14A(receivedCmd, len); + if (isCrcCorrect) { + int block = receivedCmd[1] + 12; // first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] + emlSetMem_xt(&receivedCmd[2], block, 1, 4); + // send ACK + EmSend4bit(CARD_ACK); + } else { + // send NACK 0x1 == crc/parity error + EmSend4bit(CARD_NACK_PA); + } + } else { + // send NACK 0x0 == invalid argument + EmSend4bit(CARD_NACK_IV); + } + p_response = NULL; } else if (receivedCmd[0] == MIFARE_ULEV1_READSIG && tagType == 7) { // Received a READ SIGNATURE -- // first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] uint16_t start = 4 * 4; diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index 747f0c529..d066cb157 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -104,6 +104,10 @@ typedef struct { # define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1) #endif +#ifndef CheckCrc14A +# define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len)) +#endif + extern void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par); extern tDemod *GetDemod(void); diff --git a/client/cliparser/argtable3.c b/client/cliparser/argtable3.c index 0750ed601..f8e4c2387 100644 --- a/client/cliparser/argtable3.c +++ b/client/cliparser/argtable3.c @@ -3263,7 +3263,6 @@ static const TRexChar *trex_matchnode(TRex *exp, TRexNode *node, const TRexChar return asd; } return NULL; - break; } case OP_EXPR: case OP_NOCAPEXPR: { diff --git a/client/cmdanalyse.c b/client/cmdanalyse.c index 1813917aa..5ca75b79f 100644 --- a/client/cmdanalyse.c +++ b/client/cmdanalyse.c @@ -615,7 +615,7 @@ int CmdAnalyseA(const char *Cmd) { } */ - return 0; +// return 0; // 14443-A uint8_t u14_c[] = {0x09, 0x78, 0x00, 0x92, 0x02, 0x54, 0x13, 0x02, 0x04, 0x2d, 0xe8 }; // atqs w crc diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 39a25019c..c25bebdd3 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -405,7 +405,7 @@ int CmdHFiClassSim(const char *Cmd) { break; size_t datalen = NUM_CSNS * 24; - void *dump = calloc(datalen, sizeof(uint8_t)); + uint8_t *dump = calloc(datalen, sizeof(uint8_t)); if (!dump) { PrintAndLogEx(WARNING, "Failed to allocate memory"); return 2; @@ -458,7 +458,7 @@ int CmdHFiClassSim(const char *Cmd) { break; size_t datalen = NUM_CSNS * 24; - void *dump = calloc(datalen, sizeof(uint8_t)); + uint8_t *dump = calloc(datalen, sizeof(uint8_t)); if (!dump) { PrintAndLogEx(WARNING, "Failed to allocate memory"); return 2; @@ -2194,7 +2194,6 @@ int CmdHFiClassLookUp(const char *Cmd) { } cmdp += 2; break; - break; case 'e': use_elite = true; cmdp++; diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index b25054b2d..dd02db95e 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1292,13 +1292,8 @@ static void printT5x7KnownBlock0(uint32_t b0) { snprintf(s + strlen(s), sizeof(s) - strlen(s), "T55x7 Raw "); break; case T55X7_EM_UNIQUE_CONFIG_BLOCK: - snprintf(s + strlen(s), sizeof(s) - strlen(s), "EM Unique "); + snprintf(s + strlen(s), sizeof(s) - strlen(s), "EM unique, Paxton "); break; - /* - case T55X7_EM_PAXTON_CONFIG_BLOCK: - snprintf(s + strlen(s), sizeof(s)-strlen(s), "EM Paxton "); - break; - */ case T55X7_FDXB_CONFIG_BLOCK: snprintf(s + strlen(s), sizeof(s) - strlen(s), "FDXB "); break; @@ -1339,10 +1334,8 @@ static void printT5x7KnownBlock0(uint32_t b0) { break; } - if (strlen(s) > 0) { - PrintAndLogEx(NORMAL, " Known T55x7 Config block found : " _YELLOW_("%s"), s); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); - } + if (strlen(s) > 0) + PrintAndLogEx(NORMAL, "\n Config block match : " _YELLOW_("%s"), s); } int CmdT55xxInfo(const char *Cmd) { @@ -1476,9 +1469,12 @@ int CmdT55xxInfo(const char *Cmd) { PrintAndLogEx(NORMAL, " Block 0 : 0x%08X", block0); else PrintAndLogEx(NORMAL, " Block 0 : 0x%08X %s", block0, sprint_bin(DemodBuffer + config.offset, 32)); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); + if (((!gotdata) && (!config.Q5)) || (gotdata && (!dataasq5))) printT5x7KnownBlock0(block0); + + PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); + return 0; } diff --git a/client/emv/crypto_polarssl.c b/client/emv/crypto_polarssl.c index e1f59ddf3..3b0a7d801 100644 --- a/client/emv/crypto_polarssl.c +++ b/client/emv/crypto_polarssl.c @@ -248,7 +248,6 @@ static size_t crypto_pk_polarssl_get_nbits(const struct crypto_pk *_cp) { struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp; return cp->ctx.len * 8; - return 0; } static unsigned char *crypto_pk_polarssl_get_parameter(const struct crypto_pk *_cp, unsigned param, size_t *plen) { @@ -270,7 +269,7 @@ static unsigned char *crypto_pk_polarssl_get_parameter(const struct crypto_pk *_ mbedtls_mpi_write_binary(&cp->ctx.E, result, *plen); break; default: - printf("Error get parameter. Param=%d", param); + printf("Error get parameter. Param = %u", param); break; } diff --git a/client/emv/emv_pki.c b/client/emv/emv_pki.c index 33d4eeb16..cb2486bb4 100644 --- a/client/emv/emv_pki.c +++ b/client/emv/emv_pki.c @@ -332,7 +332,7 @@ unsigned char *emv_pki_sdatl_fill(const struct tlvdb *db, size_t *sdatl_len) { *sdatl_len = 0; const struct tlv *sda_tl = tlvdb_get(db, 0x9f4a, NULL); - if (!sda_tl || sda_tl->len <= 0) + if (!sda_tl || sda_tl->len == 0) return NULL; for (int i = 0; i < sda_tl->len; i++) { diff --git a/client/jansson/utf.c b/client/jansson/utf.c index 003c422bd..61f0a381b 100644 --- a/client/jansson/utf.c +++ b/client/jansson/utf.c @@ -122,7 +122,7 @@ const char *utf8_iterate(const char *buffer, size_t bufsize, int32_t *codepoint) return buffer; count = utf8_check_first(buffer[0]); - if (count <= 0) + if (count == 0) return NULL; if (count == 1) diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 9c99f95a3..905fdcc82 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -960,7 +960,6 @@ int detect_classic_nackbug(bool verbose) { int gc = getchar(); (void)gc; return -1; - break; } if (WaitForResponseTimeout(CMD_ACK, &resp, 500)) { diff --git a/client/mifare/ndef.c b/client/mifare/ndef.c index b888d8269..da03ecc8f 100644 --- a/client/mifare/ndef.c +++ b/client/mifare/ndef.c @@ -344,7 +344,6 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { case 0xfe: { PrintAndLogEx(INFO, "-- NDEF Terminator. Done."); return 0; - break; } default: { PrintAndLogEx(ERR, "unknown tag 0x%02x", ndef[indx]); diff --git a/client/scripts/test_t55x7.lua b/client/scripts/test_t55x7.lua new file mode 100644 index 000000000..3b7ea2e02 --- /dev/null +++ b/client/scripts/test_t55x7.lua @@ -0,0 +1,200 @@ +local cmds = require('commands') +local getopt = require('getopt') +local bin = require('bin') +local utils = require('utils') + +local format=string.format +local floor=math.floor + +copyright = '' +author = "Iceman" +version = '' +desc =[[ +This script will program a T55x7 TAG with a configuration and four blocks of data. +It will then try to detect and read back those block data and compare if read data matches the expected data. + + +lf t55xx wipe +lf t55xx detect +lf t55xx write b 1 d 00000000 +lf t55xx write b 2 d ffffffff +lf t55xx write b 3 d 80000000 +lf t55xx write b 4 d 00000001 + +Loop: + +try write different configuration blocks, and read block1-4 and comparing the read values with the values used to write. + +testsuit for T55XX commands demodulation + +]] +example = [[ + 1. script run test_t55x7 +]] +usage = [[ + +script run test_t55x7 + +Arguments: + -h this help +]] + +local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds +local DEBUG = true -- the debug flag + +local data_blocks_cmds = { + [1] = '00000000', + [2] = 'ffffffff', + [3] = '80000000', + [4] = '00000001', +} + +--- +-- A debug printout-function +local function dbg(args) + if not DEBUG then + return + end + + if type(args) == "table" then + local i = 1 + while args[i] do + dbg(args[i]) + i = i+1 + end + else + print("###", args) + end +end +--- +-- This is only meant to be used when errors occur +local function oops(err) + print("ERROR: ",err) +end +--- +-- Usage help +local function help() + print(copyright) + print(author) + print(version) + print(desc) + print("Example usage") + print(example) +end +--- +-- Exit message +local function exitMsg(msg) + print( string.rep('--',20) ) + print( string.rep('--',20) ) + print(msg) + print() +end + +local function WipeCard() + + local wipe_cmds = { + [1] = 'lf t55xx wipe', + [2] = 'lf t55xx detect', + } + for _ = 1, #wipe_cmds do + local c = wipe_cmds[_] + dbg(c); core.console(c) + end + + local wipe_data_cmd = "lf t55xx write b %s d %s" + for _ = 1, #data_blocks_cmds do + local val = data_blocks_cmds[_] + local c = string.format(wipe_data_cmd, _, val); + core.console(c) + end +end +--- +-- lf t55xx read +local function CheckReadBlock(block) + local data, msg + -- blockno, page1, override, pwd + data, msg = core.t55xx_readblock(block, "0", "0", "") + if not data then + return "" + end + return ('%08X'):format(data) +end + +local function test() + + -- PSK1 Modulations to test. (2blocks) + local process_block0_cmds = { + [1] = '00001040', + [2] = '00041040', + [3] = '00081040', + [4] = '000c1040', + [5] = '00101040', + [6] = '00141040', + [7] = '00181040', + [8] = '001c1040', + } + + local y + local block = "00" + + for _ = 1, #process_block0_cmds do + + local p_config_cmd = process_block0_cmds[_] + core.clearCommandBuffer() + + -- Write Config block + dbg(('lf t55xx write b 0 d %s'):format(p_config_cmd)) + local config = tonumber(p_config_cmd, 16) + local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK,arg1 = config, arg2 = block, arg3 = '00', data = '00'} + local err = core.SendCommand(writecmd:getBytes()) + if err then return oops(err) end + local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT) + + -- Detect + local res, msg = core.t55xx_detect() + if not res then + print("can't detect modulation, skip to next config") + else + -- Loop block1-2 + for _ = 1, #data_blocks_cmds do + local val = data_blocks_cmds[_] + local blockdata, msg = CheckReadBlock(_) + if blockdata ~= val then + print( ('Test %s == %s Failed'):format(val, blockdata)) + core.console( format('rem -- block %d value %s failed', _, val)) + else + print( ('Test %s == %s OK'):format(val, blockdata)) + end + end + end + end +end + +local function main(args) + + print( string.rep('--',20) ) + print( string.rep('--',20) ) + + -- Arguments for the script + for o, arg in getopt.getopt(args, 'h') do + if o == "h" then return help() end + end + + core.clearCommandBuffer() + + print('Starting test, wiping card') + WipeCard() + print('Detecting card') + local res, msg = core.t55xx_detect() + if res then + print('Starting test') + test() + else + print("can't detect modulation. Test failed. Ending.") + end + +-- test() + exitMsg('Tests finished') + +end +main(args) diff --git a/client/tinycbor/cborinternal_p.h b/client/tinycbor/cborinternal_p.h index 8609ce2ad..65c42cdf4 100644 --- a/client/tinycbor/cborinternal_p.h +++ b/client/tinycbor/cborinternal_p.h @@ -87,7 +87,7 @@ static inline double decode_half(unsigned short half) { if (exp == 0) val = ldexp(mant, -24); else if (exp != 31) val = ldexp(mant + 1024, exp - 25); else val = mant == 0 ? INFINITY : NAN; - return half & 0x8000 ? -val : val; + return (half & 0x8000) ? -val : val; } # endif #endif /* CBOR_NO_HALF_FLOAT_TYPE */ diff --git a/client/tinycbor/cbortojson.c b/client/tinycbor/cbortojson.c index 533e6a721..3ea90cee8 100644 --- a/client/tinycbor/cbortojson.c +++ b/client/tinycbor/cbortojson.c @@ -284,8 +284,7 @@ static CborError add_value_metadata(FILE *out, CborType type, const ConversionSt type = flags & FinalTypeMask; flags &= ~(FinalTypeMask | TypeWasTagged); - if (fprintf(out, "\"tag\":\"%" PRIu64 "\"%s", status->lastTag, - flags & ~TypeWasTagged ? "," : "") < 0) + if (fprintf(out, "\"tag\":\"%" PRIu64 "\"%s", status->lastTag, (flags & ~TypeWasTagged) ? "," : "") < 0) return CborErrorIO; } @@ -300,11 +299,10 @@ static CborError add_value_metadata(FILE *out, CborType type, const ConversionSt if (fprintf(out, ",\"v\":\"nan\"") < 0) return CborErrorIO; if (flags & NumberWasInfinite) - if (fprintf(out, ",\"v\":\"%sinf\"", flags & NumberWasNegative ? "-" : "") < 0) + if (fprintf(out, ",\"v\":\"%sinf\"", (flags & NumberWasNegative) ? "-" : "") < 0) return CborErrorIO; if (flags & NumberPrecisionWasLost) - if (fprintf(out, ",\"v\":\"%c%" PRIx64 "\"", flags & NumberWasNegative ? '-' : '+', - status->originalNumber) < 0) + if (fprintf(out, ",\"v\":\"%c%" PRIx64 "\"", (flags & NumberWasNegative) ? '-' : '+', status->originalNumber) < 0) return CborErrorIO; if (type == CborSimpleType) if (fprintf(out, ",\"v\":%d", (int)status->originalNumber) < 0) diff --git a/common/lfdemod.c b/common/lfdemod.c index 0d33091a6..cfac0a0b5 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -1614,25 +1614,19 @@ int askdemod(uint8_t *bits, size_t *size, int *clk, int *invert, int maxErr, uin // by marshmellow - demodulate NRZ wave - requires a read with strong signal // peaks invert bit (high=1 low=0) each clock cycle = 1 bit determined by last peak int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int *startIdx) { - if (signalprop.isnoise) return -1; + if (signalprop.isnoise) { + if (g_debugMode == 2) prnt("DEBUG nrzRawDemod: just noise detected - quitting"); + return -1; + } + size_t clkStartIdx = 0; *clk = DetectNRZClock(dest, *size, *clk, &clkStartIdx); if (*clk == 0) return -2; - size_t i, gLen = 4096; - if (gLen > *size) - gLen = *size - 20; - - - // just noise - no super good detection. good enough - if (signalprop.isnoise) { - if (g_debugMode == 2) prnt("DEBUG nrzRawDemod: just noise detected - quitting"); - return -3; - } - + size_t i; int high, low; - //getHiLo(dest, gLen, &high, &low, 75, 75); + getHiLo(&high, &low, 75, 75); getHiLo(&high, &low, 75, 75); @@ -1675,7 +1669,7 @@ size_t fsk_wave_demod(uint8_t *dest, size_t size, uint8_t fchigh, uint8_t fclow, size_t LastSample = 0; size_t currSample = 0; size_t last_transition = 0; - size_t idx = 1; + size_t idx; size_t numBits = 0; //find start of modulating data in trace @@ -1915,7 +1909,14 @@ int pskRawDemod_ext(uint8_t *dest, size_t *size, int *clock, int *invert, int *s waveLenCnt = waveEnd - waveStart; if (waveLenCnt > fc) { //this wave is a phase shift - //prnt("DEBUG: phase shift at: %d, len: %d, nextClk: %d, i: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+*clock-tol,i+1,fc); + /* + prnt("DEBUG: phase shift at: %d, len: %d, nextClk: %d, i: %d, fc: %d" + , waveStart + , waveLenCnt + , lastClkBit + *clock - tol + , i + 1 + , fc); + */ if (i + 1 >= lastClkBit + *clock - tol) { //should be a clock bit curPhase ^= 1; dest[numBits++] = curPhase; diff --git a/common/protocols.h b/common/protocols.h index 9fc168d46..f85ebb49b 100644 --- a/common/protocols.h +++ b/common/protocols.h @@ -167,7 +167,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define MIFARE_EV1_SETMODE 0x43 #define MIFARE_ULC_WRITE 0xA2 -//#define MIFARE_ULC__COMP_WRITE 0xA0 +#define MIFARE_ULC_COMP_WRITE 0xA0 #define MIFARE_ULC_AUTH_1 0x1A #define MIFARE_ULC_AUTH_2 0xAF