Paradox clone functionality implemented (#747)
author☃ Stephen Shkardoon ☃ <ss23@ss23.geek.nz>
Sat, 5 Jan 2019 08:48:59 +0000 (21:48 +1300)
committerpwpiwi <pwpiwi@users.noreply.github.com>
Sat, 5 Jan 2019 08:48:59 +0000 (09:48 +0100)
This involves a refactor to the arm HID code to allow for arbitrary
preambles (such as HID Proximity and Paradox).
The client also borrows from the HID code, but is not shared, so could
use a significant refactor in the future.

CHANGELOG.md
armsrc/appmain.c
armsrc/apps.h
armsrc/lfops.c
client/cmdlfhid.c
client/cmdlfhid.h
client/cmdlfparadox.c
client/hidcardformatutils.c
include/usb_cmd.h

index 8b856ec1180d19cc011df1a8fef7f4bc1d23adf5..19db519529cc57bfae2fb04059ae638984c50c65 100644 (file)
@@ -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
index 35c9e5bfcc3fa6db04ab6c3d37b89b3f0698ace6..c5c17867d708df5306739389327af9aad08cdfc2 100644 (file)
@@ -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);
index 6af22b57d379f255a14f607b9c6cde1f06d6ce5b..b9b1f3deaf4c59c4fea92be47a9db62203060c78 100644 (file)
@@ -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
index b56c3f51d7cef1bb7d86a850463a5f26904924c4..1816bdcaf600f8f7e398a2108377b7083b2dc579 100644 (file)
@@ -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);
        }
index 38e7073ce65b796d90cada35bb6bb47536846c92..14340082f19624dcaf143ffc50650a9067e1ad5b 100644 (file)
@@ -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);
index ef907f671cc0398db6a8df13defd35f0caa5a939..353805db779496407b8e0124b6fed94062d8c7fd 100644 (file)
@@ -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
index e918c7fef15dc0aba2ae9a5bf1d077e6fddaca38..d6710219ced94356a054b96d644df8ffc119b361 100644 (file)
 #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, "<ID> -- Clone Paradox to T55x7 (tag must be in antenna)"},
        {NULL, NULL, 0, NULL}
 };
 
index 3abee223f249710836cce3f8fca247f1e8bf2cbc..e4fb634924df60b442daa943b2293f5b03959efb 100644 (file)
@@ -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
+}
index fa66634f2ee688ca6df737900ad16e5c7c3a5858..306c52bf246eccc008fa2fdec167e1e7bae5bb02 100644 (file)
@@ -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 */
Impressum, Datenschutz