From f80cd7e687a37231ca47d3d7ca75a3df46f5bfaf Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 3 Jan 2017 19:33:21 +0100 Subject: [PATCH 01/16] syntax suger, some tabs fixed --- client/cmdhficlass.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 1caeebb8..ab527cc6 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -1669,7 +1669,7 @@ int CmdHFiClassManageKeys(const char *Cmd) { } static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, + {"help", CmdHelp, 1, "This help"}, {"calcnewkey", CmdHFiClassCalcNewKey, 1, "[options..] Calc Diversified keys (blocks 3 & 4) to write new keys"}, {"clone", CmdHFiClassCloneTag, 0, "[options..] Authenticate and Clone from iClass bin file"}, {"decrypt", CmdHFiClassDecrypt, 1, "[f ] Decrypt tagdump" }, @@ -1680,7 +1680,7 @@ static command_t CommandTable[] = { {"loclass", CmdHFiClass_loclass, 1, "[options..] Use loclass to perform bruteforce of reader attack dump"}, {"managekeys", CmdHFiClassManageKeys, 1, "[options..] Manage the keys to use with iClass"}, {"readblk", CmdHFiClass_ReadBlock, 0, "[options..] Authenticate and Read iClass block"}, - {"reader",CmdHFiClassReader, 0, "Read an iClass tag"}, + {"reader", CmdHFiClassReader, 0, "Read an iClass tag"}, {"readtagfile", CmdHFiClassReadTagFile, 1, "[options..] Display Content from tagfile"}, {"replay", CmdHFiClassReader_Replay, 0, " Read an iClass tag via Reply Attack"}, {"sim", CmdHFiClassSim, 0, "[options..] Simulate iClass tag"}, -- 2.39.5 From c48211f7ed175c91d92044e7e08b921e06f8ff3f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 5 Jan 2017 01:51:47 +0100 Subject: [PATCH 02/16] ADD: 'lf animal' commands. CLONE/SIM/READ/DEMOD of FXD-B animal tags. Still some work left. --- client/Makefile | 1 + client/cmddata.c | 33 +++-- client/cmdlf.c | 1 + client/cmdlf.h | 2 +- client/cmdlffdx.c | 352 ++++++++++++++++++++++++++++++++++++++++++++++ client/cmdlffdx.h | 38 +++++ 6 files changed, 409 insertions(+), 18 deletions(-) create mode 100644 client/cmdlffdx.c create mode 100644 client/cmdlffdx.h diff --git a/client/Makefile b/client/Makefile index dc1ce801..db33d77a 100644 --- a/client/Makefile +++ b/client/Makefile @@ -142,6 +142,7 @@ CMDSRCS = mifarehost.c \ cmdlfjablotron.c \ cmdlfvisa2000.c \ cmdlfnoralsy.c \ + cmdlffdx.c \ pm3_binlib.c \ scripting.c \ cmdscript.c \ diff --git a/client/cmddata.c b/client/cmddata.c index 12ac7bf9..97d840c5 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -253,19 +253,17 @@ void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx) if ( size >= MAX_DEMOD_BUF_LEN) size = MAX_DEMOD_BUF_LEN; - - size_t i = 0; - for (; i < size; i++){ + + for (size_t i = 0; i < size; i++) DemodBuffer[i]=buff[startIdx++]; - } + DemodBufferLen = size; } -int CmdSetDebugMode(const char *Cmd) -{ - int demod=0; +int CmdSetDebugMode(const char *Cmd) { + int demod = 0; sscanf(Cmd, "%i", &demod); - g_debugMode=(uint8_t)demod; + g_debugMode = (uint8_t)demod; return 1; } @@ -1691,12 +1689,7 @@ int CmdFDXBdemodBI(const char *Cmd){ if (g_debugMode) PrintAndLog("DEBUG: Error - FDXB error removeParity:: %d", size); return 0; } - if (g_debugMode) { - char *bin = sprint_bin_break(BitStream,size,16); - PrintAndLog("DEBUG BinStream:\n%s",bin); - } PrintAndLog("\nFDX-B / ISO 11784/5 Animal Tag ID Found:"); - if (g_debugMode) PrintAndLog("Start marker %d; Size %d", preambleIndex, size); //got a good demod uint64_t NationalCode = ((uint64_t)(bytebits_to_byteLSBF(BitStream+32,6)) << 32) | bytebits_to_byteLSBF(BitStream,32); @@ -1717,11 +1710,17 @@ int CmdFDXBdemodBI(const char *Cmd){ PrintAndLog("Animal ID: %04u-%012llu", countryCode, NationalCode); PrintAndLog("National Code: %012llu", NationalCode); PrintAndLog("CountryCode: %04u", countryCode); - PrintAndLog("Extended Data: %s", dataBlockBit ? "True" : "False"); - PrintAndLog("reserved Code: %u", reservedCode); - PrintAndLog("Animal Tag: %s", animalBit ? "True" : "False"); + + PrintAndLog("Reserved/RFU: %u", reservedCode); + PrintAndLog("Animal Tag: %s", animalBit ? "True" : "False"); + PrintAndLog("Has extended data: %s [0x%X]", dataBlockBit ? "True" : "False", extended); PrintAndLog("CRC: 0x%04X - [%04X] - %s", crc16, calcCrc, (calcCrc == crc16) ? "Passed" : "Failed"); - PrintAndLog("Extended: 0x%X\n", extended); + + if (g_debugMode) { + PrintAndLog("Start marker %d; Size %d", preambleIndex, size); + char *bin = sprint_bin_break(BitStream,size,16); + PrintAndLog("DEBUG BinStream:\n%s",bin); + } return 1; } diff --git a/client/cmdlf.c b/client/cmdlf.c index 6ed53477..967dc4af 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -1181,6 +1181,7 @@ int CmdLFfind(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, + {"animal", CmdLFFdx, 1, "{ Animal RFIDs... }"}, {"awid", CmdLFAWID, 1, "{ AWID RFIDs... }"}, {"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"}, {"guard", CmdLFGuard, 1, "{ Guardall RFIDs... }"}, diff --git a/client/cmdlf.h b/client/cmdlf.h index 3bd63e07..8415616e 100644 --- a/client/cmdlf.h +++ b/client/cmdlf.h @@ -40,7 +40,7 @@ #include "cmdlfjablotron.h" // for JABLOTRON menu #include "cmdlfvisa2000.h" // for VISA2000 menu #include "cmdlfnoralsy.h" // for NORALSY meny - +#include "cmdlffdx.h" // for FDX-B meny int CmdLF(const char *Cmd); int CmdLFCommandRead(const char *Cmd); diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c new file mode 100644 index 00000000..58c2cb7c --- /dev/null +++ b/client/cmdlffdx.c @@ -0,0 +1,352 @@ +//----------------------------------------------------------------------------- +// +// 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 Presco tag commands +//----------------------------------------------------------------------------- + +#include "cmdlffdx.h" + +/* + FDX-B ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits) + 8 databits + 1 parity (1) + CIITT 16 checksum + NATIONAL CODE, ICAR database + COUNTRY CODE (ISO3166) or http://cms.abvma.ca/uploads/ManufacturersISOsandCountryCodes.pdf + FLAG (animal/non-animal) + + 38 IDbits + 10 country code + 1 extra app bit + 14 reserved bits + 1 animal bit + 16 ccitt CRC chksum over 64bit ID CODE. + 24 appli bits. + + sample: 985121004515220 [ 37FF65B88EF94 ] +*/ + +static int CmdHelp(const char *Cmd); + +int usage_lf_fdx_clone(void){ + PrintAndLog("clone a FDX-B Animal tag to a T55x7 tag."); + PrintAndLog("Usage: lf fdx clone [h] "); + PrintAndLog("Options:"); + PrintAndLog(" h : This help"); + PrintAndLog(" : Country id"); + PrintAndLog(" : Animal id"); + // has extended data? + //reserved/rfu + //is animal tag + // extended data + PrintAndLog(" : specify write to Q5 (t5555 instead of t55x7)"); + PrintAndLog(""); + PrintAndLog("Sample: lf fdx clone 999 112233"); + return 0; +} + +int usage_lf_fdx_sim(void) { + PrintAndLog("Enables simulation of FDX-B Animal tag"); + PrintAndLog("Simulation runs until the button is pressed or another USB command is issued."); + PrintAndLog(""); + PrintAndLog("Usage: lf fdx sim [h] "); + PrintAndLog("Options:"); + PrintAndLog(" h : This help"); + PrintAndLog(" : Country id"); + PrintAndLog(" : Animal id"); + PrintAndLog(""); + PrintAndLog("Sample: lf fdx sim 999 112233"); + return 0; +} +// clearing the topbit needed for the preambl detection. +static void verify_values(uint32_t countryid, uint64_t animalid){ + if ((animalid & 0x3FFFFFFFFF) != animalid) { + animalid &= 0x3FFFFFFFFF; + PrintAndLog("Animal ID Truncated to 38bits: %"PRIx64, animalid); + } + if ( (countryid & 0x3ff) != countryid ) { + countryid &= 0x3ff; + PrintAndLog("Country ID Truncated to 10bits: %03d", countryid); + } +} + +static uint16_t getFDXchksum (uint64_t raw){ + uint8_t arr[8]; + num_to_bytes(raw, 64, arr); + return crc16_ccitt_kermit(arr, 8); +} + +int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits) { + + uint64_t raw = 0; + uint8_t data[117] = {0}; + + raw |= isanimal; + raw |= (0x000 & 0x3ff) << 1; + raw |= isextended << 14; + raw |= (country & 0x3ff) << 15; + raw |= (national_id & 0x3FFFFFFFFF) << 25; + + uint16_t crc = getFDXchksum(raw); + + // add raw to bitarray + num_to_bytebits(raw, 64, data); + + // add crc to bitarray + num_to_bytebits(crc, 16, data+64); + + // add extended data to bitarray + num_to_bytebits(extended, 24, data+64+16); + + //reverse array + printf("ICE:\n %s\n", sprint_bin(data, 104) ); + for (uint8_t i = 0; i <104/2; ++i) { + uint8_t tmp = data[i]; + data[i] = data[104-i]; + data[104-i] = tmp; + } + printf("ICE:\n %s\n", sprint_bin(data, 104) ); + + // add parity always EVEN (2), every 8bits + // into output array + uint8_t bitlen = addParity(data, bits+11, 104, 9, 2); + if (bitlen != 117 ) + printf("ICE ERROR PARITY BITLEN 119 != %d\n", bitlen); + + // add preamble ten 0x00 and one 0x01 + memset(bits, 0x00, 10); + bits[10] = 1; + printf("%s\n", sprint_bin_break(bits, 128, 32) ); + /* + // 128bits + // every 9th bit is 0x01, but we can just fill the rest with 0x01 and overwrite + memset(bits, 0x01, 128); + + // add preamble ten 0x00 and one 0x01 + memset(bits, 0x00, 10); + + // add reserved + num_to_bytebitsLSBF(0x00, 7, bits + 66); + num_to_bytebitsLSBF(0x00 >> 7, 7, bits + 74); + + // add animal flag - OK + bits[65] = isanimal; + + // add extended flag - OK + bits[81] = isextended; + + // add national code 40bits - OK + num_to_bytebitsLSBF(national_id >> 0, 8, bits+11); + num_to_bytebitsLSBF(national_id >> 8, 8, bits+20); + num_to_bytebitsLSBF(national_id >> 16, 8, bits+29); + num_to_bytebitsLSBF(national_id >> 24, 8, bits+38); + num_to_bytebitsLSBF(national_id >> 32, 6, bits+47); + + // add country code - OK + num_to_bytebitsLSBF(country >> 0, 2, bits+53); + num_to_bytebitsLSBF(country >> 2, 8, bits+56); + + // add crc-16 - OK + uint8_t raw[8]; + for (uint8_t i=0; i<8; ++i) + raw[i] = bytebits_to_byte(bits + 11 + i * 9, 8); + + uint16_t crc = crc16_ccitt_kermit(raw, 8); + num_to_bytebitsLSBF(crc >> 0, 8, bits+83); + num_to_bytebitsLSBF(crc >> 8, 8, bits+92); + + // extended data - OK + num_to_bytebitsLSBF( extended >> 0 , 8, bits+101); + num_to_bytebitsLSBF( extended >> 8 , 8, bits+110); + num_to_bytebitsLSBF( extended >> 16, 8, bits+119); + + */ + return 1; +} + +//see ASKDemod for what args are accepted +//almost the same demod as cmddata.c/CmdFDXBdemodBI +int CmdFdxDemod(const char *Cmd) { + + //Differential Biphase / di-phase (inverted biphase) + //get binary from ask wave + if (!ASKbiphaseDemod("0 32 1 0", FALSE)) { + if (g_debugMode) PrintAndLog("DEBUG: Error - FDX-B ASKbiphaseDemod failed"); + return 0; + } + size_t size = DemodBufferLen; + int ans = FDXBdemodBI(DemodBuffer, &size); + if (ans < 0){ + if (g_debugMode){ + if (ans == -1) + PrintAndLog("DEBUG: Error - FDX-B too few bits found"); + else if (ans == -2) + PrintAndLog("DEBUG: Error - FDX-B preamble not found"); + else if (ans == -3) + PrintAndLog("DEBUG: Error - FDX-B Size not correct: %d", size); + else + PrintAndLog("DEBUG: Error - FDX-B ans: %d", ans); + } + return 0; + } + + setDemodBuf(DemodBuffer, 128, ans); + // remove marker bits (1's every 9th digit after preamble) (pType = 2) + size = removeParity(DemodBuffer, 11, 9, 2, 117); + if ( size != 104 ) { + if (g_debugMode) PrintAndLog("DEBUG: Error - FDX-B error removeParity: %d", size); + return 0; + } + + //got a good demod + uint64_t NationalCode = ((uint64_t)(bytebits_to_byteLSBF(DemodBuffer+32,6)) << 32) | bytebits_to_byteLSBF(DemodBuffer,32); + uint16_t countryCode = bytebits_to_byteLSBF(DemodBuffer+38,10); + uint8_t dataBlockBit = DemodBuffer[48]; + uint32_t reservedCode = bytebits_to_byteLSBF(DemodBuffer+49,14); + uint8_t animalBit = DemodBuffer[63]; + uint32_t crc16 = bytebits_to_byteLSBF(DemodBuffer+64,16); + uint32_t extended = bytebits_to_byteLSBF(DemodBuffer+80,24); + uint64_t rawid = ((uint64_t) + //bytebits_to_byte(DemodBuffer, 8) << 96) | + //bytebits_to_byte(DemodBuffer,32) << 64) | + bytebits_to_byte(DemodBuffer,32) << 32) | + bytebits_to_byte(DemodBuffer+32, 32); + uint8_t raw[8]; + num_to_bytes(rawid, 8, raw); + + uint16_t calcCrc = crc16_ccitt_kermit(raw, 8); + + PrintAndLog("\nFDX-B / ISO 11784/5 Animal Tag ID Found: Raw : %s", sprint_hex(raw, 8)); + PrintAndLog("Animal ID %04u-%012llu", countryCode, NationalCode); + PrintAndLog("National Code %012llu (0x%llX)", NationalCode, NationalCode); + PrintAndLog("Country Code %04u", countryCode); + PrintAndLog("Reserved/RFU %u (0x04%X)", reservedCode, reservedCode); + PrintAndLog(""); + PrintAndLog("Animal Tag %s", animalBit ? "True" : "False"); + PrintAndLog("Has extended data %s [0x%X]", dataBlockBit ? "True" : "False", extended); + PrintAndLog("CRC-16 0x%04X - 0x%04X [%s]", crc16, calcCrc, (calcCrc == crc16) ? "Ok" : "Failed"); + + if (g_debugMode) { + PrintAndLog("Start marker %d; Size %d", ans, size); + char *bin = sprint_bin_break(DemodBuffer, size, 16); + PrintAndLog("DEBUG bin stream:\n%s", bin); + } + return 1; +} + +int CmdFdxRead(const char *Cmd) { + CmdLFRead("s"); + getSamples("12000", TRUE); + return CmdFdxDemod(Cmd); +} + +int CmdFdxClone(const char *Cmd) { + + uint32_t countryid = 0; + uint64_t animalid = 0; + uint32_t blocks[5] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_32 | 4<= 0; --i) { + c.arg[0] = blocks[i]; + c.arg[1] = i; + clearCommandBuffer(); + SendCommand(&c); + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){ + PrintAndLog("Error occurred, device did not respond during write operation."); + return -1; + } + } + return 0; +} + +int CmdFdxSim(const char *Cmd) { + uint32_t countryid = 0; + uint64_t animalid = 0; + + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_fdx_sim(); + + countryid = param_get32ex(Cmd, 0, 0, 10); + animalid = param_get64ex(Cmd, 1, 0, 10); + + verify_values(countryid, animalid); + + uint8_t clk = 32, encoding = 2, separator = 0, invert = 1; + uint16_t arg1, arg2; + size_t size = 128; + arg1 = clk << 8 | encoding; + arg2 = invert << 8 | separator; + + PrintAndLog("Simulating FDX-B animal ID: %04u-%"PRIu64, countryid, animalid); + + UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}}; + + //getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits) + getFDXBits(animalid, countryid, 1, 0, 0, c.d.asBytes); + clearCommandBuffer(); + SendCommand(&c); + return 0; +} + +static command_t CommandTable[] = { + {"help", CmdHelp, 1, "This help"}, + {"demod", CmdFdxDemod,1, "Attempt extract tag data from graphbuf"}, + {"read", CmdFdxRead, 0, "Attempt to read and extract tag data"}, + {"clone", CmdFdxClone,0, "clone animal ID tag"}, + {"sim", CmdFdxSim, 0, "simulate animal ID tag"}, + {NULL, NULL, 0, NULL} +}; + +int CmdLFFdx(const char *Cmd) { + clearCommandBuffer(); + CmdsParse(CommandTable, Cmd); + return 0; +} + +int CmdHelp(const char *Cmd) { + CmdsHelp(CommandTable); + return 0; +} diff --git a/client/cmdlffdx.h b/client/cmdlffdx.h new file mode 100644 index 00000000..4f502610 --- /dev/null +++ b/client/cmdlffdx.h @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------------- +// +// 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 T55xx commands +//----------------------------------------------------------------------------- +#ifndef CMDLFFDX_H__ +#define CMDLFFDX_H__ +#include +#include +#include +#include "proxmark3.h" +#include "ui.h" +#include "util.h" +#include "graph.h" +#include "cmdparser.h" +#include "cmddata.h" +#include "cmdmain.h" +#include "cmdlf.h" +#include "crc16.h" // for checksum crc-16_ccitt +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // parityTest +int CmdLFFdx(const char *Cmd); +int CmdFdxClone(const char *Cmd); +int CmdFdxSim(const char *Cmd); +int CmdFdxRead(const char *Cmd); +int CmdFdxDemod(const char *Cmd); + +int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits); + +int usage_lf_fdx_clone(void); +int usage_lf_fdx_sim(void); +int usage_lf_fdx_read(void); +int usage_lf_fdx_demod(void); +#endif + -- 2.39.5 From 29f649c5cedbdf5243c27d9c91b88838d3c0495a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 5 Jan 2017 15:53:32 +0100 Subject: [PATCH 03/16] CHG: change the indala output abit, to only show when in debug mode. (ie: data setdebug 1) --- client/cmdlf.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index 967dc4af..e1cb1bdf 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -294,12 +294,11 @@ int CmdIndalaDemod(const char *Cmd) count = 0; } } + if ( rawbit<1 ) return 0; - if ( rawbit>0 ){ + if (g_debugMode) { PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32); PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); - } else { - return 0; } // Finding the start of a UID @@ -327,15 +326,14 @@ int CmdIndalaDemod(const char *Cmd) } if (start == rawbit - uidlen + 1) { - PrintAndLog("nothing to wait for"); + if (g_debugMode) PrintAndLog("nothing to wait for"); return 0; } // Inverting signal if needed if (first == 1) { - for (i = start; i < rawbit; i++) { + for (i = start; i < rawbit; i++) rawbits[i] = !rawbits[i]; - } } // Dumping UID @@ -414,7 +412,7 @@ int CmdIndalaDemod(const char *Cmd) times += 1; } - PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen); + if (g_debugMode) PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen); // Remodulating for tag cloning // HACK: 2015-01-04 this will have an impact on our new way of seening lf commands (demod) -- 2.39.5 From 87c10b2a0f49b1542258b5a4ed6f83a125c5da8f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 5 Jan 2017 15:55:19 +0100 Subject: [PATCH 04/16] CHG: some indala output is now only in debug mode CHG: added 34|37 bits AWID format. I'm guessing 37bit is wrong since the parity is still there. Which it shouldn't --- client/cmddata.c | 28 +++++++-- client/cmdlfawid.c | 137 +++++++++++++++++++++++++++------------------ client/cmdlfawid.h | 2 + 3 files changed, 110 insertions(+), 57 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 97d840c5..1e7947ff 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1460,6 +1460,7 @@ int CmdFSKdemodAWID(const char *Cmd) uint32_t code1 = 0; uint32_t code2 = 0; uint8_t fmtLen = bytebits_to_byte(BitStream, 8); + switch(fmtLen) { case 26: fc = bytebits_to_byte(BitStream + 9, 8); @@ -1467,6 +1468,22 @@ int CmdFSKdemodAWID(const char *Cmd) code1 = bytebits_to_byte(BitStream + 8,fmtLen); PrintAndLog("AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo); break; + case 34: + fc = bytebits_to_byte(BitStream + 9, 8); + cardnum = bytebits_to_byte(BitStream + 17, 24); + code1 = bytebits_to_byte(BitStream + 8, (fmtLen-32) ); + code2 = bytebits_to_byte(BitStream + 8 + (fmtLen-32), 32); + PrintAndLog("AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, code2, rawHi2, rawHi, rawLo); + break; + case 37: + fc = bytebits_to_byte(BitStream + 9, 13); + cardnum = bytebits_to_byte(BitStream + 22, 18); + code1 = bytebits_to_byte(BitStream + 8, (fmtLen-32) ); + code2 = bytebits_to_byte(BitStream + 8 + (fmtLen-32), 32); + PrintAndLog("AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, code2, rawHi2, rawHi, rawLo); + break; + // case 40: + // break; case 50: fc = bytebits_to_byte(BitStream + 9, 16); cardnum = bytebits_to_byte(BitStream + 25, 32); @@ -1801,21 +1818,24 @@ int CmdIndalaDecode(const char *Cmd) if (invert) if (g_debugMode) PrintAndLog("DEBUG: Error - Indala had to invert bits"); - PrintAndLog("BitLen: %d",DemodBufferLen); //convert UID to HEX uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; uid1 = bytebits_to_byte(DemodBuffer,32); uid2 = bytebits_to_byte(DemodBuffer+32,32); if (DemodBufferLen==64){ - PrintAndLog("Indala UID=%s (%x%08x)", sprint_bin_break(DemodBuffer,DemodBufferLen,16), uid1, uid2); + PrintAndLog("Indala Found - Bitlength %d, UID = (%x%08x)\n%s", + DemodBufferLen, uid1, uid2, sprint_bin_break(DemodBuffer,DemodBufferLen,32) + ); } else { uid3 = bytebits_to_byte(DemodBuffer+64,32); uid4 = bytebits_to_byte(DemodBuffer+96,32); uid5 = bytebits_to_byte(DemodBuffer+128,32); uid6 = bytebits_to_byte(DemodBuffer+160,32); uid7 = bytebits_to_byte(DemodBuffer+192,32); - PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)", - sprint_bin_break(DemodBuffer,DemodBufferLen,16), uid1, uid2, uid3, uid4, uid5, uid6, uid7); + PrintAndLog("Indala Found - Bitlength %d, UID = (%x%08x%08x%08x%08x%08x%08x)\n%s", + DemodBufferLen, + uid1, uid2, uid3, uid4, uid5, uid6, uid7, sprint_bin_break(DemodBuffer,DemodBufferLen,32) + ); } if (g_debugMode){ PrintAndLog("DEBUG: Indala - printing demodbuffer:"); diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 8e6e4073..8b04a3d6 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -36,7 +36,7 @@ int usage_lf_awid_sim(void) { PrintAndLog("Usage: lf awid sim [h] "); PrintAndLog("Options:"); PrintAndLog(" h : This help"); - PrintAndLog(" : format length 26|50"); + PrintAndLog(" : format length 26|34|37|50"); PrintAndLog(" : 8|16bit value facility code"); PrintAndLog(" : 16|32-bit value card number"); PrintAndLog(""); @@ -53,7 +53,7 @@ int usage_lf_awid_clone(void) { PrintAndLog("Usage: lf awid clone [h] [Q5]"); PrintAndLog("Options:"); PrintAndLog(" h : This help"); - PrintAndLog(" : format length 26|50"); + PrintAndLog(" : format length 26|34|37|50"); PrintAndLog(" : 8|16bit value facility code"); PrintAndLog(" : 16|32-bit value card number"); PrintAndLog(" Q5 : optional - clone to Q5 (T5555) instead of T55x7 chip"); @@ -126,6 +126,12 @@ int CmdAWIDDemodFSK(const char *Cmd) { return 0; } +int CmdAWIDRead(const char *Cmd) { + CmdLFRead("s"); + getSamples("12000", TRUE); + return CmdFSKdemodAWID(Cmd); +} + //refactored by marshmellow int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits) { @@ -139,16 +145,35 @@ int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits) { num_to_bytebits(fmtlen, 8, pre); // add facilitycode, cardnumber and wiegand parity bits - if ( fmtlen == 26 ) { - uint8_t wiegand[24]; - num_to_bytebits(fc, 8, wiegand); - num_to_bytebits(cn, 16, wiegand+8); - wiegand_add_parity(pre+8, wiegand, sizeof(wiegand)); - } else { - uint8_t wiegand[48]; - num_to_bytebits(fc, 16, wiegand); - num_to_bytebits(cn, 32, wiegand+16); - wiegand_add_parity(pre+8, wiegand, sizeof(wiegand)); + switch (fmtlen) { + case 26:{ + uint8_t wiegand[24]; + num_to_bytebits(fc, 8, wiegand); + num_to_bytebits(cn, 16, wiegand+8); + wiegand_add_parity(pre+8, wiegand, sizeof(wiegand)); + break; + } + case 34:{ + uint8_t wiegand[32]; + num_to_bytebits(fc, 8, wiegand); + num_to_bytebits(cn, 24, wiegand+8); + wiegand_add_parity(pre+8, wiegand, sizeof(wiegand)); + break; + } + case 37:{ + uint8_t wiegand[31]; + num_to_bytebits(fc, 13, wiegand); + num_to_bytebits(cn, 18, wiegand+13); + wiegand_add_parity(pre+8, wiegand, sizeof(wiegand)); + break; + } + case 50: { + uint8_t wiegand[48]; + num_to_bytebits(fc, 16, wiegand); + num_to_bytebits(cn, 32, wiegand+16); + wiegand_add_parity(pre+8, wiegand, sizeof(wiegand)); + break; + } } // add AWID 4bit parity @@ -158,6 +183,49 @@ int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits) { return 1; } +static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn){ + switch (*fmtlen) { + case 50: + if ((*fc & 0xFFFF) != *fc) { + *fc &= 0xFFFF; + PrintAndLog("Facility-Code Truncated to 16-bits (AWID50): %u", *fc); + } + break; + case 37: + if ((*fc & 0x1FFF) != *fc) { + *fc &= 0x1FFF; + PrintAndLog("Facility-Code Truncated to 13-bits (AWID37): %u", *fc); + } + if ((*cn & 0x3FFFF) != *cn) { + *cn &= 0x3FFFF; + PrintAndLog("Card Number Truncated to 18-bits (AWID37): %u", *cn); + } + break; + case 34: + if ((*fc & 0xFF) != *fc) { + *fc &= 0xFF; + PrintAndLog("Facility-Code Truncated to 8-bits (AWID34): %u", *fc); + } + if ((*cn & 0xFFFFFF) != *cn) { + *cn &= 0xFFFFFF; + PrintAndLog("Card Number Truncated to 24-bits (AWID34): %u", *cn); + } + break; + case 26: + default: + *fmtlen = 26; + 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); + } + break; + } +} + int CmdAWIDSim(const char *Cmd) { uint32_t fc = 0, cn = 0; uint8_t fmtlen = 0; @@ -177,26 +245,7 @@ int CmdAWIDSim(const char *Cmd) { cn = param_get32ex(Cmd, 2, 0, 10); if ( !fc || !cn) return usage_lf_awid_sim(); - switch(fmtlen) { - case 26: - 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); - } - break; - case 50: - if ((fc & 0xFFFF) != fc) { - fc &= 0xFFFF; - PrintAndLog("Facility-Code Truncated to 16-bits (AWID50): %u", fc); - } - break; - default: break; - } + verify_values(&fmtlen, &fc, &cn); PrintAndLog("Emulating AWID %u -- FC: %u; CN: %u\n", fmtlen, fc, cn); PrintAndLog("Press pm3-button to abort simulation or run another command"); @@ -233,31 +282,12 @@ int CmdAWIDClone(const char *Cmd) { if ( !fc || !cn) return usage_lf_awid_clone(); - switch(fmtlen) { - case 50: - if ((fc & 0xFFFF) != fc) { - fc &= 0xFFFF; - PrintAndLog("Facility-Code Truncated to 16-bits (AWID50): %u", fc); - } - break; - default: - fmtlen = 26; - 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); - } - break; - } - if (param_getchar(Cmd, 4) == 'Q' || param_getchar(Cmd, 4) == 'q') //t5555 (Q5) BITRATE = (RF-2)/2 (iceman) blocks[0] = T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | 50< Date: Thu, 5 Jan 2017 15:56:52 +0100 Subject: [PATCH 05/16] CHG: textual changes. CHG: remove unused #includes and added some comments --- client/cmdlffdx.c | 4 ++-- client/cmdlffdx.h | 17 ++++++----------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 58c2cb7c..bc67ade5 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -335,8 +335,8 @@ static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"demod", CmdFdxDemod,1, "Attempt extract tag data from graphbuf"}, {"read", CmdFdxRead, 0, "Attempt to read and extract tag data"}, - {"clone", CmdFdxClone,0, "clone animal ID tag"}, - {"sim", CmdFdxSim, 0, "simulate animal ID tag"}, + {"clone", CmdFdxClone,0, "Clone animal ID tag to T55x7"}, + {"sim", CmdFdxSim, 0, "Animal ID tag simulator"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmdlffdx.h b/client/cmdlffdx.h index 4f502610..4960b220 100644 --- a/client/cmdlffdx.h +++ b/client/cmdlffdx.h @@ -8,28 +8,23 @@ //----------------------------------------------------------------------------- #ifndef CMDLFFDX_H__ #define CMDLFFDX_H__ -#include -#include -#include -#include "proxmark3.h" -#include "ui.h" -#include "util.h" -#include "graph.h" +#include "proxmark3.h" // Definitions, USB controls, etc +#include "ui.h" // PrintAndLog +#include "util.h" // weigandparity #include "cmdparser.h" #include "cmddata.h" #include "cmdmain.h" -#include "cmdlf.h" +#include "cmdlf.h" // lf read #include "crc16.h" // for checksum crc-16_ccitt #include "protocols.h" // for T55xx config register definitions -#include "lfdemod.h" // parityTest +#include "lfdemod.h" // parityTest + int CmdLFFdx(const char *Cmd); int CmdFdxClone(const char *Cmd); int CmdFdxSim(const char *Cmd); int CmdFdxRead(const char *Cmd); int CmdFdxDemod(const char *Cmd); - int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits); - int usage_lf_fdx_clone(void); int usage_lf_fdx_sim(void); int usage_lf_fdx_read(void); -- 2.39.5 From ea6a49dc5edcf3ffbb9e9bcf6d35429e812b05af Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 5 Jan 2017 15:57:37 +0100 Subject: [PATCH 06/16] CHG: missing file extension. --- traces/README.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/traces/README.txt b/traces/README.txt index 95b09761..09873963 100644 --- a/traces/README.txt +++ b/traces/README.txt @@ -6,7 +6,7 @@ EM4102-3.pm3: credit card style card EM4102 tag (ID: 010872e14f) em4x05.pm3: ear tag FDX-B ISO-11784/5 (ID: 6DB0840800F80001 - Application Identifier: 8000, Country Code: 124 (Canada), National ID: 270601654) em4x50.pm3: credit card style card EM4x50 tag (ID: DE2A3F00) hid-proxCardII-05512-11432784-1.pm3: clamshell-style HID ProxCard II card -indala-00002-12345678-1A: Indala credit-card style card +indala-00002-12345678-1A.pm3: Indala credit-card style card homeagain.pm3: HomeAgain animal (cat) tag - ID 985121004515220 homeagain1600.pm3: HomeAgain animal (cat) tag - ID 985121004515220 keri.pm3: Keri PSK-3 Key Ring tag (back of tag: 1460 3411) -- 2.39.5 From e585a58ed1ec3ed10b264e736e5e20eb7285a668 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 6 Jan 2017 00:01:14 +0100 Subject: [PATCH 07/16] CHG: looks bad but works. --- client/cmdlffdx.c | 42 ++---------------------------------------- 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index bc67ade5..6c0f0751 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -79,47 +79,11 @@ static uint16_t getFDXchksum (uint64_t raw){ } int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits) { - - uint64_t raw = 0; - uint8_t data[117] = {0}; - - raw |= isanimal; - raw |= (0x000 & 0x3ff) << 1; - raw |= isextended << 14; - raw |= (country & 0x3ff) << 15; - raw |= (national_id & 0x3FFFFFFFFF) << 25; - - uint16_t crc = getFDXchksum(raw); - // add raw to bitarray - num_to_bytebits(raw, 64, data); - - // add crc to bitarray - num_to_bytebits(crc, 16, data+64); - - // add extended data to bitarray - num_to_bytebits(extended, 24, data+64+16); - - //reverse array - printf("ICE:\n %s\n", sprint_bin(data, 104) ); - for (uint8_t i = 0; i <104/2; ++i) { - uint8_t tmp = data[i]; - data[i] = data[104-i]; - data[104-i] = tmp; - } - printf("ICE:\n %s\n", sprint_bin(data, 104) ); - - // add parity always EVEN (2), every 8bits - // into output array - uint8_t bitlen = addParity(data, bits+11, 104, 9, 2); - if (bitlen != 117 ) - printf("ICE ERROR PARITY BITLEN 119 != %d\n", bitlen); - // add preamble ten 0x00 and one 0x01 memset(bits, 0x00, 10); bits[10] = 1; - printf("%s\n", sprint_bin_break(bits, 128, 32) ); - /* + // 128bits // every 9th bit is 0x01, but we can just fill the rest with 0x01 and overwrite memset(bits, 0x01, 128); @@ -153,7 +117,7 @@ int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t for (uint8_t i=0; i<8; ++i) raw[i] = bytebits_to_byte(bits + 11 + i * 9, 8); - uint16_t crc = crc16_ccitt_kermit(raw, 8); + crc = crc16_ccitt_kermit(raw, 8); num_to_bytebitsLSBF(crc >> 0, 8, bits+83); num_to_bytebitsLSBF(crc >> 8, 8, bits+92); @@ -161,8 +125,6 @@ int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t num_to_bytebitsLSBF( extended >> 0 , 8, bits+101); num_to_bytebitsLSBF( extended >> 8 , 8, bits+110); num_to_bytebitsLSBF( extended >> 16, 8, bits+119); - - */ return 1; } -- 2.39.5 From 38a30dbf1842290f12d2d42b73c403efa0711705 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 6 Jan 2017 00:02:52 +0100 Subject: [PATCH 08/16] CHG: forgot to remove unused function. --- client/cmdlffdx.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 6c0f0751..511806dd 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -72,12 +72,6 @@ static void verify_values(uint32_t countryid, uint64_t animalid){ } } -static uint16_t getFDXchksum (uint64_t raw){ - uint8_t arr[8]; - num_to_bytes(raw, 64, arr); - return crc16_ccitt_kermit(arr, 8); -} - int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits) { // add preamble ten 0x00 and one 0x01 @@ -117,7 +111,7 @@ int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t for (uint8_t i=0; i<8; ++i) raw[i] = bytebits_to_byte(bits + 11 + i * 9, 8); - crc = crc16_ccitt_kermit(raw, 8); + uint16_t crc = crc16_ccitt_kermit(raw, 8); num_to_bytebitsLSBF(crc >> 0, 8, bits+83); num_to_bytebitsLSBF(crc >> 8, 8, bits+92); -- 2.39.5 From 0ecec5395b9426dc1d721065cde2339aef234751 Mon Sep 17 00:00:00 2001 From: Iceman Date: Fri, 6 Jan 2017 19:10:48 +0100 Subject: [PATCH 09/16] Update README.md added instructions for installing the blacklist / udev rules for Ubuntu --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7f41607b..136e33ae 100644 --- a/README.md +++ b/README.md @@ -147,7 +147,10 @@ Get devkitARM release 41 from SourceForge (choose either the 64/32 bit depending - Get the latest commits `git pull` -- CLEAN COMPILE +- Install the blacklist rules +`make udev` + +- Clean and complete compilation `make clean && make all` - Flash the BOOTROM -- 2.39.5 From dd83c4572b8a32af50beaf1e90a92b563a4781ab Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Jan 2017 22:15:36 +0100 Subject: [PATCH 10/16] CHG: coverity complains about not reading the value from mifare_send_short CHG: ubuntu 14.04 gcc4.8.4 complains about mem_avail still. Don't know why. --- armsrc/iso14443a.c | 2 +- armsrc/mifareutil.c | 6 +- client/cmdhficlass.c | 2 +- client/cmdhw.c | 348 +++++++++++-------------------------------- 4 files changed, 97 insertions(+), 261 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 7c0913d8..3daab199 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2222,7 +2222,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ) { sync_cycles = PRNG_SEQUENCE_LENGTH; // Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces). nt_attacked = 0; - if (MF_DBGLEVEL >= 4) Dbprintf("Mifare::Sync %08x", sync_time); + if (MF_DBGLEVEL >= 4) Dbprintf("Mifare::Sync %u", sync_time); if (first_try) { mf_nr_ar3 = 0; diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index ca2cbeb7..a9e48781 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -471,7 +471,11 @@ int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) { } int mifare_classic_halt_ex(struct Crypto1State *pcs) { uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00}; - mifare_sendcmd_short(pcs, (pcs == NULL) ? CRYPT_NONE : CRYPT_ALL, 0x50, 0x00, receivedAnswer, NULL, NULL); + uint16_t len = mifare_sendcmd_short(pcs, (pcs == NULL) ? CRYPT_NONE : CRYPT_ALL, 0x50, 0x00, receivedAnswer, NULL, NULL); + if (len != 0) { + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("halt warning. response len: %x", len); + return 1; + } return 0; } int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) { diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index ab527cc6..89c0f758 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -769,7 +769,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) { if (have_debit_key) memcpy(tag_data+(3*8),div_key,8); if (have_credit_key) memcpy(tag_data+(4*8),c_div_key,8); - printf("Num of bytes: %lu\n", gotBytes); + printf("Num of bytes: %u\n", gotBytes); // print the dump printf("------+--+-------------------------+\n"); diff --git a/client/cmdhw.c b/client/cmdhw.c index 24b4bada..e7bdb6cb 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -30,112 +30,45 @@ static void lookupChipID(uint32_t iChipID, uint32_t mem_used) memset(asBuff, 0, sizeof(asBuff)); uint32_t mem_avail = 0; - switch(iChipID) - { - case 0x270B0A40: - sprintf(asBuff,"AT91SAM7S512 Rev A"); - break; - case 0x270B0A4F: - sprintf(asBuff,"AT91SAM7S512 Rev B"); - break; - case 0x270D0940: - sprintf(asBuff,"AT91SAM7S256 Rev A"); - break; - case 0x270B0941: - sprintf(asBuff,"AT91SAM7S256 Rev B"); - break; - case 0x270B0942: - sprintf(asBuff,"AT91SAM7S256 Rev C"); - break; - case 0x270B0943: - sprintf(asBuff,"AT91SAM7S256 Rev D"); - break; - case 0x270C0740: - sprintf(asBuff,"AT91SAM7S128 Rev A"); - break; - case 0x270A0741: - sprintf(asBuff,"AT91SAM7S128 Rev B"); - break; - case 0x270A0742: - sprintf(asBuff,"AT91SAM7S128 Rev C"); - break; - case 0x270A0743: - sprintf(asBuff,"AT91SAM7S128 Rev D"); - break; - case 0x27090540: - sprintf(asBuff,"AT91SAM7S64 Rev A"); - break; - case 0x27090543: - sprintf(asBuff,"AT91SAM7S64 Rev B"); - break; - case 0x27090544: - sprintf(asBuff,"AT91SAM7S64 Rev C"); - break; - case 0x27080342: - sprintf(asBuff,"AT91SAM7S321 Rev A"); - break; - case 0x27080340: - sprintf(asBuff,"AT91SAM7S32 Rev A"); - break; - case 0x27080341: - sprintf(asBuff,"AT91SAM7S32 Rev B"); - break; - case 0x27050241: - sprintf(asBuff,"AT9SAM7S161 Rev A"); - break; - case 0x27050240: - sprintf(asBuff,"AT91SAM7S16 Rev A"); - break; + switch(iChipID) { + case 0x270B0A40: sprintf(asBuff,"AT91SAM7S512 Rev A"); break; + case 0x270B0A4F: sprintf(asBuff,"AT91SAM7S512 Rev B"); break; + case 0x270D0940: sprintf(asBuff,"AT91SAM7S256 Rev A"); break; + case 0x270B0941: sprintf(asBuff,"AT91SAM7S256 Rev B"); break; + case 0x270B0942: sprintf(asBuff,"AT91SAM7S256 Rev C"); break; + case 0x270B0943: sprintf(asBuff,"AT91SAM7S256 Rev D"); break; + case 0x270C0740: sprintf(asBuff,"AT91SAM7S128 Rev A"); break; + case 0x270A0741: sprintf(asBuff,"AT91SAM7S128 Rev B"); break; + case 0x270A0742: sprintf(asBuff,"AT91SAM7S128 Rev C"); break; + case 0x270A0743: sprintf(asBuff,"AT91SAM7S128 Rev D"); break; + case 0x27090540: sprintf(asBuff,"AT91SAM7S64 Rev A"); break; + case 0x27090543: sprintf(asBuff,"AT91SAM7S64 Rev B"); break; + case 0x27090544: sprintf(asBuff,"AT91SAM7S64 Rev C"); break; + case 0x27080342: sprintf(asBuff,"AT91SAM7S321 Rev A"); break; + case 0x27080340: sprintf(asBuff,"AT91SAM7S32 Rev A"); break; + case 0x27080341: sprintf(asBuff,"AT91SAM7S32 Rev B"); break; + case 0x27050241: sprintf(asBuff,"AT9SAM7S161 Rev A"); break; + case 0x27050240: sprintf(asBuff,"AT91SAM7S16 Rev A"); break; } PrintAndLog("uC: %s",asBuff); - switch((iChipID&0xE0)>>5) - { - case 1: - sprintf(asBuff,"ARM946ES"); - break; - case 2: - sprintf(asBuff,"ARM7TDMI"); - break; - case 4: - sprintf(asBuff,"ARM920T"); - break; - case 5: - sprintf(asBuff,"ARM926EJS"); - break; + switch( (iChipID & 0xE0) >> 5) { + case 1: sprintf(asBuff,"ARM946ES"); break; + case 2: sprintf(asBuff,"ARM7TDMI"); break; + case 4: sprintf(asBuff,"ARM920T"); break; + case 5: sprintf(asBuff,"ARM926EJS"); break; } PrintAndLog("Embedded Processor: %s",asBuff); - switch((iChipID&0xF00)>>8) - { - case 0: - mem_avail = 0; - break; - case 1: - mem_avail = 8; - break; - case 2: - mem_avail = 16; - break; - case 3: - mem_avail = 32; - break; - case 5: - mem_avail = 64; - break; - case 7: - mem_avail = 128; - break; - case 9: - mem_avail = 256; - break; - case 10: - mem_avail = 512; - break; - case 12: - mem_avail = 1024; - break; - case 14: - mem_avail = 2048; - break; + switch( (iChipID & 0xF00) >> 8) { + case 0: mem_avail = 0; break; + case 1: mem_avail = 8; break; + case 2: mem_avail = 16; break; + case 3: mem_avail = 32; break; + case 5: mem_avail = 64; break; + case 7: mem_avail = 128; break; + case 9: mem_avail = 256; break; + case 10: mem_avail = 512; break; + case 12: mem_avail = 1024; break; + case 14: mem_avail = 2048; break; } uint32_t mem_left = 0; @@ -148,168 +81,67 @@ static void lookupChipID(uint32_t iChipID, uint32_t mem_used) mem_avail == 0 ? 0.0f : (float)mem_used/(mem_avail*1024)*100, mem_left, mem_avail == 0 ? 0.0f : (float)mem_left/(mem_avail*1024)*100 - ); - switch((iChipID&0xF000)>>12) - { - case 0: - sprintf(asBuff,"None"); - break; - case 1: - sprintf(asBuff,"8K bytes"); - break; - case 2: - sprintf(asBuff,"16K bytes"); - break; - case 3: - sprintf(asBuff,"32K bytes"); - break; - case 5: - sprintf(asBuff,"64K bytes"); - break; - case 7: - sprintf(asBuff,"128K bytes"); - break; - case 9: - sprintf(asBuff,"256K bytes"); - break; - case 10: - sprintf(asBuff,"512K bytes"); - break; - case 12: - sprintf(asBuff,"1024K bytes"); - break; - case 14: - sprintf(asBuff,"2048K bytes"); - break; + ); + + switch( (iChipID & 0xF000) >> 12 ) { + case 0: sprintf(asBuff,"None"); break; + case 1: sprintf(asBuff,"8K bytes"); break; + case 2: sprintf(asBuff,"16K bytes"); break; + case 3: sprintf(asBuff,"32K bytes"); break; + case 5: sprintf(asBuff,"64K bytes"); break; + case 7: sprintf(asBuff,"128K bytes"); break; + case 9: sprintf(asBuff,"256K bytes"); break; + case 10: sprintf(asBuff,"512K bytes"); break; + case 12: sprintf(asBuff,"1024K bytes"); break; + case 14: sprintf(asBuff,"2048K bytes"); break; } PrintAndLog("Second Nonvolatile Program Memory Size: %s",asBuff); - switch((iChipID&0xF0000)>>16) - { - case 1: - sprintf(asBuff,"1K bytes"); - break; - case 2: - sprintf(asBuff,"2K bytes"); - break; - case 3: - sprintf(asBuff,"6K bytes"); - break; - case 4: - sprintf(asBuff,"112K bytes"); - break; - case 5: - sprintf(asBuff,"4K bytes"); - break; - case 6: - sprintf(asBuff,"80K bytes"); - break; - case 7: - sprintf(asBuff,"160K bytes"); - break; - case 8: - sprintf(asBuff,"8K bytes"); - break; - case 9: - sprintf(asBuff,"16K bytes"); - break; - case 10: - sprintf(asBuff,"32K bytes"); - break; - case 11: - sprintf(asBuff,"64K bytes"); - break; - case 12: - sprintf(asBuff,"128K bytes"); - break; - case 13: - sprintf(asBuff,"256K bytes"); - break; - case 14: - sprintf(asBuff,"96K bytes"); - break; - case 15: - sprintf(asBuff,"512K bytes"); - break; + switch( (iChipID & 0xF0000) >> 16) { + case 1: sprintf(asBuff,"1K bytes"); break; + case 2: sprintf(asBuff,"2K bytes"); break; + case 3: sprintf(asBuff,"6K bytes"); break; + case 4: sprintf(asBuff,"112K bytes"); break; + case 5: sprintf(asBuff,"4K bytes"); break; + case 6: sprintf(asBuff,"80K bytes"); break; + case 7: sprintf(asBuff,"160K bytes"); break; + case 8: sprintf(asBuff,"8K bytes"); break; + case 9: sprintf(asBuff,"16K bytes"); break; + case 10: sprintf(asBuff,"32K bytes"); break; + case 11: sprintf(asBuff,"64K bytes"); break; + case 12: sprintf(asBuff,"128K bytes"); break; + case 13: sprintf(asBuff,"256K bytes"); break; + case 14: sprintf(asBuff,"96K bytes"); break; + case 15: sprintf(asBuff,"512K bytes");break; } PrintAndLog("Internal SRAM Size: %s",asBuff); - switch((iChipID&0xFF00000)>>20) - { - case 0x19: - sprintf(asBuff,"AT91SAM9xx Series"); - break; - case 0x29: - sprintf(asBuff,"AT91SAM9XExx Series"); - break; - case 0x34: - sprintf(asBuff,"AT91x34 Series"); - break; - case 0x37: - sprintf(asBuff,"CAP7 Series"); - break; - case 0x39: - sprintf(asBuff,"CAP9 Series"); - break; - case 0x3B: - sprintf(asBuff,"CAP11 Series"); - break; - case 0x40: - sprintf(asBuff,"AT91x40 Series"); - break; - case 0x42: - sprintf(asBuff,"AT91x42 Series"); - break; - case 0x55: - sprintf(asBuff,"AT91x55 Series"); - break; - case 0x60: - sprintf(asBuff,"AT91SAM7Axx Series"); - break; - case 0x61: - sprintf(asBuff,"AT91SAM7AQxx Series"); - break; - case 0x63: - sprintf(asBuff,"AT91x63 Series"); - break; - case 0x70: - sprintf(asBuff,"AT91SAM7Sxx Series"); - break; - case 0x71: - sprintf(asBuff,"AT91SAM7XCxx Series"); - break; - case 0x72: - sprintf(asBuff,"AT91SAM7SExx Series"); - break; - case 0x73: - sprintf(asBuff,"AT91SAM7Lxx Series"); - break; - case 0x75: - sprintf(asBuff,"AT91SAM7Xxx Series"); - break; - case 0x92: - sprintf(asBuff,"AT91x92 Series"); - break; - case 0xF0: - sprintf(asBuff,"AT75Cxx Series"); - break; + switch( (iChipID & 0xFF00000) >> 20) { + case 0x19: sprintf(asBuff,"AT91SAM9xx Series"); break; + case 0x29: sprintf(asBuff,"AT91SAM9XExx Series"); break; + case 0x34: sprintf(asBuff,"AT91x34 Series"); break; + case 0x37: sprintf(asBuff,"CAP7 Series"); break; + case 0x39: sprintf(asBuff,"CAP9 Series"); break; + case 0x3B: sprintf(asBuff,"CAP11 Series"); break; + case 0x40: sprintf(asBuff,"AT91x40 Series"); break; + case 0x42: sprintf(asBuff,"AT91x42 Series"); break; + case 0x55: sprintf(asBuff,"AT91x55 Series"); break; + case 0x60: sprintf(asBuff,"AT91SAM7Axx Series"); break; + case 0x61: sprintf(asBuff,"AT91SAM7AQxx Series"); break; + case 0x63: sprintf(asBuff,"AT91x63 Series"); break; + case 0x70: sprintf(asBuff,"AT91SAM7Sxx Series"); break; + case 0x71: sprintf(asBuff,"AT91SAM7XCxx Series"); break; + case 0x72: sprintf(asBuff,"AT91SAM7SExx Series"); break; + case 0x73: sprintf(asBuff,"AT91SAM7Lxx Series"); break; + case 0x75: sprintf(asBuff,"AT91SAM7Xxx Series"); break; + case 0x92: sprintf(asBuff,"AT91x92 Series"); break; + case 0xF0: sprintf(asBuff,"AT75Cxx Series"); break; } PrintAndLog("Architecture Identifier: %s",asBuff); - switch((iChipID&0x70000000)>>28) - { - case 0: - sprintf(asBuff,"ROM"); - break; - case 1: - sprintf(asBuff,"ROMless or on-chip Flash"); - break; - case 4: - sprintf(asBuff,"SRAM emulating ROM"); - break; - case 2: - sprintf(asBuff,"Embedded Flash Memory"); - break; - case 3: - sprintf(asBuff,"ROM and Embedded Flash Memory\nNVPSIZ is ROM size\nNVPSIZ2 is Flash size"); - break; + switch( (iChipID & 0x70000000) >> 28 ) { + case 0: sprintf(asBuff,"ROM"); break; + case 1: sprintf(asBuff,"ROMless or on-chip Flash"); break; + case 2: sprintf(asBuff,"Embedded Flash Memory"); break; + case 3: sprintf(asBuff,"ROM and Embedded Flash Memory\nNVPSIZ is ROM size\nNVPSIZ2 is Flash size"); break; + case 4: sprintf(asBuff,"SRAM emulating ROM"); break; } PrintAndLog("Nonvolatile Program Memory Type: %s",asBuff); } -- 2.39.5 From a0a61c91ccefed75187e810cca0e3bcb319ecdcf Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Jan 2017 22:17:43 +0100 Subject: [PATCH 11/16] CHG: adding the HID wiegand calcs again. Still need to set the bit37 indicator etc. --- client/cmdlfhid.c | 198 +++++++++++++++++++--------------------------- client/cmdlfhid.h | 4 +- 2 files changed, 85 insertions(+), 117 deletions(-) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index d4fd1522..3abbfdec 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -175,28 +175,22 @@ typedef struct { size_t Wiegand_n; } wiegand_t; -// static void addHIDMarker(uint8_t fmtlen, uint8_t *out) { - -// } -//static void getParity26(uint32_t *hi, uint32_t *lo){ - // uint32_t result = 0; - // int i; - // // even parity - // for (i = 24;i >= 13;i--) - // result ^= (*lo >> i) & 1; - // // even parity 26th bit - // *lo |= result << 25; - - // // odd parity - // result = 0; - // for (i = 12;i >= 1;i--) - // result ^= (*lo >> i) & 1; - // *lo |= !result; -//} - -// static void getParity33(uint32_t *hi, uint32_t *lo){ +static void addHIDMarker(uint8_t fmtlen, uint8_t *out) { + + switch(fmtlen) { + case 26: + //*out |= (1 << 26); // why this? + //*out |= (1 << 37); // bit format for hid? + break; + case 34: + // set bit format for less than 37 bit format + // 5+32= 1 + //*hi = (1 << 5) | (fc >> 15); + break; + default:break; + } +} -// } // static void getParity34(uint32_t *hi, uint32_t *lo){ // uint32_t result = 0; // int i; @@ -216,28 +210,6 @@ typedef struct { // *lo |= !result; // } -// static void getParity35(uint32_t *hi, uint32_t *lo){ -// } -// static void getParity37S(uint32_t *hi,uint32_t *lo){ - // uint32_t result = 0; - // int i; - - // // even parity - // for (i = 4; i >= 0; i--) - // result ^= (*hi >> i) & 1; - - // for (i = 31; i >= 20; i--) - // result ^= (*lo >> i) & 1; - - // *hi |= result; - - // // odd parity - // result = 0; - // for (i = 19; i >= 1; i--) - // result ^= (*lo >> i) & 1; - - // *lo |= result; -// } // static void getParity37H(uint32_t *hi, uint32_t *lo){ // uint32_t result = 0; // int i; @@ -257,48 +229,46 @@ typedef struct { // } //static void calc26(uint16_t fc, uint32_t cardno, uint32_t *hi, uint32_t *lo){ -void calc26(uint16_t fc, uint32_t cardno, uint8_t *out){ - +static void calc26(uint16_t fc, uint32_t cardno, uint8_t *out){ uint8_t wiegand[24]; num_to_bytebits(fc, 8, wiegand); num_to_bytebits(cardno, 16, wiegand+8); wiegand_add_parity(out, wiegand, sizeof(wiegand) ); - -// *out |= (1 << 26); // why this? -// *out |= (1 << 37); // bit format for hid? } // static void calc33(uint16_t fc, uint32_t cardno, uint32_t *hi, uint32_t *lo){ - -// } -// static void calc34(uint16_t fc, uint32_t cardno, uint32_t *hi, uint32_t *lo){ - // // put card number first bit 1 .. 20 // - // *lo = ((cardno & 0X000F7FFF) << 1) | ((fc & 0XFFFF) << 17); - // // set bit format for less than 37 bit format - // *hi = (1 << 5) | (fc >> 15); // } +static void calc34(uint16_t fc, uint32_t cardno, uint8_t *out){ + uint8_t wiegand[32]; + num_to_bytebits(fc, 16, wiegand); + num_to_bytebits(cardno, 16, wiegand + 16); + wiegand_add_parity(out, wiegand, sizeof(wiegand) ); +} // static void calc35(uint16_t fc, uint32_t cardno, uint32_t *hi, uint32_t *lo){ // *lo = ((cardno & 0xFFFFF) << 1) | fc << 21; // *hi = (1 << 5) | ((fc >> 11) & 1); // } -// static void calc37S(uint16_t fc, uint32_t cardno, uint32_t *hi, uint32_t *lo){ - // // FC 2 - 17 - 16 bit - // // cardno 18 - 36 - 19 bit - // // Even P1 1 - 19 - // // Odd P37 19 - 36 - - // fc = fc & 0xFFFF; - // *lo = ((fc << 20) | (cardno & 0x7FFFF) << 1); - // *hi = (fc >> 12); -// } -// static void calc37H(uint64_t cardno, uint32_t *hi, uint32_t *lo){ - // // SC NONE - // // cardno 1-35 34 bits - // // Even Parity 0th bit 1-18 - // // Odd Parity 36th bit 19-35 - // cardno = (cardno & 0x00000003FFFFFFFF); - // *lo = (cardno << 1); - // *hi = (cardno >> 31); -// } +static void calc37S(uint16_t fc, uint32_t cardno, uint8_t *out){ + // FC 2 - 17 - 16 bit + // cardno 18 - 36 - 19 bit + // Even P1 1 - 19 + // Odd P37 19 - 36 + uint8_t wiegand[35]; + num_to_bytebits(fc, 16, wiegand); + num_to_bytebits(cardno, 19, wiegand + 16); + wiegand_add_parity(out, wiegand, sizeof(wiegand) ); +} +static void calc37H(uint64_t cardno, uint8_t *out){ + // SC NONE + // cardno 1-35 34 bits + // Even Parity 0th bit 1-18 + // Odd Parity 36th bit 19-35 + uint8_t wiegand[37]; + num_to_bytebits( (uint32_t)(cardno >> 32), 2, wiegand); + num_to_bytebits( (uint32_t)(cardno >> 0), 32, wiegand + 2); + wiegand_add_parity(out, wiegand, sizeof(wiegand) ); + + printf("%x %x\n", (uint32_t)(cardno >> 32), (uint32_t)cardno ); +} // static void calc40(uint64_t cardno, uint32_t *hi, uint32_t *lo){ // cardno = (cardno & 0xFFFFFFFFFF); // *lo = ((cardno & 0xFFFFFFFF) << 1 ); @@ -308,51 +278,48 @@ void calc26(uint16_t fc, uint32_t cardno, uint8_t *out){ void calcWiegand(uint8_t fmtlen, uint16_t fc, uint64_t cardno, uint8_t *bits){ // uint32_t hi = 0, lo = 0; - // uint32_t cn32 = (cardno & 0xFFFFFFFF); - // switch ( fmtlen ) { - // case 26 : { - // calc26(fc, cn32, bits); - // addHIDFormatMarker(fmtlen, bits); - // break; - // } + uint32_t cn32 = (cardno & 0xFFFFFFFF); + switch ( fmtlen ) { + case 26 : { + calc26(fc, cn32, bits); + //addHIDFormatMarker(fmtlen, bits); + break; + } // case 33 : { // // calc33(fc, cn32, hi, lo); // // getParity33(hi, lo); // break; // } - // case 34 : { - // calc34(fc, cn32, hi, lo); - // getParity34(hi, lo); - // break; - // } + case 34 : { + calc34(fc, cn32, bits); + //addHIDFormatMarker(fmtlen, bits); + break; + } // case 35 : { // calc35(fc, cn32, hi, lo); // getParity35(hi, lo); // break; // } - // case 37 : { - // calc37S(fc, cn32, hi, lo); - // getParity37S(hi, lo); - // break; - // } - // case 38 : { - // calc37H(cn32, hi, lo); - // getParity37H(hi, lo); - // break; - // } + case 37 : { + calc37S(fc, cn32, bits); + //addHIDFormatMarker(fmtlen, bits); + break; + } + case 38 : { + calc37H(cardno, bits); + break; + } // case 40 : calc40(cardno, hi, lo); break; // case 44 : { break; } // case 84 : { break; } - // } - + default: break; + } } int CmdHIDWiegand(const char *Cmd) { uint32_t oem = 0, fc = 0; uint64_t cardnum = 0; - - uint32_t blocks[2] = {0,0}; - uint32_t wiegand[2] = {0,0}; + uint64_t blocks = 0, wiegand = 0; uint8_t bits[96]; uint8_t *bs = bits; @@ -365,24 +332,25 @@ int CmdHIDWiegand(const char *Cmd) { fc = param_get32ex(Cmd, 1, 0, 10); cardnum = param_get64ex(Cmd, 2, 0, 10); - // - uint8_t ftmlen[] = {26,33,34,35,37,38,40}; + uint8_t fmtlen[] = {26,33,34,35,37,38,40}; - PrintAndLog("HID | OEM | FC | CN | Wiegand | HID Formatted"); - PrintAndLog("----+-----+-----+-------+-----------+--------------------"); - for (uint8_t i = 0; i < sizeof(ftmlen); i++){ - calcWiegand( ftmlen[i], fc, cardnum, bs); - blocks[0] = bytebits_to_byte(bs,32); - blocks[1] = bytebits_to_byte(bs+32,32); - PrintAndLog(" %d | %d | %d | %llu | %08X%08X | %08X%08X ", - ftmlen, + PrintAndLog("HID | OEM | FC | CN | Wiegand | HID Formatted"); + PrintAndLog("----+-----+------+---------+-----------+--------------------"); + for (uint8_t i = 0; i < sizeof(fmtlen); i++){ + memset(bits, 0x00, sizeof(bits)); + calcWiegand( fmtlen[i], fc, cardnum, bs); + wiegand = (uint64_t)bytebits_to_byte(bs, 32) << 32 | bytebits_to_byte(bs+32, 32); + blocks = (uint64_t)bytebits_to_byte(bs, 32) << 32 | bytebits_to_byte(bs+32, 32); + uint8_t shifts = 64-fmtlen[i]; + wiegand >>= shifts; + + PrintAndLog(" %u | %03u | %03u | %llu | %llX | %llX", + fmtlen[i], oem, fc, cardnum, - wiegand[0], - wiegand[1], - blocks[0], - blocks[1] + wiegand, + blocks ); } PrintAndLog("----+-----+-----+-------+-----------+--------------------"); diff --git a/client/cmdlfhid.h b/client/cmdlfhid.h index 57603b2f..5f540967 100644 --- a/client/cmdlfhid.h +++ b/client/cmdlfhid.h @@ -17,7 +17,7 @@ #include "ui.h" #include "graph.h" #include "cmdparser.h" -#include "util.h" +#include "util.h" // wiegand_add_parity etc #include "cmdmain.h" #include "sleep.h" #include "lfdemod.h" @@ -35,6 +35,6 @@ int usage_lf_hid_sim(void); int usage_lf_hid_clone(void); int usage_lf_hid_brute(void); -void calc26(uint16_t fc, uint32_t cardno, uint8_t *out); +//void calc26(uint16_t fc, uint32_t cardno, uint8_t *out); void calcWiegand(uint8_t fmtlen, uint16_t fc, uint64_t cardno, uint8_t *bits); #endif -- 2.39.5 From 76c74bf9ad3db017873a460a496ca9dbb432fa23 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 10 Jan 2017 18:23:05 +0100 Subject: [PATCH 12/16] CHG: 'hf iclass decrypt' - adjusted the loops, to only decrypt Application 1. However I've noticed not all blocks in Application 1 is encrypted. :/ Still needs to be adjusted. CHG: 'hf iclass reader' - added some output accessrights from the CopyReader source code. And ofcourse, moved around stuff, like the usages in cmdhficlass.c --- client/cmdhficlass.c | 397 +++++++++++++++++++++---------------------- client/cmdhficlass.h | 24 +++ common/protocols.c | 55 +++--- common/protocols.h | 22 +++ 4 files changed, 270 insertions(+), 228 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 89c0f758..020ee51a 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -10,32 +10,11 @@ // High frequency iClass commands //----------------------------------------------------------------------------- -#include -#include -#include -#include -#include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type -#include "data.h" -#include "proxmark3.h" -#include "ui.h" -#include "cmdparser.h" #include "cmdhficlass.h" -#include "common.h" -#include "util.h" -#include "cmdmain.h" -#include "loclass/des.h" -#include "loclass/cipherutils.h" -#include "loclass/cipher.h" -#include "loclass/ikeys.h" -#include "loclass/elite_crack.h" -#include "loclass/fileutils.h" -#include "protocols.h" -#include "usb_cmd.h" -#include "cmdhfmfu.h" -#include "cmdhf.h" static int CmdHelp(const char *Cmd); +#define NUM_CSNS 15 #define ICLASS_KEYS_MAX 8 static uint8_t iClass_Key_Table[ICLASS_KEYS_MAX][8] = { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, @@ -52,6 +31,148 @@ typedef struct iclass_block { uint8_t d[8]; } iclass_block_t; +int usage_hf_iclass_sim(void) { + PrintAndLog("Usage: hf iclass sim