mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-23 22:55:37 -07:00
Merge pull request #2471 from douniwan5788/fix_em410x
fix: clone a EM410x ID to Hitag S/8211 with clock
This commit is contained in:
commit
896e99514e
5 changed files with 83 additions and 51 deletions
|
@ -1360,8 +1360,11 @@ static int selectHitagS(const lf_hitag_data_t *packet, uint8_t *tx, size_t sizeo
|
||||||
tx[i] = ((NrAr >> (56 - (i * 8))) & 0xFF);
|
tx[i] = ((NrAr >> (56 - (i * 8))) & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (packet->cmd == RHTSF_PLAIN || packet->cmd == WHTSF_PLAIN) {
|
||||||
|
Dbprintf("Error, " _YELLOW_("AUT=1") " This tag is configured in Authentication Mode");
|
||||||
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
Dbprintf("Error , unknown function: " _RED_("%d"), packet->cmd);
|
Dbprintf("Error, unknown function: " _RED_("%d"), packet->cmd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
#include "generator.h"
|
#include "generator.h"
|
||||||
#include "cliparser.h"
|
#include "cliparser.h"
|
||||||
#include "cmdhw.h"
|
#include "cmdhw.h"
|
||||||
#include <hitag.h>
|
#include "hitag.h"
|
||||||
|
|
||||||
static uint64_t gs_em410xid = 0;
|
static uint64_t gs_em410xid = 0;
|
||||||
|
|
||||||
|
@ -675,7 +675,7 @@ static size_t concatbits(uint8_t *dst, size_t dstskip, const uint8_t *src, size_
|
||||||
static int CmdEM410xClone(const char *Cmd) {
|
static int CmdEM410xClone(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf em 410x clone",
|
CLIParserInit(&ctx, "lf em 410x clone",
|
||||||
"clone a EM410x ID to a T55x7, Q5/T5555 or EM4305/4469 tag.",
|
"clone a EM410x ID to a T55x7, Q5/T5555, EM4305/4469 or Hitag S/8211 tag.",
|
||||||
"lf em 410x clone --id 0F0368568B -> encode for T55x7 tag\n"
|
"lf em 410x clone --id 0F0368568B -> encode for T55x7 tag\n"
|
||||||
"lf em 410x clone --id 0F0368568B --q5 -> encode for Q5/T5555 tag\n"
|
"lf em 410x clone --id 0F0368568B --q5 -> encode for Q5/T5555 tag\n"
|
||||||
"lf em 410x clone --id 0F0368568B --em -> encode for EM4305/4469\n"
|
"lf em 410x clone --id 0F0368568B --em -> encode for EM4305/4469\n"
|
||||||
|
@ -710,9 +710,15 @@ static int CmdEM410xClone(const char *Cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hs && IfPm3Hitag() == false) {
|
if (hs) {
|
||||||
PrintAndLogEx(FAILED, "Device not compiled to support Hitag");
|
if (IfPm3Hitag() == false) {
|
||||||
return PM3_EINVARG;
|
PrintAndLogEx(FAILED, "Device not compiled to support Hitag");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
if (clk == 40) {
|
||||||
|
PrintAndLogEx(FAILED, "supported clock rates for Hitag are " _YELLOW_("16, 32, 64"));
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allowed clock rates: 16, 32, 40 and 64
|
// Allowed clock rates: 16, 32, 40 and 64
|
||||||
|
@ -722,31 +728,14 @@ static int CmdEM410xClone(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t id = bytes_to_num(uid, uid_len);
|
uint64_t id = bytes_to_num(uid, uid_len);
|
||||||
PrintAndLogEx(SUCCESS, "Preparing to clone EM4102 to " _YELLOW_("%s") " tag with EM Tag ID " _GREEN_("%010" PRIX64) " (RF/%d)", q5 ? "Q5/T5555" : (em ? "EM4305/4469" : "T55x7"), id, clk);
|
PrintAndLogEx(SUCCESS, "Preparing to clone EM4102 to " _YELLOW_("%s") " tag with EM Tag ID " _GREEN_("%010" PRIX64) " (RF/%d)",
|
||||||
|
q5 ? "Q5/T5555" : (em ? "EM4305/4469" : (hs ? "Hitag S/8211" : "T55x7")), id, clk);
|
||||||
|
|
||||||
struct {
|
uint8_t data[HITAG_BLOCK_SIZE * 2] = {0xFF, 0x80}; // EM410X_HEADER 9 bits of one
|
||||||
bool Q5;
|
|
||||||
bool EM;
|
|
||||||
bool add_electra;
|
|
||||||
uint8_t clock;
|
|
||||||
uint32_t high;
|
|
||||||
uint32_t low;
|
|
||||||
} PACKED payload;
|
|
||||||
|
|
||||||
payload.Q5 = q5;
|
|
||||||
payload.EM = em;
|
|
||||||
payload.add_electra = add_electra;
|
|
||||||
payload.clock = clk;
|
|
||||||
payload.high = (uint32_t)(id >> 32);
|
|
||||||
payload.low = (uint32_t)id;
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t data[8] = {0xFF, 0x80}; // EM410X_HEADER 9 bits of one
|
|
||||||
uint32_t databits = 9;
|
uint32_t databits = 9;
|
||||||
uint8_t c_parity = 0;
|
uint8_t c_parity = 0;
|
||||||
|
|
||||||
for (int i = 36; i >= 0; i -= 4)
|
for (int i = 36; i >= 0; i -= 4) {
|
||||||
{
|
|
||||||
uint8_t r_parity = 0;
|
uint8_t r_parity = 0;
|
||||||
uint8_t nibble = id >> i & 0xF;
|
uint8_t nibble = id >> i & 0xF;
|
||||||
|
|
||||||
|
@ -758,7 +747,8 @@ static int CmdEM410xClone(const char *Cmd) {
|
||||||
c_parity ^= nibble;
|
c_parity ^= nibble;
|
||||||
}
|
}
|
||||||
data[7] |= c_parity << 1;
|
data[7] |= c_parity << 1;
|
||||||
// print_hex_noascii_break(data, 8, 10);
|
|
||||||
|
PrintAndLogEx(INFO, "Encoded to %s", sprint_hex(data, sizeof(data)));
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
|
@ -767,14 +757,37 @@ static int CmdEM410xClone(const char *Cmd) {
|
||||||
lf_hitag_data_t packet;
|
lf_hitag_data_t packet;
|
||||||
memset(&packet, 0, sizeof(packet));
|
memset(&packet, 0, sizeof(packet));
|
||||||
|
|
||||||
for (size_t page = 4; page <= 5; page++) {
|
for (size_t steps = 0; steps < 3; steps++) {
|
||||||
packet.cmd = WHTSF_PLAIN;
|
switch (steps) {
|
||||||
packet.page = page;
|
case 0:
|
||||||
memcpy(packet.data, &data[(page-4)*4], 4);
|
packet.data[0] = 0xCA; //compatiable for 82xx, no impact on Hitag S
|
||||||
|
// clk -> TTFDR1 TTFDR0
|
||||||
|
// 32 -> 0x00 4 kBit/s
|
||||||
|
// 16 -> 0x10 8 kBit/s
|
||||||
|
// 64 -> 0x20 2 kBit/s
|
||||||
|
packet.data[1] = 0x04;
|
||||||
|
switch (clk) {
|
||||||
|
case 32: break;
|
||||||
|
case 16: packet.data[1] |= 0x10; break;
|
||||||
|
case 64: packet.data[1] |= 0x20; break;
|
||||||
|
}
|
||||||
|
packet.data[2] = 0;
|
||||||
|
packet.data[3] = 0; //TODO: keep PWDH0?
|
||||||
|
packet.page = 1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
memcpy(packet.data, &data[HITAG_BLOCK_SIZE * 0], HITAG_BLOCK_SIZE);
|
||||||
|
packet.page = 4;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
memcpy(packet.data, &data[HITAG_BLOCK_SIZE * 1], HITAG_BLOCK_SIZE);
|
||||||
|
packet.page = 5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
packet.cmd = WHTSF_PLAIN;
|
||||||
SendCommandNG(CMD_LF_HITAGS_WRITE, (uint8_t *)&packet, sizeof(packet));
|
SendCommandNG(CMD_LF_HITAGS_WRITE, (uint8_t *)&packet, sizeof(packet));
|
||||||
if (WaitForResponseTimeout(CMD_LF_HITAGS_WRITE, &resp, 4000) == false)
|
if (WaitForResponseTimeout(CMD_LF_HITAGS_WRITE, &resp, 4000) == false) {
|
||||||
{
|
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
@ -784,6 +797,22 @@ static int CmdEM410xClone(const char *Cmd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
struct {
|
||||||
|
bool Q5;
|
||||||
|
bool EM;
|
||||||
|
bool add_electra;
|
||||||
|
uint8_t clock;
|
||||||
|
uint32_t high;
|
||||||
|
uint32_t low;
|
||||||
|
} PACKED payload;
|
||||||
|
|
||||||
|
payload.Q5 = q5;
|
||||||
|
payload.EM = em;
|
||||||
|
payload.add_electra = add_electra;
|
||||||
|
payload.clock = clk;
|
||||||
|
payload.high = (uint32_t)(id >> 32);
|
||||||
|
payload.low = (uint32_t)id;
|
||||||
|
|
||||||
SendCommandNG(CMD_LF_EM410X_CLONE, (uint8_t *)&payload, sizeof(payload));
|
SendCommandNG(CMD_LF_EM410X_CLONE, (uint8_t *)&payload, sizeof(payload));
|
||||||
WaitForResponse(CMD_LF_EM410X_CLONE, &resp);
|
WaitForResponse(CMD_LF_EM410X_CLONE, &resp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "comms.h"
|
#include "comms.h"
|
||||||
#include "cmdtrace.h"
|
#include "cmdtrace.h"
|
||||||
#include "commonutil.h"
|
#include "commonutil.h"
|
||||||
#include "hitag.h"
|
|
||||||
#include "fileutils.h" // savefile
|
#include "fileutils.h" // savefile
|
||||||
#include "protocols.h" // defines
|
#include "protocols.h" // defines
|
||||||
#include "cliparser.h"
|
#include "cliparser.h"
|
||||||
|
|
|
@ -20,23 +20,8 @@
|
||||||
#define CMDLFHITAG_H__
|
#define CMDLFHITAG_H__
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "hitag.h"
|
||||||
|
|
||||||
|
|
||||||
#define HITAG_NRAR_SIZE 8
|
|
||||||
#define HITAG_CRYPTOKEY_SIZE 6
|
|
||||||
#define HITAG_PASSWORD_SIZE 4
|
|
||||||
#define HITAG_UID_SIZE 4
|
|
||||||
#define HITAG_BLOCK_SIZE 4
|
|
||||||
#define HITAG2_MAX_BLOCKS 8
|
|
||||||
#define HITAG2_MAX_BYTE_SIZE (HITAG2_MAX_BLOCKS * HITAG_BLOCK_SIZE)
|
|
||||||
|
|
||||||
// need to see which limits these cards has
|
|
||||||
#define HITAG1_MAX_BYTE_SIZE 64
|
|
||||||
#define HITAGS_MAX_BYTE_SIZE 64
|
|
||||||
#define HITAGU_MAX_BYTE_SIZE 64
|
|
||||||
#define HITAG_MAX_BYTE_SIZE (64 * HITAG_BLOCK_SIZE)
|
|
||||||
|
|
||||||
#define HITAG2_CONFIG_BLOCK 3
|
|
||||||
#define HITAG2_CONFIG_OFFSET (HITAG_BLOCK_SIZE * HITAG2_CONFIG_BLOCK)
|
#define HITAG2_CONFIG_OFFSET (HITAG_BLOCK_SIZE * HITAG2_CONFIG_BLOCK)
|
||||||
#define HITAG_DICTIONARY "ht2_default"
|
#define HITAG_DICTIONARY "ht2_default"
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,22 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
#define HITAG_NRAR_SIZE 8
|
||||||
|
#define HITAG_CRYPTOKEY_SIZE 6
|
||||||
|
#define HITAG_PASSWORD_SIZE 4
|
||||||
|
#define HITAG_UID_SIZE 4
|
||||||
|
#define HITAG_BLOCK_SIZE 4
|
||||||
|
#define HITAG2_MAX_BLOCKS 8
|
||||||
|
#define HITAG2_MAX_BYTE_SIZE (HITAG2_MAX_BLOCKS * HITAG_BLOCK_SIZE)
|
||||||
|
|
||||||
|
// need to see which limits these cards has
|
||||||
|
#define HITAG1_MAX_BYTE_SIZE 64
|
||||||
|
#define HITAGS_MAX_BYTE_SIZE 64
|
||||||
|
#define HITAGU_MAX_BYTE_SIZE 64
|
||||||
|
#define HITAG_MAX_BYTE_SIZE (64 * HITAG_BLOCK_SIZE)
|
||||||
|
|
||||||
|
#define HITAG2_CONFIG_BLOCK 3
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RHTSF_PLAIN,
|
RHTSF_PLAIN,
|
||||||
WHTSF_PLAIN,
|
WHTSF_PLAIN,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue