diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 86e42c17..64a75fce 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -140,14 +140,13 @@ static void frame_clean(struct legic_frame * const f) { /* Generate Keystream */ uint32_t get_key_stream(int skip, int count) { - uint32_t key = 0; + int i; // Use int to enlarge timer tc to 32bit legic_prng_bc += prng_timer->TC_CV; // reset the prng timer. - ResetTimer(prng_timer); /* If skip == -1, forward prng time based */ if(skip == -1) { @@ -161,55 +160,41 @@ uint32_t get_key_stream(int skip, int count) { i = (count == 6) ? -1 : legic_read_count; - /* Write Time Data into LOG */ - // uint8_t *BigBuf = BigBuf_get_addr(); - // BigBuf[OFFSET_LOG+128+i] = legic_prng_count(); - // BigBuf[OFFSET_LOG+256+i*4] = (legic_prng_bc >> 0) & 0xff; - // BigBuf[OFFSET_LOG+256+i*4+1] = (legic_prng_bc >> 8) & 0xff; - // BigBuf[OFFSET_LOG+256+i*4+2] = (legic_prng_bc >>16) & 0xff; - // BigBuf[OFFSET_LOG+256+i*4+3] = (legic_prng_bc >>24) & 0xff; - // BigBuf[OFFSET_LOG+384+i] = count; + // log + //uint8_t cmdbytes[] = {bits, BYTEx(data, 0), BYTEx(data, 1), BYTEx(send, 0), BYTEx(send, 1), legic_prng_count()}; + //LogTrace(cmdbytes, sizeof(cmdbytes), starttime, GET_TICKS, NULL, TRUE); /* Generate KeyStream */ - for(i=0; iPIO_OER = GPIO_SSC_DOUT; AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - /* Use time to crypt frame */ - if(crypt) { - legic_prng_forward(2); /* TAG_FRAME_WAIT -> shift by 2 */ - response ^= legic_prng_get_bits(bits); - } + /* TAG_FRAME_WAIT -> shift by 2 */ + legic_prng_forward(2); + response ^= legic_prng_get_bits(bits); /* Wait for the frame start */ - WaitUS( TAG_FRAME_WAIT ); + WaitTicks( TAG_FRAME_WAIT ); - uint8_t bit = 0; - for(int i = 0; i < bits; i++) { - - bit = response & 1; - response >>= 1; - - if (bit) - HIGH(GPIO_SSC_DOUT); + for (; mask < BITMASK(bits); mask <<= 1) { + if (send & mask) + OPEN_COIL; else - LOW(GPIO_SSC_DOUT); - - WaitUS(100); + SHORT_COIL; + WaitTicks(TAG_BIT_PERIOD); } - LOW(GPIO_SSC_DOUT); + SHORT_COIL; } /* Send a frame in reader mode, the FPGA must have been set up by @@ -775,26 +760,26 @@ static void frame_handle_tag(struct legic_frame const * const f) { uint8_t *BigBuf = BigBuf_get_addr(); - /* First Part of Handshake (IV) */ - if(f->bits == 7) { + /* First Part of Handshake (IV) */ + if(f->bits == 7) { + + LED_C_ON(); - LED_C_ON(); - // Reset prng timer ResetTimer(prng_timer); - - legic_prng_init(f->data); - frame_send_tag(0x3d, 6, 1); /* 0x3d^0x26 = 0x1B */ - legic_state = STATE_IV; - legic_read_count = 0; - legic_prng_bc = 0; - legic_prng_iv = f->data; - - + + legic_prng_init(f->data); + frame_send_tag(0x3d, 6); /* 0x3d^0x26 = 0x1B */ + legic_state = STATE_IV; + legic_read_count = 0; + legic_prng_bc = 0; + legic_prng_iv = f->data; + + ResetTimer(timer); WaitUS(280); - return; - } + return; + } /* 0x19==??? */ if(legic_state == STATE_IV) { @@ -828,7 +813,7 @@ static void frame_handle_tag(struct legic_frame const * const f) //Dbprintf("Data:%03.3x, key:%03.3x, addr: %03.3x, read_c:%u", f->data, key, addr, read_c); legic_prng_forward(legic_reqresp_drift); - frame_send_tag(hash | data, 12, 1); + frame_send_tag(hash | data, 12); ResetTimer(timer); legic_prng_forward(2); diff --git a/armsrc/legicrf.h b/armsrc/legicrf.h index 40f2d010..c4b3e582 100644 --- a/armsrc/legicrf.h +++ b/armsrc/legicrf.h @@ -27,7 +27,7 @@ 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_send_tag(uint16_t response, uint8_t bits); void frame_sendAsReader(uint32_t data, uint8_t bits); int legic_read_byte( uint16_t index, uint8_t cmd_sz); diff --git a/client/cmdhf.c b/client/cmdhf.c index 47203808..bc8d2ecc 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -882,7 +882,7 @@ int CmdHFSearch(const char *Cmd){ PrintAndLog("\nValid Topaz Tag Found - Quiting Search\n"); return 1; } - ans = HFLegicInfo("", false); + ans = HFLegicReader("", false); if ( ans == 0) { PrintAndLog("\nValid LEGIC Tag Found - Quiting Search\n"); return 1; diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 6b880da6..72c12a40 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -88,8 +88,19 @@ int usage_legic_fill(void){ PrintAndLog("Missing help text."); return 0; } +int usage_legic_reader(void){ + PrintAndLog("Read UID and type information from a legic tag."); + PrintAndLog("Usage: hf legic reader [h]"); + PrintAndLog("Options:"); + PrintAndLog(" h : this help"); + PrintAndLog(""); + PrintAndLog("Samples:"); + PrintAndLog(" hf legic reader"); + return 0; +} int usage_legic_info(void){ - PrintAndLog("Read info from a legic tag."); + PrintAndLog("Reads information from a legic prime tag."); + PrintAndLog("Shows systemarea, user areas etc"); PrintAndLog("Usage: hf legic info [h]"); PrintAndLog("Options:"); PrintAndLog(" h : this help"); @@ -98,12 +109,30 @@ int usage_legic_info(void){ PrintAndLog(" hf legic info"); return 0; } +int usage_legic_dump(void){ + PrintAndLog("Reads all pages from LEGIC MIM22, MIM256, MIM1024"); + PrintAndLog("and saves binary dump into the file `filename.bin` or `cardUID.bin`"); + PrintAndLog("It autodetects card type.\n"); + PrintAndLog("Usage: hf legic dump [h] o "); + PrintAndLog("Options:"); + PrintAndLog(" h : this help"); + PrintAndLog(" n : filename w/o .bin to save the dump as"); + PrintAndLog(""); + PrintAndLog("Samples:"); + PrintAndLog(" hf legic dump"); + PrintAndLog(" hf legic dump o myfile"); + return 0; +} + /* * Output BigBuf and deobfuscate LEGIC RF tag data. * This is based on information given in the talk held * by Henryk Ploetz and Karsten Nohl at 26c3 */ -int CmdLegicDecode(const char *Cmd) { +int CmdLegicInfo(const char *Cmd) { + + char cmdp = param_getchar(Cmd, 0); + if ( cmdp == 'H' || cmdp == 'h' ) return usage_legic_info(); int i = 0, k = 0, segmentNum = 0, segment_len = 0, segment_flag = 0; int crc = 0, wrp = 0, wrc = 0; @@ -113,6 +142,8 @@ int CmdLegicDecode(const char *Cmd) { int dcf = 0; int bIsSegmented = 0; + CmdLegicRFRead("0 21 55"); + // copy data from device GetEMLFromBigBuf(data, sizeof(data), 0); if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2000)){ @@ -834,7 +865,7 @@ int CmdLegicCalcCrc8(const char *Cmd){ return 0; } -int HFLegicInfo(const char *Cmd, bool verbose) { +int HFLegicReader(const char *Cmd, bool verbose) { char cmdp = param_getchar(Cmd, 0); if ( cmdp == 'H' || cmdp == 'h' ) return usage_legic_info(); @@ -870,22 +901,29 @@ int HFLegicInfo(const char *Cmd, bool verbose) { } return 0; } -int CmdLegicInfo(const char *Cmd){ - return HFLegicInfo(Cmd, TRUE); +int CmdLegicReader(const char *Cmd){ + return HFLegicReader(Cmd, TRUE); } + +int CmdLegicDump(const char *Cmd){ + char cmdp = param_getchar(Cmd, 0); + if ( cmdp == 'H' || cmdp == 'h' ) return usage_legic_dump(); + return 0; +} static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, - {"decode", CmdLegicDecode, 0, "Display deobfuscated and decoded LEGIC RF tag data (use after hf legic reader)"}, - {"read", CmdLegicRFRead, 0, "[offset][length] -- read bytes from a LEGIC card"}, - {"save", CmdLegicSave, 0, " [] -- Store samples"}, - {"load", CmdLegicLoad, 0, " -- Restore samples"}, - {"sim", CmdLegicRfSim, 0, "[phase drift [frame drift [req/resp drift]]] Start tag simulator (use after load or read)"}, - {"write", CmdLegicRfWrite,0, " -- Write sample buffer (user after load or read)"}, + {"help", CmdHelp, 1, "This help"}, + {"reader", CmdLegicReader, 1, "LEGIC Prime Reader UID and Type tag info"}, + {"info", CmdLegicInfo, 0, "Display deobfuscated and decoded LEGIC Prime tag data"}, + {"dump", CmdLegicDump, 0, "Dump LEGIC Prime card to binary file"}, + {"rdmem", CmdLegicRFRead, 0, "[offset][length] -- read bytes from a LEGIC card"}, + {"save", CmdLegicSave, 0, " [] -- Store samples"}, + {"load", CmdLegicLoad, 0, " -- Restore samples"}, + {"sim", CmdLegicRfSim, 0, "[phase drift [frame drift [req/resp drift]]] Start tag simulator (use after load or read)"}, + {"write", CmdLegicRfWrite, 0, " -- Write sample buffer (user after load or read)"}, {"writeraw",CmdLegicRfRawWrite, 0, "
-- Write direct to address"}, - {"fill", CmdLegicRfFill, 0, " -- Fill/Write tag with constant value"}, - {"crc8", CmdLegicCalcCrc8, 1, "Calculate Legic CRC8 over given hexbytes"}, - {"info", CmdLegicInfo, 1, "Information"}, + {"fill", CmdLegicRfFill, 0, " -- Fill/Write tag with constant value"}, + {"crc8", CmdLegicCalcCrc8, 1, "Calculate Legic CRC8 over given hexbytes"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmdhflegic.h b/client/cmdhflegic.h index 78527f23..6d973998 100644 --- a/client/cmdhflegic.h +++ b/client/cmdhflegic.h @@ -24,9 +24,9 @@ #include "legic.h" // legic_card_select_t struct int CmdHFLegic(const char *Cmd); +int CmdLegicInfo(const char *Cmd); int CmdLegicRFRead(const char *Cmd); -int CmdLegicDecode(const char *Cmd); int CmdLegicLoad(const char *Cmd); int CmdLegicSave(const char *Cmd); int CmdLegicRfSim(const char *Cmd); @@ -35,11 +35,21 @@ int CmdLegicRfRawWrite(const char *Cmd); int CmdLegicRfFill(const char *Cmd); int CmdLegicCalcCrc8(const char *Cmd); -int CmdLegicInfo(const char *Cmd); -int HFLegicInfo(const char *Cmd, bool verbose); + +int CmdLegicReader(const char *Cmd); +int HFLegicReader(const char *Cmd, bool verbose); + +int CmdLegicDump(const char *Cmd); + int usage_legic_calccrc8(void); int usage_legic_load(void); int usage_legic_read(void); +int usage_legic_sim(void); +int usage_legic_write(void); +int usage_legic_rawwrite(void); +int usage_legic_fill(void); +int usage_legic_reader(void); int usage_legic_info(void); +int usage_legic_dump(void); #endif