From: iceman1001 Date: Fri, 29 Jul 2016 09:04:12 +0000 (+0200) Subject: ADD: LF JABLOTRON functionality. with clone/sim and detection in LF SEARCH. X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/6c283951062aaad9d0d1ba8670b02895047be438 ADD: LF JABLOTRON functionality. with clone/sim and detection in LF SEARCH. CHG: removed no-existing crc8ja code FIX: a check in ASKbiphaseDemod to make sure graphbuff is not empty. --- diff --git a/client/Makefile b/client/Makefile index 3f1d13ed..11246a1c 100644 --- a/client/Makefile +++ b/client/Makefile @@ -130,6 +130,7 @@ CMDSRCS = mifarehost.c \ cmdlfpyramid.c \ cmdlfguard.c \ cmdlfnedap.c \ + cmdlfjablotron.c \ pm3_binlib.c \ scripting.c \ cmdscript.c \ diff --git a/client/cmdanalyse.c b/client/cmdanalyse.c index b5f9cb52..6a8e5bc0 100644 --- a/client/cmdanalyse.c +++ b/client/cmdanalyse.c @@ -70,7 +70,7 @@ static uint8_t calcSumCrumbAdd( uint8_t* bytes, uint8_t len, uint32_t mask) { sum += CRUMB(bytes[i], 4); sum += CRUMB(bytes[i], 6); } - sum ^= mask; + sum &= mask; return sum; } static uint8_t calcSumCrumbAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) { @@ -82,7 +82,7 @@ static uint8_t calcSumNibbleAdd( uint8_t* bytes, uint8_t len, uint32_t mask) { sum += NIBBLE_LOW(bytes[i]); sum += NIBBLE_HIGH(bytes[i]); } - sum ^= mask; + sum &= mask; return sum; } static uint8_t calcSumNibbleAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask){ @@ -93,7 +93,7 @@ static uint8_t calcSumByteAdd( uint8_t* bytes, uint8_t len, uint32_t mask) { uint8_t sum = 0; for (uint8_t i = 0; i < len; i++) sum += bytes[i]; - sum ^= mask; + sum &= mask; return sum; } // Ones complement @@ -105,7 +105,7 @@ static uint8_t calcSumByteSub( uint8_t* bytes, uint8_t len, uint32_t mask) { uint8_t sum = 0; for (uint8_t i = 0; i < len; i++) sum -= bytes[i]; - sum ^= mask; + sum &= mask; return sum; } static uint8_t calcSumByteSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask){ @@ -117,7 +117,7 @@ static uint8_t calcSumNibbleSub( uint8_t* bytes, uint8_t len, uint32_t mask) { sum -= NIBBLE_LOW(bytes[i]); sum -= NIBBLE_HIGH(bytes[i]); } - sum ^= mask; + sum &= mask; return sum; } static uint8_t calcSumNibbleSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask) { @@ -155,8 +155,7 @@ int CmdAnalyseCRC(const char *Cmd) { } len >>= 1; - PrintAndLog("\nTests with '%s' hex bytes", sprint_hex(data, len)); - PrintAndLog(" JA: CRC8: %X (0x6C expected)", CRC8ja(data, len) ); + //PrintAndLog("\nTests with '%s' hex bytes", sprint_hex(data, len)); PrintAndLog("\nTests of reflection. Two current methods in source code"); PrintAndLog(" reflect(0x3e23L,3) is %04X == 0x3e26", reflect(0x3e23L,3) ); @@ -170,7 +169,6 @@ int CmdAnalyseCRC(const char *Cmd) { uint8_t dataStr[] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39 }; uint8_t legic8 = CRC8Legic(dataStr, sizeof(dataStr)); - PrintAndLog("JA: CRC8 : %X (0x28 expected)", CRC8ja(dataStr, sizeof(dataStr)) ); PrintAndLog("LEGIC: CRC16: %X", CRC16Legic(dataStr, sizeof(dataStr), legic8)); //these below has been tested OK. diff --git a/client/cmddata.c b/client/cmddata.c index 6570b243..18edd33e 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -527,7 +527,11 @@ int ASKbiphaseDemod(const char *Cmd, bool verbose) sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr); uint8_t BitStream[MAX_DEMOD_BUF_LEN]; - size_t size = getFromGraphBuf(BitStream); + size_t size = getFromGraphBuf(BitStream); + if (size == 0 ) { + if (g_debugMode) PrintAndLog("DEBUG: no data in graphbuf"); + return 0; + } //invert here inverts the ask raw demoded bits which has no effect on the demod, but we need the pointer int errCnt = askdemod(BitStream, &size, &clk, &invert, maxErr, 0, 0); if ( errCnt < 0 || errCnt > maxErr ) { diff --git a/client/cmdlf.c b/client/cmdlf.c index 0ab24dba..f48a4371 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -637,115 +637,113 @@ int CmdLFSim(const char *Cmd) return 0; } -// by marshmellow - sim ask data given clock, fcHigh, fcLow, invert +// by marshmellow - sim fsk data given clock, fcHigh, fcLow, invert // - allow pull data from DemodBuffer int CmdLFfskSim(const char *Cmd) { //might be able to autodetect FCs and clock from Graphbuffer if using demod buffer // otherwise will need FChigh, FClow, Clock, and bitstream - uint8_t fcHigh=0, fcLow=0, clk=0; - uint8_t invert=0; - bool errors = FALSE; - char hexData[32] = {0x00}; // store entered hex data - uint8_t data[255] = {0x00}; - int dataLen = 0; - uint8_t cmdp = 0; - while(param_getchar(Cmd, cmdp) != 0x00) - { - switch(param_getchar(Cmd, cmdp)) - { - case 'h': - return usage_lf_simfsk(); - case 'i': - invert = 1; - cmdp++; - break; - case 'c': - errors |= param_getdec(Cmd,cmdp+1,&clk); - cmdp+=2; - break; - case 'H': - errors |= param_getdec(Cmd,cmdp+1,&fcHigh); - cmdp+=2; - break; - case 'L': - errors |= param_getdec(Cmd,cmdp+1,&fcLow); - cmdp+=2; - break; - //case 's': - // separator=1; - // cmdp++; - // break; - case 'd': - dataLen = param_getstr(Cmd, cmdp+1, hexData); - if (dataLen==0) { - errors=TRUE; - } else { - dataLen = hextobinarray((char *)data, hexData); - } - if (dataLen==0) errors=TRUE; - if (errors) PrintAndLog ("Error getting hex data"); - cmdp+=2; - break; - default: - PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = TRUE; - break; - } - if(errors) break; - } - if(cmdp == 0 && DemodBufferLen == 0) - { - errors = TRUE;// No args - } - - //Validations - if(errors) - { - return usage_lf_simfsk(); - } + uint8_t fcHigh = 0, fcLow = 0, clk = 0; + uint8_t invert = 0; + bool errors = FALSE; + char hexData[32] = {0x00}; // store entered hex data + uint8_t data[255] = {0x00}; + int dataLen = 0; + uint8_t cmdp = 0; + + while(param_getchar(Cmd, cmdp) != 0x00) + { + switch(param_getchar(Cmd, cmdp)) + { + case 'h': + return usage_lf_simfsk(); + case 'i': + invert = 1; + cmdp++; + break; + case 'c': + errors |= param_getdec(Cmd, cmdp+1, &clk); + cmdp += 2; + break; + case 'H': + errors |= param_getdec(Cmd, cmdp+1, &fcHigh); + cmdp += 2; + break; + case 'L': + errors |= param_getdec(Cmd, cmdp+1, &fcLow); + cmdp += 2; + break; + //case 's': + // separator = 1; + // cmdp++; + // break; + case 'd': + dataLen = param_getstr(Cmd, cmdp+1, hexData); + if (dataLen == 0) + errors = TRUE; + else + dataLen = hextobinarray((char *)data, hexData); + + if (dataLen == 0) errors = TRUE; + if (errors) PrintAndLog ("Error getting hex data"); + cmdp+=2; + break; + default: + PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = TRUE; + break; + } + if(errors) break; + } + + // No args + if(cmdp == 0 && DemodBufferLen == 0) + errors = TRUE; - if (dataLen == 0){ //using DemodBuffer - if (clk==0 || fcHigh==0 || fcLow==0){ //manual settings must set them all - uint8_t ans = fskClocks(&fcHigh, &fcLow, &clk, 0); - if (ans==0){ - if (!fcHigh) fcHigh=10; - if (!fcLow) fcLow=8; - if (!clk) clk=50; - } - } - } else { - setDemodBuf(data, dataLen, 0); - } + //Validations + if(errors) return usage_lf_simfsk(); + + if (dataLen == 0){ //using DemodBuffer + if (clk == 0 || fcHigh == 0 || fcLow == 0){ //manual settings must set them all + uint8_t ans = fskClocks(&fcHigh, &fcLow, &clk, 0); + if (ans==0){ + if (!fcHigh) fcHigh = 10; + if (!fcLow) fcLow = 8; + if (!clk) clk = 50; + } + } + } else { + setDemodBuf(data, dataLen, 0); + } //default if not found - if (clk == 0) clk = 50; - if (fcHigh == 0) fcHigh = 10; - if (fcLow == 0) fcLow = 8; + if (clk == 0) clk = 50; + if (fcHigh == 0) fcHigh = 10; + if (fcLow == 0) fcLow = 8; - uint16_t arg1, arg2; - arg1 = fcHigh << 8 | fcLow; - arg2 = invert << 8 | clk; - size_t size = DemodBufferLen; - if (size > USB_CMD_DATA_SIZE) { - PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE); - size = USB_CMD_DATA_SIZE; - } - UsbCommand c = {CMD_FSK_SIM_TAG, {arg1, arg2, size}}; + uint16_t arg1, arg2; + arg1 = fcHigh << 8 | fcLow; + arg2 = invert << 8 | clk; + size_t size = DemodBufferLen; + if (size > USB_CMD_DATA_SIZE) { + PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE); + size = USB_CMD_DATA_SIZE; + } + UsbCommand c = {CMD_FSK_SIM_TAG, {arg1, arg2, size}}; - memcpy(c.d.asBytes, DemodBuffer, size); + memcpy(c.d.asBytes, DemodBuffer, size); clearCommandBuffer(); - SendCommand(&c); - return 0; + SendCommand(&c); + return 0; } // by marshmellow - sim ask data given clock, invert, manchester or raw, separator // - allow pull data from DemodBuffer int CmdLFaskSim(const char *Cmd) { - //autodetect clock from Graphbuffer if using demod buffer + // autodetect clock from Graphbuffer if using demod buffer // needs clock, invert, manchester/raw as m or r, separator as s, and bitstream - uint8_t encoding = 1, separator = 0, clk=0, invert=0; + uint8_t encoding = 1, separator = 0, clk = 0, invert = 0; bool errors = FALSE; char hexData[32] = {0x00}; uint8_t data[255]= {0x00}; // store entered hex data @@ -760,35 +758,35 @@ int CmdLFaskSim(const char *Cmd) cmdp++; break; case 'c': - errors |= param_getdec(Cmd,cmdp+1,&clk); - cmdp+=2; + errors |= param_getdec(Cmd, cmdp+1, &clk); + cmdp += 2; break; case 'b': - encoding=2; //biphase + encoding = 2; //biphase cmdp++; break; case 'm': - encoding=1; + encoding = 1; //manchester cmdp++; break; case 'r': - encoding=0; + encoding = 0; //raw cmdp++; break; case 's': - separator=1; + separator = 1; cmdp++; break; case 'd': dataLen = param_getstr(Cmd, cmdp+1, hexData); - if (dataLen==0) + if (dataLen == 0) errors = TRUE; else dataLen = hextobinarray((char *)data, hexData); - if (dataLen==0) errors = TRUE; + if (dataLen == 0) errors = TRUE; if (errors) PrintAndLog ("Error getting hex data, datalen: %d", dataLen); - cmdp+=2; + cmdp += 2; break; default: PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); @@ -797,9 +795,10 @@ int CmdLFaskSim(const char *Cmd) } if(errors) break; } - + + // No args if(cmdp == 0 && DemodBufferLen == 0) - errors = TRUE;// No args + errors = TRUE; //Validations if(errors) return usage_lf_simask(); @@ -1050,75 +1049,69 @@ int CmdLFfind(const char *Cmd) { ans=CmdFSKdemodIO(""); if (ans>0) { - PrintAndLog("\nValid IO Prox ID Found!"); - return 1; + PrintAndLog("\nValid IO Prox ID Found!"); + return 1; } - ans=CmdFSKdemodPyramid(""); if (ans>0) { - PrintAndLog("\nValid Pyramid ID Found!"); - return 1; + PrintAndLog("\nValid Pyramid ID Found!"); + return 1; } - ans=CmdFSKdemodParadox(""); if (ans>0) { - PrintAndLog("\nValid Paradox ID Found!"); - return 1; + PrintAndLog("\nValid Paradox ID Found!"); + return 1; } - ans=CmdFSKdemodAWID(""); if (ans>0) { - PrintAndLog("\nValid AWID ID Found!"); - return 1; + PrintAndLog("\nValid AWID ID Found!"); + return 1; } - ans=CmdFSKdemodHID(""); if (ans>0) { - PrintAndLog("\nValid HID Prox ID Found!"); - return 1; + PrintAndLog("\nValid HID Prox ID Found!"); + return 1; } - ans=CmdAskEM410xDemod(""); if (ans>0) { - PrintAndLog("\nValid EM410x ID Found!"); - return 1; + PrintAndLog("\nValid EM410x ID Found!"); + return 1; } - ans=CmdG_Prox_II_Demod(""); if (ans>0) { - PrintAndLog("\nValid Guardall G-Prox II ID Found!"); - return 1; + PrintAndLog("\nValid Guardall G-Prox II ID Found!"); + return 1; } - ans=CmdFDXBdemodBI(""); if (ans>0) { PrintAndLog("\nValid FDX-B ID Found!"); return 1; } - ans=EM4x50Read("", false); if (ans>0) { PrintAndLog("\nValid EM4x50 ID Found!"); return 1; } - ans=CmdVikingDemod(""); if (ans>0) { PrintAndLog("\nValid Viking ID Found!"); return 1; } - ans=CmdIndalaDecode(""); if (ans>0) { PrintAndLog("\nValid Indala ID Found!"); return 1; } - ans=CmdPSKNexWatch(""); if (ans>0) { PrintAndLog("\nValid NexWatch ID Found!"); return 1; } + ans=CmdJablotronDemod(""); + if (ans>0) { + PrintAndLog("\nValid Jablotron ID Found!"); + return 1; + } ans=CmdLFNedapDemod(""); if (ans>0) { PrintAndLog("\nValid NEDAP ID Found!"); @@ -1197,6 +1190,7 @@ static command_t CommandTable[] = {"hid", CmdLFHID, 1, "{ HID RFIDs... }"}, {"hitag", CmdLFHitag, 1, "{ HITAG RFIDs... }"}, {"io", CmdLFIO, 1, "{ IOPROX RFIDs... }"}, + {"jablotron", CmdLFJablotron, 1, "{ JABLOTRON RFIDs... }"}, {"nedap", CmdLFNedap, 1, "{ NEDAP RFIDs... }"}, {"pcf7931", CmdLFPCF7931, 1, "{ PCF7931 RFIDs... }"}, {"presco", CmdLFPresco, 1, "{ Presco RFIDs... }"}, diff --git a/client/cmdlf.h b/client/cmdlf.h index d04f9679..9b9c495f 100644 --- a/client/cmdlf.h +++ b/client/cmdlf.h @@ -17,26 +17,27 @@ #include "proxmark3.h" #include "lfdemod.h" -#include "util.h" // for parsing cli command utils -#include "ui.h" // for show graph controls -#include "graph.h" // for graph data -#include "cmdparser.h" // for getting cli commands included in cmdmain.h -#include "cmdmain.h" // for sending cmds to device -#include "data.h" // for GetFromBigBuf -#include "cmddata.h" // for `lf search` -#include "cmdlfawid.h" // for awid menu -#include "cmdlfem4x.h" // for em4x menu -#include "cmdlfhid.h" // for hid menu -#include "cmdlfhitag.h" // for hitag menu -#include "cmdlfio.h" // for ioprox menu -#include "cmdlft55xx.h" // for t55xx menu -#include "cmdlfti.h" // for ti menu -#include "cmdlfpresco.h" // for presco menu -#include "cmdlfpcf7931.h"// for pcf7931 menu -#include "cmdlfpyramid.h"// for pyramid menu -#include "cmdlfviking.h" // for viking menu -#include "cmdlfguard.h" // for GuardAll menu -#include "cmdlfnedap.h" // for NEDAP menu +#include "util.h" // for parsing cli command utils +#include "ui.h" // for show graph controls +#include "graph.h" // for graph data +#include "cmdparser.h" // for getting cli commands included in cmdmain.h +#include "cmdmain.h" // for sending cmds to device +#include "data.h" // for GetFromBigBuf +#include "cmddata.h" // for `lf search` +#include "cmdlfawid.h" // for awid menu +#include "cmdlfem4x.h" // for em4x menu +#include "cmdlfhid.h" // for hid menu +#include "cmdlfhitag.h" // for hitag menu +#include "cmdlfio.h" // for ioprox menu +#include "cmdlft55xx.h" // for t55xx menu +#include "cmdlfti.h" // for ti menu +#include "cmdlfpresco.h" // for presco menu +#include "cmdlfpcf7931.h" // for pcf7931 menu +#include "cmdlfpyramid.h" // for pyramid menu +#include "cmdlfviking.h" // for viking menu +#include "cmdlfguard.h" // for GuardAll menu +#include "cmdlfnedap.h" // for NEDAP menu +#include "cmdlfjablotron.h" // for JABLOTRON menu int CmdLF(const char *Cmd); diff --git a/client/cmdlfjablotron.c b/client/cmdlfjablotron.c new file mode 100644 index 00000000..a97bb770 --- /dev/null +++ b/client/cmdlfjablotron.c @@ -0,0 +1,206 @@ +//----------------------------------------------------------------------------- +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Low frequency Presco tag commands +//----------------------------------------------------------------------------- +#include "cmdlfjablotron.h" + +static int CmdHelp(const char *Cmd); + +int usage_lf_jablotron_clone(void){ + PrintAndLog("clone a Jablotron tag to a T55x7 tag."); + PrintAndLog("Usage: lf jablotron clone d "); + PrintAndLog("Options :"); + PrintAndLog(" d : jablotron card ID"); + PrintAndLog(" : specify write to Q5 (t5555 instead of t55x7)"); + PrintAndLog(""); + PrintAndLog("Sample : lf jablotron clone d 123456789"); + return 0; +} + +int usage_lf_jablotron_sim(void) { + PrintAndLog("Enables simulation of jablotron card with specified card number."); + PrintAndLog("Simulation runs until the button is pressed or another USB command is issued."); + PrintAndLog("Per jablotron format, the card number is 9 digit number and can contain *# chars. Larger values are truncated."); + PrintAndLog(""); + PrintAndLog("Usage: lf jablotron sim d or H "); + PrintAndLog("Options :"); + PrintAndLog(" d : jablotron card number"); +// PrintAndLog(" H : 8 digit hex card number"); + PrintAndLog(""); + PrintAndLog("Sample : lf jablotron sim d 123456789"); + return 0; +} + +int getJablotronBits(uint64_t fullcode, uint8_t *bits) { + //preamp + num_to_bytebits(0xFFFF, 16, bits); + + //fullcode + num_to_bytebits(fullcode, 40, bits+16); + + //chksum byte + uint8_t crc = 0; + for (int i=16; i < 56; i += 8) { + crc += bytebits_to_byte(bits+i,8); + } + crc ^= 0x3A; + num_to_bytebits(crc, 8, bits+56); + + return 1; +} + +//see ASKDemod for what args are accepted +int CmdJablotronDemod(const char *Cmd) { + + //Differential Biphase / di-phase (inverted biphase) + //get binary from ask wave + if (!ASKbiphaseDemod("0 64 1 0", FALSE)) { + if (g_debugMode) PrintAndLog("Error Jablotron: ASKbiphaseDemod failed"); + return 0; + } + size_t size = DemodBufferLen; + int ans = JablotronDemod(DemodBuffer, &size); + if (ans < 0){ + if (g_debugMode){ + // if (ans == -5) + // PrintAndLog("DEBUG: Error - not enough samples"); + // else if (ans == -1) + // PrintAndLog("DEBUG: Error - only noise found"); + // else if (ans == -2) + // PrintAndLog("DEBUG: Error - problem during ASK/Biphase demod"); + if (ans == -3) + PrintAndLog("DEBUG: Error - Size not correct: %d", size); + else if (ans == -4) + PrintAndLog("DEBUG: Error - Jablotron preamble not found"); + else + PrintAndLog("DEBUG: Error - ans: %d", ans); + } + return 0; + } + //got a good demod + uint32_t raw1 = bytebits_to_byte(DemodBuffer+ans, 32); + uint32_t raw2 = bytebits_to_byte(DemodBuffer+ans+32, 32); + uint64_t cardid = (raw1 & 0x0000FFFF); + cardid <<= 32; + cardid |= (raw2 >> 8); + + PrintAndLog("Jablotron Tag Found: Card ID %12X", cardid); + PrintAndLog("Raw: %08X%08X", raw1 ,raw2); + + setDemodBuf(DemodBuffer+ans, 64, 0); + + //PrintAndLog("1410-%u-%u-%08X-%02X", fullcode); + return 1; +} + +int CmdJablotronRead(const char *Cmd) { + // read lf silently + CmdLFRead("s"); + // get samples silently + getSamples("30000",false); + // demod and output Presco ID + return CmdJablotronDemod(Cmd); +} + +int CmdJablotronClone(const char *Cmd) { + + uint64_t fullcode = 0; + uint32_t blocks[3] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_64 | 2<=0; i--) { + c.arg[0] = blocks[i]; + c.arg[1] = i; + clearCommandBuffer(); + SendCommand(&c); + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){ + PrintAndLog("Error occurred, device did not respond during write operation."); + return -1; + } + } + return 0; +} + +int CmdJablotronSim(const char *Cmd) { + uint64_t fullcode = 0; + + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_jablotron_sim(); + + fullcode = param_get64ex(Cmd, 1, 0, 16); + + uint8_t clk = 64, encoding = 2, separator = 0, invert = 1; + uint16_t arg1, arg2; + size_t size = 64; + arg1 = clk << 8 | encoding; + arg2 = invert << 8 | separator; + + PrintAndLog("Simulating Jablotron - FullCode: %12X", fullcode); + + UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}}; + getJablotronBits(fullcode, c.d.asBytes); + clearCommandBuffer(); + SendCommand(&c); + return 0; +} + +static command_t CommandTable[] = { + {"help", CmdHelp, 1, "This help"}, + {"read", CmdJablotronRead, 0, "Attempt to read and Extract tag data"}, + {"clone", CmdJablotronClone, 0, "h [Q5] clone jablotron tag"}, + {"sim", CmdJablotronSim, 0, "h simulate jablotron tag"}, + {NULL, NULL, 0, NULL} +}; + +int CmdLFJablotron(const char *Cmd) { + clearCommandBuffer(); + CmdsParse(CommandTable, Cmd); + return 0; +} + +int CmdHelp(const char *Cmd) { + CmdsHelp(CommandTable); + return 0; +} diff --git a/client/cmdlfjablotron.h b/client/cmdlfjablotron.h new file mode 100644 index 00000000..5e76df1f --- /dev/null +++ b/client/cmdlfjablotron.h @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Low frequency T55xx commands +//----------------------------------------------------------------------------- +#ifndef CMDLFJABLOTRON_H__ +#define CMDLFJABLOTRON_H__ +#include +#include +#include "proxmark3.h" +#include "ui.h" +#include "util.h" +#include "graph.h" +#include "cmdparser.h" +#include "cmddata.h" +#include "cmdmain.h" +#include "cmdlf.h" +#include "protocols.h" // for T55xx config register definitions +#include "lfdemod.h" // parityTest +int CmdLFJablotron(const char *Cmd); +int CmdJablotronClone(const char *Cmd); +int CmdJablotronSim(const char *Cmd); +int CmdJablotronRead(const char *Cmd); +int CmdJablotronDemod(const char *Cmd); + +int getJablotronBits(uint64_t fullcode, uint8_t *bits); + +int usage_lf_jablotron_clone(void); +int usage_lf_jablotron_sim(void); +int usage_lf_jablotron_read(void); +int usage_lf_jablotron_demod(void); +#endif + diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index 2aaae5db..9e6a624b 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -82,16 +82,11 @@ int GetNedapBits(uint32_t cn, uint8_t *nedapBits) { int CmdLFNedapDemod(const char *Cmd) { //raw ask demod no start bit finding just get binary from wave - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - size_t size = getFromGraphBuf(BitStream); - if (size==0) return 0; - - //get binary from ask wave if (!ASKbiphaseDemod("0 64 0 0", FALSE)) { if (g_debugMode) PrintAndLog("Error NEDAP: ASKbiphaseDemod failed"); return 0; } - size = DemodBufferLen; + size_t size = DemodBufferLen; int idx = NedapDemod(DemodBuffer, &size); if (idx < 0){ if (g_debugMode){ @@ -143,13 +138,13 @@ int CmdLFNedapDemod(const char *Cmd) { uint8_t firstParity = GetParity( DemodBuffer, EVEN, 63); if ( firstParity != DemodBuffer[63] ) { PrintAndLog("1st 64bit parity check failed: %d|%d ", DemodBuffer[63], firstParity); - //return 0; + return 0; } uint8_t secondParity = GetParity( DemodBuffer+64, EVEN, 63); if ( secondParity != DemodBuffer[127] ) { PrintAndLog("2st 64bit parity check failed: %d|%d ", DemodBuffer[127], secondParity); - //return 0; + return 0; } // ok valid card found! diff --git a/common/crc.c b/common/crc.c index 451282bf..311a676c 100644 --- a/common/crc.c +++ b/common/crc.c @@ -94,17 +94,6 @@ uint32_t CRC8Legic(uint8_t *buff, size_t size) { return reflect(crc_finish(&crc), 8); } -// credits to marshmellow -// width=8 poly=0xA3, reversed poly=0x8B, init=0xB0 refin=true refout=true xorout=0x00 check=0x28 name="CRC-8/JA" -uint32_t CRC8ja(uint8_t *buff, size_t size) { - crc_t crc; - crc_init_ref(&crc, 8, 0xA3, 0x42, 0x00, TRUE, TRUE); - for ( int i=0; i < size; ++i) - crc_update(&crc, buff[i], 8); - return crc_finish(&crc); - //return reflect(crc_finish(&crc), 8); -} - // This CRC-16 is used in Legic Advant systems. // width=8 poly=0xB400, reversed poly=0x init=depends refin=true refout=true xorout=0x0000 check= name="CRC-16/LEGIC" uint32_t CRC16Legic(uint8_t *buff, size_t size, uint8_t uidcrc) { diff --git a/common/crc.h b/common/crc.h index 957226a4..5a9bcfa7 100644 --- a/common/crc.h +++ b/common/crc.h @@ -65,9 +65,6 @@ uint32_t CRC8Legic(uint8_t *buff, size_t size); // ie: uidcrc = 0x78 then initial_value == 0x7878 uint32_t CRC16Legic(uint8_t *buff, size_t size, uint8_t uidcrc); -// Calculate CRC-8/ja checksum -uint32_t CRC8ja(uint8_t *buff, size_t size); - // test crc 16. uint32_t CRC16_DNP(uint8_t *buff, size_t size); uint32_t CRC16_CCITT(uint8_t *buff, size_t size); diff --git a/common/lfdemod.c b/common/lfdemod.c index 8b31f1a4..2f376e5f 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -723,6 +723,33 @@ int FDXBdemodBI(uint8_t *dest, size_t *size) return (int)startIdx; } +// ASK/Diphase fc/64 (inverted Biphase) +// Note: this i s not a demod, this is only a detection +// the parameter *dest needs to be demoded before call +int JablotronDemod(uint8_t *dest, size_t *size){ + //make sure buffer has enough data + if (*size < 64) return -1; + + size_t startIdx = 0; + // 0xFFFF preamble, 64bits + uint8_t preamble[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; + + uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx); + if (errChk == 0) return -4; //preamble not found + + uint8_t checkCalc = 0; + for (int i=16; i < 56; i += 8) { + checkCalc += bytebits_to_byte(dest+startIdx+i,8); + } + checkCalc ^= 0x3A; + + uint8_t crc = bytebits_to_byte(dest+startIdx+56,8); + + if ( checkCalc != crc ) return -5; + if (*size != 64) return -6; + return (int)startIdx; +} + // by marshmellow // FSK Demod then try to locate an AWID ID int AWIDdemodFSK(uint8_t *dest, size_t *size) diff --git a/common/lfdemod.h b/common/lfdemod.h index 9895434c..aefdadb8 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -56,4 +56,5 @@ int PyramiddemodFSK(uint8_t *dest, size_t *size); int VikingDemod_AM(uint8_t *dest, size_t *size); int PrescoDemod(uint8_t *dest, size_t *size); int NedapDemod(uint8_t *dest, size_t *size); +int JablotronDemod(uint8_t *dest, size_t *size); #endif