From: iceman1001 Date: Thu, 29 Sep 2016 10:23:09 +0000 (+0200) Subject: CHG: a select_legic function with structs and stuff and X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/a39944216dd5d765e16917c1092bacc6061b518f CHG: a select_legic function with structs and stuff and --- 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