mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-07-15 01:23:04 -07:00
ADD: 'lf t55xx deviceconfig' - command that allows for setting t55xx timings via the client. If run on a RDV40, it also saves the config to flashmemory. This gives you option to have custom timings for your custom antenna in order for your RDV40 to work optimal against a t55xx tag and with your custom antenna. (@iceman)
This commit is contained in:
parent
5959cdf62c
commit
ba2543b627
10 changed files with 185 additions and 26 deletions
|
@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
|
|||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Added 'lf t55xx deviceconfig' - enables custom t55xx timing settings. (RDV40) (@iceman)
|
||||
- Chg adaptations for FPC communications (work in progress) (@iceman)
|
||||
- Fix 'stand-alone Colin' - remake to benefit from flashmem for persistence. (@cjbrigato)
|
||||
- Fix 'LEGIC SIM' - remake of legic sim (@drandreas)
|
||||
|
|
|
@ -392,7 +392,8 @@ void SendStatus(void) {
|
|||
I2C_print_status();
|
||||
#endif
|
||||
#ifdef WITH_LF
|
||||
printConfig(); //LF Sampling config
|
||||
printConfig(); // LF Sampling config
|
||||
printT55xxConfig(); // LF T55XX Config
|
||||
#endif
|
||||
printUSBSpeed();
|
||||
Dbprintf("Various");
|
||||
|
@ -625,6 +626,9 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
|||
|
||||
switch(c->cmd) {
|
||||
#ifdef WITH_LF
|
||||
case CMD_SET_LF_T55XX_CONFIG:
|
||||
setT55xxConfig((t55xx_config *) c->d.asBytes);
|
||||
break;
|
||||
case CMD_SET_LF_SAMPLING_CONFIG:
|
||||
setSamplingConfig((sample_config *) c->d.asBytes);
|
||||
break;
|
||||
|
@ -701,9 +705,10 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
|||
c->d.asDwords[4], c->d.asDwords[5], c->d.asDwords[6]
|
||||
);
|
||||
break;
|
||||
case CMD_T55XX_READ_BLOCK:
|
||||
case CMD_T55XX_READ_BLOCK: {
|
||||
T55xxReadBlock(c->arg[0], c->arg[1], c->arg[2]);
|
||||
break;
|
||||
}
|
||||
case CMD_T55XX_WRITE_BLOCK:
|
||||
T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
|
||||
break;
|
||||
|
@ -1475,6 +1480,10 @@ void __attribute__((noreturn)) AppMain(void) {
|
|||
usart_init();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_FLASH
|
||||
loadT55xxConfig();
|
||||
#endif
|
||||
|
||||
// This is made as late as possible to ensure enumeration without timeout
|
||||
// against device such as http://www.hobbytronics.co.uk/usb-host-board-v2
|
||||
usb_disable();
|
||||
|
|
|
@ -108,6 +108,10 @@ void TurnReadLFOn(uint32_t delay);
|
|||
void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd);
|
||||
void EM4xWriteWord(uint32_t flag, uint32_t data, uint32_t pwd);
|
||||
void Cotag(uint32_t arg0);
|
||||
void setT55xxConfig(t55xx_config *c);
|
||||
t55xx_config * getT55xxConfig(void);
|
||||
void printT55xxConfig(void);
|
||||
void loadT55xxConfig(void);
|
||||
|
||||
/// iso14443b.h
|
||||
void SimulateIso14443bTag(uint32_t pupi);
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include "flashmem.h"
|
||||
|
||||
|
||||
|
||||
/* here: use NCPS2 @ PA10: */
|
||||
#define SPI_CSR_NUM 2
|
||||
#define SPI_PCS(npcs) ((~(1 << (npcs)) & 0xF) << 16)
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "lfsampling.h"
|
||||
#include "protocols.h"
|
||||
#include "usb_cdc.h" // for usb_poll_validate_length
|
||||
#include "common.h"
|
||||
#include "flashmem.h" // persistence on mem
|
||||
|
||||
#ifndef SHORT_COIL
|
||||
# define SHORT_COIL() LOW(GPIO_SSC_DOUT)
|
||||
|
@ -26,11 +28,11 @@
|
|||
# define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
|
||||
#endif
|
||||
|
||||
#define START_GAP 28*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (15fc)
|
||||
#define WRITE_GAP 17*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (10fc)
|
||||
#define WRITE_0 15*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (24fc)
|
||||
#define WRITE_1 47*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (56fc) 432 for T55x7; 448 for E5550
|
||||
#define READ_GAP 15*8
|
||||
//#define START_GAP 31*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (15fc)
|
||||
//#define WRITE_GAP 8*8 // 17*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (10fc)
|
||||
//#define WRITE_0 15*8 // 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (24fc)
|
||||
//#define WRITE_1 47*8 // 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (56fc) 432 for T55x7; 448 for E5550
|
||||
//#define READ_GAP 15*8
|
||||
|
||||
// VALUES TAKEN FROM EM4x function: SendForward
|
||||
// START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle)
|
||||
|
@ -49,7 +51,68 @@
|
|||
// new timer:
|
||||
// = 1us = 1.5ticks
|
||||
// 1fc = 8us = 12ticks
|
||||
/*
|
||||
Default LF T55xx config is set to:
|
||||
startgap = 31*8
|
||||
writegap = 17*8
|
||||
write_0 = 15*8
|
||||
write_1 = 47*8
|
||||
read_gap = 15*8
|
||||
*/
|
||||
t55xx_config t_config = { 31*8, 17*8, 15*8, 47*8, 15*8 } ;
|
||||
|
||||
void printT55xxConfig(void) {
|
||||
Dbprintf("LF T55XX config");
|
||||
Dbprintf(" [q] startgap............%d*8 (%d)", t_config.start_gap/8, t_config.start_gap);
|
||||
Dbprintf(" [b] writegap............%d*8 (%d)", t_config.write_gap/8, t_config.write_gap);
|
||||
Dbprintf(" [d] write_0.............%d*8 (%d)", t_config.write_0/8, t_config.write_0);
|
||||
Dbprintf(" [a] write_1.............%d*8 (%d)", t_config.write_1/8, t_config.write_1);
|
||||
Dbprintf(" [t] readgap.............%d*8 (%d)", t_config.read_gap/8, t_config.read_gap);
|
||||
}
|
||||
void setT55xxConfig(t55xx_config *c) {
|
||||
|
||||
if (c->start_gap != 0) t_config.start_gap = c->start_gap*8;
|
||||
if (c->write_gap != 0) t_config.write_gap = c->write_gap*8;
|
||||
if (c->write_0 != 0) t_config.write_0 = c->write_0*8;
|
||||
if (c->write_1 != 0) t_config.write_1 = c->write_1*8;
|
||||
if (c->read_gap != 0) t_config.read_gap = c->read_gap*8;
|
||||
|
||||
printT55xxConfig();
|
||||
|
||||
#if WITH_FLASH
|
||||
if (!FlashInit())
|
||||
return;
|
||||
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
|
||||
uint16_t isok = Flash_WriteDataCont(T55XX_CONFIG_OFFSET, (uint8_t *)&t_config, sizeof(t55xx_config));
|
||||
FlashStop();
|
||||
|
||||
if ( isok == T55XX_CONFIG_LEN) {
|
||||
if (MF_DBGLEVEL > 1) DbpString("T55XX Config save success");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
t55xx_config* getT55xxConfig(void) {
|
||||
return &t_config;
|
||||
}
|
||||
|
||||
void loadT55xxConfig(void) {
|
||||
#if WITH_FLASH
|
||||
if (!FlashInit())
|
||||
return;
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
Flash_WriteEnable();
|
||||
|
||||
uint16_t isok = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, (uint8_t *)&t_config, T55XX_CONFIG_LEN);
|
||||
FlashStop();
|
||||
|
||||
if ( isok == T55XX_CONFIG_LEN) {
|
||||
if (MF_DBGLEVEL > 1) DbpString("T55XX Config load success");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to do a modulation and then get samples.
|
||||
|
@ -1266,11 +1329,11 @@ void TurnReadLF_off(uint32_t delay) {
|
|||
// Write one bit to card
|
||||
void T55xxWriteBit(int bit) {
|
||||
if (!bit)
|
||||
TurnReadLFOn(WRITE_0);
|
||||
TurnReadLFOn(t_config.write_0);
|
||||
else
|
||||
TurnReadLFOn(WRITE_1);
|
||||
TurnReadLFOn(t_config.write_1);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF_LF);
|
||||
WaitUS(WRITE_GAP);
|
||||
WaitUS(t_config.write_gap);
|
||||
}
|
||||
|
||||
// Send T5577 reset command then read stream (see if we can identify the start of the stream)
|
||||
|
@ -1284,17 +1347,17 @@ void T55xxResetRead(void) {
|
|||
// Set up FPGA, 125kHz
|
||||
LFSetupFPGAForADC(95, true);
|
||||
// make sure tag is fully powered up...
|
||||
WaitMS(6);
|
||||
WaitMS(4);
|
||||
|
||||
// Trigger T55x7 in mode.
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF_LF);
|
||||
WaitUS(START_GAP);
|
||||
WaitUS(t_config.start_gap);
|
||||
|
||||
// reset tag - op code 00
|
||||
T55xxWriteBit(0);
|
||||
T55xxWriteBit(0);
|
||||
|
||||
TurnReadLFOn(READ_GAP);
|
||||
TurnReadLFOn(t_config.read_gap);
|
||||
|
||||
// Acquisition
|
||||
DoPartialAcquisition(0, true, BigBuf_max_traceLen(), 0);
|
||||
|
@ -1319,10 +1382,10 @@ void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg)
|
|||
LFSetupFPGAForADC(95, true);
|
||||
|
||||
// make sure tag is fully powered up...
|
||||
WaitMS(6);
|
||||
WaitMS(4);
|
||||
// Trigger T55x7 in mode.
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF_LF);
|
||||
WaitUS(START_GAP);
|
||||
WaitUS(t_config.start_gap);
|
||||
|
||||
if (testMode) Dbprintf("TestMODE");
|
||||
// Std Opcode 10
|
||||
|
@ -1404,10 +1467,10 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
|
|||
// Set up FPGA, 125kHz to power up the tag
|
||||
LFSetupFPGAForADC(95, true);
|
||||
// make sure tag is fully powered up...
|
||||
WaitMS(6);
|
||||
WaitMS(4);
|
||||
// Trigger T55x7 Direct Access Mode with start gap
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF_LF);
|
||||
WaitUS(START_GAP);
|
||||
WaitUS(t_config.start_gap);
|
||||
|
||||
// Opcode 1[page]
|
||||
T55xxWriteBit(1);
|
||||
|
@ -1450,11 +1513,11 @@ void T55xxWakeUp(uint32_t Pwd){
|
|||
// Set up FPGA, 125kHz
|
||||
LFSetupFPGAForADC(95, true);
|
||||
// make sure tag is fully powered up...
|
||||
WaitMS(6);
|
||||
WaitMS(4);
|
||||
|
||||
// Trigger T55x7 Direct Access Mode
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF_LF);
|
||||
WaitUS(START_GAP);
|
||||
WaitUS(t_config.start_gap);
|
||||
|
||||
// Opcode 10
|
||||
T55xxWriteBit(1);
|
||||
|
|
|
@ -187,6 +187,22 @@ int usage_t55xx_recoverpw(){
|
|||
PrintAndLogEx(NORMAL, " lf t55xx wipe Q5 - wipes a t5555 Q5 tag, config block 0x6001F004");
|
||||
return 0;
|
||||
}
|
||||
int usage_lf_deviceconfig(){
|
||||
PrintAndLogEx(NORMAL, "Usage: lf t55xx deviceconfig a <gap> b <gap> c <gap> d <gap> e <gap>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h - This help");
|
||||
PrintAndLogEx(NORMAL, " a <8..28> - Set start gap");
|
||||
PrintAndLogEx(NORMAL, " b <8..28> - Set write gap");
|
||||
PrintAndLogEx(NORMAL, " c <8..28> - Set write ZERO gap");
|
||||
PrintAndLogEx(NORMAL, " d <8..28> - Set write ONE gap");
|
||||
PrintAndLogEx(NORMAL, " e <8..28> - Set read gap");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " lf t55xx deviceconfig a 31 - start gap 31*8");
|
||||
PrintAndLogEx(NORMAL, " lf t55xx deviceconfig a 31 b 20 - start gap 31*8, write gap 20*8");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return 0;
|
||||
}
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
void printT5xxHeader(uint8_t page){
|
||||
|
@ -461,8 +477,7 @@ static int SanityOfflineCheck( bool useGraphBuffer ){
|
|||
|
||||
int CmdT55xxDetect(const char *Cmd){
|
||||
bool errors = false;
|
||||
bool useGB = false;
|
||||
bool usepwd = false;
|
||||
bool useGB = false, usepwd = false;
|
||||
uint32_t password = 0;
|
||||
uint8_t cmdp = 0;
|
||||
|
||||
|
@ -1291,7 +1306,7 @@ int CmdT55xxDump(const char *Cmd){
|
|||
return 1;
|
||||
}
|
||||
|
||||
bool AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ){
|
||||
bool AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ) {
|
||||
// arg0 bitmodes:
|
||||
// bit0 = pwdmode
|
||||
// bit1 = page to read from
|
||||
|
@ -1882,11 +1897,60 @@ int CmdT55xxDetectPage1(const char *Cmd){
|
|||
return success;
|
||||
}
|
||||
|
||||
int CmdT55xxSetDeviceConfig(const char *Cmd){
|
||||
uint8_t startgap = 0, writegap = 0;
|
||||
uint8_t write0 = 0, write1 = 0, readgap = 0;
|
||||
bool errors = false;
|
||||
uint8_t cmdp = 0;
|
||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h':
|
||||
return usage_lf_deviceconfig();
|
||||
case 'a':
|
||||
errors |= param_getdec(Cmd, cmdp+1, &startgap);
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'b':
|
||||
errors |= param_getdec(Cmd, cmdp+1, &writegap);
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'c':
|
||||
errors |= param_getdec(Cmd, cmdp+1, &write0);
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'd':
|
||||
errors |= param_getdec(Cmd, cmdp+1, &write1);
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'e':
|
||||
errors |= param_getdec(Cmd, cmdp+1, &readgap);
|
||||
cmdp += 2;
|
||||
break;
|
||||
default:
|
||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Validations
|
||||
if (errors || cmdp == 0) return usage_lf_deviceconfig();
|
||||
|
||||
t55xx_config config = { startgap, writegap, write0, write1, readgap };
|
||||
|
||||
UsbCommand c = {CMD_SET_LF_T55XX_CONFIG, {0,0,0} };
|
||||
memcpy(c.d.asBytes, &config, sizeof(t55xx_config));
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"bruteforce", CmdT55xxBruteForce,0, "<start password> <end password> [i <*.dic>] Simple bruteforce attack to find password"},
|
||||
{"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},
|
||||
{"detect", CmdT55xxDetect, 1, "[1] Try detecting the tag modulation from reading the configuration block."},
|
||||
{"deviceconfig", CmdT55xxSetDeviceConfig, 1, "Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap"},
|
||||
{"p1detect", CmdT55xxDetectPage1,1, "[1] Try detecting if this is a t55xx tag by reading page 1"},
|
||||
{"dump", CmdT55xxDump, 0, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},
|
||||
{"info", CmdT55xxInfo, 1, "[1] Show T55x7 configuration data (page 0/ blk 0)"},
|
||||
|
|
|
@ -160,6 +160,7 @@ extern bool tryDetectP1(bool getData);
|
|||
bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5);
|
||||
int special(const char *Cmd);
|
||||
bool AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password );
|
||||
bool AquireDataEx( uint8_t page, uint8_t block, bool pwdmode, uint32_t password, uint32_t timing ) ;
|
||||
|
||||
bool detectPassword(int password);
|
||||
|
||||
|
|
|
@ -105,6 +105,7 @@ typedef struct {
|
|||
#define CMD_VIKING_CLONE_TAG 0x0222
|
||||
#define CMD_T55XX_WAKEUP 0x0224
|
||||
#define CMD_COTAG 0x0225
|
||||
#define CMD_SET_LF_T55XX_CONFIG 0x0226
|
||||
|
||||
/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ extern uint32_t FLASHMEM_SPIBAUDRATE;
|
|||
#endif
|
||||
|
||||
#ifndef FLASH_MEM_MAX_SIZE
|
||||
# define FLASH_MEM_MAX_SIZE 0x3FFFF
|
||||
# define FLASH_MEM_MAX_SIZE 0x3FFFF // (262143)
|
||||
#endif
|
||||
|
||||
#ifndef FLASH_MEM_ID_LEN
|
||||
|
@ -70,6 +70,15 @@ extern uint32_t FLASHMEM_SPIBAUDRATE;
|
|||
# define FLASH_MEM_SIGNATURE_OFFSET (FLASH_MEM_MAX_SIZE - FLASH_MEM_SIGNATURE_LEN)
|
||||
#endif
|
||||
|
||||
#if WITH_FLASH
|
||||
#ifndef T55XX_CONFIG_LEN
|
||||
# define T55XX_CONFIG_LEN sizeof( t55xx_config )
|
||||
#endif
|
||||
|
||||
#ifndef T55XX_CONFIG_OFFSET
|
||||
#define T55XX_CONFIG_OFFSET (FLASH_MEM_MAX_SIZE - FLASH_MEM_SIGNATURE_LEN - T55XX_CONFIG_LEN)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// RDV40, validation structure to help identifying that client/firmware is talking with RDV40
|
||||
typedef struct {
|
||||
|
|
|
@ -43,6 +43,14 @@ typedef struct{
|
|||
int trigger_threshold;
|
||||
} sample_config;
|
||||
|
||||
typedef struct{
|
||||
uint16_t start_gap;
|
||||
uint16_t write_gap;
|
||||
uint16_t write_0;
|
||||
uint16_t write_1;
|
||||
uint16_t read_gap;
|
||||
} t55xx_config;
|
||||
|
||||
// For the bootloader
|
||||
#define CMD_DEVICE_INFO 0x0000
|
||||
#define CMD_SETUP_WRITE 0x0001
|
||||
|
@ -130,6 +138,7 @@ typedef struct{
|
|||
#define CMD_VIKING_CLONE_TAG 0x0222
|
||||
#define CMD_T55XX_WAKEUP 0x0224
|
||||
#define CMD_COTAG 0x0225
|
||||
#define CMD_SET_LF_T55XX_CONFIG 0x0226
|
||||
|
||||
/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue