From a39944216dd5d765e16917c1092bacc6061b518f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Sep 2016 12:23:09 +0200 Subject: [PATCH 01/16] CHG: a select_legic function with structs and stuff and --- armsrc/legicrf.c | 117 +++++++++++++++++++++----------------------- armsrc/legicrf.h | 5 +- client/cmdhflegic.c | 51 ++++++++++--------- client/cmdhflegic.h | 1 + common/crc.c | 20 +++++--- common/protocols.c | 5 +- include/legic.h | 26 ++++++++++ 7 files changed, 131 insertions(+), 94 deletions(-) create mode 100644 include/legic.h diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index d2e2e856..ca56b235 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -10,7 +10,7 @@ #include "legicrf.h" static struct legic_frame { - int bits; + uint8_t bits; uint32_t data; } current_frame; @@ -426,7 +426,7 @@ static uint32_t legic4Crc(uint8_t legicCmd, uint16_t byte_index, uint8_t value, int legic_read_byte(int byte_index, int cmd_sz) { - uint8_t byte = 0, crc = 0, calcCrc = 0; + uint8_t byte = 0; //, crc = 0, calcCrc = 0; uint32_t cmd = (byte_index << 1) | LEGIC_READ; // (us)| ticks @@ -440,13 +440,13 @@ int legic_read_byte(int byte_index, int cmd_sz) { byte = BYTEx(current_frame.data, 0); - calcCrc = legic4Crc(LEGIC_READ, byte_index, byte, cmd_sz); - crc = BYTEx(current_frame.data, 1); + // calcCrc = legic4Crc(LEGIC_READ, byte_index, byte, cmd_sz); + // crc = BYTEx(current_frame.data, 1); - if( calcCrc != crc ) { - Dbprintf("!!! crc mismatch: expected %x but got %x !!!", calcCrc, crc); - return -1; - } + // if( calcCrc != crc ) { + // Dbprintf("!!! crc mismatch: expected %x but got %x !!!", calcCrc, crc); + // return -1; + // } legic_prng_forward(4); WaitTicks(40); @@ -526,56 +526,37 @@ int legic_write_byte(uint8_t byte, uint16_t addr, uint8_t addr_sz) { int LegicRfReader(int offset, int bytes, int iv) { uint16_t byte_index = 0; - uint8_t cmd_sz = 0, isOK = 1; - int card_sz = 0; - + uint8_t isOK = 1; + legic_card_select_t card; + LegicCommonInit(); - - uint32_t tag_type = setup_phase_reader(iv); + if ( legic_select_card(&card) ) { + isOK = 0; + goto OUT; + } + switch_off_tag_rwd(); - switch(tag_type) { - case 0x0d: - if ( MF_DBGLEVEL >= 2) DbpString("MIM22 card found, reading card"); - cmd_sz = 6; - card_sz = 22; - break; - case 0x1d: - if ( MF_DBGLEVEL >= 2) DbpString("MIM256 card found, reading card"); - cmd_sz = 9; - card_sz = 256; - break; - case 0x3d: - if ( MF_DBGLEVEL >= 2) DbpString("MIM1024 card found, reading card"); - cmd_sz = 11; - card_sz = 1024; - break; - default: - if ( MF_DBGLEVEL >= 1) Dbprintf("Unknown card format: %x", tag_type); - isOK = 0; - goto OUT; - break; - } if (bytes == -1) - bytes = card_sz; + bytes = card.cardsize; - if (bytes + offset >= card_sz) - bytes = card_sz - offset; + if (bytes + offset >= card.cardsize) + bytes = card.cardsize - offset; // Start setup and read bytes. setup_phase_reader(iv); LED_B_ON(); while (byte_index < bytes) { - int r = legic_read_byte(byte_index + offset, cmd_sz); + int r = legic_read_byte(byte_index + offset, card.cmdsize); if (r == -1 || BUTTON_PRESS()) { if ( MF_DBGLEVEL >= 3) DbpString("operation aborted"); isOK = 0; goto OUT; } - cardmem[++byte_index] = r; + cardmem[byte_index++] = r; WDT_HIT(); } @@ -765,47 +746,61 @@ void LegicRfRawWriter(int address, int byte, int iv) { if ( MF_DBGLEVEL >= 1) DbpString("write successful"); } -void LegicRfInfo(void){ +int legic_select_card(legic_card_select_t *p_card){ - LegicCommonInit(); - uint32_t tag_type = setup_phase_reader(0x1); - uint8_t cmd_sz = 0; - uint16_t card_sz = 0; + if ( p_card == NULL ) return 1; - switch(tag_type) { + p_card->tagtype = setup_phase_reader(0x1); + + switch(p_card->tagtype) { case 0x0d: - cmd_sz = 6; - card_sz = 22; + p_card->cmdsize = 6; + p_card->cardsize = 22; break; case 0x1d: - cmd_sz = 9; - card_sz = 256; + p_card->cmdsize = 9; + p_card->cardsize = 256; break; case 0x3d: - cmd_sz = 11; - card_sz = 1024; + p_card->cmdsize = 11; + p_card->cardsize = 1024; break; default: - cmd_send(CMD_ACK,0,0,0,0,0); - goto OUT; + p_card->cmdsize = 0; + p_card->cardsize = 0; + return 2; + break; + } + return 0; +} + +void LegicRfInfo(void){ + + uint8_t buf[sizeof(legic_card_select_t)] = {0x00}; + legic_card_select_t *card = (legic_card_select_t*) buf; + + LegicCommonInit(); + + if ( legic_select_card(card) ) { + cmd_send(CMD_ACK,0,0,0,0,0); + goto OUT; } // read UID bytes. - uint8_t uid[] = {0,0,0,0}; - for ( uint8_t i = 0; i < sizeof(uid); ++i) { - int r = legic_read_byte(i, cmd_sz); + for ( uint8_t i = 0; i < sizeof(card->uid); ++i) { + int r = legic_read_byte(i, card->cmdsize); if ( r == -1 ) { cmd_send(CMD_ACK,0,0,0,0,0); goto OUT; } - uid[i] = r & 0xFF; + card->uid[i] = r & 0xFF; } - cmd_send(CMD_ACK,1,card_sz,0,uid,sizeof(uid)); -OUT: + cmd_send(CMD_ACK, 1 ,0 , 0, buf, sizeof(legic_card_select_t)); + +OUT: switch_off_tag_rwd(); LEDsoff(); - } /* Handle (whether to respond) a frame in tag mode diff --git a/armsrc/legicrf.h b/armsrc/legicrf.h index 99287842..f885ef19 100644 --- a/armsrc/legicrf.h +++ b/armsrc/legicrf.h @@ -1,4 +1,4 @@ -//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- // (c) 2009 Henryk Plötz // // This code is licensed to you under the terms of the GNU GPL, version 2 or, @@ -18,6 +18,7 @@ #include "legic_prng.h" // legic PRNG impl #include "crc.h" // legic crc-4 #include "ticks.h" // timers +#include "legic.h" // legic_card_select_t struct extern void LegicRfSimulate(int phase, int frame, int reqresp); extern int LegicRfReader(int offset, int bytes, int iv); @@ -29,7 +30,7 @@ uint32_t get_key_stream(int skip, int count); void frame_send_tag(uint16_t response, uint8_t bits, uint8_t crypt); void frame_sendAsReader(uint32_t data, uint8_t bits); -int ice_legic_select_card(); +int legic_select_card(legic_card_select_t *p_card); void ice_legic_setup(); #endif /* __LEGICRF_H */ diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 5bc24e9b..f4d0827f 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -11,7 +11,6 @@ static int CmdHelp(const char *Cmd); -#define SESSION_IV 0x55 #define MAX_LENGTH 1024 int usage_legic_calccrc8(void){ @@ -400,16 +399,21 @@ int CmdLegicRFRead(const char *Cmd) { sscanf(Cmd, "%x %x %x", &offset, &len, &IV); // OUT-OF-BOUNDS check - if(len + offset > MAX_LENGTH) len = MAX_LENGTH - offset; + if ( len + offset > MAX_LENGTH ) { + len = MAX_LENGTH - offset; + PrintAndLog("Out-of-bound, shorten len to %d",len); + } if ( (IV & 0x7F) != IV ){ IV &= 0x7F; PrintAndLog("Truncating IV to 7bits"); } + if ( (IV & 1) == 0 ){ - IV |= 0x01; // IV must be odd + IV |= 0x01; PrintAndLog("LSB of IV must be SET"); } + PrintAndLog("Using IV: 0x%02x", IV); UsbCommand c = {CMD_READER_LEGIC_RF, {offset, len, IV}}; @@ -818,28 +822,31 @@ int HFLegicInfo(const char *Cmd, bool verbose) { clearCommandBuffer(); SendCommand(&c); UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { - uint8_t isOK = resp.arg[0] & 0xFF; - uint16_t tagtype = resp.arg[1] & 0xFFF; - if ( isOK ) { - PrintAndLog(" UID : %s", sprint_hex(resp.d.asBytes, 4)); - switch(tagtype) { - case 22: PrintAndLog("MIM22 card (22bytes)"); break; - case 256: PrintAndLog("MIM256 card (256bytes)"); break; - case 1024: PrintAndLog("MIM1024 card (1024bytes)"); break; - default: { - PrintAndLog("Unknown card format: %x", tagtype); - return 1; - } - } - } else { - if ( verbose ) PrintAndLog("legic card select failed"); - return 1; - } - } else { + if (!WaitForResponseTimeout(CMD_ACK, &resp, 500)) { if ( verbose ) PrintAndLog("command execution time out"); return 1; } + + uint8_t isOK = resp.arg[0] & 0xFF; + if ( !isOK ) { + if ( verbose ) PrintAndLog("legic card select failed"); + return 1; + } + + legic_card_select_t card; + memcpy(&card, (legic_card_select_t *)resp.d.asBytes, sizeof(legic_card_select_t)); + + PrintAndLog(" UID : %s", sprint_hex(card.uid, sizeof(card.uid))); + switch(card.cardsize) { + case 22: + case 256: + case 1024: + PrintAndLog(" TYPE : MIM%d card (%d bytes)", card.cardsize, card.cardsize); break; + default: { + PrintAndLog("Unknown card format: %d", card.cardsize); + return 1; + } + } return 0; } int CmdLegicInfo(const char *Cmd){ diff --git a/client/cmdhflegic.h b/client/cmdhflegic.h index b43c47fe..78527f23 100644 --- a/client/cmdhflegic.h +++ b/client/cmdhflegic.h @@ -21,6 +21,7 @@ #include "util.h" #include "crc.h" #include "legic_prng.h" +#include "legic.h" // legic_card_select_t struct int CmdHFLegic(const char *Cmd); diff --git a/common/crc.c b/common/crc.c index 2f11f5f4..540ae668 100644 --- a/common/crc.c +++ b/common/crc.c @@ -29,6 +29,7 @@ void crc_init(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, u } void crc_clear(crc_t *crc) { + crc->state = crc->initial_value & crc->mask; if (crc->refin) crc->state = reflect(crc->state, crc->order); @@ -36,26 +37,33 @@ void crc_clear(crc_t *crc) { void crc_update(crc_t *crc, uint32_t indata, int data_width){ + uint32_t poly = crc->polynom; + + // if requested, return the initial CRC */ + if (indata == 0) + return crc->initial_value; + //reflected - if (crc->refin) indata = reflect(indata, data_width); + if (crc->refin) + indata = reflect(indata, data_width); // Bring the next byte into the remainder. crc->state ^= indata << (crc->order - data_width); - for( uint8_t bit = data_width; bit > 0; --bit) { - - + for( uint8_t bit = data_width; bit > 0; --bit) { // Try to divide the current data bit. if (crc->state & crc->topbit) - crc->state = (crc->state << 1) ^ crc->polynom; + crc->state = (crc->state << 1) ^ poly; else crc->state = (crc->state << 1); } + return crc ^ model->xorout; } void crc_update2(crc_t *crc, uint32_t data, int data_width) { - if (crc->refin) data = reflect(data, data_width); + if (crc->refin) + data = reflect(data, data_width); int i; for(i=0; i Date: Thu, 29 Sep 2016 12:23:35 +0200 Subject: [PATCH 02/16] ADD: @zhovner 's mfd file parser https://github.com/zhovner/mfdread Looks really nice the parsed fileoutput. --- client/pm3_mfdread.py | 160 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 client/pm3_mfdread.py diff --git a/client/pm3_mfdread.py b/client/pm3_mfdread.py new file mode 100644 index 00000000..9958adf8 --- /dev/null +++ b/client/pm3_mfdread.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# mfdread.py - Mifare dumps parser in human readable format +# Pavel Zhovner +# https://github.com/zhovner/mfdread + + + +import codecs +import sys +from struct import unpack +from datetime import datetime +from bitstring import BitArray + + +if len(sys.argv) == 1: + print(''' +------------------ +Usage: mfdread.py ./dump.mfd +Mifare dumps reader. + +''') + sys.exit(); + + + + +class bashcolors: + BLUE = '\033[34m' + RED = '\033[91m' + GREEN = '\033[32m' + WARNING = '\033[93m' + ENDC = '\033[0m' + + +def accbits_for_blocknum(accbits_str, blocknum): + ''' + Decodes the access bit string for block "blocknum". + Returns the three access bits for the block or False if the + inverted bits do not match the access bits. + ''' + bits = BitArray([0]) + inverted = BitArray([0]) + # Block 0 access bits + if blocknum == 0: + bits = BitArray([accbits_str[11], accbits_str[23], accbits_str[19]]) + inverted = BitArray([accbits_str[7], accbits_str[3], accbits_str[15]]) + + # Block 0 access bits + elif blocknum == 1: + bits = BitArray([accbits_str[10], accbits_str[22], accbits_str[18]]) + inverted = BitArray([accbits_str[6], accbits_str[2], accbits_str[14]]) + # Block 0 access bits + elif blocknum == 2: + bits = BitArray([accbits_str[9], accbits_str[21], accbits_str[17]]) + inverted = BitArray([accbits_str[5], accbits_str[1], accbits_str[13]]) + # Sector trailer / Block 3 access bits + elif blocknum == 3: + bits = BitArray([accbits_str[8], accbits_str[20], accbits_str[16]]) + inverted = BitArray([accbits_str[4], accbits_str[0], accbits_str[12]]) + + # Check the decoded bits + inverted.invert() + if bits.bin == inverted.bin: + return bits + else: + return False + + + + +def accbit_info(accbits): + ''' + Returns a dictionary of a access bits for all three blocks in a sector. + If the access bits for block could not be decoded properly, the value is set to False. + ''' + decAccbits = {} + # Decode access bits for all 4 blocks of the sector + for i in range(0, 4): + decAccbits[i] = accbits_for_blocknum(accbits, i) + return decAccbits + + + + + +def print_info(data): + + blocksmatrix = [] + blockrights = {} + + # determine what dump we get 1k or 4k + if len(data) == 4096: + cardsize = 64 + elif len(data) == 1024: + cardsize = 16 + else: + print("Wrong file size: %d bytes.\nOnly 1024 or 4096 allowed." % len(data)) + sys.exit(); + + # read all sectors + for i in range(0, cardsize): + start = i * 64 + end = (i + 1) * 64 + sector = data[start:end] + sector = codecs.encode(sector, 'hex') + if not type(sector) is str: + sector = str(sector, 'ascii') + blocksmatrix.append([sector[x:x+32] for x in range(0, len(sector), 32)]) + + # add colors for each keyA, access bits, KeyB + for c in range(0, len(blocksmatrix)): + # Fill in the access bits + blockrights[c] = accbit_info(BitArray('0x'+blocksmatrix[c][3][12:20])) + # Prepare colored output of the sector trailor + keyA = bashcolors.RED + blocksmatrix[c][3][0:12] + bashcolors.ENDC + accbits = bashcolors.GREEN + blocksmatrix[c][3][12:20] + bashcolors.ENDC + keyB = bashcolors.BLUE + blocksmatrix[c][3][20:32] + bashcolors.ENDC + blocksmatrix[c][3] = keyA + accbits + keyB + + + print("File size: %d bytes. Expected %d sectors" %(len(data),cardsize)) + print("\n\tUID: " + blocksmatrix[0][0][0:8]) + print("\tBCC: " + blocksmatrix[0][0][8:10]) + print("\tSAK: " + blocksmatrix[0][0][10:12]) + print("\tATQA: " + blocksmatrix[0][0][12:14]) + print(" %sKey A%s %sAccess Bits%s %sKey B%s" %(bashcolors.RED,bashcolors.ENDC,bashcolors.GREEN,bashcolors.ENDC,bashcolors.BLUE,bashcolors.ENDC)) + print("╔═════════╦═════╦══════════════════════════════════╦═══════════════╗") + print("║ Sector ║Block║ Data ║ Access Bits ║") + for q in range(0, len(blocksmatrix)): + print("╠═════════╬═════╬══════════════════════════════════╬═══════════════╣") + + # z is the block in each sector + for z in range(0, len(blocksmatrix[q])): + # Format the access bits. Print ERR in case of an error + accbits = "" + if isinstance(blockrights[q][z], BitArray): + accbits = bashcolors.GREEN + blockrights[q][z].bin + bashcolors.ENDC + else: + accbits = bashcolors.WARNING + "ERR" + bashcolors.ENDC + + # Add Padding after the sector number + padLen = max(1, 5 - len(str(q))) + padding = " " * padLen + # Only print the sector number in the second third row + if (z == 2): + print("║ %d%s║ %d ║ %s ║ %s ║" %(q,padding,z,blocksmatrix[q][z], accbits)) + else: + print("║ ║ %d ║ %s ║ %s ║" %(z,blocksmatrix[q][z], accbits)) + print("╚═════════╩═════╩══════════════════════════════════╩═══════════════╝") + + +def main(filename): + with open(filename, "rb") as f: + data = f.read() + print_info(data) + +if __name__ == "__main__": + main(sys.argv[1]) -- 2.39.5 From b7e8338d2b15b636017118e983c849f3de6784ae Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Sep 2016 12:29:42 +0200 Subject: [PATCH 03/16] FIX: forgot I removed some other stuff --- common/crc.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/common/crc.c b/common/crc.c index 540ae668..f8179008 100644 --- a/common/crc.c +++ b/common/crc.c @@ -35,29 +35,21 @@ void crc_clear(crc_t *crc) { crc->state = reflect(crc->state, crc->order); } -void crc_update(crc_t *crc, uint32_t indata, int data_width){ - - uint32_t poly = crc->polynom; - - // if requested, return the initial CRC */ - if (indata == 0) - return crc->initial_value; - - //reflected +void crc_update(crc_t *crc, uint32_t data, int data_width){ + if (crc->refin) - indata = reflect(indata, data_width); + data = reflect(data, data_width); // Bring the next byte into the remainder. - crc->state ^= indata << (crc->order - data_width); + crc->state ^= data << (crc->order - data_width); for( uint8_t bit = data_width; bit > 0; --bit) { - // Try to divide the current data bit. + if (crc->state & crc->topbit) - crc->state = (crc->state << 1) ^ poly; + crc->state = (crc->state << 1) ^ crc->polynom; else crc->state = (crc->state << 1); } - return crc ^ model->xorout; } void crc_update2(crc_t *crc, uint32_t data, int data_width) -- 2.39.5 From ce1cccd697034c4eb18223ad9895f84ac1161354 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Sep 2016 14:18:21 +0200 Subject: [PATCH 04/16] UPD: got the latest updates (@badboy) from @zhovner mfdread. --- client/pm3_mfdread.py | 84 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 10 deletions(-) diff --git a/client/pm3_mfdread.py b/client/pm3_mfdread.py index 9958adf8..0d2883e7 100644 --- a/client/pm3_mfdread.py +++ b/client/pm3_mfdread.py @@ -9,21 +9,28 @@ import codecs import sys +import copy from struct import unpack from datetime import datetime from bitstring import BitArray +class Options: + FORCE_1K = False if len(sys.argv) == 1: print(''' ------------------ Usage: mfdread.py ./dump.mfd Mifare dumps reader. - ''') sys.exit(); - +def d(bytes): + decoded = codecs.decode(bytes, "hex") + try: + return str(decoded, "utf-8").rstrip('\0') + except: + return "" class bashcolors: @@ -68,6 +75,37 @@ def accbits_for_blocknum(accbits_str, blocknum): return False +def accbits_to_permission_sector(accbits): + permissions = { + '000': "- A | A - | A A [read B]", + '010': "- - | A - | A - [read B]", + '100': "- B | A/B - | - B", + '110': "- - | A/B - | - -", + '001': "- A | A A | A A [transport]", + '011': "- B | A/B B | - B", + '101': "- - | A/B B | - -", + '111': "- - | A/B - | - -", + } + if isinstance(accbits, BitArray): + return permissions.get(accbits.bin, "unknown") + else: + return "" + +def accbits_to_permission_data(accbits): + permissions = { + '000': "A/B | A/B | A/B | A/B [transport]", + '010': "A/B | - | - | - [r/w]", + '100': "A/B | B | - | - [r/w]", + '110': "A/B | B | B | A/B [value]", + '001': "A/B | - | - | A/B [value]", + '011': " B | B | - | - [r/w]", + '101': " B | - | - | - [r/w]", + '111': " - | - | - | - [r/w]", + } + if isinstance(accbits, BitArray): + return permissions.get(accbits.bin, "unknown") + else: + return "" def accbit_info(accbits): @@ -99,6 +137,9 @@ def print_info(data): print("Wrong file size: %d bytes.\nOnly 1024 or 4096 allowed." % len(data)) sys.exit(); + if Options.FORCE_1K: + cardsize = 16 + # read all sectors for i in range(0, cardsize): start = i * 64 @@ -109,6 +150,7 @@ def print_info(data): sector = str(sector, 'ascii') blocksmatrix.append([sector[x:x+32] for x in range(0, len(sector), 32)]) + blocksmatrix_clear = copy.deepcopy(blocksmatrix) # add colors for each keyA, access bits, KeyB for c in range(0, len(blocksmatrix)): # Fill in the access bits @@ -126,10 +168,12 @@ def print_info(data): print("\tSAK: " + blocksmatrix[0][0][10:12]) print("\tATQA: " + blocksmatrix[0][0][12:14]) print(" %sKey A%s %sAccess Bits%s %sKey B%s" %(bashcolors.RED,bashcolors.ENDC,bashcolors.GREEN,bashcolors.ENDC,bashcolors.BLUE,bashcolors.ENDC)) - print("╔═════════╦═════╦══════════════════════════════════╦═══════════════╗") - print("║ Sector ║Block║ Data ║ Access Bits ║") + print("╔═════════╦═════╦══════════════════════════════════╦════════╦═════════════════════════════════════╗") + print("║ Sector ║Block║ Data ║ Access ║ A | Acc. | B ║") + print("║ ║ ║ ║ ║ r w | r w | r w [info] ║") + print("║ ║ ║ ║ ║ r | w | i | d/t/r ║") for q in range(0, len(blocksmatrix)): - print("╠═════════╬═════╬══════════════════════════════════╬═══════════════╣") + print("╠═════════╬═════╬══════════════════════════════════╬════════╬═════════════════════════════════════╣") # z is the block in each sector for z in range(0, len(blocksmatrix[q])): @@ -140,21 +184,41 @@ def print_info(data): else: accbits = bashcolors.WARNING + "ERR" + bashcolors.ENDC + if (q == 0 and z == 0): + permissions = "-" + elif (z == 3): + permissions = accbits_to_permission_sector(blockrights[q][z]) + else: + permissions = accbits_to_permission_data(blockrights[q][z]) + # Add Padding after the sector number padLen = max(1, 5 - len(str(q))) padding = " " * padLen # Only print the sector number in the second third row if (z == 2): - print("║ %d%s║ %d ║ %s ║ %s ║" %(q,padding,z,blocksmatrix[q][z], accbits)) + print("║ %d%s║ %d ║ %s ║ %s ║ %-35s ║ %s" %(q,padding,z,blocksmatrix[q][z], accbits, permissions, d(blocksmatrix_clear[q][z]))) else: - print("║ ║ %d ║ %s ║ %s ║" %(z,blocksmatrix[q][z], accbits)) - print("╚═════════╩═════╩══════════════════════════════════╩═══════════════╝") + print("║ ║ %d ║ %s ║ %s ║ %-35s ║ %s" %(z,blocksmatrix[q][z], accbits, permissions, d(blocksmatrix_clear[q][z]))) + print("╚═════════╩═════╩══════════════════════════════════╩════════╩═════════════════════════════════════╝") + + +def main(args): + if args[0] == '-n': + args.pop(0) + bashcolors.BLUE = "" + bashcolors.RED = "" + bashcolors.GREEN = "" + bashcolors.WARNING = "" + bashcolors.ENDC = "" + if args[0] == '-1': + args.pop(0) + Options.FORCE_1K = True -def main(filename): + filename = args[0] with open(filename, "rb") as f: data = f.read() print_info(data) if __name__ == "__main__": - main(sys.argv[1]) + main(sys.argv[1:]) -- 2.39.5 From cb7902cdcd0d4f93857d4143abdf9a197ebdbc15 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Sep 2016 14:46:12 +0200 Subject: [PATCH 05/16] CHG: removed some debug data CHG: reverted back to old crc imp. --- armsrc/legicrf.c | 53 ++++++++++++++---------------------------------- common/crc.c | 4 ++-- 2 files changed, 17 insertions(+), 40 deletions(-) diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index ca56b235..65e4b3e6 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -221,7 +221,6 @@ void frame_sendAsReader(uint32_t data, uint8_t bits){ uint32_t starttime = GET_TICKS, send = 0; uint16_t mask = 1; - uint8_t prngstart = legic_prng_count() ; // xor lsfr onto data. send = data ^ legic_prng_get_bits(bits); @@ -243,9 +242,7 @@ void frame_sendAsReader(uint32_t data, uint8_t bits){ BYTEx(data, 0), BYTEx(data, 1), BYTEx(send, 0), - BYTEx(send, 1), - prngstart, - legic_prng_count() + BYTEx(send, 1) }; LogTrace(cmdbytes, sizeof(cmdbytes), starttime, sendFrameStop, NULL, TRUE); } @@ -287,19 +284,15 @@ static void frame_receiveAsReader(struct legic_frame * const f, uint8_t bits) { // calibrate the prng. legic_prng_forward(2); - uint8_t prngstart = legic_prng_count() ; data = lsfr = legic_prng_get_bits(bits); //FIXED time between sending frame and now listening frame. 330us - // 387 = 0x19 0001 1001 uint32_t starttime = GET_TICKS; //uint16_t mywait = TAG_FRAME_WAIT - (starttime - sendFrameStop); - //uint16_t mywait = 495 - (starttime - sendFrameStop); if ( bits == 6) { //WaitTicks( 495 - 9 - 9 ); WaitTicks( 475 ); } else { - //Dbprintf("x WAIT %d", mywait ); //WaitTicks( mywait ); WaitTicks( 450 ); } @@ -321,7 +314,6 @@ static void frame_receiveAsReader(struct legic_frame * const f, uint8_t bits) { next_bit_at += TAG_BIT_PERIOD; // We expect 42 edges == ONE - //if (edges > 20 && edges < 64) if ( edges > 20 ) data ^= the_bit; @@ -332,15 +324,8 @@ static void frame_receiveAsReader(struct legic_frame * const f, uint8_t bits) { f->data = data; f->bits = bits; - uint8_t cmdbytes[] = { - bits, - BYTEx(data, 0), - BYTEx(data, 1), - BYTEx(data, 0) ^ BYTEx(lsfr, 0), - BYTEx(data, 1) ^ BYTEx(lsfr, 1), - prngstart, - legic_prng_count() - }; + //log + uint8_t cmdbytes[] = {bits, BYTEx(data, 0), BYTEx(data, 1)}; LogTrace(cmdbytes, sizeof(cmdbytes), starttime, GET_TICKS, NULL, FALSE); } @@ -413,26 +398,18 @@ static void switch_off_tag_rwd(void) { } // calculate crc4 for a legic READ command -// 5,8,10 address size. static uint32_t legic4Crc(uint8_t legicCmd, uint16_t byte_index, uint8_t value, uint8_t cmd_sz) { crc_clear(&legic_crc); - //uint32_t temp = (value << cmd_sz) | (byte_index << 1) | legicCmd; - //crc_update(&legic_crc, temp, cmd_sz + 8 ); - crc_update(&legic_crc, 1, 1); /* CMD_READ */ - crc_update(&legic_crc, byte_index, cmd_sz-1); - crc_update(&legic_crc, value, 8); + uint32_t temp = (value << cmd_sz) | (byte_index << 1) | legicCmd; + crc_update(&legic_crc, temp, cmd_sz + 8 ); return crc_finish(&legic_crc); } int legic_read_byte(int byte_index, int cmd_sz) { - uint8_t byte = 0; //, crc = 0, calcCrc = 0; + uint8_t byte = 0, crc = 0, calcCrc = 0; uint32_t cmd = (byte_index << 1) | LEGIC_READ; - - // (us)| ticks - // ------------- - // 330 | 495 - // 244 | 366 + WaitTicks(366); frame_sendAsReader(cmd, cmd_sz); @@ -440,13 +417,13 @@ int legic_read_byte(int byte_index, int cmd_sz) { byte = BYTEx(current_frame.data, 0); - // calcCrc = legic4Crc(LEGIC_READ, byte_index, byte, cmd_sz); - // crc = BYTEx(current_frame.data, 1); + calcCrc = legic4Crc(LEGIC_READ, byte_index, byte, cmd_sz); + crc = BYTEx(current_frame.data, 1); - // if( calcCrc != crc ) { - // Dbprintf("!!! crc mismatch: expected %x but got %x !!!", calcCrc, crc); - // return -1; - // } + if( calcCrc != crc ) { + Dbprintf("!!! crc mismatch: expected %x but got %x !!!", calcCrc, crc); + return -1; + } legic_prng_forward(4); WaitTicks(40); @@ -535,9 +512,9 @@ int LegicRfReader(int offset, int bytes, int iv) { isOK = 0; goto OUT; } - + switch_off_tag_rwd(); - + if (bytes == -1) bytes = card.cardsize; diff --git a/common/crc.c b/common/crc.c index f8179008..613f566d 100644 --- a/common/crc.c +++ b/common/crc.c @@ -35,7 +35,7 @@ void crc_clear(crc_t *crc) { crc->state = reflect(crc->state, crc->order); } -void crc_update(crc_t *crc, uint32_t data, int data_width){ +void crc_update2(crc_t *crc, uint32_t data, int data_width){ if (crc->refin) data = reflect(data, data_width); @@ -52,7 +52,7 @@ void crc_update(crc_t *crc, uint32_t data, int data_width){ } } -void crc_update2(crc_t *crc, uint32_t data, int data_width) +void crc_update(crc_t *crc, uint32_t data, int data_width) { if (crc->refin) data = reflect(data, data_width); -- 2.39.5 From fabef615ec2fbe1fbe4b69af9482931e781d8d08 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Sep 2016 17:43:39 +0200 Subject: [PATCH 06/16] CHG: added addresize to legic select struct. CHG: TIMER, it turns out the TC0, TC1 and TC2 is only 16bit. So adjust to use two clocks to get a 32bit timer. CHG: code clean up in legic device side. consistency with variable names.. --- armsrc/legicrf.c | 131 +++++++++++++++++++++----------------------- armsrc/legicrf.h | 9 ++- armsrc/ticks.c | 20 ++++++- armsrc/ticks.h | 2 +- client/cmdhflegic.c | 8 +-- include/legic.h | 3 +- 6 files changed, 93 insertions(+), 80 deletions(-) diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 65e4b3e6..7f8c05a6 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -91,8 +91,6 @@ static void setup_timer(void) { # define OPEN_COIL HIGH(GPIO_SSC_DOUT); #endif -uint32_t sendFrameStop = 0; - // Pause pulse, off in 20us / 30ticks, // ONE / ZERO bit pulse, // one == 80us / 120ticks @@ -226,25 +224,18 @@ void frame_sendAsReader(uint32_t data, uint8_t bits){ send = data ^ legic_prng_get_bits(bits); for (; mask < BITMASK(bits); mask <<= 1) { - if (send & mask) { + if (send & mask) COIL_PULSE(RWD_TIME_1); - } else { + else COIL_PULSE(RWD_TIME_0); - } } // Final pause to mark the end of the frame COIL_PULSE(0); - sendFrameStop = GET_TICKS; - uint8_t cmdbytes[] = { - bits, - BYTEx(data, 0), - BYTEx(data, 1), - BYTEx(send, 0), - BYTEx(send, 1) - }; - LogTrace(cmdbytes, sizeof(cmdbytes), starttime, sendFrameStop, NULL, TRUE); + // log + uint8_t cmdbytes[] = {bits, BYTEx(data, 0), BYTEx(data, 1), BYTEx(send, 0), BYTEx(send, 1)}; + LogTrace(cmdbytes, sizeof(cmdbytes), starttime, GET_TICKS, NULL, TRUE); } /* Receive a frame from the card in reader emulation mode, the FPGA and @@ -270,15 +261,16 @@ void frame_sendAsReader(uint32_t data, uint8_t bits){ */ static void frame_receiveAsReader(struct legic_frame * const f, uint8_t bits) { - frame_clean(f); if ( bits > 32 ) return; uint8_t i = bits, edges = 0; uint16_t lsfr = 0; uint32_t the_bit = 1, next_bit_at = 0, data = 0; + uint32_t old_level = 0; + volatile uint32_t level = 0; - int old_level = 0, level = 0; - + frame_clean(f); + AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_DIN; AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DIN; @@ -288,12 +280,10 @@ static void frame_receiveAsReader(struct legic_frame * const f, uint8_t bits) { //FIXED time between sending frame and now listening frame. 330us uint32_t starttime = GET_TICKS; - //uint16_t mywait = TAG_FRAME_WAIT - (starttime - sendFrameStop); if ( bits == 6) { //WaitTicks( 495 - 9 - 9 ); WaitTicks( 475 ); } else { - //WaitTicks( mywait ); WaitTicks( 450 ); } @@ -313,7 +303,7 @@ static void frame_receiveAsReader(struct legic_frame * const f, uint8_t bits) { next_bit_at += TAG_BIT_PERIOD; - // We expect 42 edges == ONE + // We expect 42 edges (ONE) if ( edges > 20 ) data ^= the_bit; @@ -324,7 +314,7 @@ static void frame_receiveAsReader(struct legic_frame * const f, uint8_t bits) { f->data = data; f->bits = bits; - //log + // log uint8_t cmdbytes[] = {bits, BYTEx(data, 0), BYTEx(data, 1)}; LogTrace(cmdbytes, sizeof(cmdbytes), starttime, GET_TICKS, NULL, FALSE); } @@ -398,17 +388,17 @@ static void switch_off_tag_rwd(void) { } // calculate crc4 for a legic READ command -static uint32_t legic4Crc(uint8_t legicCmd, uint16_t byte_index, uint8_t value, uint8_t cmd_sz) { +static uint32_t legic4Crc(uint8_t cmd, uint16_t byte_index, uint8_t value, uint8_t cmd_sz) { crc_clear(&legic_crc); - uint32_t temp = (value << cmd_sz) | (byte_index << 1) | legicCmd; + uint32_t temp = (value << cmd_sz) | (byte_index << 1) | cmd; crc_update(&legic_crc, temp, cmd_sz + 8 ); return crc_finish(&legic_crc); } -int legic_read_byte(int byte_index, int cmd_sz) { +int legic_read_byte( uint16_t index, uint8_t cmd_sz) { - uint8_t byte = 0, crc = 0, calcCrc = 0; - uint32_t cmd = (byte_index << 1) | LEGIC_READ; + uint8_t byte, crc, calcCrc = 0; + uint32_t cmd = (index << 1) | LEGIC_READ; WaitTicks(366); @@ -416,9 +406,9 @@ int legic_read_byte(int byte_index, int cmd_sz) { frame_receiveAsReader(¤t_frame, 12); byte = BYTEx(current_frame.data, 0); - - calcCrc = legic4Crc(LEGIC_READ, byte_index, byte, cmd_sz); crc = BYTEx(current_frame.data, 1); + + calcCrc = legic4Crc(LEGIC_READ, index, byte, cmd_sz); if( calcCrc != crc ) { Dbprintf("!!! crc mismatch: expected %x but got %x !!!", calcCrc, crc); @@ -426,7 +416,7 @@ int legic_read_byte(int byte_index, int cmd_sz) { } legic_prng_forward(4); - WaitTicks(40); + WaitTicks(50); return byte; } @@ -500,40 +490,38 @@ int legic_write_byte(uint8_t byte, uint16_t addr, uint8_t addr_sz) { return -1; } -int LegicRfReader(int offset, int bytes, int iv) { +int LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) { - uint16_t byte_index = 0; + len &= 0x3FF; + + uint16_t i = 0; uint8_t isOK = 1; legic_card_select_t card; LegicCommonInit(); - if ( legic_select_card(&card) ) { + if ( legic_select_card_iv(&card, iv) ) { isOK = 0; goto OUT; } switch_off_tag_rwd(); - if (bytes == -1) - bytes = card.cardsize; - - if (bytes + offset >= card.cardsize) - bytes = card.cardsize - offset; + if (len + offset >= card.cardsize) + len = card.cardsize - offset; - // Start setup and read bytes. setup_phase_reader(iv); LED_B_ON(); - while (byte_index < bytes) { - int r = legic_read_byte(byte_index + offset, card.cmdsize); + while (i < len) { + int r = legic_read_byte(offset + i, card.cmdsize); if (r == -1 || BUTTON_PRESS()) { - if ( MF_DBGLEVEL >= 3) DbpString("operation aborted"); + if ( MF_DBGLEVEL >= 2) DbpString("operation aborted"); isOK = 0; goto OUT; } - cardmem[byte_index++] = r; + cardmem[i++] = r; WDT_HIT(); } @@ -541,7 +529,6 @@ OUT: WDT_HIT(); switch_off_tag_rwd(); LEDsoff(); - uint8_t len = (bytes & 0x3FF); cmd_send(CMD_ACK,isOK,len,0,cardmem,len); return 0; } @@ -587,25 +574,27 @@ OUT: return 0; }*/ -void LegicRfWriter(int offset, int bytes, int iv) { - - int byte_index = 0, addr_sz = 0; +void LegicRfWriter(uint16_t offset, uint16_t bytes, uint8_t iv) { - LegicCommonInit(); + int byte_index = 0; + uint8_t isOK = 1; + legic_card_select_t card; - if ( MF_DBGLEVEL >= 2) DbpString("setting up legic card"); + LegicCommonInit(); - uint32_t tag_type = setup_phase_reader(iv); + if ( legic_select_card_iv(&card, iv) ) { + isOK = 0; + goto OUT; + } switch_off_tag_rwd(); - switch(tag_type) { + switch(card.tagtype) { case 0x0d: if(offset+bytes > 22) { Dbprintf("Error: can not write to 0x%03.3x on MIM22", offset + bytes); return; } - addr_sz = 5; if ( MF_DBGLEVEL >= 2) Dbprintf("MIM22 card found, writing 0x%02.2x - 0x%02.2x ...", offset, offset + bytes); break; case 0x1d: @@ -613,7 +602,6 @@ void LegicRfWriter(int offset, int bytes, int iv) { Dbprintf("Error: can not write to 0x%03.3x on MIM256", offset + bytes); return; } - addr_sz = 8; if ( MF_DBGLEVEL >= 2) Dbprintf("MIM256 card found, writing 0x%02.2x - 0x%02.2x ...", offset, offset + bytes); break; case 0x3d: @@ -621,11 +609,9 @@ void LegicRfWriter(int offset, int bytes, int iv) { Dbprintf("Error: can not write to 0x%03.3x on MIM1024", offset + bytes); return; } - addr_sz = 10; if ( MF_DBGLEVEL >= 2) Dbprintf("MIM1024 card found, writing 0x%03.3x - 0x%03.3x ...", offset, offset + bytes); break; default: - Dbprintf("No or unknown card found, aborting"); return; } @@ -637,33 +623,35 @@ void LegicRfWriter(int offset, int bytes, int iv) { //check if the DCF should be changed if ( ((byte_index+offset) == 0x05) && (bytes >= 0x02) ) { //write DCF in reverse order (addr 0x06 before 0x05) - r = legic_write_byte(cardmem[(0x06-byte_index)], (0x06-byte_index), addr_sz); + r = legic_write_byte(cardmem[(0x06-byte_index)], (0x06-byte_index), card.addrsize); - // write second byte on success... + // write second byte on success if(r == 0) { byte_index++; - r = legic_write_byte(cardmem[(0x06-byte_index)], (0x06-byte_index), addr_sz); + r = legic_write_byte(cardmem[(0x06-byte_index)], (0x06-byte_index), card.addrsize); } } else { - r = legic_write_byte(cardmem[byte_index+offset], byte_index+offset, addr_sz); + r = legic_write_byte(cardmem[byte_index+offset], byte_index+offset, card.addrsize); } if ((r != 0) || BUTTON_PRESS()) { Dbprintf("operation aborted @ 0x%03.3x", byte_index); - switch_off_tag_rwd(); - LEDsoff(); - return; + isOK = 0; + goto OUT; } WDT_HIT(); byte_index++; } - LEDsoff(); - if ( MF_DBGLEVEL >= 1) DbpString("write successful"); + +OUT: + cmd_send(CMD_ACK, isOK, 0,0,0,0); + switch_off_tag_rwd(); + LEDsoff(); } -void LegicRfRawWriter(int address, int byte, int iv) { +void LegicRfRawWriter(int address, int byte, uint8_t iv) { int byte_index = 0, addr_sz = 0; @@ -723,33 +711,40 @@ void LegicRfRawWriter(int address, int byte, int iv) { if ( MF_DBGLEVEL >= 1) DbpString("write successful"); } -int legic_select_card(legic_card_select_t *p_card){ +int legic_select_card_iv(legic_card_select_t *p_card, uint8_t iv){ if ( p_card == NULL ) return 1; - p_card->tagtype = setup_phase_reader(0x1); + p_card->tagtype = setup_phase_reader(iv); switch(p_card->tagtype) { case 0x0d: p_card->cmdsize = 6; + p_card->addrsize = 5; p_card->cardsize = 22; break; case 0x1d: p_card->cmdsize = 9; + p_card->addrsize = 8; p_card->cardsize = 256; break; case 0x3d: p_card->cmdsize = 11; + p_card->addrsize = 10; p_card->cardsize = 1024; break; default: p_card->cmdsize = 0; + p_card->addrsize = 0; p_card->cardsize = 0; return 2; break; } return 0; } +int legic_select_card(legic_card_select_t *p_card){ + return legic_select_card_iv(p_card, 0x01); +} void LegicRfInfo(void){ @@ -763,7 +758,7 @@ void LegicRfInfo(void){ goto OUT; } - // read UID bytes. + // read UID bytes for ( uint8_t i = 0; i < sizeof(card->uid); ++i) { int r = legic_read_byte(i, card->cmdsize); if ( r == -1 ) { @@ -773,7 +768,7 @@ void LegicRfInfo(void){ card->uid[i] = r & 0xFF; } - cmd_send(CMD_ACK, 1 ,0 , 0, buf, sizeof(legic_card_select_t)); + cmd_send(CMD_ACK, 1, 0, 0, buf, sizeof(legic_card_select_t)); OUT: switch_off_tag_rwd(); diff --git a/armsrc/legicrf.h b/armsrc/legicrf.h index f885ef19..40f2d010 100644 --- a/armsrc/legicrf.h +++ b/armsrc/legicrf.h @@ -21,16 +21,19 @@ #include "legic.h" // legic_card_select_t struct extern void LegicRfSimulate(int phase, int frame, int reqresp); -extern int LegicRfReader(int offset, int bytes, int iv); -extern void LegicRfWriter(int offset, int bytes, int iv); -extern void LegicRfRawWriter(int address, int data, int iv); +extern int LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv); +extern void LegicRfWriter(uint16_t offset, uint16_t byte, uint8_t iv); +extern void LegicRfRawWriter(int address, int data, uint8_t iv); extern void LegicRfInfo(void); uint32_t get_key_stream(int skip, int count); void frame_send_tag(uint16_t response, uint8_t bits, uint8_t crypt); void frame_sendAsReader(uint32_t data, uint8_t bits); +int legic_read_byte( uint16_t index, uint8_t cmd_sz); + int legic_select_card(legic_card_select_t *p_card); +int legic_select_card_iv(legic_card_select_t *p_card, uint8_t iv); void ice_legic_setup(); #endif /* __LEGICRF_H */ diff --git a/armsrc/ticks.c b/armsrc/ticks.c index 555685cc..0117030e 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -178,14 +178,26 @@ uint32_t RAMFUNC GetCountSspClk(void) { // ------------------------------------------------------------------------- void StartTicks(void){ //initialization of the timer + // tc1 is higher 0xFFFF0000 + // tc0 is lower 0x0000FFFF AT91C_BASE_PMC->PMC_PCER |= (1 << 12) | (1 << 13) | (1 << 14); AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE; AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; //clock at 48/32 MHz + AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK(48MHz) / 32 + AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_ACPA_CLEAR | + AT91C_TC_ACPC_SET | AT91C_TC_ASWTRG_SET; + AT91C_BASE_TC0->TC_RA = 1; + AT91C_BASE_TC0->TC_RC = 0xBFFF + 1; // 0xC000 + + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // timer disable + AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_XC1; // from TC0 + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; AT91C_BASE_TCB->TCB_BCR = 1; + // wait until timer becomes zero. - while (AT91C_BASE_TC0->TC_CV > 1); + while (AT91C_BASE_TC1->TC_CV >= 1); } // Wait - Spindelay in ticks. // if called with a high number, this will trigger the WDT... @@ -206,7 +218,9 @@ void WaitMS(uint16_t ms){ } // Starts Clock and waits until its reset void ResetTicks(){ - ResetTimer(AT91C_BASE_TC0); + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + while (AT91C_BASE_TC1->TC_CV >= 1); } void ResetTimer(AT91PS_TC timer){ timer->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; diff --git a/armsrc/ticks.h b/armsrc/ticks.h index 050cb6ae..17a9ff18 100644 --- a/armsrc/ticks.h +++ b/armsrc/ticks.h @@ -19,7 +19,7 @@ #include "proxmark3.h" #ifndef GET_TICKS -# define GET_TICKS AT91C_BASE_TC0->TC_CV +# define GET_TICKS ((AT91C_BASE_TC1->TC_CV << 16) | AT91C_BASE_TC0->TC_CV) #endif void SpinDelay(int ms); diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index f4d0827f..7707c076 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -390,8 +390,8 @@ int CmdLegicDecode(const char *Cmd) { int CmdLegicRFRead(const char *Cmd) { // params: - // offset in data - // number of bytes. + // offset in data memory + // number of bytes to read char cmdp = param_getchar(Cmd, 0); if ( cmdp == 'H' || cmdp == 'h' ) return usage_legic_read(); @@ -401,7 +401,7 @@ int CmdLegicRFRead(const char *Cmd) { // OUT-OF-BOUNDS check if ( len + offset > MAX_LENGTH ) { len = MAX_LENGTH - offset; - PrintAndLog("Out-of-bound, shorten len to %d",len); + PrintAndLog("Out-of-bound, shorten len to %d", len); } if ( (IV & 0x7F) != IV ){ @@ -414,7 +414,7 @@ int CmdLegicRFRead(const char *Cmd) { PrintAndLog("LSB of IV must be SET"); } - PrintAndLog("Using IV: 0x%02x", IV); + //PrintAndLog("Using IV: 0x%02x | Offset: 0x%02x | Len: 0x%02x ", IV, offset, len); UsbCommand c = {CMD_READER_LEGIC_RF, {offset, len, IV}}; clearCommandBuffer(); diff --git a/include/legic.h b/include/legic.h index 9f3eccf2..246af0e8 100644 --- a/include/legic.h +++ b/include/legic.h @@ -20,7 +20,8 @@ typedef struct { uint8_t uid[4]; uint32_t tagtype; uint8_t cmdsize; - uint16_t cardsize; + uint8_t addrsize; + uint16_t cardsize; } legic_card_select_t; #endif // _LEGIC_H_ -- 2.39.5 From c649c43389d23fef7d28541739c89d22ad1f5250 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Sep 2016 21:36:43 +0200 Subject: [PATCH 07/16] CHG: finally, the ticks timer does what it is supposed to do. 32bits and working. --- armsrc/legicrf.c | 30 +++++++++++++++--------------- armsrc/ticks.c | 2 +- armsrc/ticks.h | 2 +- client/cmdhflegic.c | 6 ++++-- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 7f8c05a6..b1c6b196 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -72,7 +72,7 @@ static void setup_timer(void) { #define RWD_TIME_1 120 // READER_TIME_PAUSE 20us off, 80us on = 100us 80 * 1.5 == 120ticks #define RWD_TIME_0 60 // READER_TIME_PAUSE 20us off, 40us on = 60us 40 * 1.5 == 60ticks #define RWD_TIME_PAUSE 30 // 20us == 20 * 1.5 == 30ticks */ -#define TAG_BIT_PERIOD 143 // 100us == 100 * 1.5 == 150ticks +#define TAG_BIT_PERIOD 142 // 100us == 100 * 1.5 == 150ticks #define TAG_FRAME_WAIT 495 // 330us from READER frame end to TAG frame start. 330 * 1.5 == 495 #define RWD_TIME_FUZZ 20 // rather generous 13us, since the peak detector + hysteresis fuzz quite a bit @@ -264,7 +264,6 @@ static void frame_receiveAsReader(struct legic_frame * const f, uint8_t bits) { if ( bits > 32 ) return; uint8_t i = bits, edges = 0; - uint16_t lsfr = 0; uint32_t the_bit = 1, next_bit_at = 0, data = 0; uint32_t old_level = 0; volatile uint32_t level = 0; @@ -276,18 +275,19 @@ static void frame_receiveAsReader(struct legic_frame * const f, uint8_t bits) { // calibrate the prng. legic_prng_forward(2); - data = lsfr = legic_prng_get_bits(bits); + data = legic_prng_get_bits(bits); //FIXED time between sending frame and now listening frame. 330us uint32_t starttime = GET_TICKS; - if ( bits == 6) { - //WaitTicks( 495 - 9 - 9 ); - WaitTicks( 475 ); - } else { - WaitTicks( 450 ); - } + //if ( bits == 6 || bits == 7) { + // its about 9+9 ticks delay from end-send to here. + //WaitTicks( 495 - 9 - 9 ); + WaitTicks( 477 ); + //} else { +// WaitTicks( 477 ); +// } - next_bit_at = GET_TICKS + TAG_BIT_PERIOD; + next_bit_at = GET_TICKS + TAG_BIT_PERIOD; while ( i-- ){ edges = 0; @@ -400,14 +400,16 @@ int legic_read_byte( uint16_t index, uint8_t cmd_sz) { uint8_t byte, crc, calcCrc = 0; uint32_t cmd = (index << 1) | LEGIC_READ; - WaitTicks(366); + //WaitTicks(366); + WaitTicks(330); + //WaitTicks(50); frame_sendAsReader(cmd, cmd_sz); frame_receiveAsReader(¤t_frame, 12); + // CRC check. byte = BYTEx(current_frame.data, 0); crc = BYTEx(current_frame.data, 1); - calcCrc = legic4Crc(LEGIC_READ, index, byte, cmd_sz); if( calcCrc != crc ) { @@ -416,7 +418,6 @@ int legic_read_byte( uint16_t index, uint8_t cmd_sz) { } legic_prng_forward(4); - WaitTicks(50); return byte; } @@ -738,7 +739,6 @@ int legic_select_card_iv(legic_card_select_t *p_card, uint8_t iv){ p_card->addrsize = 0; p_card->cardsize = 0; return 2; - break; } return 0; } @@ -752,7 +752,7 @@ void LegicRfInfo(void){ legic_card_select_t *card = (legic_card_select_t*) buf; LegicCommonInit(); - + if ( legic_select_card(card) ) { cmd_send(CMD_ACK,0,0,0,0,0); goto OUT; diff --git a/armsrc/ticks.c b/armsrc/ticks.c index 0117030e..633e963a 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -187,7 +187,7 @@ void StartTicks(void){ AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_ACPA_CLEAR | AT91C_TC_ACPC_SET | AT91C_TC_ASWTRG_SET; AT91C_BASE_TC0->TC_RA = 1; - AT91C_BASE_TC0->TC_RC = 0xBFFF + 1; // 0xC000 + AT91C_BASE_TC0->TC_RC = 0; AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // timer disable AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_XC1; // from TC0 diff --git a/armsrc/ticks.h b/armsrc/ticks.h index 17a9ff18..1b05289d 100644 --- a/armsrc/ticks.h +++ b/armsrc/ticks.h @@ -19,7 +19,7 @@ #include "proxmark3.h" #ifndef GET_TICKS -# define GET_TICKS ((AT91C_BASE_TC1->TC_CV << 16) | AT91C_BASE_TC0->TC_CV) +# define GET_TICKS (uint32_t)((AT91C_BASE_TC1->TC_CV << 16) | AT91C_BASE_TC0->TC_CV) #endif void SpinDelay(int ms); diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 7707c076..f0fb12be 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -425,12 +425,14 @@ int CmdLegicRFRead(const char *Cmd) { uint16_t len = resp.arg[1] & 0x3FF; if ( isOK ) { PrintAndLog("use 'hf legic decode'"); - } + uint8_t *data = resp.d.asBytes; PrintAndLog("\nData |"); PrintAndLog("-----------------------------"); PrintAndLog(" %s|\n", sprint_hex(data, len)); - // } + } else { + PrintAndLog("failed reading tag"); + } } else { PrintAndLog("command execution time out"); return 1; -- 2.39.5 From 61f97ca7ad5d1f06289fd053ecdabe4b52f37032 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Sep 2016 21:37:19 +0200 Subject: [PATCH 08/16] CHG: annotation now only print relevant help text given selected protocoll. --- client/cmdhf.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index 845cfd5d..b49b35e9 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -515,20 +515,6 @@ uint8_t iclass_CRC_check(bool isResponse, uint8_t* data, uint8_t len) } } -uint8_t legic_CRC_check(bool isResponse, uint8_t* data, uint8_t len){ - if (len > 2) return 2; - - uint8_t calccrc = CRC8Legic(data, len); - - return 0; - // crc_init(&legic_crc, 4, 0x19 >> 1, 0x5, 0); - // crc_clear(&legic_crc); - // crc_update(&legic_crc, 1, 1); /* CMD_READ */ - // crc_update(&legic_crc, byte_index, cmd_sz-1); - // crc_update(&legic_crc, value, 8); - // return crc_finish(&legic_crc); -} - bool is_last_record(uint16_t tracepos, uint8_t *trace, uint16_t traceLen) { return(tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) >= traceLen); @@ -645,8 +631,6 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui default: break; } - } else if ( data_len == 2 && protocol == LEGIC ){ - crcStatus = legic_CRC_check(isResponse, frame, data_len); } //0 CRC-command, CRC not ok //1 CRC-command, CRC ok @@ -848,8 +832,12 @@ int CmdHFList(const char *Cmd) { PrintAndLog("Recorded Activity (TraceLen = %d bytes)", traceLen); PrintAndLog(""); PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer"); - PrintAndLog("iso14443a - All times are in carrier periods (1/13.56Mhz)"); - PrintAndLog("iClass - Timings are not as accurate"); + if ( protocol == ISO_14443A ) + PrintAndLog("iso14443a - All times are in carrier periods (1/13.56Mhz)"); + if ( protocol == ICLASS ) + PrintAndLog("iClass - Timings are not as accurate"); + if ( protocol == LEGIC ) + PrintAndLog("LEGIC - Timings are in ticks (1us == 1.5ticks)"); PrintAndLog(""); PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC | Annotation |"); PrintAndLog("------------|------------|-----|-----------------------------------------------------------------|-----|--------------------|"); -- 2.39.5 From 5660920679bb5c5ae48a0e189b52886b0d0776f5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 2 Oct 2016 12:29:18 +0200 Subject: [PATCH 09/16] FIX: the "hf list legic" on MIM1024 wrapped around readingbyte 255 due to a too small varible size. Causing the upperbits to drop silently --- client/cmdhf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index b49b35e9..47203808 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -389,7 +389,7 @@ void annotateLegic(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize){ case 9: case 11: { uint8_t cmdBit = (cmd[1] & 1); - uint8_t address = (cmd[2] << 7) | cmd[1] >> 1; + uint16_t address = (cmd[2] << 7) | cmd[1] >> 1; if (cmdBit == LEGIC_READ) snprintf(exp, size, "READ Byte(%d)", address); -- 2.39.5 From 44d9c722f0d3ba31d53ecb3f6af8be0e878ed769 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 3 Oct 2016 08:03:47 +0200 Subject: [PATCH 10/16] CHG: Patch for making PM3 compatible to MCU's CDC-Host libraries Thanks to @cjbrigato to tweak the cdc imp. https://gist.github.com/cjbrigato/ef7fc18119f7c4900efbbef9bda0eb0f --- common/usb_cdc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/usb_cdc.c b/common/usb_cdc.c index 9a24dc13..9d621777 100644 --- a/common/usb_cdc.c +++ b/common/usb_cdc.c @@ -57,7 +57,7 @@ const char devDescriptor[] = { 0x01,0x00, // Device release number (0001) 0x01, // iManufacturer // 0x01 0x00, // iProduct - 0x00, // SerialNumber + 0xFD, // SerialNumber 0x01 // bNumConfigs }; @@ -72,7 +72,7 @@ const char cfgDescriptor[] = { 0x01, // CbConfigurationValue 0x00, // CiConfiguration 0xC0, // CbmAttributes 0xA0 - 0x00, // CMaxPower + 0xFA, // CMaxPower /* Communication Class Interface Descriptor Requirement */ 0x09, // bLength @@ -82,7 +82,7 @@ const char cfgDescriptor[] = { 0x01, // bNumEndpoints 0x02, // bInterfaceClass 0x02, // bInterfaceSubclass - 0x00, // bInterfaceProtocol + 0x01, // bInterfaceProtocol 0x00, // iInterface /* Header Functional Descriptor */ @@ -96,7 +96,7 @@ const char cfgDescriptor[] = { 0x04, // bFunctionLength 0x24, // bDescriptor Type: CS_INTERFACE 0x02, // bDescriptor Subtype: ACM Func Desc - 0x00, // bmCapabilities + 0x02, // bmCapabilities /* Union Functional Descriptor */ 0x05, // bFunctionLength -- 2.39.5 From 0b0b182fe26cf7b94eb8480ef1d4a674981491b8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 3 Oct 2016 23:24:59 +0200 Subject: [PATCH 11/16] CHG: changed to use BigBuff_Eml memory instead of big_buff_malloc. CHG: downloading eml memory from device should use uint's CHG: "hf legic read" has a different printing. It now prints 32bytes / row --- armsrc/legicrf.c | 24 ++++++++++-------------- client/cmdhflegic.c | 22 +++++++++++++++++----- client/data.c | 2 +- client/data.h | 2 +- 4 files changed, 29 insertions(+), 21 deletions(-) diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index b1c6b196..63799c7b 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -72,7 +72,7 @@ static void setup_timer(void) { #define RWD_TIME_1 120 // READER_TIME_PAUSE 20us off, 80us on = 100us 80 * 1.5 == 120ticks #define RWD_TIME_0 60 // READER_TIME_PAUSE 20us off, 40us on = 60us 40 * 1.5 == 60ticks #define RWD_TIME_PAUSE 30 // 20us == 20 * 1.5 == 30ticks */ -#define TAG_BIT_PERIOD 142 // 100us == 100 * 1.5 == 150ticks +#define TAG_BIT_PERIOD 144 // 100us == 100 * 1.5 == 150ticks #define TAG_FRAME_WAIT 495 // 330us from READER frame end to TAG frame start. 330 * 1.5 == 495 #define RWD_TIME_FUZZ 20 // rather generous 13us, since the peak detector + hysteresis fuzz quite a bit @@ -279,13 +279,9 @@ static void frame_receiveAsReader(struct legic_frame * const f, uint8_t bits) { //FIXED time between sending frame and now listening frame. 330us uint32_t starttime = GET_TICKS; - //if ( bits == 6 || bits == 7) { - // its about 9+9 ticks delay from end-send to here. - //WaitTicks( 495 - 9 - 9 ); - WaitTicks( 477 ); - //} else { -// WaitTicks( 477 ); -// } + // its about 9+9 ticks delay from end-send to here. + //WaitTicks( 495 - 9 - 9 ); + WaitTicks( 477 ); next_bit_at = GET_TICKS + TAG_BIT_PERIOD; @@ -324,7 +320,7 @@ static uint32_t setup_phase_reader(uint8_t iv) { // Switch on carrier and let the tag charge for 1ms HIGH(GPIO_SSC_DOUT); - WaitUS(1000); + WaitUS(2000); ResetTicks(); @@ -370,7 +366,7 @@ static void LegicCommonInit(void) { AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; // reserve a cardmem, meaning we can use the tracelog function in bigbuff easier. - cardmem = BigBuf_malloc(LEGIC_CARD_MEMSIZE); + cardmem = BigBuf_get_EM_addr(); memset(cardmem, 0x00, LEGIC_CARD_MEMSIZE); clear_trace(); @@ -402,7 +398,6 @@ int legic_read_byte( uint16_t index, uint8_t cmd_sz) { //WaitTicks(366); WaitTicks(330); - //WaitTicks(50); frame_sendAsReader(cmd, cmd_sz); frame_receiveAsReader(¤t_frame, 12); @@ -457,7 +452,7 @@ int legic_write_byte(uint8_t byte, uint16_t addr, uint8_t addr_sz) { frame_sendAsReader(cmd, cmd_sz); - // wllm-rbnt doesnt have these + AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_DIN; AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DIN; @@ -471,13 +466,13 @@ int legic_write_byte(uint8_t byte, uint16_t addr, uint8_t addr_sz) { edges = 0; next_bit_at += TAG_BIT_PERIOD; while(timer->TC_CV < next_bit_at) { - int level = (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN); + volatile uint32_t level = (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN); if(level != old_level) edges++; old_level = level; } - if(edges > 20 && edges < 60) { /* expected are 42 edges */ + if(edges > 20 ) { /* expected are 42 edges */ int t = timer->TC_CV; int c = t / TAG_BIT_PERIOD; @@ -618,6 +613,7 @@ void LegicRfWriter(uint16_t offset, uint16_t bytes, uint8_t iv) { LED_B_ON(); setup_phase_reader(iv); + int r = 0; while(byte_index < bytes) { diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index f0fb12be..5bfa9eaf 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -414,7 +414,7 @@ int CmdLegicRFRead(const char *Cmd) { PrintAndLog("LSB of IV must be SET"); } - //PrintAndLog("Using IV: 0x%02x | Offset: 0x%02x | Len: 0x%02x ", IV, offset, len); + //PrintAndLog("Using IV: 0x%02x", IV); UsbCommand c = {CMD_READER_LEGIC_RF, {offset, len, IV}}; clearCommandBuffer(); @@ -424,12 +424,24 @@ int CmdLegicRFRead(const char *Cmd) { uint8_t isOK = resp.arg[0] & 0xFF; uint16_t len = resp.arg[1] & 0x3FF; if ( isOK ) { - PrintAndLog("use 'hf legic decode'"); - uint8_t *data = resp.d.asBytes; - PrintAndLog("\nData |"); + uint8_t *data = malloc(len); + if ( !data ){ + PrintAndLog("Cannot allocate memory"); + return 2; + } + // copy data from device + GetEMLFromBigBuf(data, len, 0); + if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2000)){ + PrintAndLog("Command execute timeout"); + if ( data ) + free(data); + return 1; + } + + PrintAndLog("\nData"); PrintAndLog("-----------------------------"); - PrintAndLog(" %s|\n", sprint_hex(data, len)); + print_hex_break( data, len, 32); } else { PrintAndLog("failed reading tag"); } diff --git a/client/data.c b/client/data.c index 49034769..184a63b6 100644 --- a/client/data.c +++ b/client/data.c @@ -23,7 +23,7 @@ void GetFromBigBuf(uint8_t *dest, int bytes, int start_index) { clearCommandBuffer(); SendCommand(&c); } -void GetEMLFromBigBuf(uint8_t *dest, int bytes, int start_index) { +void GetEMLFromBigBuf(uint8_t *dest, uint32_t bytes, uint32_t start_index) { sample_buf = dest; UsbCommand c = {CMD_DOWNLOAD_EML_BIGBUF, {start_index, bytes, 0}}; clearCommandBuffer(); diff --git a/client/data.h b/client/data.h index d156a0c8..df1f31de 100644 --- a/client/data.h +++ b/client/data.h @@ -14,5 +14,5 @@ #include "util.h" extern uint8_t* sample_buf; void GetFromBigBuf(uint8_t *dest, int bytes, int start_index); -void GetEMLFromBigBuf(uint8_t *dest, int bytes, int start_index); +void GetEMLFromBigBuf(uint8_t *dest, uint32_t bytes, uint32_t start_index); #endif -- 2.39.5 From 77a689dbeb6ea4adb93ba068825a5fff1fe2a802 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 4 Oct 2016 00:07:07 +0200 Subject: [PATCH 12/16] CHG: revert legiccrc8 to old algo. CHG: "hf legic decode" now loads EML memory CHG: legic timings is better. --- armsrc/legicrf.c | 2 +- client/cmdhflegic.c | 132 ++++++++++++++++++++++---------------------- common/crc.c | 2 +- 3 files changed, 68 insertions(+), 68 deletions(-) diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 63799c7b..4aa45b6d 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -320,7 +320,7 @@ static uint32_t setup_phase_reader(uint8_t iv) { // Switch on carrier and let the tag charge for 1ms HIGH(GPIO_SSC_DOUT); - WaitUS(2000); + WaitUS(5000); ResetTicks(); diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 5bfa9eaf..4a252bb1 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -109,86 +109,86 @@ int CmdLegicDecode(const char *Cmd) { int i = 0, k = 0, segmentNum = 0, segment_len = 0, segment_flag = 0; int crc = 0, wrp = 0, wrc = 0; uint8_t stamp_len = 0; - uint8_t data_buf[1024]; // receiver buffer + uint8_t data[1024]; // receiver buffer char token_type[5] = {0,0,0,0,0}; int dcf = 0; int bIsSegmented = 0; - // copy data from proxmark into buffer - GetFromBigBuf(data_buf,sizeof(data_buf),0); + // copy data from device + GetEMLFromBigBuf(data, sizeof(data), 0); if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2000)){ PrintAndLog("Command execute timeout"); return 1; } // Output CDF System area (9 bytes) plus remaining header area (12 bytes) - crc = data_buf[4]; - uint32_t calc_crc = CRC8Legic(data_buf, 4); + crc = data[4]; + uint32_t calc_crc = CRC8Legic(data, 4); PrintAndLog("\nCDF: System Area"); PrintAndLog("------------------------------------------------------"); PrintAndLog("MCD: %02x, MSN: %02x %02x %02x, MCC: %02x %s", - data_buf[0], - data_buf[1], - data_buf[2], - data_buf[3], - data_buf[4], - (calc_crc == crc) ? "OK":"Fail" + data[0], + data[1], + data[2], + data[3], + data[4], + (calc_crc == crc) ? "OK":"Fail" ); token_type[0] = 0; - dcf = ((int)data_buf[6] << 8) | (int)data_buf[5]; + dcf = ((int)data[6] << 8) | (int)data[5]; // New unwritten media? if(dcf == 0xFFFF) { PrintAndLog("DCF: %d (%02x %02x), Token Type=NM (New Media)", dcf, - data_buf[5], - data_buf[6] + data[5], + data[6] ); } else if(dcf > 60000) { // Master token? int fl = 0; - if(data_buf[6] == 0xec) { + if(data[6] == 0xec) { strncpy(token_type, "XAM", sizeof(token_type)); fl = 1; - stamp_len = 0x0c - (data_buf[5] >> 4); + stamp_len = 0x0c - (data[5] >> 4); } else { - switch (data_buf[5] & 0x7f) { + switch (data[5] & 0x7f) { case 0x00 ... 0x2f: strncpy(token_type, "IAM", sizeof(token_type)); - fl = (0x2f - (data_buf[5] & 0x7f)) + 1; + fl = (0x2f - (data[5] & 0x7f)) + 1; break; case 0x30 ... 0x6f: strncpy(token_type, "SAM", sizeof(token_type)); - fl = (0x6f - (data_buf[5] & 0x7f)) + 1; + fl = (0x6f - (data[5] & 0x7f)) + 1; break; case 0x70 ... 0x7f: strncpy(token_type, "GAM", sizeof(token_type)); - fl = (0x7f - (data_buf[5] & 0x7f)) + 1; + fl = (0x7f - (data[5] & 0x7f)) + 1; break; } - stamp_len = 0xfc - data_buf[6]; + stamp_len = 0xfc - data[6]; } PrintAndLog("DCF: %d (%02x %02x), Token Type=%s (OLE=%01u), OL=%02u, FL=%02u", dcf, - data_buf[5], - data_buf[6], + data[5], + data[6], token_type, - (data_buf[5] & 0x80 )>> 7, + (data[5] & 0x80 )>> 7, stamp_len, fl ); } else { // Is IM(-S) type of card... - if(data_buf[7] == 0x9F && data_buf[8] == 0xFF) { + if(data[7] == 0x9F && data[8] == 0xFF) { bIsSegmented = 1; strncpy(token_type, "IM-S", sizeof(token_type)); } else { @@ -197,10 +197,10 @@ int CmdLegicDecode(const char *Cmd) { PrintAndLog("DCF: %d (%02x %02x), Token Type=%s (OLE=%01u)", dcf, - data_buf[5], - data_buf[6], + data[5], + data[6], token_type, - (data_buf[5]&0x80) >> 7 + (data[5]&0x80) >> 7 ); } @@ -209,10 +209,10 @@ int CmdLegicDecode(const char *Cmd) { if(bIsSegmented) { PrintAndLog("WRP=%02u, WRC=%01u, RD=%01u, SSC=%02x", - data_buf[7] & 0x0f, - (data_buf[7] & 0x70) >> 4, - (data_buf[7] & 0x80) >> 7, - data_buf[8] + data[7] & 0x0f, + (data[7] & 0x70) >> 4, + (data[7] & 0x80) >> 7, + data[8] ); } @@ -220,10 +220,10 @@ int CmdLegicDecode(const char *Cmd) { if(bIsSegmented || dcf > 60000) { if(dcf > 60000) { PrintAndLog("Master token data"); - PrintAndLog("%s", sprint_hex(data_buf+8, 14)); + PrintAndLog("%s", sprint_hex(data+8, 14)); } else { PrintAndLog("Remaining Header Area"); - PrintAndLog("%s", sprint_hex(data_buf+9, 13)); + PrintAndLog("%s", sprint_hex(data+9, 13)); } } } @@ -246,10 +246,10 @@ int CmdLegicDecode(const char *Cmd) { // decode segments for (segmentNum=1; segmentNum < 128; segmentNum++ ) { - segment_len = ((data_buf[i+1] ^ crc) & 0x0f) * 256 + (data_buf[i] ^ crc); - segment_flag = ((data_buf[i+1] ^ crc) & 0xf0) >> 4; - wrp = (data_buf[i+2] ^ crc); - wrc = ((data_buf[i+3] ^ crc) & 0x70) >> 4; + segment_len = ((data[i+1] ^ crc) & 0x0f) * 256 + (data[i] ^ crc); + segment_flag = ((data[i+1] ^ crc) & 0xf0) >> 4; + wrp = (data[i+2] ^ crc); + wrc = ((data[i+3] ^ crc) & 0x70) >> 4; bool hasWRC = (wrc > 0); bool hasWRP = (wrp > wrc); @@ -257,31 +257,31 @@ int CmdLegicDecode(const char *Cmd) { int remain_seg_payload_len = (segment_len - wrp - 5); // validate segment-crc - segCrcBytes[0]=data_buf[0]; //uid0 - segCrcBytes[1]=data_buf[1]; //uid1 - segCrcBytes[2]=data_buf[2]; //uid2 - segCrcBytes[3]=data_buf[3]; //uid3 - segCrcBytes[4]=(data_buf[i] ^ crc); //hdr0 - segCrcBytes[5]=(data_buf[i+1] ^ crc); //hdr1 - segCrcBytes[6]=(data_buf[i+2] ^ crc); //hdr2 - segCrcBytes[7]=(data_buf[i+3] ^ crc); //hdr3 + segCrcBytes[0]=data[0]; //uid0 + segCrcBytes[1]=data[1]; //uid1 + segCrcBytes[2]=data[2]; //uid2 + segCrcBytes[3]=data[3]; //uid3 + segCrcBytes[4]=(data[i] ^ crc); //hdr0 + segCrcBytes[5]=(data[i+1] ^ crc); //hdr1 + segCrcBytes[6]=(data[i+2] ^ crc); //hdr2 + segCrcBytes[7]=(data[i+3] ^ crc); //hdr3 segCalcCRC = CRC8Legic(segCrcBytes, 8); - segCRC = data_buf[i+4] ^ crc; + segCRC = data[i+4] ^ crc; PrintAndLog("Segment %02u \nraw header | 0x%02X 0x%02X 0x%02X 0x%02X \nSegment len: %u, Flag: 0x%X (valid:%01u, last:%01u), WRP: %02u, WRC: %02u, RD: %01u, CRC: 0x%02X (%s)", segmentNum, - data_buf[i] ^ crc, - data_buf[i+1] ^ crc, - data_buf[i+2] ^ crc, - data_buf[i+3] ^ crc, + data[i] ^ crc, + data[i+1] ^ crc, + data[i+2] ^ crc, + data[i+3] ^ crc, segment_len, segment_flag, (segment_flag & 0x4) >> 2, (segment_flag & 0x8) >> 3, wrp, wrc, - ((data_buf[i+3]^crc) & 0x80) >> 7, + ((data[i+3]^crc) & 0x80) >> 7, segCRC, ( segCRC == segCalcCRC ) ? "OK" : "fail" ); @@ -294,9 +294,9 @@ int CmdLegicDecode(const char *Cmd) { PrintAndLog("-----+------------------------------------------------"); for ( k=i; k < (i + wrc); ++k) - data_buf[k] ^= crc; + data[k] ^= crc; - print_hex_break( data_buf+i, wrc, 16); + print_hex_break( data+i, wrc, 16); i += wrc; } @@ -307,15 +307,15 @@ int CmdLegicDecode(const char *Cmd) { PrintAndLog("-----+------------------------------------------------"); for (k=i; k < (i+wrp_len); ++k) - data_buf[k] ^= crc; + data[k] ^= crc; - print_hex_break( data_buf+i, wrp_len, 16); + print_hex_break( data+i, wrp_len, 16); i += wrp_len; // does this one work? (Answer: Only if KGH/BGH is used with BCD encoded card number! So maybe this will show just garbage...) if( wrp_len == 8 ) - PrintAndLog("Card ID: %2X%02X%02X", data_buf[i-4]^crc, data_buf[i-3]^crc, data_buf[i-2]^crc); + PrintAndLog("Card ID: %2X%02X%02X", data[i-4]^crc, data[i-3]^crc, data[i-2]^crc); } PrintAndLog("Remaining segment payload: (I %d | K %d | Remain LEN %d)", i, k, remain_seg_payload_len); @@ -323,9 +323,9 @@ int CmdLegicDecode(const char *Cmd) { PrintAndLog("-----+------------------------------------------------"); for ( k=i; k < (i+remain_seg_payload_len); ++k) - data_buf[k] ^= crc; + data[k] ^= crc; - print_hex_break( data_buf+i, remain_seg_payload_len, 16); + print_hex_break( data+i, remain_seg_payload_len, 16); i += remain_seg_payload_len; @@ -341,8 +341,8 @@ int CmdLegicDecode(const char *Cmd) { // Data start point on unsegmented cards i = 8; - wrp = data_buf[7] & 0x0F; - wrc = (data_buf[7] & 0x70) >> 4; + wrp = data[7] & 0x0F; + wrc = (data[7] & 0x70) >> 4; bool hasWRC = (wrc > 0); bool hasWRP = (wrp > wrc); @@ -352,14 +352,14 @@ int CmdLegicDecode(const char *Cmd) { PrintAndLog("Unsegmented card - WRP: %02u, WRC: %02u, RD: %01u", wrp, wrc, - (data_buf[7] & 0x80) >> 7 + (data[7] & 0x80) >> 7 ); if ( hasWRC ) { PrintAndLog("WRC protected area: (I %d | WRC %d)", i, wrc); PrintAndLog("\nrow | data"); PrintAndLog("-----+------------------------------------------------"); - print_hex_break( data_buf+i, wrc, 16); + print_hex_break( data+i, wrc, 16); i += wrc; } @@ -367,18 +367,18 @@ int CmdLegicDecode(const char *Cmd) { PrintAndLog("Remaining write protected area: (I %d | WRC %d | WRP %d | WRP_LEN %d)", i, wrc, wrp, wrp_len); PrintAndLog("\nrow | data"); PrintAndLog("-----+------------------------------------------------"); - print_hex_break( data_buf + i, wrp_len, 16); + print_hex_break( data + i, wrp_len, 16); i += wrp_len; // does this one work? (Answer: Only if KGH/BGH is used with BCD encoded card number! So maybe this will show just garbage...) if( wrp_len == 8 ) - PrintAndLog("Card ID: %2X%02X%02X", data_buf[i-4], data_buf[i-3], data_buf[i-2]); + PrintAndLog("Card ID: %2X%02X%02X", data[i-4], data[i-3], data[i-2]); } PrintAndLog("Remaining segment payload: (I %d | Remain LEN %d)", i, remain_seg_payload_len); PrintAndLog("\nrow | data"); PrintAndLog("-----+------------------------------------------------"); - print_hex_break( data_buf + i, remain_seg_payload_len, 16); + print_hex_break( data + i, remain_seg_payload_len, 16); i += remain_seg_payload_len; PrintAndLog("-----+------------------------------------------------\n"); diff --git a/common/crc.c b/common/crc.c index 613f566d..47e21426 100644 --- a/common/crc.c +++ b/common/crc.c @@ -115,7 +115,7 @@ uint32_t CRC8Legic(uint8_t *buff, size_t size) { crc_t crc; crc_init_ref(&crc, 8, 0x63, 0x55, 0, TRUE, TRUE); for ( int i = 0; i < size; ++i) - crc_update(&crc, buff[i], 8); + crc_update2(&crc, buff[i], 8); return reflect(crc_finish(&crc), 8); } -- 2.39.5 From 7bc3c99e7ea67d2d67c4c7a44abcea92fa523231 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 4 Oct 2016 18:05:55 +0200 Subject: [PATCH 13/16] CHG: "hf legic write" started to change this command to the updated code --- armsrc/legicrf.c | 13 ++++++------- client/cmdhflegic.c | 26 +++++++++++++++++--------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 4aa45b6d..42e7649c 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -72,7 +72,7 @@ static void setup_timer(void) { #define RWD_TIME_1 120 // READER_TIME_PAUSE 20us off, 80us on = 100us 80 * 1.5 == 120ticks #define RWD_TIME_0 60 // READER_TIME_PAUSE 20us off, 40us on = 60us 40 * 1.5 == 60ticks #define RWD_TIME_PAUSE 30 // 20us == 20 * 1.5 == 30ticks */ -#define TAG_BIT_PERIOD 144 // 100us == 100 * 1.5 == 150ticks +#define TAG_BIT_PERIOD 142 // 100us == 100 * 1.5 == 150ticks #define TAG_FRAME_WAIT 495 // 330us from READER frame end to TAG frame start. 330 * 1.5 == 495 #define RWD_TIME_FUZZ 20 // rather generous 13us, since the peak detector + hysteresis fuzz quite a bit @@ -433,11 +433,11 @@ int legic_write_byte(uint8_t byte, uint16_t addr, uint8_t addr_sz) { crc_update(&legic_crc, addr, addr_sz); crc_update(&legic_crc, byte, 8); uint32_t crc = crc_finish(&legic_crc); - uint32_t crc2 = legic4Crc(LEGIC_WRITE, addr, byte, addr_sz+1); - if ( crc != crc2 ) + if ( crc != crc2 ) { Dbprintf("crc is missmatch"); - + return 1; + } // send write command uint32_t cmd = ((crc <<(addr_sz+1+8)) //CRC |(byte <<(addr_sz+1)) //Data @@ -448,11 +448,10 @@ int legic_write_byte(uint8_t byte, uint16_t addr, uint8_t addr_sz) { legic_prng_forward(2); /* we wait anyways */ - WaitUS(TAG_FRAME_WAIT); + WaitTicks(330); frame_sendAsReader(cmd, cmd_sz); - - + AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_DIN; AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DIN; diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 4a252bb1..ea75e15f 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -604,7 +604,6 @@ int CmdLegicRfWrite(const char *Cmd) { uint32_t offset = 0, len = 0, IV = 0; - UsbCommand c = {CMD_WRITER_LEGIC_RF, {0,0,0}}; int res = sscanf(Cmd, "%x %x %x", &offset, &len, &IV); if(res < 2) { PrintAndLog("Please specify the offset and length as two hex strings and, optionally, the IV also as an hex string"); @@ -612,8 +611,10 @@ int CmdLegicRfWrite(const char *Cmd) { } // OUT-OF-BOUNDS check - if(len + offset > MAX_LENGTH) len = MAX_LENGTH - offset; - + if ( len + offset > MAX_LENGTH ) { + len = MAX_LENGTH - offset; + PrintAndLog("Out-of-bound, shorten len to %d", len); + } if ( (IV & 0x7F) != IV ){ IV &= 0x7F; PrintAndLog("Truncating IV to 7bits"); @@ -623,14 +624,21 @@ int CmdLegicRfWrite(const char *Cmd) { PrintAndLog("LSB of IV must be SET"); } - PrintAndLog("Current IV: 0x%02x", IV); - - c.arg[0] = offset; - c.arg[1] = len; - c.arg[2] = IV; - + UsbCommand c = {CMD_WRITER_LEGIC_RF, {offset, len, IV}}; clearCommandBuffer(); SendCommand(&c); + UsbCommand resp; + if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + uint8_t isOK = resp.arg[0] & 0xFF; + if ( isOK ) { + } else { + PrintAndLog("failed writig tag"); + } + } else { + PrintAndLog("command execution time out"); + return 1; + } + return 0; } -- 2.39.5 From 86087eba009ffe9440c3b24720ea5f3b8001e850 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 4 Oct 2016 18:43:11 +0200 Subject: [PATCH 14/16] Textual changes in helptext. Still no clear. --- armsrc/legicrf.c | 5 ++-- client/cmdhflegic.c | 61 +++++++++++++++++++++++---------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 42e7649c..4e0bc240 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -72,7 +72,7 @@ static void setup_timer(void) { #define RWD_TIME_1 120 // READER_TIME_PAUSE 20us off, 80us on = 100us 80 * 1.5 == 120ticks #define RWD_TIME_0 60 // READER_TIME_PAUSE 20us off, 40us on = 60us 40 * 1.5 == 60ticks #define RWD_TIME_PAUSE 30 // 20us == 20 * 1.5 == 30ticks */ -#define TAG_BIT_PERIOD 142 // 100us == 100 * 1.5 == 150ticks +#define TAG_BIT_PERIOD 143 // 100us == 100 * 1.5 == 150ticks #define TAG_FRAME_WAIT 495 // 330us from READER frame end to TAG frame start. 330 * 1.5 == 495 #define RWD_TIME_FUZZ 20 // rather generous 13us, since the peak detector + hysteresis fuzz quite a bit @@ -280,7 +280,6 @@ static void frame_receiveAsReader(struct legic_frame * const f, uint8_t bits) { //FIXED time between sending frame and now listening frame. 330us uint32_t starttime = GET_TICKS; // its about 9+9 ticks delay from end-send to here. - //WaitTicks( 495 - 9 - 9 ); WaitTicks( 477 ); next_bit_at = GET_TICKS + TAG_BIT_PERIOD; @@ -524,7 +523,7 @@ OUT: WDT_HIT(); switch_off_tag_rwd(); LEDsoff(); - cmd_send(CMD_ACK,isOK,len,0,cardmem,len); + cmd_send(CMD_ACK, isOK, len, 0, cardmem, len); return 0; } diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index ea75e15f..ae67dd76 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -44,13 +44,14 @@ int usage_legic_read(void){ PrintAndLog("Usage: hf legic read [h] "); PrintAndLog("Options:"); PrintAndLog(" h : this help"); - PrintAndLog(" : offset in data array to start download from"); - PrintAndLog(" : number of bytes to download"); - PrintAndLog(" : (optional) Initialization vector to use (ODD and 7bits)"); + PrintAndLog(" : offset in data array to start download from (hex)"); + PrintAndLog(" : number of bytes to read (hex)"); + PrintAndLog(" : (optional) Initialization vector to use (hex, odd and 7bits)"); PrintAndLog(""); PrintAndLog("Samples:"); - PrintAndLog(" hf legic read"); - PrintAndLog(" hf legic read 10 4"); + PrintAndLog(" hf legic read 0 21 - reads from byte[0] 21 bytes(system header)"); + PrintAndLog(" hf legic read 0 4 55 - reads from byte[0] 4 bytes with IV 0x55"); + PrintAndLog(" hf legic read 0 100 55 - reads 256bytes with IV 0x55"); return 0; } int usage_legic_sim(void){ @@ -62,27 +63,25 @@ int usage_legic_write(void){ PrintAndLog("Usage: hf legic write [h] "); PrintAndLog("Options:"); PrintAndLog(" h : this help"); - PrintAndLog(" : offset in data array to start writing from"); - PrintAndLog(" : number of bytes to write"); + PrintAndLog(" : offset in data array to start writing from (hex)"); + PrintAndLog(" : number of bytes to write (hex)"); PrintAndLog(" : (optional) Initialization vector to use (ODD and 7bits)"); PrintAndLog(""); PrintAndLog("Samples:"); - PrintAndLog(" hf legic write"); - PrintAndLog(" hf legic write 10 4"); + PrintAndLog(" hf legic write 10 4 - writes 0x4 to byte[0x10]"); return 0; } int usage_legic_rawwrite(void){ - PrintAndLog("Write raw data direct to a specific address on legic tag."); - PrintAndLog("Usage: hf legic writeraw [h]
"); + PrintAndLog("Write raw data direct to a specific offset on legic tag."); + PrintAndLog("Usage: hf legic writeraw [h] "); PrintAndLog("Options:"); PrintAndLog(" h : this help"); - PrintAndLog("
: address to write to"); - PrintAndLog(" : value to write"); - PrintAndLog(" : (optional) Initialization vector to use (ODD and 7bits)"); + PrintAndLog(" : offset to write to (hex)"); + PrintAndLog(" : value (hex)"); + PrintAndLog(" : (optional) Initialization vector to use (hex, odd and 7bits)"); PrintAndLog(""); PrintAndLog("Samples:"); - PrintAndLog(" hf legic writeraw"); - PrintAndLog(" hf legic writeraw 10 4"); + PrintAndLog(" hf legic writeraw 10 4 - writes 0x4 to byte[0x10]"); return 0; } int usage_legic_fill(void){ @@ -422,16 +421,20 @@ int CmdLegicRFRead(const char *Cmd) { UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { uint8_t isOK = resp.arg[0] & 0xFF; - uint16_t len = resp.arg[1] & 0x3FF; + uint16_t readlen = resp.arg[1] & 0x3FF; if ( isOK ) { - uint8_t *data = malloc(len); + uint8_t *data = malloc(readlen); if ( !data ){ PrintAndLog("Cannot allocate memory"); return 2; } + + if ( readlen != len ) + PrintAndLog("Fail, only managed to read 0x%02X bytes", readlen); + // copy data from device - GetEMLFromBigBuf(data, len, 0); + GetEMLFromBigBuf(data, readlen, 0); if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2000)){ PrintAndLog("Command execute timeout"); if ( data ) @@ -441,7 +444,7 @@ int CmdLegicRFRead(const char *Cmd) { PrintAndLog("\nData"); PrintAndLog("-----------------------------"); - print_hex_break( data, len, 32); + print_hex_break( data, readlen, 32); } else { PrintAndLog("failed reading tag"); } @@ -647,17 +650,18 @@ int CmdLegicRfRawWrite(const char *Cmd) { char cmdp = param_getchar(Cmd, 0); if ( cmdp == 'H' || cmdp == 'h' ) return usage_legic_rawwrite(); - uint32_t address = 0, data = 0, IV = 0; + uint32_t offset = 0, data = 0, IV = 0; char answer; - UsbCommand c = { CMD_RAW_WRITER_LEGIC_RF, {0,0,0} }; - int res = sscanf(Cmd, "%x %x %x", &address, &data, &IV); + int res = sscanf(Cmd, "%x %x %x", &offset, &data, &IV); if(res < 2) return usage_legic_rawwrite(); - + // OUT-OF-BOUNDS check - if(address > MAX_LENGTH) - return usage_legic_rawwrite(); + if ( offset > MAX_LENGTH ) { + offset = MAX_LENGTH; + PrintAndLog("Out-of-bound, shorten len to %d", offset); + } if ( (IV & 0x7F) != IV ){ IV &= 0x7F; @@ -667,11 +671,8 @@ int CmdLegicRfRawWrite(const char *Cmd) { IV |= 0x01; // IV must be odd PrintAndLog("LSB of IV must be SET"); } - PrintAndLog("Current IV: 0x%02x", IV); - c.arg[0] = address; - c.arg[1] = data; - c.arg[2] = IV; + UsbCommand c = { CMD_RAW_WRITER_LEGIC_RF, {offset, data, IV} }; if (c.arg[0] == 0x05 || c.arg[0] == 0x06) { PrintAndLog("############# DANGER !! #############"); -- 2.39.5 From 7a8db2f67821d2e55c98a9a4b7badcd17947777d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 4 Oct 2016 21:26:19 +0200 Subject: [PATCH 15/16] CHG: "hf legic read" - increased timeout values client side, reading MIM1024 takes a bit of time --- armsrc/legicrf.c | 6 ++---- client/cmdhflegic.c | 16 +++++++--------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 4e0bc240..2d02b636 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -72,7 +72,7 @@ static void setup_timer(void) { #define RWD_TIME_1 120 // READER_TIME_PAUSE 20us off, 80us on = 100us 80 * 1.5 == 120ticks #define RWD_TIME_0 60 // READER_TIME_PAUSE 20us off, 40us on = 60us 40 * 1.5 == 60ticks #define RWD_TIME_PAUSE 30 // 20us == 20 * 1.5 == 30ticks */ -#define TAG_BIT_PERIOD 143 // 100us == 100 * 1.5 == 150ticks +#define TAG_BIT_PERIOD 142 // 100us == 100 * 1.5 == 150ticks #define TAG_FRAME_WAIT 495 // 330us from READER frame end to TAG frame start. 330 * 1.5 == 495 #define RWD_TIME_FUZZ 20 // rather generous 13us, since the peak detector + hysteresis fuzz quite a bit @@ -486,8 +486,6 @@ int legic_write_byte(uint8_t byte, uint16_t addr, uint8_t addr_sz) { int LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) { - len &= 0x3FF; - uint16_t i = 0; uint8_t isOK = 1; legic_card_select_t card; @@ -507,7 +505,7 @@ int LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) { setup_phase_reader(iv); LED_B_ON(); - while (i < len) { + while (i <= len) { int r = legic_read_byte(offset + i, card.cmdsize); if (r == -1 || BUTTON_PRESS()) { diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index ae67dd76..13313866 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -400,7 +400,7 @@ int CmdLegicRFRead(const char *Cmd) { // OUT-OF-BOUNDS check if ( len + offset > MAX_LENGTH ) { len = MAX_LENGTH - offset; - PrintAndLog("Out-of-bound, shorten len to %d", len); + PrintAndLog("Out-of-bound, shorten len to %d (0x%02X)", len); } if ( (IV & 0x7F) != IV ){ @@ -412,16 +412,14 @@ int CmdLegicRFRead(const char *Cmd) { IV |= 0x01; PrintAndLog("LSB of IV must be SET"); } - - //PrintAndLog("Using IV: 0x%02x", IV); UsbCommand c = {CMD_READER_LEGIC_RF, {offset, len, IV}}; clearCommandBuffer(); SendCommand(&c); UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + if (WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { uint8_t isOK = resp.arg[0] & 0xFF; - uint16_t readlen = resp.arg[1] & 0x3FF; + uint16_t readlen = resp.arg[1]; if ( isOK ) { uint8_t *data = malloc(readlen); @@ -435,7 +433,7 @@ int CmdLegicRFRead(const char *Cmd) { // copy data from device GetEMLFromBigBuf(data, readlen, 0); - if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2000)){ + if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2500)){ PrintAndLog("Command execute timeout"); if ( data ) free(data); @@ -616,7 +614,7 @@ int CmdLegicRfWrite(const char *Cmd) { // OUT-OF-BOUNDS check if ( len + offset > MAX_LENGTH ) { len = MAX_LENGTH - offset; - PrintAndLog("Out-of-bound, shorten len to %d", len); + PrintAndLog("Out-of-bound, shorten len to %d (0x%02X)", len); } if ( (IV & 0x7F) != IV ){ IV &= 0x7F; @@ -659,8 +657,8 @@ int CmdLegicRfRawWrite(const char *Cmd) { // OUT-OF-BOUNDS check if ( offset > MAX_LENGTH ) { - offset = MAX_LENGTH; - PrintAndLog("Out-of-bound, shorten len to %d", offset); + PrintAndLog("Out-of-bound, offset"); + return 1; } if ( (IV & 0x7F) != IV ){ -- 2.39.5 From 1daa1226fd76500a2e0be384195f30229bf7dfef Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 4 Oct 2016 21:41:21 +0200 Subject: [PATCH 16/16] CHG: reading a complete MIM1024 takes about 2.8sec. This timeout is changed to 3sec now. --- client/cmdhflegic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 13313866..4f06b96a 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -417,7 +417,7 @@ int CmdLegicRFRead(const char *Cmd) { clearCommandBuffer(); SendCommand(&c); UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { + if (WaitForResponseTimeout(CMD_ACK, &resp, 3000)) { uint8_t isOK = resp.arg[0] & 0xFF; uint16_t readlen = resp.arg[1]; if ( isOK ) { -- 2.39.5