diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b856ec1..19db5195 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,8 +22,10 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `lf hitag reader 03` - read block (instead of pages) - Added `lf hitag reader 04` - read block (instead of pages) - Added `hf fido` `assert` and `make` commands from fido2 protocol (authenticatorMakeCredential and authenticatorGetAssertion) (Merlok) +- Added `lf paradox clone` to clone a Paradox card - Added `emv` commmands working for both contactless and smart cards (Merlok) + ## [v3.1.0][2018-10-10] ### Changed diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 35c9e5bf..c5c17867 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -744,7 +744,7 @@ void SamyRun() /* need this delay to prevent catching some weird data */ SpinDelay(500); - CopyHIDtoT55x7(tops[selected] & 0x000FFFFF, high[selected], low[selected], (tops[selected] != 0 && ((high[selected]& 0xFFFFFFC0) != 0))); + CopyHIDtoT55x7(tops[selected] & 0x000FFFFF, high[selected], low[selected], (tops[selected] != 0 && ((high[selected]& 0xFFFFFFC0) != 0)), 0x1D); if (tops[selected] > 0) Dbprintf("Cloned %x %x%08x%08x", selected, tops[selected], high[selected], low[selected]); else @@ -1003,7 +1003,11 @@ void UsbPacketReceived(uint8_t *packet, int len) CmdPSKsimTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); break; case CMD_HID_CLONE_TAG: - CopyHIDtoT55x7(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]); + CopyHIDtoT55x7(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0], 0x1D); + break; + case CMD_PARADOX_CLONE_TAG: + // Paradox cards are the same as HID, with a different preamble, so we can reuse the same function + CopyHIDtoT55x7(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0], 0x0F); break; case CMD_IO_DEMOD_FSK: CmdIOdemodFSK(c->arg[0], 0, 0, 1); diff --git a/armsrc/apps.h b/armsrc/apps.h index 6af22b57..b9b1f3de 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -78,7 +78,7 @@ void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol); // Realt void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol); void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol); void CopyIOtoT55x7(uint32_t hi, uint32_t lo); // Clone an ioProx card to T5557/T5567 -void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567 +void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, uint8_t preamble); // Clone an HID-like card to T5557/T5567 void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5); void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo); void CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-bit tag by UID to T55x7 diff --git a/armsrc/lfops.c b/armsrc/lfops.c index b56c3f51..1816bdca 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1417,8 +1417,8 @@ void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) { } } -// Copy HID id to card and setup block 0 config -void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) { +// Copy a HID-like card (e.g. HID Proximity, Paradox) to a T55x7 compatible card +void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, uint8_t preamble) { uint32_t data[] = {0,0,0,0,0,0,0}; uint8_t last_block = 0; @@ -1430,15 +1430,15 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) { } // Build the 6 data blocks for supplied 84bit ID last_block = 6; - // load preamble (1D) & long format identifier (9E manchester encoded) - data[1] = 0x1D96A900 | (manchesterEncode2Bytes((hi2 >> 16) & 0xF) & 0xFF); + // load preamble & long format identifier (9E manchester encoded) + data[1] = (preamble << 24) | 0x96A900 | (manchesterEncode2Bytes((hi2 >> 16) & 0xF) & 0xFF); // load raw id from hi2, hi, lo to data blocks (manchester encoded) data[2] = manchesterEncode2Bytes(hi2 & 0xFFFF); data[3] = manchesterEncode2Bytes(hi >> 16); data[4] = manchesterEncode2Bytes(hi & 0xFFFF); data[5] = manchesterEncode2Bytes(lo >> 16); data[6] = manchesterEncode2Bytes(lo & 0xFFFF); - } else { + } else { // Ensure no more than 44 bits supplied if (hi>0xFFF) { DbpString("Tags can only have 44 bits."); @@ -1447,7 +1447,7 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) { // Build the 3 data blocks for supplied 44bit ID last_block = 3; // load preamble - data[1] = 0x1D000000 | (manchesterEncode2Bytes(hi) & 0xFFFFFF); + data[1] = (preamble << 24) | (manchesterEncode2Bytes(hi) & 0xFFFFFF); data[2] = manchesterEncode2Bytes(lo >> 16); data[3] = manchesterEncode2Bytes(lo & 0xFFFF); } diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 38e7073c..14340082 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -39,7 +39,7 @@ * * Returns the number of nibbles (4 bits) entered. */ -int hexstring_to_int96(/* out */ uint32_t* hi2,/* out */ uint32_t* hi, /* out */ uint32_t* lo, const char* str) { +int hid_hexstring_to_int96(/* out */ uint32_t* hi2,/* out */ uint32_t* hi, /* out */ uint32_t* lo, const char* str) { // TODO: Replace this with param_gethex when it supports arbitrary length // inputs. int n = 0, i = 0; @@ -201,7 +201,7 @@ int CmdHIDReadFSK(const char *Cmd) int CmdHIDSim(const char *Cmd) { uint32_t hi2 = 0, hi = 0, lo = 0; - hexstring_to_int96(&hi2, &hi, &lo, Cmd); + hid_hexstring_to_int96(&hi2, &hi, &lo, Cmd); if (hi2 != 0) { PrintAndLog("Emulating tag with ID %x%08x%08x", hi2, hi, lo); } else { @@ -218,7 +218,7 @@ int CmdHIDSim(const char *Cmd) int CmdHIDClone(const char *Cmd) { unsigned int top = 0, mid = 0, bot = 0; - hexstring_to_int96(&top, &mid, &bot, Cmd); + hid_hexstring_to_int96(&top, &mid, &bot, Cmd); hidproxmessage_t packed = initialize_proxmessage_object(top, mid, bot); Write(&packed); return 0; @@ -234,7 +234,7 @@ int CmdHIDDecode(const char *Cmd){ uint32_t top = 0, mid = 0, bot = 0; bool ignoreParity = false; - hexstring_to_int96(&top, &mid, &bot, Cmd); + hid_hexstring_to_int96(&top, &mid, &bot, Cmd); hidproxmessage_t packed = initialize_proxmessage_object(top, mid, bot); char opt = param_getchar(Cmd, 1); diff --git a/client/cmdlfhid.h b/client/cmdlfhid.h index ef907f67..353805db 100644 --- a/client/cmdlfhid.h +++ b/client/cmdlfhid.h @@ -22,4 +22,6 @@ int CmdHIDClone(const char *Cmd); int CmdHIDDecode(const char *Cmd); int CmdHIDEncode(const char *Cmd); int CmdHIDWrite(const char *Cmd); +// This is used by the Paradox code +int hid_hexstring_to_int96(/* out */ uint32_t* hi2,/* out */ uint32_t* hi, /* out */ uint32_t* lo, const char* str); #endif diff --git a/client/cmdlfparadox.c b/client/cmdlfparadox.c index e918c7fe..d6710219 100644 --- a/client/cmdlfparadox.c +++ b/client/cmdlfparadox.c @@ -19,7 +19,14 @@ #include "cmddata.h" #include "cmdlf.h" #include "lfdemod.h" +#include "comms.h" +// This card type is similar to HID, so we include the utils from there +#include "cmdlfhid.h" +#include "hidcardformats.h" +#include "hidcardformatutils.h" + static int CmdHelp(const char *Cmd); +void ParadoxWrite(hidproxmessage_t *packed); //by marshmellow //Paradox Prox demod - FSK RF/50 with preamble of 00001111 (then manchester encoded) @@ -55,14 +62,24 @@ int CmdFSKdemodParadox(const char *Cmd) if (g_debugMode) PrintAndLog("DEBUG: Error - no value found"); return 0; } + uint32_t fc = ((hi & 0x3)<<6) | (lo>>26); uint32_t cardnum = (lo>>10)&0xFFFF; uint32_t rawLo = bytebits_to_byte(BitStream+idx+64,32); uint32_t rawHi = bytebits_to_byte(BitStream+idx+32,32); uint32_t rawHi2 = bytebits_to_byte(BitStream+idx,32); - PrintAndLog("Paradox TAG ID: %x%08x - FC: %d - Card: %d - Checksum: %02x - RAW: %08x%08x%08x", - hi>>10, (hi & 0x3)<<26 | (lo>>10), fc, cardnum, (lo>>2) & 0xFF, rawHi2, rawHi, rawLo); + // Steal the HID parsing to output a "full" ID we can send to the HID cloning function + hidproxmessage_t packed = initialize_proxmessage_object(hi2, hi, lo); + + if (packed.top != 0) { + PrintAndLog("Paradox TAG ID: %x%08x (Full ID: %x%08x%08x) - FC: %d - Card: %d - Checksum: %02x - RAW: %08x%08x%08x", + hi>>10, (hi & 0x3)<<26 | (lo>>10), (uint32_t)packed.top, (uint32_t)packed.mid, (uint32_t)packed.bot, fc, cardnum, (lo>>2) & 0xFF, rawHi2, rawHi, rawLo); + } else { + PrintAndLog("Paradox TAG ID: %x%08x (Full ID: %x%08x) - FC: %d - Card: %d - Checksum: %02x - RAW: %08x%08x%08x", + hi>>10, (hi & 0x3)<<26 | (lo>>10), (uint32_t)packed.mid, (uint32_t)packed.bot, fc, cardnum, (lo>>2) & 0xFF, rawHi2, rawHi, rawLo); + + } setDemodBuf(BitStream,BitLen,idx); setClockGrid(50, waveIdx + (idx*50)); if (g_debugMode){ @@ -80,10 +97,31 @@ int CmdParadoxRead(const char *Cmd) { return CmdFSKdemodParadox(Cmd); } +int CmdParadoxClone(const char *Cmd) +{ + unsigned int top = 0, mid = 0, bot = 0; + hid_hexstring_to_int96(&top, &mid, &bot, Cmd); + hidproxmessage_t packed = initialize_proxmessage_object(top, mid, bot); + ParadoxWrite(&packed); + return 0; +} + +void ParadoxWrite(hidproxmessage_t *packed){ + UsbCommand c; + c.d.asBytes[0] = (packed->top != 0 && ((packed->mid & 0xFFFFFFC0) != 0)) + ? 1 : 0; // Writing long format? + c.cmd = CMD_PARADOX_CLONE_TAG; + c.arg[0] = (packed->top & 0x000FFFFF); + c.arg[1] = packed->mid; + c.arg[2] = packed->bot; + SendCommand(&c); +} + static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"demod", CmdFSKdemodParadox, 1, "Demodulate a Paradox FSK tag from the GraphBuffer"}, {"read", CmdParadoxRead, 0, "Attempt to read and Extract tag data from the antenna"}, + {"clone", CmdParadoxClone, 0, " -- Clone Paradox to T55x7 (tag must be in antenna)"}, {NULL, NULL, 0, NULL} }; diff --git a/client/hidcardformatutils.c b/client/hidcardformatutils.c index 3abee223..e4fb6349 100644 --- a/client/hidcardformatutils.c +++ b/client/hidcardformatutils.c @@ -169,4 +169,4 @@ bool add_HID_header(/* inout */hidproxmessage_t* data){ data->bot |= 1 << data->Length; // leading 1: start bit } return true; -} \ No newline at end of file +} diff --git a/include/usb_cmd.h b/include/usb_cmd.h index fa66634f..306c52bf 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -111,6 +111,8 @@ typedef struct{ #define CMD_VIKING_CLONE_TAG 0x0223 #define CMD_T55XX_WAKEUP 0x0224 #define CMD_COTAG 0x0225 +// misc extra +#define CMD_PARADOX_CLONE_TAG 0x0226 /* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */