- 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
/* 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
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);
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
}
}
-// 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;
}
// 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.");
// 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);
}
*
* 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;
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 {
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;
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);
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
#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)
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){
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}
};
data->bot |= 1 << data->Length; // leading 1: start bit
}
return true;
-}
\ No newline at end of file
+}
#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 */