From b29d55f24b7bbdfad0e4c1644d06a046336c07ae Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sat, 27 Jun 2015 22:49:26 -0400 Subject: [PATCH 01/45] change lf config threshold, hf 14b reader, adjust lf config threshold to coincide with graph values and trigger on highs over the threshold or lows under the threshold * -1 split general hf 14b reader from full info printing --- CHANGELOG.md | 6 ++-- armsrc/lfsampling.c | 9 ++++-- client/cmdhf14b.c | 76 +++++++++++++++++++++++++++++++++++++-------- client/cmdlf.c | 2 +- 4 files changed, 74 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f9546d9..0f420915 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,11 +5,13 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [Unreleased][unreleased] ### Changed +- Changed lf config's `threshold` to a graph (signed) metric and it will trigger on + or - value set to. (example: set to 50 and recording would begin at first graphed value of >= 50 or <= -50) (marshmellow) - 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 `hf 14b reader` to `hf search` (marshmellow) ### 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) +- Add `hf 14b reader` to find and print general info about known 14b tags (marshmellow) +- Add `hf 14b info` to find and print full info about std 14b tags and sri tags (using 14b raw commands in the client) (marshmellow) - Add PACE replay functionality (frederikmoellers) ### Fixed diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 120c0801..662ebf24 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -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++; diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index d1d668e9..acbd0c2c 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -197,6 +197,7 @@ int CmdHF14BCmdRaw (const char *Cmd) { 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 (" App Data: %s", sprint_hex(data+5,4)); @@ -245,6 +246,7 @@ static void print_atqb_resp(uint8_t *data){ 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,7 +265,8 @@ char *get_ST_Chip_Model(uint8_t data){ return retStr; } -static void print_st_info(uint8_t *data){ +// 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])); @@ -271,8 +274,18 @@ static void print_st_info(uint8_t *data){ return; } +// 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; +} + +// 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) @@ -294,19 +307,30 @@ int HF14BStdInfo(uint8_t *data, uint8_t *datalen){ //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 (data[0] != 0x50 || *datalen != 14 || !crc) return 0; PrintAndLog ("\n14443-3b tag found:"); - print_atqb_resp(data); + PrintAndLog (" UID: %s", sprint_hex(data+1,4)); 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)) return 0; + + //add locking bit information here. + + + return 1; +} + +// SRx get and print general info about SRx chip from UID +int HF14B_ST_Reader(uint8_t *data, uint8_t *datalen){ bool crc = true; *datalen = 2; //wake cmd @@ -342,12 +366,12 @@ int HF14B_ST_Info(uint8_t *data, uint8_t *datalen){ if (*datalen != 10 || !crc) return 0; PrintAndLog("\n14443-3b ST tag found:"); - print_st_info(data); + print_st_general_info(data); 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,7 +380,7 @@ 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:"); @@ -369,7 +393,7 @@ 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:"); @@ -382,7 +406,7 @@ 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:"); @@ -390,11 +414,11 @@ int HF14B_Other_Info(uint8_t *data, uint8_t *datalen){ 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 +431,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)) 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 +536,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"}, diff --git a/client/cmdlf.c b/client/cmdlf.c index edf02932..1acee39b 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -388,7 +388,7 @@ int usage_lf_config() PrintAndLog(" b Sets resolution of bits per sample. Default (max): 8"); PrintAndLog(" d 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 Sets trigger threshold. 0 means no threshold"); + PrintAndLog(" t Sets trigger threshold. 0 means no threshold (range: 0-128)"); PrintAndLog("Examples:"); PrintAndLog(" lf config b 8 L"); PrintAndLog(" Samples at 125KHz, 8bps."); From 8a258b5880f37ecabd81de9920b6a41e47699a50 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sat, 27 Jun 2015 23:10:00 -0400 Subject: [PATCH 02/45] re-order 14b reader/info functions to avoid warnings --- client/cmdhf14b.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index acbd0c2c..f1568b94 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -274,16 +274,6 @@ static void print_st_general_info(uint8_t *data){ return; } -// 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; -} - // 14b get and print UID only (general info) int HF14BStdReader(uint8_t *data, uint8_t *datalen){ //05 00 00 = find one tag in field @@ -319,12 +309,12 @@ int HF14BStdReader(uint8_t *data, uint8_t *datalen){ 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)) return 0; - - //add locking bit information here. +// 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; } @@ -370,6 +360,16 @@ int HF14B_ST_Reader(uint8_t *data, uint8_t *datalen){ 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)) return 0; + + //add locking bit information here. + + + return 1; +} + // test for other 14b type tags (mimic another reader - don't have tags to identify) int HF14B_Other_Reader(uint8_t *data, uint8_t *datalen){ bool crc = true; From cc34cc7b56a7c6cedb123303ce6ed2f10b544bb8 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 28 Jun 2015 23:47:30 -0400 Subject: [PATCH 03/45] add SRx tag lock bit to hf 14b info --- client/cmdhf14b.c | 93 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 81 insertions(+), 12 deletions(-) diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index f1568b94..8e0c54ba 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -265,12 +265,77 @@ char *get_ST_Chip_Model(uint8_t data){ return retStr; } +int print_ST_Lock_info(uint8_t model){ + //assume connection open and tag selected... + uint8_t data[8] = {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(8,data+3)); + PrintAndLog(" 07/08: %slocked", blk1, (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(16,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(8,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; } @@ -320,7 +385,7 @@ int HF14BStdInfo(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){ +int HF14B_ST_Reader(uint8_t *data, uint8_t *datalen, bool closeCon){ bool crc = true; *datalen = 2; //wake cmd @@ -340,7 +405,6 @@ int HF14B_ST_Reader(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(); @@ -349,10 +413,11 @@ int HF14B_ST_Reader(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(); + //leave power on + if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return rawClose(); + //power off ? + if (closeCon) rawClose(); + if (*datalen != 10 || !crc) return 0; PrintAndLog("\n14443-3b ST tag found:"); @@ -362,10 +427,11 @@ int HF14B_ST_Reader(uint8_t *data, uint8_t *datalen){ // 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)) return 0; + 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; } @@ -385,6 +451,7 @@ int HF14B_Other_Reader(uint8_t *data, uint8_t *datalen){ PrintAndLog ("\n14443-3b tag found:"); PrintAndLog ("Unknown tag type answered to a 0x000b3f80 command ans:"); PrintAndLog ("%s",sprint_hex(data,*datalen)); + rawClose(); return 1; } } @@ -398,6 +465,7 @@ int HF14B_Other_Reader(uint8_t *data, uint8_t *datalen){ PrintAndLog ("\n14443-3b tag found:"); PrintAndLog ("Unknown tag type answered to a 0x0A command ans:"); PrintAndLog ("%s",sprint_hex(data,*datalen)); + rawClose(); return 1; } } @@ -411,6 +479,7 @@ int HF14B_Other_Reader(uint8_t *data, uint8_t *datalen){ PrintAndLog ("\n14443-3b tag found:"); PrintAndLog ("Unknown tag type answered to a 0x0C command ans:"); PrintAndLog ("%s",sprint_hex(data,*datalen)); + rawClose(); return 1; } } @@ -451,7 +520,7 @@ int HF14BReader(bool verbose){ if (HF14BStdReader(data, &datalen)) return 1; // try st 14b - if (HF14B_ST_Reader(data, &datalen)) return 1; + 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. From 8e00825a3491113508085b4ea949b10aa47499b9 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Mon, 29 Jun 2015 14:33:44 -0400 Subject: [PATCH 04/45] fixed improper printBits usage. --- client/cmdhf14b.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index 8e0c54ba..fafe92ca 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -295,7 +295,7 @@ int print_ST_Lock_info(uint8_t model){ case 0x7: // (SRI4K) //only need data[3] blk1 = 9; - PrintAndLog(" raw: %s",printBits(8,data+3)); + PrintAndLog(" raw: %s",printBits(1,data+3)); PrintAndLog(" 07/08: %slocked", blk1, (data[3] & 1) ? "not " : "" ); for (uint8_t i = 1; i<8; i++){ PrintAndLog(" %02u: %slocked", blk1, (data[3] & (1 << i)) ? "not " : "" ); @@ -307,7 +307,7 @@ int print_ST_Lock_info(uint8_t model){ case 0xC: // (SRT512) //need data[2] and data[3] blk1 = 0; - PrintAndLog(" raw: %s",printBits(16,data+2)); + 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 " : "" ); @@ -318,7 +318,7 @@ int print_ST_Lock_info(uint8_t model){ case 0x2: // (SR176) //need data[2] blk1 = 0; - PrintAndLog(" raw: %s",printBits(8,data+2)); + 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; From c3ebcce424827a2ae8e4321d06db2bfacc4df183 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Mon, 29 Jun 2015 16:34:41 -0400 Subject: [PATCH 05/45] fixed output bug in sri4k info output. too many parameters line 299 --- client/cmdhf14b.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index fafe92ca..bfec86c5 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -267,7 +267,7 @@ char *get_ST_Chip_Model(uint8_t data){ int print_ST_Lock_info(uint8_t model){ //assume connection open and tag selected... - uint8_t data[8] = {0x00}; + uint8_t data[16] = {0x00}; uint8_t datalen = 2; bool crc = true; uint8_t resplen; @@ -296,9 +296,9 @@ int print_ST_Lock_info(uint8_t model){ //only need data[3] blk1 = 9; PrintAndLog(" raw: %s",printBits(1,data+3)); - PrintAndLog(" 07/08: %slocked", blk1, (data[3] & 1) ? "not " : "" ); + 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 " : "" ); + PrintAndLog(" %02u:%slocked", blk1, (data[3] & (1 << i)) ? " not " : " " ); blk1++; } break; @@ -310,7 +310,7 @@ int print_ST_Lock_info(uint8_t model){ 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 " : "" ); + PrintAndLog(" %02u:%slocked", blk1, (data[b] & (1 << i)) ? " not " : " " ); blk1++; } } @@ -320,7 +320,7 @@ int print_ST_Lock_info(uint8_t model){ 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 " ); + PrintAndLog(" %02u/%02u:%slocked", blk1, blk1+1, (data[2] & (1 << i)) ? " " : " not " ); blk1+=2; } break; @@ -415,11 +415,12 @@ int HF14B_ST_Reader(uint8_t *data, uint8_t *datalen, bool closeCon){ //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(); - if (*datalen != 10 || !crc) return 0; - PrintAndLog("\n14443-3b ST tag found:"); print_st_general_info(data); return 1; From b8edab0f831881c8a2aa13e9df45177ed092663b Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Mon, 29 Jun 2015 21:33:10 -0400 Subject: [PATCH 06/45] add -s to hf 14b raw to select a std 14b tag first --- client/cmdhf14b.c | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index bfec86c5..9c65bb2f 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -132,6 +132,7 @@ int CmdHF14BCmdRaw (const char *Cmd) { bool reply = true; bool crc = false; bool power = false; + bool select = false; char buf[5] = ""; uint8_t data[100] = {0x00}; uint8_t datalen = 0; @@ -142,7 +143,8 @@ int CmdHF14BCmdRaw (const char *Cmd) { 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"); + return 0; } // strip @@ -164,6 +166,10 @@ int CmdHF14BCmdRaw (const char *Cmd) { case 'P': power = true; break; + case 's': + case 'S': + select = true; + break; default: PrintAndLog("Invalid option"); return 0; @@ -194,6 +200,30 @@ int CmdHF14BCmdRaw (const char *Cmd) { return 0; } + if (select){ + uint8_t cmd2[16]; + uint8_t cmdLen = 3; + bool crc2 = true; + cmd2[0] = 0x05; + cmd2[1] = 0x00; + cmd2[2] = 0x08; + + if (HF14BCmdRaw(true, &crc2, true, cmd2, &cmdLen, false)==0) return rawClose(); + + if (cmd2[0] != 0x50 || cmdLen != 14 || !crc2) return rawClose(); + + data[0] = 0x1D; + data[5] = 0x00; + data[6] = 0x08; + data[7] = 0x01; + data[8] = 0x00; + + cmdLen = 9; + if (HF14BCmdRaw(true, &crc2, true, cmd2, &cmdLen, false)==0) return rawClose(); + + if (cmd2[0] != 0x10 || cmdLen != 3 || !crc2) return rawClose(); + } + return HF14BCmdRaw(reply, &crc, power, data, &datalen, true); } @@ -342,9 +372,9 @@ static void print_st_general_info(uint8_t *data){ // 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]) @@ -366,7 +396,7 @@ int HF14BStdReader(uint8_t *data, uint8_t *datalen){ if (HF14BCmdRaw(true, &crc, false, data, datalen, false)==0) return 0; - if (data[0] != 0x50 || *datalen != 14 || !crc) return 0; + if (data[0] != 0x50 || *datalen != 14 || !crc) return 0; PrintAndLog ("\n14443-3b tag found:"); PrintAndLog (" UID: %s", sprint_hex(data+1,4)); From 1c7d367e249f6ac133950b65d48d740c36859a65 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Mon, 29 Jun 2015 21:41:48 -0400 Subject: [PATCH 07/45] update comments and changelog --- CHANGELOG.md | 7 +++---- client/cmdhf14b.c | 9 ++++++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f420915..75b9ad9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,13 +5,12 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [Unreleased][unreleased] ### Changed -- Changed lf config's `threshold` to a graph (signed) metric and it will trigger on + or - value set to. (example: set to 50 and recording would begin at first graphed value of >= 50 or <= -50) (marshmellow) +- 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 reader` to `hf search` (marshmellow) +- Added `hf 14b info` to `hf search` (marshmellow) ### Added -- Add `hf 14b reader` to find and print general info about known 14b tags (marshmellow) -- Add `hf 14b info` to find and print full info about std 14b tags and sri tags (using 14b raw commands in the client) (marshmellow) +- Add `hf 14b info` to find and print info about std 14b tags and sri tags (using 14b raw commands in the client) (marshmellow) - Add PACE replay functionality (frederikmoellers) ### Fixed diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index 9c65bb2f..6bc5daf2 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -200,7 +200,7 @@ int CmdHF14BCmdRaw (const char *Cmd) { return 0; } - if (select){ + if (select){ //auto select 14b tag uint8_t cmd2[16]; uint8_t cmdLen = 3; bool crc2 = true; @@ -208,17 +208,20 @@ int CmdHF14BCmdRaw (const char *Cmd) { cmd2[1] = 0x00; cmd2[2] = 0x08; + // REQB if (HF14BCmdRaw(true, &crc2, true, cmd2, &cmdLen, false)==0) return rawClose(); if (cmd2[0] != 0x50 || cmdLen != 14 || !crc2) return rawClose(); - data[0] = 0x1D; + data[0] = 0x1D; + // UID from data[1 - 4] data[5] = 0x00; data[6] = 0x08; data[7] = 0x01; data[8] = 0x00; - cmdLen = 9; + + // attrib if (HF14BCmdRaw(true, &crc2, true, cmd2, &cmdLen, false)==0) return rawClose(); if (cmd2[0] != 0x10 || cmdLen != 3 || !crc2) return rawClose(); From 9d84e689647c7f5b3bae29de8f2dce4781aa63b4 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Tue, 30 Jun 2015 09:46:37 -0400 Subject: [PATCH 08/45] fix 14b raw -s option, + get rid of... --- armsrc/iso14443b.c | 30 ++++++++++++++++-------------- client/cmdhf14b.c | 10 +++++----- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 33c047d8..7a0fc8e0 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -334,8 +334,6 @@ void SimulateIso14443bTag(void) 0x00, 0x21, 0x85, 0x5e, 0xd7 }; - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - clear_trace(); set_tracing(TRUE); @@ -350,6 +348,8 @@ void SimulateIso14443bTag(void) uint16_t len; uint16_t cmdsRecvd = 0; + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + // prepare the (only one) tag answer: CodeIso14443bAsTag(response1, sizeof(response1)); uint8_t *resp1Code = BigBuf_malloc(ToSendMax); @@ -908,6 +908,9 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len) //----------------------------------------------------------------------------- void ReadSTMemoryIso14443b(uint32_t dwLast) { + clear_trace(); + set_tracing(TRUE); + uint8_t i = 0x00; FpgaDownloadAndGo(FPGA_BITSTREAM_HF); @@ -926,9 +929,6 @@ void ReadSTMemoryIso14443b(uint32_t dwLast) FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ); SpinDelay(200); - clear_trace(); - set_tracing(TRUE); - // First command: wake up the tag using the INITIATE command uint8_t cmd1[] = {0x06, 0x00, 0x97, 0x5b}; CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); @@ -1199,17 +1199,19 @@ void SendRawCommand14443B(uint32_t datalen, uint32_t recv, uint8_t powerfield, u FpgaDownloadAndGo(FPGA_BITSTREAM_HF); 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/client/cmdhf14b.c b/client/cmdhf14b.c index 6bc5daf2..77dba684 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -213,12 +213,12 @@ int CmdHF14BCmdRaw (const char *Cmd) { if (cmd2[0] != 0x50 || cmdLen != 14 || !crc2) return rawClose(); - data[0] = 0x1D; + cmd2[0] = 0x1D; // UID from data[1 - 4] - data[5] = 0x00; - data[6] = 0x08; - data[7] = 0x01; - data[8] = 0x00; + cmd2[5] = 0x00; + cmd2[6] = 0x08; + cmd2[7] = 0x01; + cmd2[8] = 0x00; cmdLen = 9; // attrib From 5f605b8fc859f495ecf25184fbee9f8eca1f96d2 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Tue, 30 Jun 2015 13:00:51 -0400 Subject: [PATCH 09/45] re-add piwi's trace memory fixes --- armsrc/iso14443b.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 7a0fc8e0..10b9e953 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -334,6 +334,8 @@ void SimulateIso14443bTag(void) 0x00, 0x21, 0x85, 0x5e, 0xd7 }; + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + clear_trace(); set_tracing(TRUE); @@ -348,8 +350,6 @@ void SimulateIso14443bTag(void) uint16_t len; uint16_t cmdsRecvd = 0; - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - // prepare the (only one) tag answer: CodeIso14443bAsTag(response1, sizeof(response1)); uint8_t *resp1Code = BigBuf_malloc(ToSendMax); @@ -908,9 +908,6 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len) //----------------------------------------------------------------------------- void ReadSTMemoryIso14443b(uint32_t dwLast) { - clear_trace(); - set_tracing(TRUE); - uint8_t i = 0x00; FpgaDownloadAndGo(FPGA_BITSTREAM_HF); @@ -929,6 +926,9 @@ void ReadSTMemoryIso14443b(uint32_t dwLast) FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ); SpinDelay(200); + clear_trace(); + set_tracing(TRUE); + // First command: wake up the tag using the INITIATE command uint8_t cmd1[] = {0x06, 0x00, 0x97, 0x5b}; CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); @@ -1199,7 +1199,7 @@ void SendRawCommand14443B(uint32_t datalen, uint32_t recv, uint8_t powerfield, u FpgaDownloadAndGo(FPGA_BITSTREAM_HF); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); FpgaSetupSsc(); - + if (datalen){ set_tracing(TRUE); From f3b83bee837314a4d2bf97bc5e17cd3705a21fde Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Thu, 2 Jul 2015 15:04:09 -0400 Subject: [PATCH 10/45] small fixes to 14b info, added 14b sim cmds --- armsrc/iso14443b.c | 52 ++++++++++++++++++++++++++++++++++++---------- client/cmdhf14b.c | 42 ++++++++++++++++++++++++++++++------- 2 files changed, 75 insertions(+), 19 deletions(-) diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 10b9e953..76ad9e9a 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -321,10 +321,16 @@ 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 }; + // the only commands we understand is REQB, AFI=0, Select All, N=8: + static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; // REQB // ... and REQB, AFI=0, Normal Request, N=0: - static const uint8_t cmd2[] = { 0x05, 0x00, 0x00, 0x71, 0xFF }; + static const uint8_t cmd2[] = { 0x05, 0x00, 0x00, 0x71, 0xFF }; // REQB + // ... and WUPB, AFI=0, N=8: + static const uint8_t cmd3[] = { 0x05, 0x08, 0x08, 0xF9, 0xBD }; // WUPB + // ... and HLTB + static const uint8_t cmd4[] = { 0x50, 0xff, 0xff, 0xff, 0xff }; // HLTB + // ... and ATTRIB + static const uint8_t cmd5[] = { 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 +339,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); @@ -356,6 +365,12 @@ void SimulateIso14443bTag(void) 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(); @@ -376,23 +391,38 @@ 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) ) { + || (len == sizeof(cmd2) && memcmp(receivedCmd, cmd2, len) == 0) + || (len == sizeof(cmd3) && memcmp(receivedCmd, cmd3, len) == 0) ) { resp = response1; respLen = sizeof(response1); respCode = resp1Code; respCodeLen = resp1CodeLen; + } else if ( (len == sizeof(cmd4) && receivedCmd[0] == cmd4[0]) + || (len == sizeof(cmd5) && receivedCmd[0] == cmd5[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++; diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index 77dba684..bec1d19c 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -206,7 +206,7 @@ int CmdHF14BCmdRaw (const char *Cmd) { bool crc2 = true; cmd2[0] = 0x05; cmd2[1] = 0x00; - cmd2[2] = 0x08; + cmd2[2] = 0x00; // REQB if (HF14BCmdRaw(true, &crc2, true, cmd2, &cmdLen, false)==0) return rawClose(); @@ -224,7 +224,7 @@ int CmdHF14BCmdRaw (const char *Cmd) { // attrib if (HF14BCmdRaw(true, &crc2, true, cmd2, &cmdLen, false)==0) return rawClose(); - if (cmd2[0] != 0x10 || cmdLen != 3 || !crc2) return rawClose(); + if (cmdLen != 3 || !crc2) return rawClose(); } return HF14BCmdRaw(reply, &crc, power, data, &datalen, true); @@ -232,7 +232,7 @@ int CmdHF14BCmdRaw (const char *Cmd) { // 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]; @@ -267,14 +267,15 @@ 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; } @@ -390,20 +391,44 @@ int HF14BStdReader(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] = 0x08; + data[2] = 0x00; - 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; } @@ -414,6 +439,7 @@ int HF14BStdInfo(uint8_t *data, uint8_t *datalen){ //add more info here print_atqb_resp(data); + return 1; } From 146600578c1ab840c33321662ee91ce169bb9086 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Fri, 3 Jul 2015 22:35:03 -0400 Subject: [PATCH 11/45] fix my understanding of REQB vs WUPB --- armsrc/iso14443b.c | 20 +++++++++----------- client/cmdhf14b.c | 4 ++-- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 76ad9e9a..31634a83 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -321,16 +321,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=8: - static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; // REQB - // ... and REQB, AFI=0, Normal Request, N=0: + // 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 WUPB, AFI=0, N=8: - static const uint8_t cmd3[] = { 0x05, 0x08, 0x08, 0xF9, 0xBD }; // WUPB // ... and HLTB - static const uint8_t cmd4[] = { 0x50, 0xff, 0xff, 0xff, 0xff }; // HLTB + static const uint8_t cmd3[] = { 0x50, 0xff, 0xff, 0xff, 0xff }; // HLTB // ... and ATTRIB - static const uint8_t cmd5[] = { 0x1D, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; // 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, @@ -391,14 +389,13 @@ 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) - || (len == sizeof(cmd3) && memcmp(receivedCmd, cmd3, len) == 0) ) { + || (len == sizeof(cmd2) && memcmp(receivedCmd, cmd2, len) == 0) ) { resp = response1; respLen = sizeof(response1); respCode = resp1Code; respCodeLen = resp1CodeLen; - } else if ( (len == sizeof(cmd4) && receivedCmd[0] == cmd4[0]) - || (len == sizeof(cmd5) && receivedCmd[0] == cmd5[0]) ) { + } else if ( (len == sizeof(cmd3) && receivedCmd[0] == cmd3[0]) + || (len == sizeof(cmd4) && receivedCmd[0] == cmd4[0]) ) { resp = response2; respLen = sizeof(response2); respCode = resp2Code; @@ -412,6 +409,7 @@ void SimulateIso14443bTag(void) if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) { // Not so good, try again. DbpString("+++CRC fail"); + } else { DbpString("CRC passes"); } diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index bec1d19c..4b69ab4c 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -206,7 +206,7 @@ int CmdHF14BCmdRaw (const char *Cmd) { bool crc2 = true; cmd2[0] = 0x05; cmd2[1] = 0x00; - cmd2[2] = 0x00; + cmd2[2] = 0x08; // REQB if (HF14BCmdRaw(true, &crc2, true, cmd2, &cmdLen, false)==0) return rawClose(); @@ -397,7 +397,7 @@ int HF14BStdReader(uint8_t *data, uint8_t *datalen){ //std read cmd data[0] = 0x05; data[1] = 0x00; - data[2] = 0x00; + data[2] = 0x08; if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return rawClose(); From 7ce6e2c0b5612eaca77f4e7b1450ee168432f14a Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Fri, 3 Jul 2015 23:15:08 -0400 Subject: [PATCH 12/45] add -ss to hf 14b raw for select of SRx chips --- client/cmdhf14b.c | 61 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index 4b69ab4c..36932cbd 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -133,17 +133,19 @@ int CmdHF14BCmdRaw (const char *Cmd) { 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"); PrintAndLog(" -s active signal field ON with select"); + PrintAndLog(" -ss active signal field ON with select for SRx ST Microelectronics tags"); return 0; } @@ -169,6 +171,10 @@ int CmdHF14BCmdRaw (const char *Cmd) { case 's': case 'S': select = true; + if (Cmd[i+2]=='s' || Cmd[i+2]=='S') { + SRx = true; + i++; + } break; default: PrintAndLog("Invalid option"); @@ -192,7 +198,7 @@ int CmdHF14BCmdRaw (const char *Cmd) { continue; } PrintAndLog("Invalid char on input"); - return 1; + return 0; } if (datalen == 0) { @@ -202,31 +208,50 @@ int CmdHF14BCmdRaw (const char *Cmd) { if (select){ //auto select 14b tag uint8_t cmd2[16]; - uint8_t cmdLen = 3; bool crc2 = true; - cmd2[0] = 0x05; - cmd2[1] = 0x00; - cmd2[2] = 0x08; + 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; + } - // REQB if (HF14BCmdRaw(true, &crc2, true, cmd2, &cmdLen, false)==0) return rawClose(); - if (cmd2[0] != 0x50 || cmdLen != 14 || !crc2) 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; + } - cmd2[0] = 0x1D; - // UID from data[1 - 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(); + if (SRx && cmd2[0] != chipID) return rawClose(); } - return HF14BCmdRaw(reply, &crc, power, data, &datalen, true); } From 29b6cacc6ffece36f48bb8634b590cd82d96bf8b Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 5 Jul 2015 23:35:00 -0400 Subject: [PATCH 13/45] more verification on FDX-B tag demod - reduce... ... false positives --- client/cmddata.c | 4 ++-- common/lfdemod.c | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index bec1b5aa..bf10a6ec 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1491,9 +1491,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; } diff --git a/common/lfdemod.c b/common/lfdemod.c index f13a567c..a3a7a500 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -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; From bee99bbf906d04f234c1f47ac84dfc8ce19b89ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frederik=20M=C3=B6llers?= Date: Mon, 6 Jul 2015 17:59:23 +0200 Subject: [PATCH 14/45] Small spacing-related cleanups --- armsrc/Makefile | 18 +++++++++--------- armsrc/iso14443b.c | 28 ++++++++++++++-------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/armsrc/Makefile b/armsrc/Makefile index 1214c949..141cf0ec 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -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 +#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 -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) diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 33c047d8..1b5e07e1 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -311,7 +311,7 @@ static int GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len) } } } - + return FALSE; } @@ -353,7 +353,7 @@ 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; // We need to listen to the high-frequency, peak-detected path. @@ -377,9 +377,9 @@ 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 { Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsRecvd); @@ -429,13 +429,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 +513,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 +547,7 @@ static RAMFUNC int Handle14443bSamplesDemod(int ci, int cq) } \ } \ } - + switch(Demod.state) { case DEMOD_UNSYNCD: CHECK_FOR_SUBCARRIER(); @@ -645,7 +645,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 +713,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); @@ -1090,7 +1090,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) & @@ -1201,7 +1201,7 @@ void SendRawCommand14443B(uint32_t datalen, uint32_t recv, uint8_t powerfield, u FpgaSetupSsc(); set_tracing(TRUE); - + CodeAndTransmit14443bAsReader(data, datalen); if(recv) { @@ -1209,7 +1209,7 @@ void SendRawCommand14443B(uint32_t datalen, uint32_t recv, uint8_t powerfield, u 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(); From 4be2708381b07e36c4ced1393c99ef845aec90f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frederik=20M=C3=B6llers?= Date: Mon, 6 Jul 2015 18:01:34 +0200 Subject: [PATCH 15/45] ISO 14443 type B support for EPA functionality Added iso14443b_setup and iso14443b_apdu for general setup and communication with ISO 14443 type B tags. Updated EPA (German electronic ID card) functionality to support both card types. --- armsrc/epa.c | 76 +++++++++++++++++++++++++++---------- armsrc/epa.h | 2 +- armsrc/iso14443b.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++ armsrc/iso14443b.h | 21 ++++++++++ 4 files changed, 173 insertions(+), 21 deletions(-) create mode 100644 armsrc/iso14443b.h diff --git a/armsrc/epa.c b/armsrc/epa.c index 6bd8692e..50c7d878 100644 --- a/armsrc/epa.c +++ b/armsrc/epa.c @@ -12,10 +12,11 @@ //----------------------------------------------------------------------------- #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; } diff --git a/armsrc/epa.h b/armsrc/epa.h index 0c580205..d2ebed57 100644 --- a/armsrc/epa.h +++ b/armsrc/epa.h @@ -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(); diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 1b5e07e1..f8e6046c 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -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 @@ -896,6 +899,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. diff --git a/armsrc/iso14443b.h b/armsrc/iso14443b.h new file mode 100644 index 00000000..f90c54f3 --- /dev/null +++ b/armsrc/iso14443b.h @@ -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 */ From dd57061c11954b952ecc181d3857f94dc8d349a6 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Mon, 6 Jul 2015 15:47:03 -0400 Subject: [PATCH 16/45] fix white spaces --- armsrc/iso14443b.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 31634a83..bfbd7bf5 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -360,13 +360,13 @@ 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); + memcpy(resp2Code, ToSend, ToSendMax); uint16_t resp2CodeLen = ToSendMax; // We need to listen to the high-frequency, peak-detected path. @@ -390,15 +390,15 @@ 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; + resp = response2; respLen = sizeof(response2); - respCode = resp2Code; + respCode = resp2Code; respCodeLen = resp2CodeLen; } else { Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsRecvd); @@ -457,13 +457,13 @@ void SimulateIso14443bTag(void) (void)b; } } - + // trace the response: if (tracing) { uint8_t parity[MAX_PARITY_SIZE]; LogTrace(resp, respLen, 0, 0, parity, FALSE); } - + } } @@ -541,7 +541,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() { \ @@ -575,7 +575,7 @@ static RAMFUNC int Handle14443bSamplesDemod(int ci, int cq) } \ } \ } - + switch(Demod.state) { case DEMOD_UNSYNCD: CHECK_FOR_SUBCARRIER(); @@ -673,7 +673,7 @@ static RAMFUNC int Handle14443bSamplesDemod(int ci, int cq) Demod.metric -= Demod.thisBit; } (Demod.metricN)++; -*/ +*/ Demod.shiftReg >>= 1; if(Demod.thisBit > 0) { // logic '1' @@ -741,10 +741,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); @@ -1118,7 +1118,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) & @@ -1238,7 +1238,7 @@ void SendRawCommand14443B(uint32_t datalen, uint32_t recv, uint8_t powerfield, u 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); From 5330f5329f68fa6a95658ebd946d5eefc74e10c4 Mon Sep 17 00:00:00 2001 From: pwpiwi Date: Thu, 2 Jul 2015 08:49:34 +0200 Subject: [PATCH 17/45] - fix: trace of hf mf mifare had always been cleared by mfCheckKeys() in nonce2key() - fix: parity was not checked for reader commands in hf list 14a - add: enable tracing for hf mf nested --- armsrc/BigBuf.h | 14 +++++++------- armsrc/apps.h | 2 +- armsrc/mifarecmd.c | 14 +++++++------- client/cmdhf.c | 2 +- client/cmdhfmf.c | 22 ++++++---------------- client/mifarehost.c | 6 +++--- client/mifarehost.h | 2 +- client/nonce2key/nonce2key.c | 2 +- 8 files changed, 27 insertions(+), 37 deletions(-) diff --git a/armsrc/BigBuf.h b/armsrc/BigBuf.h index b44a1263..0e2f1744 100644 --- a/armsrc/BigBuf.h +++ b/armsrc/BigBuf.h @@ -24,15 +24,15 @@ 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 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 */ diff --git a/armsrc/apps.h b/armsrc/apps.h index bb094b33..42efd118 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -121,7 +121,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); diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index c2d85abb..fd6fde63 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -642,8 +642,8 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat // free eventually allocated BigBuf memory BigBuf_free(); - clear_trace(); - set_tracing(false); + if (calibrate) clear_trace(); + set_tracing(true); // statistics on nonce distance int16_t isOK = 0; @@ -820,18 +820,18 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); - set_tracing(TRUE); } //----------------------------------------------------------------------------- // MIFARE check keys. key count up to 85. // //----------------------------------------------------------------------------- -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) { // params - uint8_t blockNo = arg0; - uint8_t keyType = arg1; + uint8_t blockNo = arg0 & 0xff; + uint8_t keyType = (arg0 >> 8) & 0xff; + bool clearTrace = arg1; uint8_t keyCount = arg2; uint64_t ui64Key = 0; @@ -853,7 +853,7 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) LED_C_OFF(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); + if (clearTrace) clear_trace(); set_tracing(TRUE); for (i = 0; i < keyCount; i++) { diff --git a/client/cmdhf.c b/client/cmdhf.c index 4c5db589..f8daff7e 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -378,7 +378,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 { diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 5ef5273a..16612cba 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -18,7 +18,6 @@ int CmdHF14AMifare(const char *Cmd) uint32_t nt = 0, nr = 0; uint64_t par_list = 0, ks_list = 0, r_key = 0; int16_t isOK = 0; - uint8_t keyBlock[8] = {0}; UsbCommand c = {CMD_READER_MIFARE, {true, 0, 0}}; @@ -74,22 +73,13 @@ start: if (nonce2key(uid, nt, nr, par_list, ks_list, &r_key)) { isOK = 2; PrintAndLog("Key not found (lfsr_common_prefix list is null). Nt=%08x", nt); - } else { - printf("------------------------------------------------------------------\n"); - PrintAndLog("Key found:%012"llx" \n", r_key); - - num_to_bytes(r_key, 6, keyBlock); - isOK = mfCheckKeys(0, 0, 1, keyBlock, &r_key); - } - - if (!isOK) - PrintAndLog("Found valid key:%012"llx, r_key); - else - { - if (isOK != 2) PrintAndLog("Found invalid key. "); PrintAndLog("Failing is expected to happen in 25%% of all cases. Trying again with a different reader nonce..."); c.arg[0] = false; goto start; + } else { + isOK = 0; + printf("------------------------------------------------------------------\n"); + PrintAndLog("Found valid key:%012"llx" \n", r_key); } PrintAndLog(""); @@ -689,7 +679,7 @@ int CmdHF14AMfNested(const char *Cmd) for (j = 0; j < 2; j++) { if (e_sector[i].foundKey[j]) continue; - res = mfCheckKeys(FirstBlockOfSector(i), j, 6, keyBlock, &key64); + res = mfCheckKeys(FirstBlockOfSector(i), j, true, 6, keyBlock, &key64); if (!res) { e_sector[i].Key[j] = key64; @@ -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; for (uint32_t c = 0; c < keycnt; c+=max_keys) { uint32_t size = keycnt-c>max_keys?max_keys:keycnt-c; - res = mfCheckKeys(b, t, size, &keyBlock[6*c], &key64); + res = mfCheckKeys(b, t, true, size, &keyBlock[6*c], &key64); if (res != 1) { if (!res) { PrintAndLog("Found valid key:[%012"llx"]",key64); diff --git a/client/mifarehost.c b/client/mifarehost.c index 95453ebf..eb145123 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -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); num_to_bytes(key64, 6, keyBlock); key64 = 0; - if (!mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, 1, keyBlock, &key64)) { + if (!mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, false, 1, keyBlock, &key64)) { num_to_bytes(key64, 6, resultKey); break; } @@ -193,11 +193,11 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo return 0; } -int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key){ +int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key){ *key = 0; - UsbCommand c = {CMD_MIFARE_CHKKEYS, {blockNo, keyType, keycnt}}; + UsbCommand c = {CMD_MIFARE_CHKKEYS, {((blockNo & 0xff) | ((keyType&0xff)<<8)), clear_trace, keycnt}}; memcpy(c.d.asBytes, keyBlock, 6 * keycnt); SendCommand(&c); diff --git a/client/mifarehost.h b/client/mifarehost.h index a11f11d5..f6ffab3f 100644 --- a/client/mifarehost.h +++ b/client/mifarehost.h @@ -50,7 +50,7 @@ typedef struct { extern char logHexFileName[FILE_PATH_SIZE]; int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * ResultKeys, bool calibrate); -int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key); +int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key); int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount); int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount); diff --git a/client/nonce2key/nonce2key.c b/client/nonce2key/nonce2key.c index 111f58cd..70d874fe 100644 --- a/client/nonce2key/nonce2key.c +++ b/client/nonce2key/nonce2key.c @@ -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; From b362de62621f17b297f08bd53082b3aea45219e6 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sat, 11 Jul 2015 00:35:27 -0400 Subject: [PATCH 18/45] initialize global variables. --- client/cmddata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index bf10a6ec..cb1c7cd4 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -26,8 +26,8 @@ #include "crc16.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) From 40c514454d80a396e9efcf80950aa631f6647755 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Sun, 12 Jul 2015 23:38:52 +0200 Subject: [PATCH 19/45] Fixed issue #94, so lua-script 'mifare_autopwn' reacts correctly to card that are not vulnerable to darkside-attacks --- client/scripts/mifare_autopwn.lua | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/client/scripts/mifare_autopwn.lua b/client/scripts/mifare_autopwn.lua index eb98ffbf..9cc865f0 100644 --- a/client/scripts/mifare_autopwn.lua +++ b/client/scripts/mifare_autopwn.lua @@ -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 From 60034782f92e3f8d59a2a56b32663ca16cc59524 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Sun, 12 Jul 2015 23:39:27 +0200 Subject: [PATCH 20/45] Some info in the changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f9546d9..8d1cd548 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ### Changed - 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) +- Implemeted 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) From 5ebdce44c014ae29d688367508d0a6f6e6ebc673 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Sun, 12 Jul 2015 23:44:34 +0200 Subject: [PATCH 21/45] New release with FPGA compression --- CHANGELOG.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d1cd548..02431d03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,16 @@ 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] + + +## [2.2.0][2015-07-12] ### Changed - 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) -- Implemeted better detection of mifare-tags that are not vulnerable to classic attacks (`hf mf mifare`, `hf mf nested`) (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) From 2c3c08bd2fe9cce76ff5f56029bdcef961639606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frederik=20M=C3=B6llers?= Date: Mon, 13 Jul 2015 11:37:28 +0200 Subject: [PATCH 22/45] Mention EPA Type A/B support in CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02431d03..b0135cc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] +### Changed +- EPA functions (`hf epa`) now support both ISO 14443-A and 14443-B cards (frederikmoellers) ## [2.2.0][2015-07-12] From dbf6e824f932b0d5e88fbd0c24de529511fb5c05 Mon Sep 17 00:00:00 2001 From: Craig Young Date: Mon, 13 Jul 2015 15:45:28 -0400 Subject: [PATCH 23/45] Adding support for AWID26 realtime demodulation as well as cloning and simulation from facility code and card number --- armsrc/appmain.c | 3 + armsrc/apps.h | 1 + armsrc/lfops.c | 96 +++++++++++++++++- client/Makefile | 1 + client/cmdlfawid.c | 191 +++++++++++++++++++++++++++++++++++ client/cmdlfawid.h | 21 ++++ client/hid-flasher/usb_cmd.h | 1 + include/usb_cmd.h | 1 + 8 files changed, 314 insertions(+), 1 deletion(-) create mode 100644 client/cmdlfawid.c create mode 100644 client/cmdlfawid.h diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 0cbfa249..37899f57 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -681,6 +681,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 diff --git a/armsrc/apps.h b/armsrc/apps.h index 42efd118..b5638ee1 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -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 diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 7e53d4a5..188d7280 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -399,10 +399,14 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) #define OPEN_COIL() HIGH(GPIO_SSC_DOUT) i = 0; + byte_t rx[sizeof(UsbCommand)]; // Storage for usb_read call in loop for(;;) { //wait until SSC_CLK goes HIGH while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { - if(BUTTON_PRESS() || usb_poll()) { + // Craig Young - Adding a usb_read() here to avoid abort on empty UsbCommand + // My OS X client does this preventing simulation. + // Performance hit should be non-existent since the read is only performed if usb_poll is true + if(BUTTON_PRESS() || (usb_poll() && usb_read(rx,sizeof(UsbCommand)))) { DbpString("Stopped"); return; } @@ -841,6 +845,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(); diff --git a/client/Makefile b/client/Makefile index c454533d..15b1cbca 100644 --- a/client/Makefile +++ b/client/Makefile @@ -89,6 +89,7 @@ CMDSRCS = nonce2key/crapto1.c\ cmdlf.c \ cmdlfio.c \ cmdlfhid.c \ + cmdlfawid.c \ cmdlfem4x.c \ cmdlfhitag.c \ cmdlfti.c \ diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c new file mode 100644 index 00000000..cf021552 --- /dev/null +++ b/client/cmdlfawid.c @@ -0,0 +1,191 @@ +//----------------------------------------------------------------------------- +// Authored by Craig Young based on cmdlfhid.c structure +// +// cmdlfhid.c is Copyright (C) 2010 iZsh +// +// 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 // 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 + +static int CmdHelp(const char *Cmd); + +int CmdAWIDDemodFSK(const char *Cmd) +{ + int findone=0; + if(Cmd[0]=='1') findone=1; + 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) { + PrintAndLog("Usage: lf awid sim "); + return 0; + } + + 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; + + + if (sscanf(Cmd, "%u %u", &fc, &cn ) != 2) { + PrintAndLog("Usage: lf awid clone "); + return 0; + } + + 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); + } + } + 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, " -- AWID tag simulator"}, + {"clone", CmdAWIDClone, 0, " -- 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 index 00000000..603c92c7 --- /dev/null +++ b/client/cmdlfawid.h @@ -0,0 +1,21 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2010 iZsh +// +// 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); + +#endif diff --git a/client/hid-flasher/usb_cmd.h b/client/hid-flasher/usb_cmd.h index b3a7f4ec..f4013bab 100644 --- a/client/hid-flasher/usb_cmd.h +++ b/client/hid-flasher/usb_cmd.h @@ -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 */ diff --git a/include/usb_cmd.h b/include/usb_cmd.h index 524554e9..e45bf35e 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -95,6 +95,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 */ From c0c35f9bb674b5dcaa5cf89b65cc9a5fdc7997ab Mon Sep 17 00:00:00 2001 From: Craig Young Date: Mon, 13 Jul 2015 16:18:59 -0400 Subject: [PATCH 24/45] Adding CMD_AWID_DEMOD_FSK to commands.lua --- client/lualibs/commands.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/client/lualibs/commands.lua b/client/lualibs/commands.lua index 4c7bc638..127508e6 100644 --- a/client/lualibs/commands.lua +++ b/client/lualibs/commands.lua @@ -54,6 +54,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 */ From 769791d440e5be7a0e4213f56276aabee6233f8c Mon Sep 17 00:00:00 2001 From: Craig Young Date: Mon, 13 Jul 2015 16:41:50 -0400 Subject: [PATCH 25/45] Updated CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0135cc2..edf0a310 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] +### Added +- AWID26 command context added as 'lf awid' containing realtime demodulation as well as cloning/simulation based on tag numbers (Craig Young) + ### Changed - EPA functions (`hf epa`) now support both ISO 14443-A and 14443-B cards (frederikmoellers) From d6b455ed4eee2730091ed0a636ed753138adec0b Mon Sep 17 00:00:00 2001 From: Craig Young Date: Mon, 13 Jul 2015 16:47:11 -0400 Subject: [PATCH 26/45] Adding 'lf awid' context to cmdlf.c --- client/cmdlf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/cmdlf.c b/client/cmdlf.c index edf02932..6dae5164 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -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" @@ -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, " ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"}, From bcffcca25fe44473640cce8342173217c987ec52 Mon Sep 17 00:00:00 2001 From: Craig Young Date: Mon, 13 Jul 2015 18:14:12 -0400 Subject: [PATCH 27/45] Adding usage information to 'lf awid' commands --- client/cmdlfawid.c | 52 +++++++++++++++++++++++++++++++++++++++++----- client/cmdlfawid.h | 3 +++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index cf021552..233eb72c 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -19,10 +19,54 @@ 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 "); + PrintAndLog(" Options : "); + PrintAndLog(" : 8-bit value representing the AWID facility code"); + PrintAndLog(" : 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 "); + PrintAndLog(" Options : "); + PrintAndLog(" : 8-bit value representing the AWID facility code"); + PrintAndLog(" : 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]=='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); @@ -98,8 +142,7 @@ int CmdAWIDSim(const char *Cmd) uint64_t arg2 = 50; // clk RF/50 invert=0 BS = BitStream; if (sscanf(Cmd, "%u %u", &fc, &cn ) != 2) { - PrintAndLog("Usage: lf awid sim "); - return 0; + return usage_lf_awid_sim(); } fcode=(fc & 0x000000FF); @@ -137,8 +180,7 @@ int CmdAWIDClone(const char *Cmd) if (sscanf(Cmd, "%u %u", &fc, &cn ) != 2) { - PrintAndLog("Usage: lf awid clone "); - return 0; + return usage_lf_awid_clone(); } if ((fc & 0xFF) != fc) { diff --git a/client/cmdlfawid.h b/client/cmdlfawid.h index 603c92c7..00622927 100644 --- a/client/cmdlfawid.h +++ b/client/cmdlfawid.h @@ -17,5 +17,8 @@ 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 From e46fe044301490953e98776b70e0acd1117e2b20 Mon Sep 17 00:00:00 2001 From: Craig Young Date: Mon, 13 Jul 2015 18:46:42 -0400 Subject: [PATCH 28/45] Introducing a stand-alone mode for working with NFC (ISO14443a) tag UIDs. --- CHANGELOG.md | 3 + armsrc/Makefile | 2 +- armsrc/appmain.c | 226 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index edf0a310..dc015c92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [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) + ### Added - AWID26 command context added as 'lf awid' containing realtime demodulation as well as cloning/simulation based on tag numbers (Craig Young) diff --git a/armsrc/Makefile b/armsrc/Makefile index 141cf0ec..a59fa073 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 \ +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 diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 37899f57..40df5f5f 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -29,6 +29,11 @@ #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) ) //============================================================================= @@ -294,6 +299,7 @@ void SendVersion(void) } #ifdef WITH_LF +#ifndef WITH_ISO14443a_StandAlone // samy's sniff and repeat routine void SamyRun() { @@ -440,7 +446,219 @@ void SamyRun() } } #endif +#endif +#ifdef WITH_ISO14443a +#ifdef WITH_ISO14443a_StandAlone +void StandAloneMode14a() +{ + DbpString("Stand-alone mode! No PC necessary."); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + // 3 possible options? no just 1 for now +#undef OPTS +#define OPTS 2 + // Oooh pretty -- notify user we're in elite samy mode now + LED(LED_RED, 200); + LED(LED_ORANGE, 200); + LED(LED_GREEN, 200); + LED(LED_ORANGE, 200); + LED(LED_RED, 200); + LED(LED_ORANGE, 200); + LED(LED_GREEN, 200); + LED(LED_ORANGE, 200); + LED(LED_RED, 200); + + int selected = 0; + int playing = 0; + int cardRead[OPTS] = {0}; + uint8_t readUID[10] = {0}; + int uid_1st[OPTS]={0}; + int uid_2nd[OPTS]={0}; + + LED(selected + 1, 0); + + for (;;) + { + usb_poll(); + WDT_HIT(); + + // Was our button held down or pressed? + int button_pressed = BUTTON_HELD(1000); + + SpinDelay(300); + + // Button was held for a second, begin recording + if (button_pressed > 0 && cardRead[selected] == 0) + { + LEDsoff(); + LED(selected + 1, 0); + LED(LED_RED2, 0); + + // record + Dbprintf("Enabling iso14443a reader mode for [Bank: %u]...", selected); + + // wait for button to be released + while(BUTTON_PRESS()) + WDT_HIT(); + /* 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 ( ; ; ) + { + if (!iso14443a_select_card(uid, NULL, &cuid)) + continue; + else + { + Dbprintf("Read UID:"); Dbhexdump(10,uid,0); + memcpy(readUID,uid,10*sizeof(uint8_t)); + uint8_t *dst = (uint8_t *)&uid_1st[selected]; + // Set UID byte order + for (int i=0; i<4; i++) + dst[i] = uid[3-i]; + dst = (uint8_t *)&uid_2nd[selected]; + for (int i=0; i<4; i++) + dst[i] = uid[7-i]; + break; + } + } + LEDsoff(); + LED(LED_GREEN, 200); + LED(LED_ORANGE, 200); + LED(LED_GREEN, 200); + LED(LED_ORANGE, 200); + + LEDsoff(); + LED(selected + 1, 0); + // Finished recording + + // If we were previously playing, set playing off + // so next button push begins playing what we recorded + playing = 0; + + cardRead[selected] = 1; + + } +/* MF UID clone */ + else if (button_pressed > 0 && cardRead[selected] == 1) + { + 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(0x1F, 1, 0, oldBlock0); + 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(0x1F, 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 + } + LEDsoff(); + LED(selected + 1, 0); + // Finished recording + + // If we were previously playing, set playing off + // so next button push begins playing what we recorded + playing = 0; + + } + // Change where to record (or begin playing) + else if (button_pressed && cardRead[selected]) + { + // Next option if we were previously playing + if (playing) + selected = (selected + 1) % OPTS; + playing = !playing; + + LEDsoff(); + LED(selected + 1, 0); + + // Begin transmitting + if (playing) + { + LED(LED_GREEN, 0); + DbpString("Playing"); + while (!BUTTON_HELD(500)) { // Loop simulating tag until the button is held a half-sec + Dbprintf("Simulating ISO14443a tag with uid[0]: %08x, uid[1]: %08x [Bank: %u]", uid_1st[selected],uid_2nd[selected],selected); + SimulateIso14443aTag(1,uid_1st[selected],uid_2nd[selected],NULL); + } + //cardRead[selected] = 1; + Dbprintf("Done playing [Bank: %u]",selected); + + /* We pressed a button so ignore it here with a delay */ + SpinDelay(300); + + // when done, we're done playing, move to next option + selected = (selected + 1) % OPTS; + playing = !playing; + LEDsoff(); + LED(selected + 1, 0); + } + else + while(BUTTON_PRESS()) + WDT_HIT(); + } + } +} +#endif +#endif /* OBJECTIVE Listen and detect an external reader. Determine the best location @@ -1031,8 +1249,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 } } From 37824afe63d044fbaa37aaa5c0f84164216cb9c4 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Thu, 16 Jul 2015 22:47:14 +0200 Subject: [PATCH 29/45] Changed indentation to tabs --- client/cmdlfawid.c | 342 ++++++++++++++++++++++----------------------- 1 file changed, 171 insertions(+), 171 deletions(-) diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 233eb72c..17837a11 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -21,213 +21,213 @@ 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; + 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 "); - PrintAndLog(" Options : "); - PrintAndLog(" : 8-bit value representing the AWID facility code"); - PrintAndLog(" : 16-bit value representing the AWID card number"); - PrintAndLog(""); - PrintAndLog(" sample : lf awid sim 224 1337"); - return 0; + 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 "); + PrintAndLog(" Options : "); + PrintAndLog(" : 8-bit value representing the AWID facility code"); + PrintAndLog(" : 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 "); - PrintAndLog(" Options : "); - PrintAndLog(" : 8-bit value representing the AWID facility code"); - PrintAndLog(" : 16-bit value representing the AWID card number"); - PrintAndLog(""); - PrintAndLog(" sample : lf awid clone 224 1337"); - return 0; + 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 "); + PrintAndLog(" Options : "); + PrintAndLog(" : 8-bit value representing the AWID facility code"); + PrintAndLog(" : 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 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)"); + 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; + 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(); - } + 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; + 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; - + uint32_t fc=0,cn=0,blocks[4] = {0x00107060, 0, 0, 0x11111111}, i=0; + uint8_t BitStream[12]; + uint8_t *BS=BitStream; + UsbCommand c; + - if (sscanf(Cmd, "%u %u", &fc, &cn ) != 2) { - return usage_lf_awid_clone(); - } + 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); - } - } - return 0; + 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); + } + } + 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, " -- AWID tag simulator"}, - {"clone", CmdAWIDClone, 0, " -- Clone AWID to T55x7 (tag must be in range of antenna)"}, - {NULL, NULL, 0, NULL} + {"help", CmdHelp, 1, "This help"}, + {"fskdemod", CmdAWIDDemodFSK, 0, "['1'] Realtime AWID FSK demodulator (option '1' for one tag only)"}, + {"sim", CmdAWIDSim, 0, " -- AWID tag simulator"}, + {"clone", CmdAWIDClone, 0, " -- 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; + CmdsParse(CommandTable, Cmd); + return 0; } int CmdHelp(const char *Cmd) { - CmdsHelp(CommandTable); - return 0; + CmdsHelp(CommandTable); + return 0; } From 976627d5ba2939ffcdf34b68d620b566ba1afa93 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Thu, 16 Jul 2015 23:50:41 +0200 Subject: [PATCH 30/45] Fixed (?) issues from PR #129 --- armsrc/appmain.c | 1 + client/cmdlfawid.c | 10 +++++++--- client/cmdlft55xx.c | 5 +++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 37899f57..e5d448da 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -667,6 +667,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(); diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 17837a11..06397e70 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -16,7 +16,7 @@ #include "cmdparser.h" // CmdsParse, CmdsHelp #include "cmdlfawid.h" // AWID function declarations #include "lfdemod.h" // parityTest - +#include "cmdmain.h" static int CmdHelp(const char *Cmd); @@ -176,8 +176,7 @@ 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; - + UsbCommand c, resp; if (sscanf(Cmd, "%u %u", &fc, &cn ) != 2) { return usage_lf_awid_clone(); @@ -206,6 +205,11 @@ int CmdAWIDClone(const char *Cmd) 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; diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index b357e71c..0007f175 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -670,6 +670,7 @@ int CmdT55xxWriteBlock(const char *Cmd) } UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}}; + UsbCommand resp; c.d.asBytes[0] = 0x0; PrintAndLog("Writing to block: %d data : 0x%08X", block, data); @@ -681,6 +682,10 @@ int CmdT55xxWriteBlock(const char *Cmd) PrintAndLog("pwd : 0x%08X", password); } SendCommand(&c); + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){ + PrintAndLog("Error occurred, device did not ACK write operation. (May be due to old firmware)"); + return -1; + } return 0; } From 83f3f8ac40b47e220954e620a5ecbe41f54f4dc7 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Fri, 17 Jul 2015 00:01:58 +0200 Subject: [PATCH 31/45] Potential fix for 0-length usb packets seen on OSX --- armsrc/lfops.c | 6 +----- common/usb_cdc.c | 16 ++++++++++++++++ common/usb_cdc.h | 1 + 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 188d7280..733bc953 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -399,14 +399,10 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) #define OPEN_COIL() HIGH(GPIO_SSC_DOUT) i = 0; - byte_t rx[sizeof(UsbCommand)]; // Storage for usb_read call in loop for(;;) { //wait until SSC_CLK goes HIGH while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { - // Craig Young - Adding a usb_read() here to avoid abort on empty UsbCommand - // My OS X client does this preventing simulation. - // Performance hit should be non-existent since the read is only performed if usb_poll is true - if(BUTTON_PRESS() || (usb_poll() && usb_read(rx,sizeof(UsbCommand)))) { + if(BUTTON_PRESS() || (usb_poll_validate_length() )) { DbpString("Stopped"); return; } diff --git a/common/usb_cdc.c b/common/usb_cdc.c index ccbb3c50..3c6e9282 100644 --- a/common/usb_cdc.c +++ b/common/usb_cdc.c @@ -293,6 +293,22 @@ bool usb_poll() return (pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank); } +/** + In github PR #129, some users appears to get a false positive from + usb_poll, which returns true, but the usb_read operation + still returns 0. + This check is basically the same as above, but also checks + that the length available to read is non-zero, thus hopefully fixes the + bug. +**/ +bool usb_poll_validate_length() +{ + + if (!usb_check()) return false; + if (!(pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank)) return false; + return (pUdp->UDP_CSR[AT91C_EP_OUT] >> 16) > 0; +} + //*---------------------------------------------------------------------------- //* \fn usb_read //* \brief Read available data from Endpoint OUT diff --git a/common/usb_cdc.h b/common/usb_cdc.h index 59e73a47..c42da8db 100644 --- a/common/usb_cdc.h +++ b/common/usb_cdc.h @@ -41,6 +41,7 @@ void usb_disable(); void usb_enable(); bool usb_check(); bool usb_poll(); +bool usb_poll_validate_length(); uint32_t usb_read(byte_t* data, size_t len); uint32_t usb_write(const byte_t* data, const size_t len); From 40c5f34265d56fe84d290aab15a1093cb9a03951 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Fri, 17 Jul 2015 21:49:27 +0200 Subject: [PATCH 32/45] Clear command buffer --- client/cmdlft55xx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 0007f175..2291735c 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -242,6 +242,7 @@ int CmdT55xxReadBlock(const char *Cmd) { c.d.asBytes[0] = 0x1; } + clearCommandBuffer(); SendCommand(&c); if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) { PrintAndLog("command execution time out"); @@ -681,6 +682,7 @@ int CmdT55xxWriteBlock(const char *Cmd) c.d.asBytes[0] = 0x1; PrintAndLog("pwd : 0x%08X", password); } + clearCommandBuffer(); SendCommand(&c); if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){ PrintAndLog("Error occurred, device did not ACK write operation. (May be due to old firmware)"); @@ -883,6 +885,7 @@ int AquireData( uint8_t block ){ // c.d.asBytes[0] = 0x1; // } + clearCommandBuffer(); SendCommand(&c); if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) { PrintAndLog("command execution time out"); From db2dc28d34943676c0890ac0bc3fb8026a8c2808 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 20 Jul 2015 23:17:55 +0200 Subject: [PATCH 33/45] Reverted previous change to , I made it no longer cache previous results --- client/cmdhw.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index 05ad0c9f..7218f3e9 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -406,21 +406,15 @@ int CmdVersion(const char *Cmd) { 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) { - PrintAndLog("Prox/RFID mark3 RFID instrument"); - PrintAndLog((char*)resp.d.asBytes); - lookupChipID(resp.arg[0], resp.arg[1]); - } - } else if (Cmd != NULL) { + UsbCommand resp = {0, {0, 0, 0}}; + + SendCommand(&c); + if (WaitForResponseTimeout(CMD_ACK,&resp,1000) && Cmd != NULL) { PrintAndLog("Prox/RFID mark3 RFID instrument"); PrintAndLog((char*)resp.d.asBytes); lookupChipID(resp.arg[0], resp.arg[1]); } - + return 0; } From d2deaf7bcff57422c1467becfeebdd4fa7492295 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 20 Jul 2015 23:18:46 +0200 Subject: [PATCH 34/45] Fixed some indentation --- common/usb_cdc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/common/usb_cdc.c b/common/usb_cdc.c index 3c6e9282..e13ddbe2 100644 --- a/common/usb_cdc.c +++ b/common/usb_cdc.c @@ -314,26 +314,26 @@ bool usb_poll_validate_length() //* \brief Read available data from Endpoint OUT //*---------------------------------------------------------------------------- uint32_t usb_read(byte_t* data, size_t len) { - byte_t bank = btReceiveBank; + byte_t bank = btReceiveBank; uint32_t packetSize, nbBytesRcv = 0; - uint32_t time_out = 0; + uint32_t time_out = 0; while (len) { if (!usb_check()) break; if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) { packetSize = MIN(pUdp->UDP_CSR[AT91C_EP_OUT] >> 16, len); - len -= packetSize; + len -= packetSize; while(packetSize--) data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT]; pUdp->UDP_CSR[AT91C_EP_OUT] &= ~(bank); if (bank == AT91C_UDP_RX_DATA_BK0) { bank = AT91C_UDP_RX_DATA_BK1; - } else { + } else { bank = AT91C_UDP_RX_DATA_BK0; - } + } } - if (time_out++ == 0x1fff) break; + if (time_out++ == 0x1fff) break; } btReceiveBank = bank; From 23931c11d54647e29eedb774bb58ec47512bb5cc Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 20 Jul 2015 23:22:33 +0200 Subject: [PATCH 35/45] Minor fix with previous cache-removal --- client/cmdhw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index 7218f3e9..2b6f9518 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -409,7 +409,7 @@ int CmdVersion(const char *Cmd) UsbCommand resp = {0, {0, 0, 0}}; 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]); From 86a83668b571d34deec1643eeda3b871cee56b75 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Tue, 21 Jul 2015 00:13:06 +0200 Subject: [PATCH 36/45] Minor changes in iso1443-standalone mode --- armsrc/appmain.c | 438 +++++++++++++++++++++++------------------------ 1 file changed, 215 insertions(+), 223 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index ddfe001c..7aa353b2 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -298,19 +298,13 @@ 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 -#ifndef WITH_ISO14443a_StandAlone -// samy's sniff and repeat routine -void SamyRun() -{ - DbpString("Stand-alone mode! No PC necessary."); - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); +#if defined(WITH_ISO14443a_StandAlone) || defined(WITH_LF) - // 3 possible options? no just 2 for now #define OPTS 2 - int high[OPTS], low[OPTS]; - +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); @@ -322,6 +316,216 @@ 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; + int cardRead[OPTS] = {0}; + uint8_t readUID[10] = {0}; + uint32_t uid_1st[OPTS]={0}; + uint32_t uid_2nd[OPTS]={0}; + + LED(selected + 1, 0); + + for (;;) + { + usb_poll(); + WDT_HIT(); + + // Was our button held down or pressed? + int button_pressed = BUTTON_HELD(1000); + SpinDelay(300); + + // Button was held for a second, begin recording + if (button_pressed > 0 && cardRead[selected] == 0) + { + LEDsoff(); + LED(selected + 1, 0); + LED(LED_RED2, 0); + + // record + Dbprintf("Enabling iso14443a reader mode for [Bank: %u]...", selected); + + // wait for button to be released + while(BUTTON_PRESS()) + WDT_HIT(); + /* 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 (!iso14443a_select_card(uid, NULL, &cuid)) + continue; + else + { + Dbprintf("Read UID:"); Dbhexdump(10,uid,0); + memcpy(readUID,uid,10*sizeof(uint8_t)); + uint8_t *dst = (uint8_t *)&uid_1st[selected]; + // Set UID byte order + for (int i=0; i<4; i++) + dst[i] = uid[3-i]; + dst = (uint8_t *)&uid_2nd[selected]; + for (int i=0; i<4; i++) + dst[i] = uid[7-i]; + break; + } + } + LEDsoff(); + LED(LED_GREEN, 200); + LED(LED_ORANGE, 200); + LED(LED_GREEN, 200); + LED(LED_ORANGE, 200); + + LEDsoff(); + LED(selected + 1, 0); + // Finished recording + + // If we were previously playing, set playing off + // so next button push begins playing what we recorded + playing = 0; + + cardRead[selected] = 1; + + } + /* MF UID clone */ + else if (button_pressed > 0 && cardRead[selected] == 1) + { + 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(0x1F, 1, 0, oldBlock0); + 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(0x1F, 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 + } + LEDsoff(); + LED(selected + 1, 0); + // Finished recording + + // If we were previously playing, set playing off + // so next button push begins playing what we recorded + playing = 0; + + } + // Change where to record (or begin playing) + else if (button_pressed && cardRead[selected]) + { + // Next option if we were previously playing + if (playing) + selected = (selected + 1) % OPTS; + playing = !playing; + + LEDsoff(); + LED(selected + 1, 0); + + // Begin transmitting + if (playing) + { + LED(LED_GREEN, 0); + DbpString("Playing"); + while (!BUTTON_HELD(500)) { // Loop simulating tag until the button is held a half-sec + Dbprintf("Simulating ISO14443a tag with uid[0]: %08x, uid[1]: %08x [Bank: %u]", uid_1st[selected],uid_2nd[selected],selected); + SimulateIso14443aTag(1,uid_1st[selected],uid_2nd[selected],NULL); + } + //cardRead[selected] = 1; + Dbprintf("Done playing [Bank: %u]",selected); + + /* We pressed a button so ignore it here with a delay */ + SpinDelay(300); + + // when done, we're done playing, move to next option + selected = (selected + 1) % OPTS; + playing = !playing; + 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; @@ -332,7 +536,7 @@ void SamyRun() for (;;) { usb_poll(); - WDT_HIT(); + WDT_HIT(); // Was our button held down or pressed? int button_pressed = BUTTON_HELD(1000); @@ -445,219 +649,7 @@ void SamyRun() } } } -#endif -#endif -#ifdef WITH_ISO14443a -#ifdef WITH_ISO14443a_StandAlone -void StandAloneMode14a() -{ - DbpString("Stand-alone mode! No PC necessary."); - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - // 3 possible options? no just 1 for now -#undef OPTS -#define OPTS 2 - // Oooh pretty -- notify user we're in elite samy mode now - LED(LED_RED, 200); - LED(LED_ORANGE, 200); - LED(LED_GREEN, 200); - LED(LED_ORANGE, 200); - LED(LED_RED, 200); - LED(LED_ORANGE, 200); - LED(LED_GREEN, 200); - LED(LED_ORANGE, 200); - LED(LED_RED, 200); - - int selected = 0; - int playing = 0; - int cardRead[OPTS] = {0}; - uint8_t readUID[10] = {0}; - int uid_1st[OPTS]={0}; - int uid_2nd[OPTS]={0}; - - LED(selected + 1, 0); - - for (;;) - { - usb_poll(); - WDT_HIT(); - - // Was our button held down or pressed? - int button_pressed = BUTTON_HELD(1000); - - SpinDelay(300); - - // Button was held for a second, begin recording - if (button_pressed > 0 && cardRead[selected] == 0) - { - LEDsoff(); - LED(selected + 1, 0); - LED(LED_RED2, 0); - - // record - Dbprintf("Enabling iso14443a reader mode for [Bank: %u]...", selected); - - // wait for button to be released - while(BUTTON_PRESS()) - WDT_HIT(); - /* 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 ( ; ; ) - { - if (!iso14443a_select_card(uid, NULL, &cuid)) - continue; - else - { - Dbprintf("Read UID:"); Dbhexdump(10,uid,0); - memcpy(readUID,uid,10*sizeof(uint8_t)); - uint8_t *dst = (uint8_t *)&uid_1st[selected]; - // Set UID byte order - for (int i=0; i<4; i++) - dst[i] = uid[3-i]; - dst = (uint8_t *)&uid_2nd[selected]; - for (int i=0; i<4; i++) - dst[i] = uid[7-i]; - break; - } - } - LEDsoff(); - LED(LED_GREEN, 200); - LED(LED_ORANGE, 200); - LED(LED_GREEN, 200); - LED(LED_ORANGE, 200); - - LEDsoff(); - LED(selected + 1, 0); - // Finished recording - - // If we were previously playing, set playing off - // so next button push begins playing what we recorded - playing = 0; - - cardRead[selected] = 1; - - } -/* MF UID clone */ - else if (button_pressed > 0 && cardRead[selected] == 1) - { - 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(0x1F, 1, 0, oldBlock0); - 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(0x1F, 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 - } - LEDsoff(); - LED(selected + 1, 0); - // Finished recording - - // If we were previously playing, set playing off - // so next button push begins playing what we recorded - playing = 0; - - } - // Change where to record (or begin playing) - else if (button_pressed && cardRead[selected]) - { - // Next option if we were previously playing - if (playing) - selected = (selected + 1) % OPTS; - playing = !playing; - - LEDsoff(); - LED(selected + 1, 0); - - // Begin transmitting - if (playing) - { - LED(LED_GREEN, 0); - DbpString("Playing"); - while (!BUTTON_HELD(500)) { // Loop simulating tag until the button is held a half-sec - Dbprintf("Simulating ISO14443a tag with uid[0]: %08x, uid[1]: %08x [Bank: %u]", uid_1st[selected],uid_2nd[selected],selected); - SimulateIso14443aTag(1,uid_1st[selected],uid_2nd[selected],NULL); - } - //cardRead[selected] = 1; - Dbprintf("Done playing [Bank: %u]",selected); - - /* We pressed a button so ignore it here with a delay */ - SpinDelay(300); - - // when done, we're done playing, move to next option - selected = (selected + 1) % OPTS; - playing = !playing; - LEDsoff(); - LED(selected + 1, 0); - } - else - while(BUTTON_PRESS()) - WDT_HIT(); - } - } -} -#endif #endif /* OBJECTIVE From e2012d1bd33ae33703da1c1648f35964472823be Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Tue, 21 Jul 2015 23:18:51 +0200 Subject: [PATCH 37/45] Implemented 'hw status' and 'hw ping', put back client-side cacheing of 'hw version' --- armsrc/BigBuf.c | 10 ++++++ armsrc/BigBuf.h | 2 +- armsrc/appmain.c | 21 ++++++++++++- armsrc/fpgaloader.c | 8 +++++ armsrc/fpgaloader.h | 1 + armsrc/lfsampling.c | 2 +- armsrc/lfsampling.h | 4 +++ armsrc/mifareutil.h | 1 + client/cmdhw.c | 61 ++++++++++++++++++++++++++++--------- client/lualibs/commands.lua | 3 +- include/usb_cmd.h | 2 ++ 11 files changed, 96 insertions(+), 19 deletions(-) diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index 510f7bef..a938d5c6 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -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) diff --git a/armsrc/BigBuf.h b/armsrc/BigBuf.h index 0e2f1744..05b4180e 100644 --- a/armsrc/BigBuf.h +++ b/armsrc/BigBuf.h @@ -28,7 +28,7 @@ extern void BigBuf_Clear(void); extern uint8_t *BigBuf_malloc(uint16_t); extern void BigBuf_free(void); extern void BigBuf_free_keep_EM(void); - +extern void BigBuf_print_status(void); extern uint16_t BigBuf_get_traceLen(void); extern void clear_trace(); extern void set_tracing(bool enable); diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 7aa353b2..23540806 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -25,6 +25,7 @@ #include #include "lfsampling.h" #include "BigBuf.h" +#include "mifareutil.h" #ifdef WITH_LCD #include "LCD.h" #endif @@ -297,6 +298,19 @@ void SendVersion(void) uint32_t compressed_data_section_size = common_area.arg1; cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, 0, VersionString, strlen(VersionString)); } +/** + * Prints runtime information about the PM3. +**/ +void SendStatus(void) +{ + BigBuf_print_status(); + Fpga_print_status(); + printConfig(); //LF Sampling config + Dbprintf("Various"); + Dbprintf(" MF_DBGLEVEL......%d", MF_DBGLEVEL); + Dbprintf(" ToSendMax........%d",ToSendMax); + Dbprintf(" ToSendBit........%d",ToSendBit); +} #if defined(WITH_ISO14443a_StandAlone) || defined(WITH_LF) @@ -1143,7 +1157,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(); diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index 16fed7c5..308dda8c 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -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); +} diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index 0bad3809..52d6c677 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -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); diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 662ebf24..6e783769 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -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); diff --git a/armsrc/lfsampling.h b/armsrc/lfsampling.h index 6c671ec8..7d3925cd 100644 --- a/armsrc/lfsampling.h +++ b/armsrc/lfsampling.h @@ -56,4 +56,8 @@ void LFSetupFPGAForADC(int divisor, bool lf_field); void setSamplingConfig(sample_config *sc); sample_config * getSamplingConfig(); + +void printConfig(); + + #endif // LFSAMPLING_H diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index 85a34ef6..7a09ce64 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -8,6 +8,7 @@ //----------------------------------------------------------------------------- // code for work with mifare cards. //----------------------------------------------------------------------------- +#include "crapto1.h" #ifndef __MIFAREUTIL_H #define __MIFAREUTIL_H diff --git a/client/cmdhw.c b/client/cmdhw.c index 2b6f9518..23b6ce21 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -405,33 +405,64 @@ int CmdTune(const char *Cmd) int CmdVersion(const char *Cmd) { + clearCommandBuffer(); UsbCommand c = {CMD_VERSION}; - UsbCommand resp = {0, {0, 0, 0}}; + static UsbCommand resp = {0, {0, 0, 0}}; - SendCommand(&c); - if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) { + if (resp.arg[0] == 0 && resp.arg[1] == 0) { // no cached information available + SendCommand(&c); + 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 { + 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) +{ + UsbCommand c = {CMD_STATUS}; + SendCommand(&c); + 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, " -- 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, " -- 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, " -- 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, " -- 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) diff --git a/client/lualibs/commands.lua b/client/lualibs/commands.lua index 127508e6..64f16e44 100644 --- a/client/lualibs/commands.lua +++ b/client/lualibs/commands.lua @@ -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, diff --git a/include/usb_cmd.h b/include/usb_cmd.h index e45bf35e..f443e970 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -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 From 987dfb66e2982d229f0681f991b04e325613fc5f Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Tue, 21 Jul 2015 23:21:16 +0200 Subject: [PATCH 38/45] changelog docs --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 649b4d04..a8a5662e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,13 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ### 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) - -### Added - 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) ### Changed - 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] From c89274cc60bf433cbf1091d9a6ca0b813ea9b224 Mon Sep 17 00:00:00 2001 From: Craig Young Date: Sat, 25 Jul 2015 14:35:14 -0400 Subject: [PATCH 39/45] Stand Alone Mode changes for NFC (part 2) --- CHANGELOG.md | 6 +- armsrc/appmain.c | 275 ++++++++++++++++++++++++++++----------------- armsrc/iso14443a.c | 1 - armsrc/mifarecmd.c | 8 +- 4 files changed, 185 insertions(+), 105 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 649b4d04..682d87eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,14 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ### 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) - -### Added - 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) ### 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] diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 7aa353b2..b5e7d7ea 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -25,6 +25,7 @@ #include #include "lfsampling.h" #include "BigBuf.h" +#include "mifareutil.h" #ifdef WITH_LCD #include "LCD.h" #endif @@ -297,6 +298,19 @@ void SendVersion(void) uint32_t compressed_data_section_size = common_area.arg1; cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, 0, VersionString, strlen(VersionString)); } +/** + * Prints runtime information about the PM3. +**/ +void SendStatus(void) +{ + BigBuf_print_status(); + Fpga_print_status(); + printConfig(); //LF Sampling config + Dbprintf("Various"); + Dbprintf(" MF_DBGLEVEL......%d", MF_DBGLEVEL); + Dbprintf(" ToSendMax........%d",ToSendMax); + Dbprintf(" ToSendBit........%d",ToSendBit); +} #if defined(WITH_ISO14443a_StandAlone) || defined(WITH_LF) @@ -329,11 +343,14 @@ void StandAloneMode14a() FpgaDownloadAndGo(FPGA_BITSTREAM_HF); int selected = 0; - int playing = 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); @@ -341,24 +358,17 @@ void StandAloneMode14a() { usb_poll(); WDT_HIT(); - - // Was our button held down or pressed? - int button_pressed = BUTTON_HELD(1000); SpinDelay(300); - // Button was held for a second, begin recording - if (button_pressed > 0 && cardRead[selected] == 0) + 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); - - // wait for button to be released - while(BUTTON_PRESS()) - WDT_HIT(); /* need this delay to prevent catching some weird data */ SpinDelay(500); /* Code for reading from 14a tag */ @@ -369,22 +379,54 @@ void StandAloneMode14a() for ( ; ; ) { WDT_HIT(); - if (!iso14443a_select_card(uid, NULL, &cuid)) + 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_1st[selected]; + 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_2nd[selected]; + dst = (uint8_t *)&uid_tmp2; for (int i=0; i<4; i++) dst[i] = uid[7-i]; - break; + 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); @@ -393,101 +435,101 @@ void StandAloneMode14a() LEDsoff(); LED(selected + 1, 0); - // Finished recording - // If we were previously playing, set playing off - // so next button push begins playing what we recorded - playing = 0; + // Next state is replay: + playing = 1; cardRead[selected] = 1; - } - /* MF UID clone */ - else if (button_pressed > 0 && cardRead[selected] == 1) + /* MF Classic UID clone */ + else if (iGotoClone==1) { - LEDsoff(); - LED(selected + 1, 0); - LED(LED_ORANGE, 250); + 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]); + // 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); + // 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. + 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; + 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(0x1F, 1, 0, oldBlock0); - 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) + 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(0x1F, 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 - } - LEDsoff(); - LED(selected + 1, 0); - // Finished recording - - // If we were previously playing, set playing off - // so next button push begins playing what we recorded + 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 (button_pressed && cardRead[selected]) + else if (playing==1) // button_pressed == BUTTON_SINGLE_CLICK && cardRead[selected]) { - // Next option if we were previously playing - if (playing) - selected = (selected + 1) % OPTS; - playing = !playing; - LEDsoff(); LED(selected + 1, 0); @@ -496,19 +538,45 @@ void StandAloneMode14a() { LED(LED_GREEN, 0); DbpString("Playing"); - while (!BUTTON_HELD(500)) { // Loop simulating tag until the button is held a half-sec + 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); - SimulateIso14443aTag(1,uid_1st[selected],uid_2nd[selected],NULL); + 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); + } } - //cardRead[selected] = 1; - Dbprintf("Done playing [Bank: %u]",selected); + 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); - - // when done, we're done playing, move to next option - selected = (selected + 1) % OPTS; - playing = !playing; LEDsoff(); LED(selected + 1, 0); } @@ -1143,7 +1211,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(); diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 5c7367a1..f81a1a99 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1063,7 +1063,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; diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index fd6fde63..a3d6609d 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1143,6 +1143,7 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai // bit 2 - need HALT after sequence // bit 3 - need init FPGA and field before sequence // bit 4 - need reset FPGA and LED + // bit 5 - need to set datain instead of issuing USB reply (called via ARM for StandAloneMode14a) uint8_t workFlags = arg0; uint8_t blockNo = arg2; @@ -1202,7 +1203,12 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai } LED_B_ON(); - cmd_send(CMD_ACK,isOK,0,0,data,18); + if (workFlags & 0x20) { + if (isOK) + memcpy(datain, data, 18); + } + else + cmd_send(CMD_ACK,isOK,0,0,data,18); LED_B_OFF(); if ((workFlags & 0x10) || (!isOK)) { From d976c9ddb2b57ff690cbdca033f5423983f60635 Mon Sep 17 00:00:00 2001 From: Craig Young Date: Sat, 25 Jul 2015 14:38:57 -0400 Subject: [PATCH 40/45] Merging changes from main repo --- armsrc/BigBuf.c | 10 ++++++ armsrc/BigBuf.h | 2 +- armsrc/fpgaloader.c | 8 +++++ armsrc/fpgaloader.h | 1 + armsrc/lfsampling.c | 2 +- armsrc/lfsampling.h | 4 +++ armsrc/mifareutil.h | 1 + client/cmdhw.c | 61 ++++++++++++++++++++++++++++--------- client/lualibs/commands.lua | 3 +- include/usb_cmd.h | 2 ++ 10 files changed, 76 insertions(+), 18 deletions(-) diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index 510f7bef..a938d5c6 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -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) diff --git a/armsrc/BigBuf.h b/armsrc/BigBuf.h index 0e2f1744..05b4180e 100644 --- a/armsrc/BigBuf.h +++ b/armsrc/BigBuf.h @@ -28,7 +28,7 @@ extern void BigBuf_Clear(void); extern uint8_t *BigBuf_malloc(uint16_t); extern void BigBuf_free(void); extern void BigBuf_free_keep_EM(void); - +extern void BigBuf_print_status(void); extern uint16_t BigBuf_get_traceLen(void); extern void clear_trace(); extern void set_tracing(bool enable); diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index 16fed7c5..308dda8c 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -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); +} diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index 0bad3809..52d6c677 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -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); diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 662ebf24..6e783769 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -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); diff --git a/armsrc/lfsampling.h b/armsrc/lfsampling.h index 6c671ec8..7d3925cd 100644 --- a/armsrc/lfsampling.h +++ b/armsrc/lfsampling.h @@ -56,4 +56,8 @@ void LFSetupFPGAForADC(int divisor, bool lf_field); void setSamplingConfig(sample_config *sc); sample_config * getSamplingConfig(); + +void printConfig(); + + #endif // LFSAMPLING_H diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index 85a34ef6..7a09ce64 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -8,6 +8,7 @@ //----------------------------------------------------------------------------- // code for work with mifare cards. //----------------------------------------------------------------------------- +#include "crapto1.h" #ifndef __MIFAREUTIL_H #define __MIFAREUTIL_H diff --git a/client/cmdhw.c b/client/cmdhw.c index 2b6f9518..23b6ce21 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -405,33 +405,64 @@ int CmdTune(const char *Cmd) int CmdVersion(const char *Cmd) { + clearCommandBuffer(); UsbCommand c = {CMD_VERSION}; - UsbCommand resp = {0, {0, 0, 0}}; + static UsbCommand resp = {0, {0, 0, 0}}; - SendCommand(&c); - if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) { + if (resp.arg[0] == 0 && resp.arg[1] == 0) { // no cached information available + SendCommand(&c); + 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 { + 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) +{ + UsbCommand c = {CMD_STATUS}; + SendCommand(&c); + 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, " -- 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, " -- 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, " -- 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, " -- 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) diff --git a/client/lualibs/commands.lua b/client/lualibs/commands.lua index 127508e6..64f16e44 100644 --- a/client/lualibs/commands.lua +++ b/client/lualibs/commands.lua @@ -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, diff --git a/include/usb_cmd.h b/include/usb_cmd.h index e45bf35e..f443e970 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -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 From 73d336ae1dc311e8a8a8d9e893ce4c5ad8c31f49 Mon Sep 17 00:00:00 2001 From: Craig Young Date: Sun, 26 Jul 2015 11:55:50 -0400 Subject: [PATCH 41/45] Adding STL files for 3D printed coil forms --- doc/RFID_Antenna-Basic-Form.stl | Bin 0 -> 3084 bytes doc/RFID_Antenna-With-Lanyard-Hook.stl | Bin 0 -> 8484 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100755 doc/RFID_Antenna-Basic-Form.stl create mode 100755 doc/RFID_Antenna-With-Lanyard-Hook.stl diff --git a/doc/RFID_Antenna-Basic-Form.stl b/doc/RFID_Antenna-Basic-Form.stl new file mode 100755 index 0000000000000000000000000000000000000000..6679ae8b5b72814e032869494007d8b69efecffc GIT binary patch literal 3084 zcmb7_L2eU45Jme8oWL7UR>+E2umCZ@2Be@!gag$PvO-zbBH=_;vSX_xa(+?)G;7cAua9e)skM?*8Y;d7l67{wqE-Ma)CJKeaYZt;Mmm z10HIQe9!r4JuVUNk|tsF6+(VbAdPkc+E&^n;`ga-5Lh`Q)YWssR?dhxj-8{!;-M9e zPHX;U1WBXep_6S0->o$3Q$J3v4UbCX%0fE<9VnbZlB?6yYb^xo_W9LAl!)pYb5029Afw{m+A?UG1fCkY6BT2e*A5KuKtKlI^MD-Az^Qg_}ol*Q5=g#p4e$1jS z9+(utdh&4kWrXM_co`jdL&(Ec`tIrH#N%>SmB7jwp{_s&9nvG#-IB1ZMd#^?!06{A z?Q{~Tt*$&vdvaoQ)w4k{Nc8voJ*Y{j5~{?y2NC+!L^}Zuq6bFS^DK5%J(55+Lj*lo z*9qHGAaj2G{nZ;}Fs!aL$LmD(Z~{75ctpP;(t}yr(*+{ViF#I|a~|1#`|zgb3Gm*P zJ{;E@eB8U0n5Jz4G&~d}S+9D~kMmh6kk1DpqI#&qm0(R#^57`#9+(Rx7lO66h_Q1x zbPtk#KJwsb|8_C5@!h>_W$8+O=}iLBI~#J*?(yxkR-%aFiV>6M#po)&xhFz5s<<65$@$4)QqeYlz0##s)y*6pc2*5^5q^Qvl9K?C?}vJ zmoPHZ&&Qy;^Q1&n50N>q?EFpKLt0%W=|t*WSvqtg_km1xa)Yy{*1t@j&$~V6<)IVK Kn|h1j-Tn{btXe<- literal 0 HcmV?d00001 diff --git a/doc/RFID_Antenna-With-Lanyard-Hook.stl b/doc/RFID_Antenna-With-Lanyard-Hook.stl new file mode 100755 index 0000000000000000000000000000000000000000..62f5397a8391cd0a0e2ae5c176d19bc13c44083b GIT binary patch literal 8484 zcmb7J&#Ps{5pE(AXBQ9>&=E5T83zI~41zzvxi7jgL=n_%vdBt87XAxD$$%&*hzn7Y z#hdt?8R3Qe2Xn{kk3b>>gph3(3hpG^Y?AM*s;|5Hoco^Iy!%eyuKMb$s;=&HPT%KW zc>0O+zj*$c^OrAQdhk;IUAlDs$!DK__PNKm+wK3(f3J44wRZF7nOnHDU;pFfO>1v_ z)SBUXeHVR7uJ6A7@--j-=T{%>npMOkadbtr7Kk5z^RaXM_UcQp{i@r#_q`9&Zff~> zYaDO(w||}6($YhB|7!E;)vJ#9(N7^MS~1?5j~g_%um9zX2Y}qX{fAc~4m;Xatr&+{ zj5mWf&H?YP{Q39hh|fNIe^<3)yfuzDLyjDQ3|xVc;ArpfCM_SQ?+e5&aXj|upAZMp zp(V7ByH|hw>$w}u*@)v>=b+Z`@EW{gUwY2kQ!-3z6j|!Zt+A9JQ|G z6)R3!UVRzgx~>$tOEM1jmBUe2^pJH`CCVtZ#yqL6KL5?R2Uu5CGG^^4XVW(8x>A); zqRMcsQg6KyGs~kA*L7u^QCA4VXHp!Lh-1_h*1xH){(JuyH&|CAj%$1B$~IG7c||H$ zlqgrDu52^vieAN99F@4PtC;_0&}K9IZCd*QDv)j7uVOs+F@u;NG$B$__N!5$u*9rl zefyq>+9d}OtakAo?%sIw4j=E;-Vu{zh0yw7b&w+>KjXHTlR&3d<9KV4D^?)CalPMn z<%f=lj1H|BZ!PA7yC?RNi=4rSFW>11&TZ9-ahUZvhd0i_mG$A@1HsCuS~1>Q)K%O! zbRRhz9N7CNt;TV-+!LLHSr$iB_|OtM)(5?Mv3^LzW)Y5FmeX!IOI8;~HXRTf_i%Q&sunq0b z9L1}xykd;uv)W4u57~U7=ELvRXzQM|*ti6$T06#?dn(r*`)te=`o=CkXhNi9LJ(aL zt{w>0F89Q7r>^^>?2BXUoHL?60Z?~%^ayMp9N_zH?7jG~&nv&@xHWHzp&}kiG!X@T z3PR|2fh_2XK)*=ZKEykb-Ij3_1SAteUab*DG9m1CL=F#Om(3%$DJMNz@_j!9c?&n~ zmU^nus!#juzje@Bc(p{Nq{mSa=z~LzNJC6RL9WWj zJ}u#D_`g7;WG^BjZ)}MqJL9Mv?8~d*=pKQqNIHkm!z(a^XYAnFnG#+vf=~To$sk4Z zSa`kNBb?CR4I%Wq;40jPZ)oBulFnBVZ;jezhS@R>NG6250@_@!&xxWXqGauB53O*L`3e^6It^k4qnUM4w^j=wANXbBB%HhHD~ah?b(@>u6_isOJlH0>YpPCn4nNwHxZALp15WAEae zvt>+%-qr{FAG6D*Xye;5@+G3?XNkafOOJ3psgaK@Jl}^%NvPp}MWAmfz?GVcBS-s1 z)q??O3MIsnL$Dkt0xhDC>eE?hJwYhkM)gGC%4*LO)8b*Q51orrLmU+`^PRxa^y@;yRYeRB`5aWx&}Libsv;D5f4%s(=W3F4uZU1x6~u<)6^H O3=Fu$Cdpm|koJEJ#e`%4 literal 0 HcmV?d00001 From bfb01844fb0ce48e960374c3bc6ecf208b6c6bb0 Mon Sep 17 00:00:00 2001 From: pwpiwi Date: Wed, 29 Jul 2015 18:52:43 +0200 Subject: [PATCH 42/45] add: USB Speed Test to hw status fix: choose Real Time Clock divider based on actual slow clock frequency --- armsrc/appmain.c | 34 ++++++++++++++++++++++++++++++++-- armsrc/util.c | 11 ++++++----- client/cmdhw.c | 12 +++++++++++- client/cmdmain.c | 21 ++++++++++----------- 4 files changed, 59 insertions(+), 19 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index b5e7d7ea..99776a98 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -298,18 +298,48 @@ void SendVersion(void) uint32_t compressed_data_section_size = common_area.arg1; cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, 0, VersionString, strlen(VersionString)); } + +// measure the USB Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time. +// Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the UsbCommand structure included. +void printUSBSpeed(uint32_t SpeedTestBufferSize) +{ + Dbprintf("USB Speed:"); + Dbprintf(" Sending %d bytes payload...", SpeedTestBufferSize); + + uint8_t *test_data = BigBuf_get_addr(); + + uint32_t start_time = GetTickCount(); + + LED_B_ON(); + for(size_t i=0; i Client = %d Bytes/s", + end_time - start_time, + 1000* SpeedTestBufferSize / (end_time - start_time)); + +} + /** * Prints runtime information about the PM3. **/ -void SendStatus(void) +void SendStatus(uint32_t SpeedTestBufferSize) { BigBuf_print_status(); Fpga_print_status(); printConfig(); //LF Sampling config + printUSBSpeed(SpeedTestBufferSize); 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) @@ -1212,7 +1242,7 @@ void UsbPacketReceived(uint8_t *packet, int len) SendVersion(); break; case CMD_STATUS: - SendStatus(); + SendStatus(c->arg[0]); break; case CMD_PING: cmd_send(CMD_ACK,0,0,0,0,0); diff --git a/armsrc/util.c b/armsrc/util.c index 8576ddce..1dd8dc75 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -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% } /* diff --git a/client/cmdhw.c b/client/cmdhw.c index 23b6ce21..44f878af 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -18,6 +18,7 @@ #include "cmdhw.h" #include "cmdmain.h" #include "cmddata.h" +#include "data.h" /* low-level hardware control */ @@ -428,11 +429,20 @@ int CmdVersion(const char *Cmd) int CmdStatus(const char *Cmd) { - UsbCommand c = {CMD_STATUS}; + uint8_t speed_test_buffer[USB_CMD_DATA_SIZE]; + sample_buf = speed_test_buffer; + #define USB_SPEED_TEST_SIZE (1000*USB_CMD_DATA_SIZE) + + clearCommandBuffer(); + UsbCommand c = {CMD_STATUS, {USB_SPEED_TEST_SIZE}}; SendCommand(&c); + if (!WaitForResponseTimeout(CMD_ACK,&c,1500)) { + PrintAndLog("Status command failed. USB Speed Test timed out"); + } return 0; } + int CmdPing(const char *Cmd) { clearCommandBuffer(); diff --git a/client/cmdmain.c b/client/cmdmain.c index 512aa13c..9298360d 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -131,24 +131,23 @@ int getCommand(UsbCommand* response) */ bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout) { - UsbCommand resp; + UsbCommand resp; if (response == NULL) - response = &resp; + response = &resp; - // Wait until the command is received - for(size_t dm_seconds=0; dm_seconds < ms_timeout/10; dm_seconds++) { - + // 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; - } - } + 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"); + PrintAndLog("Waiting for a response from the proxmark..."); + PrintAndLog("Don't forget to cancel its operation first by pressing on the button"); } } return false; From 67b7d6fa31f4426f18d223faa06c7b1f3c59fa97 Mon Sep 17 00:00:00 2001 From: pwpiwi Date: Fri, 31 Jul 2015 20:05:30 +0200 Subject: [PATCH 43/45] fix: avoid USB Speed Test timeout in case of slow transfer speeds fix: don't add CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K commands into command buffer --- armsrc/appmain.c | 33 ++++++++++++++++++--------------- client/cmdhw.c | 5 ++--- client/cmdmain.c | 23 ++++++++++++++--------- 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 99776a98..38afd85d 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -301,39 +301,42 @@ void SendVersion(void) // 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(uint32_t SpeedTestBufferSize) +void printUSBSpeed(void) { Dbprintf("USB Speed:"); - Dbprintf(" Sending %d bytes payload...", SpeedTestBufferSize); + Dbprintf(" Sending USB packets to client..."); + #define USB_SPEED_TEST_MIN_TIME 1500 // in milliseconds uint8_t *test_data = BigBuf_get_addr(); + uint32_t end_time; - uint32_t start_time = GetTickCount(); - + uint32_t start_time = end_time = GetTickCount(); + uint32_t bytes_transferred = 0; + LED_B_ON(); - for(size_t i=0; i Client = %d Bytes/s", - end_time - start_time, - 1000* SpeedTestBufferSize / (end_time - start_time)); + 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(uint32_t SpeedTestBufferSize) +void SendStatus(void) { BigBuf_print_status(); Fpga_print_status(); printConfig(); //LF Sampling config - printUSBSpeed(SpeedTestBufferSize); + printUSBSpeed(); Dbprintf("Various"); Dbprintf(" MF_DBGLEVEL......%d", MF_DBGLEVEL); Dbprintf(" ToSendMax........%d",ToSendMax); @@ -1242,7 +1245,7 @@ void UsbPacketReceived(uint8_t *packet, int len) SendVersion(); break; case CMD_STATUS: - SendStatus(c->arg[0]); + SendStatus(); break; case CMD_PING: cmd_send(CMD_ACK,0,0,0,0,0); diff --git a/client/cmdhw.c b/client/cmdhw.c index 44f878af..33dc78ae 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -431,12 +431,11 @@ int CmdStatus(const char *Cmd) { uint8_t speed_test_buffer[USB_CMD_DATA_SIZE]; sample_buf = speed_test_buffer; - #define USB_SPEED_TEST_SIZE (1000*USB_CMD_DATA_SIZE) clearCommandBuffer(); - UsbCommand c = {CMD_STATUS, {USB_SPEED_TEST_SIZE}}; + UsbCommand c = {CMD_STATUS}; SendCommand(&c); - if (!WaitForResponseTimeout(CMD_ACK,&c,1500)) { + if (!WaitForResponseTimeout(CMD_ACK,&c,1900)) { PrintAndLog("Status command failed. USB Speed Test timed out"); } return 0; diff --git a/client/cmdmain.c b/client/cmdmain.c index 9298360d..deced558 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -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. @@ -133,9 +134,9 @@ bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeou UsbCommand resp; - if (response == NULL) + if (response == NULL) { response = &resp; - + } // Wait until the command is received for(size_t dm_seconds=0; dm_seconds < ms_timeout/10; dm_seconds++) { @@ -144,19 +145,21 @@ bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeou return true; } } - msleep(10); // XXX ugh - if (dm_seconds == 200) { // Two seconds elapsed + 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. @@ -165,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. @@ -188,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); } From f68211671cf3230b3ddbe948f3802418ee03d378 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Fri, 31 Jul 2015 23:27:09 +0200 Subject: [PATCH 44/45] Implemented `data hex2bin` and `data bin2hex` as per suggestion in http://www.proxmark.org/forum/viewtopic.php?pid=17504 --- CHANGELOG.md | 1 + client/cmddata.c | 115 ++++++++++++++++++++++++++++++++++++++++------- client/util.h | 1 + 3 files changed, 102 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 682d87eb..e2196a39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - 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) diff --git a/client/cmddata.c b/client/cmddata.c index cb1c7cd4..0907f3c5 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -24,6 +24,7 @@ #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=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 "); + 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 "); + 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"}, @@ -2287,6 +2369,9 @@ static command_t CommandTable[] = {"getbitstream", CmdGetBitStream, 1, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"}, {"grid", CmdGrid, 1, " -- overlay grid on graph window, use zero value to turn off either"}, {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, + {"bin2hex", Cmdbin2hex, 1, "bin2hex -- Converts binary to hexadecimal"}, + {"hex2bin", Cmdhex2bin, 1, "hex2bin -- Converts hexadecimal to binary"}, + {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, {"hide", CmdHide, 1, "Hide graph window"}, {"hpf", CmdHpf, 1, "Remove DC offset from trace"}, {"load", CmdLoad, 1, " -- Load trace (to graph window"}, diff --git a/client/util.h b/client/util.h index 2d2beaf4..94021c2c 100644 --- a/client/util.h +++ b/client/util.h @@ -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); From 5d01f50ae1be5c7de81cc089d60d3bdbf80dc738 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Fri, 31 Jul 2015 23:30:48 +0200 Subject: [PATCH 45/45] Minor corrections --- client/cmddata.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 0907f3c5..22da1805 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -2355,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 -- 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"}, @@ -2369,9 +2370,7 @@ static command_t CommandTable[] = {"getbitstream", CmdGetBitStream, 1, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"}, {"grid", CmdGrid, 1, " -- overlay grid on graph window, use zero value to turn off either"}, {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, - {"bin2hex", Cmdbin2hex, 1, "bin2hex -- Converts binary to hexadecimal"}, {"hex2bin", Cmdhex2bin, 1, "hex2bin -- Converts hexadecimal to binary"}, - {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, {"hide", CmdHide, 1, "Hide graph window"}, {"hpf", CmdHpf, 1, "Remove DC offset from trace"}, {"load", CmdLoad, 1, " -- Load trace (to graph window"},