Merge branch 'master' into originality_check

This commit is contained in:
pwpiwi 2019-07-23 19:12:58 +02:00
commit 3a159d1df0
36 changed files with 2521 additions and 1928 deletions

View file

@ -16,6 +16,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- `hf 15 sim` now works as expected (piwi) - `hf 15 sim` now works as expected (piwi)
### Added ### Added
- Added `hf 15 csetuid` - set UID on ISO-15693 Magic tags (t0m4)
- Added `lf config s xxxx` option to allow skipping x samples before capture (marshmellow)
- Added `lf em 4x05protect` to support changing protection blocks on em4x05 chips (marshmellow)
- Support Standard Communication Mode in HITAG S - Support Standard Communication Mode in HITAG S
- Added `hf emv scan` - commands for scan EMV card and dump data to json file (Merlok) - Added `hf emv scan` - commands for scan EMV card and dump data to json file (Merlok)
- `hf mfp` group of commands (Merlok) - `hf mfp` group of commands (Merlok)
@ -32,6 +35,10 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Added `hf mfp ndef` `hf mf ndef` parsing NDEF records (Merlok) - Added `hf mfp ndef` `hf mf ndef` parsing NDEF records (Merlok)
- Added Mifare Mini, Mifare 2K and 4K support to `hf mf sim` (piwi) - Added Mifare Mini, Mifare 2K and 4K support to `hf mf sim` (piwi)
- Added Legic detection to `hf search` (dnet) - Added Legic detection to `hf search` (dnet)
- Added Home (Pos1) and End key bindings to the plot GUI (based on @mcd1992)
- Added downlink reference mode option r <mode> [ 0 - (or missing) default/fixed bit, 1 - long leading, 2 - leading 0 and 3 - 1 of 4 ] to `lf t55xx detect`, `lf t55xx read`, `lf t55xx write`, and `lf t55xx bruteforce`
- Added special option `r 4` to bruteforce, to try all downlink modes (0,1,2 and 3) for each password
## [v3.1.0][2018-10-10] ## [v3.1.0][2018-10-10]

View file

@ -30,9 +30,10 @@ following locations:
* [RyscCorp](https://proxmark3.com/) (US) * [RyscCorp](https://proxmark3.com/) (US)
* [Hackerwarehouse](https://hackerwarehouse.com/) (US) * [Hackerwarehouse](https://hackerwarehouse.com/) (US)
* [Elechouse](http://www.elechouse.com/) (HK) * [Elechouse](http://www.elechouse.com/) (HK)
* [Lab401](https://lab401.com/) (FR) * [Lab401](https://lab401.com/) (HK)
* [RFxSecure](http://www.rfxsecure.com/) (SG) * [RFxSecure](http://www.rfxsecure.com/) (SG)
* [IceSQL](http://proxmark3.tictail.com/) (SE) * [Sneaktechnology](https://www.sneaktechnology.com/) (ASIA/OCEANIA)
Most of the ultra-low-volume contract assemblers could put Most of the ultra-low-volume contract assemblers could put
something like this together with a reasonable yield. A run of around something like this together with a reasonable yield. A run of around

View file

@ -1088,6 +1088,9 @@ void UsbPacketReceived(uint8_t *packet, int len)
case CMD_EM4X_WRITE_WORD: case CMD_EM4X_WRITE_WORD:
EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2]); EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2]);
break; break;
case CMD_EM4X_PROTECT:
EM4xProtect(c->arg[0], c->arg[1], c->arg[2]);
break;
case CMD_AWID_DEMOD_FSK: // Set realtime AWID demodulation case CMD_AWID_DEMOD_FSK: // Set realtime AWID demodulation
CmdAWIDdemodFSK(c->arg[0], 0, 0, 1); CmdAWIDdemodFSK(c->arg[0], 0, 0, 1);
break; break;
@ -1155,9 +1158,14 @@ void UsbPacketReceived(uint8_t *packet, int len)
case CMD_READER_ISO_15693: case CMD_READER_ISO_15693:
ReaderIso15693(c->arg[0]); ReaderIso15693(c->arg[0]);
break; break;
case CMD_SIMTAG_ISO_15693: case CMD_SIMTAG_ISO_15693:
SimTagIso15693(c->arg[0], c->d.asBytes); SimTagIso15693(c->arg[0], c->d.asBytes);
break; break;
case CMD_CSETUID_ISO_15693:
SetTag15693Uid(c->d.asBytes);
break;
#endif #endif
#ifdef WITH_LEGICRF #ifdef WITH_LEGICRF

View file

@ -89,6 +89,7 @@ void TurnReadLFOn();
//void T55xxReadTrace(void); //void T55xxReadTrace(void);
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode); void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
void EM4xWriteWord(uint32_t flag, uint32_t Data, uint32_t Pwd); void EM4xWriteWord(uint32_t flag, uint32_t Data, uint32_t Pwd);
void EM4xProtect(uint32_t flag, uint32_t Data, uint32_t Pwd);
void Cotag(uint32_t arg0); void Cotag(uint32_t arg0);
/// iso14443.h /// iso14443.h
@ -142,8 +143,6 @@ void MifareDES_Auth1(uint8_t arg0,uint8_t arg1,uint8_t arg2, uint8_t *datain);
void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t * datain); void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t * datain);
int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout); int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout);
size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout); size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout);
void OnSuccess();
void OnError(uint8_t reason);
/// iclass.h /// iclass.h

View file

@ -1963,7 +1963,10 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) {
uint8_t *dataout = BigBuf_malloc(255*8); uint8_t *dataout = BigBuf_malloc(255*8);
if (dataout == NULL){ if (dataout == NULL){
Dbprintf("out of memory"); Dbprintf("out of memory");
OnError(1); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_D_OFF();
cmd_send(CMD_ACK,0,1,0,0,0);
LED_A_OFF();
return; return;
} }
memset(dataout,0xFF,255*8); memset(dataout,0xFF,255*8);

View file

@ -1591,6 +1591,85 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint
LED_A_OFF(); LED_A_OFF();
} }
//-----------------------------------------------------------------------------
// Work with "magic Chinese" card.
//
//-----------------------------------------------------------------------------
// Set the UID to the tag (based on Iceman work).
void SetTag15693Uid(uint8_t *uid)
{
uint8_t cmd[4][9] = {0x00};
uint16_t crc;
int recvlen = 0;
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
LED_A_ON();
// Command 1 : 02213E00000000
cmd[0][0] = 0x02;
cmd[0][1] = 0x21;
cmd[0][2] = 0x3e;
cmd[0][3] = 0x00;
cmd[0][4] = 0x00;
cmd[0][5] = 0x00;
cmd[0][6] = 0x00;
// Command 2 : 02213F69960000
cmd[1][0] = 0x02;
cmd[1][1] = 0x21;
cmd[1][2] = 0x3f;
cmd[1][3] = 0x69;
cmd[1][4] = 0x96;
cmd[1][5] = 0x00;
cmd[1][6] = 0x00;
// Command 3 : 022138u8u7u6u5 (where uX = uid byte X)
cmd[2][0] = 0x02;
cmd[2][1] = 0x21;
cmd[2][2] = 0x38;
cmd[2][3] = uid[7];
cmd[2][4] = uid[6];
cmd[2][5] = uid[5];
cmd[2][6] = uid[4];
// Command 4 : 022139u4u3u2u1 (where uX = uid byte X)
cmd[3][0] = 0x02;
cmd[3][1] = 0x21;
cmd[3][2] = 0x39;
cmd[3][3] = uid[3];
cmd[3][4] = uid[2];
cmd[3][5] = uid[1];
cmd[3][6] = uid[0];
for (int i=0; i<4; i++) {
// Add the CRC
crc = Crc(cmd[i], 7);
cmd[i][7] = crc & 0xff;
cmd[i][8] = crc >> 8;
if (DEBUG) {
Dbprintf("SEND:");
Dbhexdump(sizeof(cmd[i]), cmd[i], false);
}
recvlen = SendDataTag(cmd[i], sizeof(cmd[i]), true, 1, recvbuf, sizeof(recvbuf), 0);
if (DEBUG) {
Dbprintf("RECV:");
Dbhexdump(recvlen, recvbuf, false);
DbdecodeIso15693Answer(recvlen, recvbuf);
}
cmd_send(CMD_ACK, recvlen>ISO15693_MAX_RESPONSE_LENGTH?ISO15693_MAX_RESPONSE_LENGTH:recvlen, 0, 0, recvbuf, ISO15693_MAX_RESPONSE_LENGTH);
}
LED_D_OFF();
LED_A_OFF();
}

View file

@ -19,6 +19,7 @@ void ReaderIso15693(uint32_t parameter);
void SimTagIso15693(uint32_t parameter, uint8_t *uid); void SimTagIso15693(uint32_t parameter, uint8_t *uid);
void BruteforceIso15693Afi(uint32_t speed); void BruteforceIso15693Afi(uint32_t speed);
void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t data[]); void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t data[]);
void SetTag15693Uid(uint8_t *uid);
void SetDebugIso15693(uint32_t flag); void SetDebugIso15693(uint32_t flag);
#endif #endif

View file

@ -1198,12 +1198,79 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
* and enlarge the gap ones. * and enlarge the gap ones.
* Q5 tags seems to have issues when these values changes. * Q5 tags seems to have issues when these values changes.
*/ */
/*
// Original Timings for reference
//note startgap must be sent after tag has been powered up for more than 3ms (per T5557 ds)
#define START_GAP 31*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (or 15fc) #define START_GAP 31*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (or 15fc)
#define WRITE_GAP 20*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (or 10fc) #define WRITE_GAP 20*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (or 10fc)
#define WRITE_0 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc) #define WRITE_0 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc)
#define WRITE_1 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (or 56fc) 432 for T55x7; 448 for E5550 #define WRITE_1 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (or 56fc) 432 for T55x7; 448 for E5550
#define READ_GAP 15*8 #define READ_GAP 15*8
*/
/* Q5 timing datasheet:
* Type | MIN | Typical | Max |
* Start_Gap | 10*8 | ? | 50*8 |
* Write_Gap Normal mode | 8*8 | 14*8 | 20*8 |
* Write_Gap Fast Mode | 8*8 | ? | 20*8 |
* Write_0 Normal mode | 16*8 | 24*8 | 32*8 |
* Write_1 Normal mode | 48*8 | 56*8 | 64*8 |
* Write_0 Fast Mode | 8*8 | 12*8 | 16*8 |
* Write_1 Fast Mode | 24*8 | 28*8 | 32*8 |
*/
/* T5557 timing datasheet:
* Type | MIN | Typical | Max |
* Start_Gap | 10*8 | ? | 50*8 |
* Write_Gap Normal mode | 8*8 |50-150us | 30*8 |
* Write_Gap Fast Mode | 8*8 | ? | 20*8 |
* Write_0 Normal mode | 16*8 | 24*8 | 31*8 |
* Write_1 Normal mode | 48*8 | 54*8 | 63*8 |
* Write_0 Fast Mode | 8*8 | 12*8 | 15*8 |
* Write_1 Fast Mode | 24*8 | 28*8 | 31*8 |
*/
/* T5577C timing datasheet for Fixed-Bit-Length protocol (defualt):
* Type | MIN | Typical | Max |
* Start_Gap | 8*8 | 15*8 | 50*8 |
* Write_Gap Normal mode | 8*8 | 10*8 | 20*8 |
* Write_Gap Fast Mode | 8*8 | 10*8 | 20*8 |
* Write_0 Normal mode | 16*8 | 24*8 | 32*8 |
* Write_1 Normal mode | 48*8 | 56*8 | 64*8 |
* Write_0 Fast Mode | 8*8 | 12*8 | 16*8 |
* Write_1 Fast Mode | 24*8 | 28*8 | 32*8 |
*/
// Structure to hold Timing values. In future will be simplier to add user changable timings.
typedef struct {
uint16_t START_GAP;
uint16_t WRITE_GAP;
uint16_t WRITE_0;
uint16_t WRITE_1;
uint16_t WRITE_2;
uint16_t WRITE_3;
uint16_t READ_GAP;
} T55xx_Timing;
// Set Initial/Default Values. Note: *8 can occure when used. This should keep things simplier here.
T55xx_Timing T55xx_Timing_FixedBit = { 31 * 8 , 20 * 8 , 18 * 8 , 50 * 8 , 0 , 0 , 15 * 8 };
T55xx_Timing T55xx_Timing_LLR = { 31 * 8 , 20 * 8 , 18 * 8 , 50 * 8 , 0 , 0 , 15 * 8 };
T55xx_Timing T55xx_Timing_Leading0 = { 31 * 8 , 20 * 8 , 18 * 8 , 40 * 8 , 0 , 0 , 15 * 8 };
T55xx_Timing T55xx_Timing_1of4 = { 31 * 8 , 20 * 8 , 18 * 8 , 34 * 8 , 50 * 8 , 66 * 8 , 15 * 8 };
// Some defines for readability
#define T55xx_DLMode_Fixed 0 // Default Mode
#define T55xx_DLMode_LLR 1 // Long Leading Reference
#define T55xx_DLMode_Leading0 2 // Leading Zero
#define T55xx_DLMode_1of4 3 // 1 of 4
#define T55xx_LongLeadingReference 4 // Value to tell Write Bit to send long reference
// Macro for code readability
#define BitStream_Byte(X) ((X) >> 3)
#define BitStream_Bit(X) ((X) & 7)
void TurnReadLFOn(int delay) { void TurnReadLFOn(int delay) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Give it a bit of time for the resonant antenna to settle. // Give it a bit of time for the resonant antenna to settle.
@ -1211,36 +1278,179 @@ void TurnReadLFOn(int delay) {
} }
// Write one bit to card // Write one bit to card
void T55xxWriteBit(int bit) { void T55xxWriteBit(int bit, T55xx_Timing *Timings) {
if (!bit)
TurnReadLFOn(WRITE_0); // If bit = 4 Send Long Leading Reference which is 138 + WRITE_0
else // Dbprintf ("Bits : %d",bit);
TurnReadLFOn(WRITE_1); switch (bit){
case 0 : TurnReadLFOn(Timings->WRITE_0); break; // Send bit 0/00
case 1 : TurnReadLFOn(Timings->WRITE_1); break; // Send bit 1/01
case 2 : TurnReadLFOn(Timings->WRITE_2); break; // Send bits 10
case 3 : TurnReadLFOn(Timings->WRITE_3); break; // Send bits 11
case 4 : TurnReadLFOn(Timings->WRITE_0 + (136 * 8)); break; // Send Long Leading Reference
}
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
WaitUS(WRITE_GAP); WaitUS(Timings->WRITE_GAP);
} }
// Send T5577 reset command then read stream (see if we can identify the start of the stream) // Function to abstract an Arbitrary length byte array to store bit pattern.
void T55xxResetRead(void) { // bit_array - Array to hold data/bit pattern
LED_A_ON(); // start_offset - bit location to start storing new bits.
//clear buffer now so it does not interfere with timing later // data - upto 32 bits of data to store
BigBuf_Clear_keep_EM(); // num_bits - how many bits (low x bits of data) Max 32 bits at a time
// max_len - how many bytes can the bit_array hold (ensure no buffer overflow)
// returns "Next" bit offset / bits stored (for next store)
//int T55xx_SetBits (uint8_t *bit_array, int start_offset, uint32_t data , int num_bits, int max_len)
int T55xx_SetBits (uint8_t *BitStream, uint8_t start_offset, uint32_t data , uint8_t num_bits, uint8_t max_len)
{
int8_t offset;
int8_t NextOffset = start_offset;
// Check if data will fit.
if ((start_offset + num_bits) <= (max_len*8)) {
// Loop through the data and store
for (offset = (num_bits-1); offset >= 0; offset--) {
if ((data >> offset) & 1) BitStream[BitStream_Byte(NextOffset)] |= (1 << BitStream_Bit(NextOffset)); // Set the bit to 1
else BitStream[BitStream_Byte(NextOffset)] &= (0xff ^ (1 << BitStream_Bit(NextOffset))); // Set the bit to 0
NextOffset++;
}
}
else {
// Note: This should never happen unless some code changes cause it.
// So short message for coders when testing.
Dbprintf ("T55 too many bits");
}
return NextOffset;
}
// Send one downlink command to the card
void T55xx_SendCMD (uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) {
/*
arg bits
xxxxxxx1 0x01 PwdMode
xxxxxx1x 0x02 Page
xxxxx1xx 0x04 testMode
xxx11xxx 0x18 downlink mode
xx1xxxxx 0x20 !reg_readmode
x1xxxxxx 0x40 called for a read, so no data packet
1xxxxxxx 0x80 reset
*/
bool PwdMode = ((arg & 0x01) == 0x01);
bool Page = (arg & 0x02);
bool testMode = ((arg & 0x04) == 0x04);
uint8_t downlink_mode = (arg >> 3) & 0x03;
bool reg_readmode = ((arg & 0x20) == 0x20);
bool read_cmd = ((arg & 0x40) == 0x40);
bool reset = (arg & 0x80);
uint8_t i = 0;
uint8_t BitStream[10]; // Max Downlink Command size ~74 bits, so 10 bytes (80 bits)
uint8_t BitStreamLen;
T55xx_Timing *Timing;
uint8_t SendBits;
// Assigning Downlink Timeing for write
switch (downlink_mode)
{
case T55xx_DLMode_Fixed : Timing = &T55xx_Timing_FixedBit; break;
case T55xx_DLMode_LLR : Timing = &T55xx_Timing_LLR; break;
case T55xx_DLMode_Leading0 : Timing = &T55xx_Timing_Leading0; break;
case T55xx_DLMode_1of4 : Timing = &T55xx_Timing_1of4; break;
default:
Timing = &T55xx_Timing_FixedBit;
}
// Build Bit Stream to send.
memset (BitStream,0x00,sizeof(BitStream));
BitStreamLen = 0; // Ensure 0 bit index to start.
// Add Leading 0 and 1 of 4 reference bit
if ((downlink_mode == T55xx_DLMode_Leading0) || (downlink_mode == T55xx_DLMode_1of4))
BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 1,sizeof(BitStream));
// Add extra reference 0 for 1 of 4
if (downlink_mode == T55xx_DLMode_1of4)
BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 1,sizeof(BitStream));
// Add Opcode
if (reset) {
// Reset : r*) 00
BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 2,sizeof(BitStream));
}
else
{
if (testMode) Dbprintf("TestMODE");
BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen,testMode ? 0 : 1 , 1,sizeof(BitStream));
BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen,testMode ? 1 : Page , 1,sizeof(BitStream));
if (PwdMode) {
// Leading 0 and 1 of 4 00 fixed bits if passsword used
if ((downlink_mode == T55xx_DLMode_Leading0) || (downlink_mode == T55xx_DLMode_1of4)) {
BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 2,sizeof(BitStream));
}
BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, Pwd, 32,sizeof(BitStream));
}
// Add Lock bit 0
if (!reg_readmode) BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 1,sizeof(BitStream));
// Add Data if a write command
if (!read_cmd) BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, Data, 32,sizeof(BitStream));
// Add Address
if (!reg_readmode) BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, Block, 3,sizeof(BitStream));
}
// Send Bits to T55xx
// Set up FPGA, 125kHz // Set up FPGA, 125kHz
LFSetupFPGAForADC(95, true); LFSetupFPGAForADC(95, true);
StartTicks(); StartTicks();
// make sure tag is fully powered up... // make sure tag is fully powered up...
WaitMS(5); WaitMS(5);
// Trigger T55x7 in mode. // Trigger T55x7 in mode.
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
WaitUS(START_GAP); WaitUS(Timing->START_GAP);
// reset tag - op code 00 // If long leading 0 send long reference pulse
T55xxWriteBit(0); if (downlink_mode == T55xx_DLMode_LLR)
T55xxWriteBit(0); T55xxWriteBit (T55xx_LongLeadingReference,Timing); // Send Long Leading Start Reference
TurnReadLFOn(READ_GAP); if ((downlink_mode == T55xx_DLMode_1of4) && (BitStreamLen > 0)) { // 1 of 4 need to send 2 bits at a time
for ( i = 0; i < BitStreamLen-1; i+=2 ) {
SendBits = (BitStream[BitStream_Byte(i )] >> (BitStream_Bit(i )) & 1) << 1; // Bit i
SendBits += (BitStream[BitStream_Byte(i+1)] >> (BitStream_Bit(i+1)) & 1); // Bit i+1;
T55xxWriteBit (SendBits & 3,Timing);
}
}
else {
for (i = 0; i < BitStreamLen; i++) {
SendBits = (BitStream[BitStream_Byte(i)] >> BitStream_Bit(i));
T55xxWriteBit (SendBits & 1,Timing);
}
}
}
// Send T5577 reset command then read stream (see if we can identify the start of the stream)
void T55xxResetRead(void) {
LED_A_ON();
// send r* 00
uint8_t arg = 0x80; // SendCMD will add correct reference mode based on flags (when added).
// Add in downlink_mode when ready
// arg |= 0x00; // dlmode << 3 (00 default - 08 leading 0 - 10 Fixed - 18 1 of 4 )
//clear buffer now so it does not interfere with timing later
BigBuf_Clear_keep_EM();
T55xx_SendCMD (0, 0, 0, arg); //, true);
TurnReadLFOn(T55xx_Timing_FixedBit.READ_GAP);
// Acquisition // Acquisition
DoPartialAcquisition(0, true, BigBuf_max_traceLen(), 0); DoPartialAcquisition(0, true, BigBuf_max_traceLen(), 0);
@ -1252,42 +1462,23 @@ void T55xxResetRead(void) {
} }
// Write one card block in page 0, no lock // Write one card block in page 0, no lock
void T55xxWriteBlockExt(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) { void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) {
LED_A_ON(); /*
bool PwdMode = arg & 0x1; arg bits
uint8_t Page = (arg & 0x2)>>1; xxxxxxx1 0x01 PwdMode
bool testMode = arg & 0x4; xxxxxx1x 0x02 Page
uint32_t i = 0; xxxxx1xx 0x04 testMode
xxx11xxx 0x18 downlink mode
xx1xxxxx 0x20 !reg_readmode
x1xxxxxx 0x40 called for a read, so no data packet
1xxxxxxx 0x80 reset
*/
// Set up FPGA, 125kHz bool testMode = ((arg & 0x04) == 0x04);
LFSetupFPGAForADC(95, true); arg &= (0xff ^ 0x40); // Called for a write, so ensure it is clear/0
StartTicks();
// make sure tag is fully powered up...
WaitMS(5);
// Trigger T55x7 in mode.
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
WaitUS(START_GAP);
if (testMode) Dbprintf("TestMODE"); LED_A_ON ();
// Std Opcode 10 T55xx_SendCMD (Data, Block, Pwd, arg) ;//, false);
T55xxWriteBit(testMode ? 0 : 1);
T55xxWriteBit(testMode ? 1 : Page); //Page 0
if (PwdMode) {
// Send Pwd
for (i = 0x80000000; i != 0; i >>= 1)
T55xxWriteBit(Pwd & i);
}
// Send Lock bit
T55xxWriteBit(0);
// Send Data
for (i = 0x80000000; i != 0; i >>= 1)
T55xxWriteBit(Data & i);
// Send Block number
for (i = 0x04; i != 0; i >>= 1)
T55xxWriteBit(Block & i);
// Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, // Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550,
// so wait a little more) // so wait a little more)
@ -1316,57 +1507,43 @@ void T55xxWriteBlockExt(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg
//DoPartialAcquisition(20, true, 12000); //DoPartialAcquisition(20, true, 12000);
} }
// turn field off // turn field off
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_A_OFF();
}
// Write one card block in page 0, no lock
void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) {
T55xxWriteBlockExt(Data, Block, Pwd, arg);
cmd_send(CMD_ACK,0,0,0,0,0); cmd_send(CMD_ACK,0,0,0,0,0);
LED_A_OFF ();
} }
// Read one card block in page [page] // Read one card block in page [page]
void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { void T55xxReadBlock (uint16_t arg0, uint8_t Block, uint32_t Pwd) {//, struct T55xx_Timing *Timing) {
LED_A_ON();
bool PwdMode = arg0 & 0x1;
uint8_t Page = (arg0 & 0x2) >> 1;
uint32_t i = 0;
bool RegReadMode = (Block == 0xFF);//regular read mode
//clear buffer now so it does not interfere with timing later LED_A_ON();
BigBuf_Clear_ext(false);
/*
arg bits
xxxxxxx1 0x01 PwdMode
xxxxxx1x 0x02 Page
xxxxx1xx 0x04 testMode
xxx11xxx 0x18 downlink mode
xx1xxxxx 0x20 !reg_readmode
x1xxxxxx 0x40 called for a read, so no data packet
1xxxxxxx 0x80 reset
*/
// Set Read Flag to ensure SendCMD does not add "data" to the packet
arg0 |= 0x40;
// RegRead Mode true of block 0xff
if (Block == 0xff) arg0 |= 0x20;
//make sure block is at max 7 //make sure block is at max 7
Block &= 0x7; Block &= 0x7;
// Set up FPGA, 125kHz to power up the tag //clear buffer now so it does not interfere with timing later
LFSetupFPGAForADC(95, true); BigBuf_Clear_ext(false);
StartTicks();
// make sure tag is fully powered up...
WaitMS(5);
// Trigger T55x7 Direct Access Mode with start gap
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
WaitUS(START_GAP);
// Opcode 1[page] T55xx_SendCMD (0, Block, Pwd, arg0); //, true);
T55xxWriteBit(1);
T55xxWriteBit(Page); //Page 0
if (PwdMode){
// Send Pwd
for (i = 0x80000000; i != 0; i >>= 1)
T55xxWriteBit(Pwd & i);
}
// Send a zero bit separation
T55xxWriteBit(0);
// Send Block number (if direct access mode)
if (!RegReadMode)
for (i = 0x04; i != 0; i >>= 1)
T55xxWriteBit(Block & i);
// Turn field on to read the response // Turn field on to read the response
// 137*8 seems to get to the start of data pretty well... // 137*8 seems to get to the start of data pretty well...
@ -1380,30 +1557,31 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
// Turn the field off // Turn the field off
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
cmd_send(CMD_ACK,0,0,0,0,0); cmd_send(CMD_ACK,0,0,0,0,0);
LED_A_OFF(); LED_A_OFF();
} }
void T55xxWakeUp(uint32_t Pwd){ void T55xxWakeUp(uint32_t Pwd){
LED_B_ON(); LED_B_ON();
uint32_t i = 0; /*
arg bits
xxxxxxx1 0x01 PwdMode
xxxxxx1x 0x02 Page
xxxxx1xx 0x04 testMode
xxx11xxx 0x18 downlink mode
xx1xxxxx 0x20 !reg_readmode
x1xxxxxx 0x40 called for a read, so no data packet
1xxxxxxx 0x80 reset
*/
// Set up FPGA, 125kHz // r* 10 (00) <pwd> r* for llr , L0 and 1/4 - (00) for L0 and 1/4 - All handled in SendCMD
LFSetupFPGAForADC(95, true); // So, default Opcode 10 and pwd.
StartTicks(); uint8_t arg = 0x01 | 0x40 | 0x20; //Password Read Call no data | reg_read no block
// make sure tag is fully powered up...
WaitMS(5);
// Trigger T55x7 Direct Access Mode // Add in downlink_mode when ready
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // arg |= 0x00; // dlmode << 3 (00 default - 08 leading 0 - 10 Fixed - 18 1 of 4 )
WaitUS(START_GAP);
// Opcode 10 T55xx_SendCMD (0, 0, Pwd, arg); //, true);
T55xxWriteBit(1);
T55xxWriteBit(0); //Page 0
// Send Pwd
for (i = 0x80000000; i != 0; i >>= 1)
T55xxWriteBit(Pwd & i);
// Turn and leave field on to let the begin repeating transmission // Turn and leave field on to let the begin repeating transmission
TurnReadLFOn(20*1000); TurnReadLFOn(20*1000);
@ -1414,7 +1592,8 @@ void T55xxWakeUp(uint32_t Pwd){
void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) { void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) {
// write last block first and config block last (if included) // write last block first and config block last (if included)
for (uint8_t i = numblocks+startblock; i > startblock; i--) { for (uint8_t i = numblocks+startblock; i > startblock; i--) {
T55xxWriteBlockExt(blockdata[i-1],i-1,0,0); T55xxWriteBlock(blockdata[i-1],i-1,0,0);//,false); //,&T55xx_Timing_FixedBit);
//T55xx_SendCMD (blockdata[i-1],i-1,0,0);//,false); //,&T55xx_Timing_FixedBit);
} }
} }
@ -1614,6 +1793,7 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) {
#define FWD_CMD_WRITE 0xA #define FWD_CMD_WRITE 0xA
#define FWD_CMD_READ 0x9 #define FWD_CMD_READ 0x9
#define FWD_CMD_DISABLE 0x5 #define FWD_CMD_DISABLE 0x5
#define FWD_CMD_PROTECT 0x3
uint8_t forwardLink_data[64]; //array of forwarded bits uint8_t forwardLink_data[64]; //array of forwarded bits
uint8_t * forward_ptr; //ptr for forward message preparation uint8_t * forward_ptr; //ptr for forward message preparation
@ -1727,7 +1907,7 @@ void SendForward(uint8_t fwd_bit_count) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
WaitUS(18*8); //18 cycles on (8us each) WaitUS(18*8); //18 cycles on (8us each)
// now start writting // now start writting - each bit should be 32*8 total length
while(fwd_bit_sz-- > 0) { //prepare next bit modulation while(fwd_bit_sz-- > 0) { //prepare next bit modulation
if(((*fwd_write_ptr++) & 1) == 1) if(((*fwd_write_ptr++) & 1) == 1)
WaitUS(32*8); //32 cycles at 125Khz (8us each) WaitUS(32*8); //32 cycles at 125Khz (8us each)
@ -1736,7 +1916,7 @@ void SendForward(uint8_t fwd_bit_count) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
WaitUS(23*8); //23 cycles off (8us each) WaitUS(23*8); //23 cycles off (8us each)
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
WaitUS(18*8); //18 cycles on (8us each) WaitUS((32-23)*8); //remaining cycles on (8us each)
} }
} }
} }
@ -1783,7 +1963,7 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
void EM4xWriteWord(uint32_t flag, uint32_t Data, uint32_t Pwd) { void EM4xWriteWord(uint32_t flag, uint32_t Data, uint32_t Pwd) {
bool PwdMode = (flag & 0xF); bool PwdMode = (flag & 0x1);
uint8_t Address = (flag >> 8) & 0xFF; uint8_t Address = (flag >> 8) & 0xFF;
uint8_t fwd_bit_count; uint8_t fwd_bit_count;
@ -1813,6 +1993,39 @@ void EM4xWriteWord(uint32_t flag, uint32_t Data, uint32_t Pwd) {
LED_A_OFF(); LED_A_OFF();
cmd_send(CMD_ACK,0,0,0,0,0); cmd_send(CMD_ACK,0,0,0,0,0);
} }
void EM4xProtect(uint32_t flag, uint32_t Data, uint32_t Pwd) {
bool PwdMode = (flag & 0x1);
uint8_t fwd_bit_count;
//clear buffer now so it does not interfere with timing later
BigBuf_Clear_ext(false);
LED_A_ON();
StartTicks();
//If password mode do login
if (PwdMode) EM4xLogin(Pwd);
forward_ptr = forwardLink_data;
fwd_bit_count = Prepare_Cmd( FWD_CMD_PROTECT );
//unsure if this needs the full packet config...
fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 );
SendForward(fwd_bit_count);
//Wait for write to complete
//SpinDelay(10);
WaitUS(6500);
//Capture response if one exists
DoPartialAcquisition(20, true, 6000, 1000);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_A_OFF();
cmd_send(CMD_ACK,0,0,0,0,0);
}
/* /*
Reading a COTAG. Reading a COTAG.

View file

@ -14,7 +14,7 @@
#include "usb_cdc.h" // for usb_poll_validate_length #include "usb_cdc.h" // for usb_poll_validate_length
#include "fpgaloader.h" #include "fpgaloader.h"
sample_config config = { 1, 8, 1, 95, 0 } ; sample_config config = { 1, 8, 1, 95, 0, 0 } ;
void printConfig() void printConfig()
{ {
@ -24,6 +24,7 @@ void printConfig()
Dbprintf(" [d] decimation: %d ", config.decimation); Dbprintf(" [d] decimation: %d ", config.decimation);
Dbprintf(" [a] averaging: %d ", config.averaging); Dbprintf(" [a] averaging: %d ", config.averaging);
Dbprintf(" [t] trigger threshold: %d ", config.trigger_threshold); Dbprintf(" [t] trigger threshold: %d ", config.trigger_threshold);
Dbprintf(" [s] samples to skip: %d ", config.samples_to_skip);
} }
@ -34,7 +35,7 @@ void printConfig()
* Other functions may read samples and ignore the sampling config, * Other functions may read samples and ignore the sampling config,
* such as functions to read the UID from a prox tag or similar. * such as functions to read the UID from a prox tag or similar.
* *
* Values set to '0' implies no change (except for averaging) * Values set to '0' implies no change (except for averaging, threshold, samples_to_skip)
* @brief setSamplingConfig * @brief setSamplingConfig
* @param sc * @param sc
*/ */
@ -44,6 +45,7 @@ void setSamplingConfig(sample_config *sc)
if(sc->bits_per_sample!= 0) config.bits_per_sample= sc->bits_per_sample; if(sc->bits_per_sample!= 0) config.bits_per_sample= sc->bits_per_sample;
if(sc->decimation!= 0) config.decimation= sc->decimation; if(sc->decimation!= 0) config.decimation= sc->decimation;
if(sc->trigger_threshold != -1) config.trigger_threshold= sc->trigger_threshold; if(sc->trigger_threshold != -1) config.trigger_threshold= sc->trigger_threshold;
if(sc->samples_to_skip != -1) config.samples_to_skip = sc->samples_to_skip;
config.averaging= sc->averaging; config.averaging= sc->averaging;
if(config.bits_per_sample > 8) config.bits_per_sample = 8; if(config.bits_per_sample > 8) config.bits_per_sample = 8;
@ -119,7 +121,7 @@ void LFSetupFPGAForADC(int divisor, bool lf_field)
* @param silent - is true, now outputs are made. If false, dbprints the status * @param silent - is true, now outputs are made. If false, dbprints the status
* @return the number of bits occupied by the samples. * @return the number of bits occupied by the samples.
*/ */
uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold, bool silent, int bufsize, int cancel_after) uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold, bool silent, int bufsize, int cancel_after, int samples_to_skip)
{ {
//. //.
uint8_t *dest = BigBuf_get_addr(); uint8_t *dest = BigBuf_get_addr();
@ -141,6 +143,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
uint32_t sample_total_numbers =0 ; uint32_t sample_total_numbers =0 ;
uint32_t sample_total_saved =0 ; uint32_t sample_total_saved =0 ;
uint32_t cancel_counter = 0; uint32_t cancel_counter = 0;
uint32_t samples_skipped = 0;
while(!BUTTON_PRESS() && !usb_poll_validate_length() ) { while(!BUTTON_PRESS() && !usb_poll_validate_length() ) {
WDT_HIT(); WDT_HIT();
@ -160,6 +163,10 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
continue; continue;
} }
trigger_threshold = 0; trigger_threshold = 0;
if (samples_to_skip > samples_skipped) {
samples_skipped++;
continue;
}
sample_total_numbers++; sample_total_numbers++;
if(averaging) if(averaging)
@ -218,7 +225,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
*/ */
uint32_t DoAcquisition_default(int trigger_threshold, bool silent) uint32_t DoAcquisition_default(int trigger_threshold, bool silent)
{ {
return DoAcquisition(1,8,0,trigger_threshold,silent,0,0); return DoAcquisition(1,8,0,trigger_threshold,silent,0,0,0);
} }
uint32_t DoAcquisition_config(bool silent, int sample_size) uint32_t DoAcquisition_config(bool silent, int sample_size)
{ {
@ -228,11 +235,12 @@ uint32_t DoAcquisition_config(bool silent, int sample_size)
,config.trigger_threshold ,config.trigger_threshold
,silent ,silent
,sample_size ,sample_size
,0); ,0
,config.samples_to_skip);
} }
uint32_t DoPartialAcquisition(int trigger_threshold, bool silent, int sample_size, int cancel_after) { uint32_t DoPartialAcquisition(int trigger_threshold, bool silent, int sample_size, int cancel_after) {
return DoAcquisition(1,8,0,trigger_threshold,silent,sample_size,cancel_after); return DoAcquisition(1,8,0,trigger_threshold,silent,sample_size,cancel_after,0);
} }
uint32_t ReadLF(bool activeField, bool silent, int sample_size) uint32_t ReadLF(bool activeField, bool silent, int sample_size)

View file

@ -23,24 +23,42 @@
#define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation) #define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation)
#define HARDNESTED_PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication #define HARDNESTED_PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication
/*
// the block number for the ISO14443-4 PCB // the block number for the ISO14443-4 PCB
static uint8_t pcb_blocknum = 0; static uint8_t pcb_blocknum = 0;
// Deselect card by sending a s-block. the crc is precalced for speed // Deselect card by sending a s-block. the crc is precalced for speed
static uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4}; static uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4};
static void OnSuccess(){
pcb_blocknum = 0;
ReaderTransmit(deselect_cmd, 3 , NULL);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
*/
static void OnError(uint8_t reason){
// pcb_blocknum = 0;
// ReaderTransmit(deselect_cmd, 3 , NULL);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_D_OFF();
cmd_send(CMD_ACK,0,reason,0,0,0);
LED_A_OFF();
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Select, Authenticate, Read a MIFARE tag. // Select, Authenticate, Read a MIFARE tag.
// read block // read block
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
{ {
// params LED_A_ON();
uint8_t blockNo = arg0; uint8_t blockNo = arg0;
uint8_t keyType = arg1; uint8_t keyType = arg1;
uint64_t ui64Key = 0; uint64_t ui64Key = 0;
ui64Key = bytes_to_num(datain, 6); ui64Key = bytes_to_num(datain, 6);
// variables
byte_t isOK = 0; byte_t isOK = 0;
byte_t dataoutbuf[16]; byte_t dataoutbuf[16];
uint8_t uid[10]; uint8_t uid[10];
@ -53,10 +71,6 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
clear_trace(); clear_trace();
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
while (true) { while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
@ -97,21 +111,18 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
LED_A_ON();
bool turnOffField = (arg0 == 1); bool turnOffField = (arg0 == 1);
LED_A_ON(); LED_B_OFF(); LED_C_OFF();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
clear_trace(); if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {
if(!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card"); if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
OnError(0); OnError(0);
return; return;
}; };
if(!mifare_ultra_auth(keybytes)){ if (!mifare_ultra_auth(keybytes)){
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed"); if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed");
OnError(1); OnError(1);
return; return;
@ -119,9 +130,11 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
if (turnOffField) { if (turnOffField) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff(); LED_D_OFF();
} }
cmd_send(CMD_ACK,1,0,0,0,0); cmd_send(CMD_ACK,1,0,0,0,0);
LED_A_OFF();
} }
// Arg0 = BlockNo, // Arg0 = BlockNo,
@ -129,17 +142,15 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
// datain = PWD bytes, // datain = PWD bytes,
void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
{ {
LED_A_ON();
uint8_t blockNo = arg0; uint8_t blockNo = arg0;
byte_t dataout[16] = {0x00}; byte_t dataout[16] = {0x00};
bool useKey = (arg1 == 1); //UL_C bool useKey = (arg1 == 1); //UL_C
bool usePwd = (arg1 == 2); //UL_EV1/NTAG bool usePwd = (arg1 == 2); //UL_EV1/NTAG
LEDsoff();
LED_A_ON();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
clear_trace();
int len = iso14443a_select_card(NULL, NULL, NULL, true, 0, true); int len = iso14443a_select_card(NULL, NULL, NULL, true, 0, true);
if(!len) { if(!len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len); if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len);
@ -148,7 +159,7 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
} }
// UL-C authentication // UL-C authentication
if ( useKey ) { if (useKey) {
uint8_t key[16] = {0x00}; uint8_t key[16] = {0x00};
memcpy(key, datain, sizeof(key) ); memcpy(key, datain, sizeof(key) );
@ -159,7 +170,7 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
} }
// UL-EV1 / NTAG authentication // UL-EV1 / NTAG authentication
if ( usePwd ) { if (usePwd) {
uint8_t pwd[4] = {0x00}; uint8_t pwd[4] = {0x00};
memcpy(pwd, datain, 4); memcpy(pwd, datain, 4);
uint8_t pack[4] = {0,0,0,0}; uint8_t pack[4] = {0,0,0,0};
@ -169,13 +180,13 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
} }
} }
if( mifare_ultra_readblock(blockNo, dataout) ) { if (mifare_ultra_readblock(blockNo, dataout)) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error"); if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error");
OnError(2); OnError(2);
return; return;
} }
if( mifare_ultra_halt() ) { if (mifare_ultra_halt()) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error"); if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");
OnError(3); OnError(3);
return; return;
@ -183,7 +194,8 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
cmd_send(CMD_ACK,1,0,0,dataout,16); cmd_send(CMD_ACK,1,0,0,dataout,16);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff(); LED_D_OFF();
LED_A_OFF();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -259,13 +271,11 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
// datain = KEY bytes // datain = KEY bytes
void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
{ {
LEDsoff();
LED_A_ON(); LED_A_ON();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
// free eventually allocated BigBuf memory // free eventually allocated BigBuf memory
BigBuf_free(); BigBuf_free();
clear_trace();
// params // params
uint8_t blockNo = arg0; uint8_t blockNo = arg0;
@ -288,7 +298,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
} }
// UL-C authentication // UL-C authentication
if ( useKey ) { if (useKey) {
uint8_t key[16] = {0x00}; uint8_t key[16] = {0x00};
memcpy(key, datain, sizeof(key) ); memcpy(key, datain, sizeof(key) );
@ -340,14 +350,14 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
return; return;
} }
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Blocks read %d", countblocks); if (MF_DBGLEVEL >= MF_DBG_DEBUG) Dbprintf("Blocks read %d", countblocks);
countblocks *= 4; cmd_send(CMD_ACK, 1, countblocks*4, BigBuf_max_traceLen(), 0, 0);
cmd_send(CMD_ACK, 1, countblocks, BigBuf_max_traceLen(), 0, 0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff(); LED_D_OFF();
BigBuf_free(); BigBuf_free();
LED_A_OFF();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1598,17 +1608,3 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){
LEDsoff(); LEDsoff();
} }
void OnSuccess(){
pcb_blocknum = 0;
ReaderTransmit(deselect_cmd, 3 , NULL);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
void OnError(uint8_t reason){
pcb_blocknum = 0;
ReaderTransmit(deselect_cmd, 3 , NULL);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
cmd_send(CMD_ACK,0,reason,0,0,0);
LEDsoff();
}

View file

@ -542,8 +542,8 @@ void MifareSim(uint8_t flags, uint8_t exitAfterNReads, uint8_t cardsize, uint8_t
break; break;
} }
if(receivedCmd_dec[0] == ISO14443A_CMD_READBLOCK if(receivedCmd_dec[0] == MIFARE_CMD_READBLOCK
|| receivedCmd_dec[0] == ISO14443A_CMD_WRITEBLOCK || receivedCmd_dec[0] == MIFARE_CMD_WRITEBLOCK
|| receivedCmd_dec[0] == MIFARE_CMD_INC || receivedCmd_dec[0] == MIFARE_CMD_INC
|| receivedCmd_dec[0] == MIFARE_CMD_DEC || receivedCmd_dec[0] == MIFARE_CMD_DEC
|| receivedCmd_dec[0] == MIFARE_CMD_RESTORE || receivedCmd_dec[0] == MIFARE_CMD_RESTORE
@ -562,7 +562,7 @@ void MifareSim(uint8_t flags, uint8_t exitAfterNReads, uint8_t cardsize, uint8_t
} }
} }
if (receivedCmd_dec[0] == ISO14443A_CMD_READBLOCK) { if (receivedCmd_dec[0] == MIFARE_CMD_READBLOCK) {
uint8_t blockNo = receivedCmd_dec[1]; uint8_t blockNo = receivedCmd_dec[1];
emlGetMem(response, blockNo, 1); emlGetMem(response, blockNo, 1);
if (IsSectorTrailer(blockNo)) { if (IsSectorTrailer(blockNo)) {
@ -593,7 +593,7 @@ void MifareSim(uint8_t flags, uint8_t exitAfterNReads, uint8_t cardsize, uint8_t
break; break;
} }
if (receivedCmd_dec[0] == ISO14443A_CMD_WRITEBLOCK) { if (receivedCmd_dec[0] == MIFARE_CMD_WRITEBLOCK) {
uint8_t blockNo = receivedCmd_dec[1]; uint8_t blockNo = receivedCmd_dec[1];
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK));
FpgaDisableTracing(); FpgaDisableTracing();

View file

@ -451,7 +451,7 @@ int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData)
return result; return result;
} }
memcpy(blockData, receivedAnswer, 14); memcpy(blockData, receivedAnswer, 16);
return 0; return 0;
} }

View file

@ -25,11 +25,6 @@
#define AUTH_FIRST 0 #define AUTH_FIRST 0
#define AUTH_NESTED 2 #define AUTH_NESTED 2
// mifare 4bit card answers
#define CARD_ACK 0x0A // 1010 - ACK
#define CARD_NACK_NA 0x04 // 0100 - NACK, not allowed (command not allowed)
#define CARD_NACK_TR 0x05 // 0101 - NACK, transmission error
// reader voltage field detector // reader voltage field detector
#define MF_MINFIELDV 4000 #define MF_MINFIELDV 4000

View file

@ -401,13 +401,7 @@ void BruteForcePCF7931(uint64_t password, uint8_t tries, uint16_t init_delay, in
return; return;
} }
pass_array[0] = password & 0xFF; num_to_bytes(password, 7, pass_array);
pass_array[1] = (password >> 8) & 0xFF;
pass_array[2] = (password >> 16) & 0xFF;
pass_array[3] = (password >> 24) & 0xFF;
pass_array[4] = (password >> 32) & 0xFF;
pass_array[5] = (password >> 40) & 0xFF;
pass_array[6] = (password >> 48) & 0xFF;
Dbprintf("Trying: %02x %02x %02x %02x %02x %02x %02x ...", Dbprintf("Trying: %02x %02x %02x %02x %02x %02x %02x ...",
pass_array[0], pass_array[0],

View file

@ -16,13 +16,14 @@
#include <stdbool.h> #include <stdbool.h>
#include "mifare.h" #include "mifare.h"
int CmdHF14A(const char *Cmd); extern int CmdHF14A(const char *Cmd);
int CmdHF14AList(const char *Cmd); extern int CmdHF14AMfDbg(const char* cmd);
int CmdHF14AMifare(const char *Cmd); extern int CmdHF14AList(const char *Cmd);
int CmdHF14AReader(const char *Cmd); extern int CmdHF14AMifare(const char *Cmd);
extern int CmdHF14AReader(const char *Cmd);
extern int CmdHF14AInfo(const char *Cmd); extern int CmdHF14AInfo(const char *Cmd);
int CmdHF14ASim(const char *Cmd); extern int CmdHF14ASim(const char *Cmd);
int CmdHF14ASnoop(const char *Cmd); extern int CmdHF14ASnoop(const char *Cmd);
extern void DropField(); extern void DropField();

View file

@ -382,6 +382,7 @@ static command_t CommandTable15[] =
{"cmd", CmdHF15Cmd, 0, "Send direct commands to ISO15693 tag"}, {"cmd", CmdHF15Cmd, 0, "Send direct commands to ISO15693 tag"},
{"findafi", CmdHF15Afi, 0, "Brute force AFI of an ISO15693 tag"}, {"findafi", CmdHF15Afi, 0, "Brute force AFI of an ISO15693 tag"},
{"dumpmemory", CmdHF15DumpMem, 0, "Read all memory pages of an ISO15693 tag"}, {"dumpmemory", CmdHF15DumpMem, 0, "Read all memory pages of an ISO15693 tag"},
{"csetuid", CmdHF15CSetUID, 0, "Set UID for magic Chinese card"},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
@ -954,6 +955,92 @@ int CmdHF15CmdWrite(const char *Cmd) {
return 0; return 0;
} }
int CmdHF15CSetUID(const char *Cmd)
{
uint8_t uid[8] = {0x00};
uint8_t oldUid[8], newUid[8] = {0x00};
uint8_t needHelp = 0;
char cmdp = 1;
if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, uid, 16)) {
PrintAndLog("UID must include 16 HEX symbols");
return 1;
}
if (uid[0] != 0xe0) {
PrintAndLog("UID must begin with the byte 'E0'");
return 1;
}
while(param_getchar(Cmd, cmdp) != 0x00)
{
switch(param_getchar(Cmd, cmdp))
{
case 'h':
case 'H':
needHelp = 1;
break;
default:
PrintAndLog("ERROR: Unknown parameter '%c'", param_getchar(Cmd, cmdp));
needHelp = 1;
break;
}
cmdp++;
}
if (strlen(Cmd) < 1 || needHelp) {
PrintAndLog("");
PrintAndLog("Usage: hf 15 csetuid <UID 16 hex symbols>");
PrintAndLog("sample: hf 15 csetuid E004013344556677");
PrintAndLog("Set UID for magic Chinese card (only works with such cards)");
return 0;
}
PrintAndLog("");
PrintAndLog("new UID | %s", sprint_hex(uid, 8));
PrintAndLog("Using backdoor Magic tag function");
if (!getUID(oldUid)) {
PrintAndLog("Can't get old UID.");
return 1;
}
UsbCommand resp;
uint8_t *recv;
char *hexout;
UsbCommand c = {CMD_CSETUID_ISO_15693, {0, 0, 0}};
memcpy(c.d.asBytes, uid, 8);
SendCommand(&c);
for (int i=0; i<4; i++) {
if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
recv = resp.d.asBytes;
PrintAndLog("received %i octets",resp.arg[0]);
hexout = (char *)malloc(resp.arg[0] * 3 + 1);
if (hexout != NULL) {
for (int i = 0; i < resp.arg[0]; i++) { // data in hex
sprintf(&hexout[i * 3], "%02X ", recv[i]);
}
PrintAndLog("%s", hexout);
free(hexout);
}
} else {
PrintAndLog("timeout while waiting for reply.");
}
}
if (!getUID(newUid)) {
PrintAndLog("Can't get new UID.");
return 1;
}
PrintAndLog("");
PrintAndLog("old UID : %02X %02X %02X %02X %02X %02X %02X %02X", oldUid[7], oldUid[6], oldUid[5], oldUid[4], oldUid[3], oldUid[2], oldUid[1], oldUid[0]);
PrintAndLog("new UID : %02X %02X %02X %02X %02X %02X %02X %02X", newUid[7], newUid[6], newUid[5], newUid[4], newUid[3], newUid[2], newUid[1], newUid[0]);
return 0;
}
static command_t CommandTable15Cmd[] = static command_t CommandTable15Cmd[] =
@ -968,6 +1055,7 @@ static command_t CommandTable15Cmd[] =
{"readmulti",CmdHF15CmdReadmulti, 0, "Reads multiple Blocks"}, {"readmulti",CmdHF15CmdReadmulti, 0, "Reads multiple Blocks"},
{"sysinfo",CmdHF15CmdSysinfo, 0, "Get Card Information"}, {"sysinfo",CmdHF15CmdSysinfo, 0, "Get Card Information"},
{"raw", CmdHF15CmdRaw, 0, "Send raw hex data to tag"}, {"raw", CmdHF15CmdRaw, 0, "Send raw hex data to tag"},
{"csetuid", CmdHF15CSetUID, 0, "Set UID for magic Chinese card"},
{"debug", CmdHF15CmdDebug, 0, "Turn debugging on/off"}, {"debug", CmdHF15CmdDebug, 0, "Turn debugging on/off"},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };

View file

@ -22,6 +22,7 @@ int CmdHF15Reader(const char *Cmd);
int CmdHF15Sim(const char *Cmd); int CmdHF15Sim(const char *Cmd);
int CmdHF15Record(const char *Cmd); int CmdHF15Record(const char *Cmd);
int CmdHF15Cmd(const char*Cmd); int CmdHF15Cmd(const char*Cmd);
int CmdHF15CSetUID(const char *Cmd);
int CmdHF15CmdHelp(const char*Cmd); int CmdHF15CmdHelp(const char*Cmd);
int CmdHF15Help(const char*Cmd); int CmdHF15Help(const char*Cmd);

View file

@ -33,6 +33,7 @@
#include "usb_cmd.h" #include "usb_cmd.h"
#include "cmdhfmfu.h" #include "cmdhfmfu.h"
#include "util_posix.h" #include "util_posix.h"
#include "cmdhf14a.h" // DropField()
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);

View file

@ -218,8 +218,10 @@ int CmdLegicRFRead(const char *Cmd)
UsbCommand resp; UsbCommand resp;
WaitForResponse(CMD_ACK,&resp); WaitForResponse(CMD_ACK,&resp);
switch (resp.arg[0]) { switch (resp.arg[0]) {
legic_card_select_t card;
case 0: case 0:
PrintAndLog("Card (MIM %i) read, use 'hf legic decode' or", ((legic_card_select_t*)resp.d.asBytes)->cardsize); memcpy(&card, resp.d.asBytes, sizeof(card));
PrintAndLog("Card (MIM %i) read, use 'hf legic decode' or", card.cardsize);
PrintAndLog("'data hexsamples %d' to view results", (resp.arg[1] + 7) & ~7); PrintAndLog("'data hexsamples %d' to view results", (resp.arg[1] + 7) & ~7);
break; break;
case 1: case 1:
@ -252,16 +254,16 @@ int CmdLegicLoad(const char *Cmd)
memcpy(filename, Cmd, len); memcpy(filename, Cmd, len);
FILE *f = fopen(filename, "r"); FILE *f = fopen(filename, "r");
if(!f) { if (!f) {
PrintAndLog("couldn't open '%s'", Cmd); PrintAndLog("couldn't open '%s'", Cmd);
return -1; return -1;
} }
char line[80]; int offset = 0; unsigned int data[8]; char line[80]; int offset = 0; unsigned int data[8];
while(fgets(line, sizeof(line), f)) { while (fgets(line, sizeof(line), f)) {
int res = sscanf(line, "%x %x %x %x %x %x %x %x", int res = sscanf(line, "%x %x %x %x %x %x %x %x",
&data[0], &data[1], &data[2], &data[3], &data[0], &data[1], &data[2], &data[3],
&data[4], &data[5], &data[6], &data[7]); &data[4], &data[5], &data[6], &data[7]);
if(res != 8) { if (res != 8) {
PrintAndLog("Error: could not read samples"); PrintAndLog("Error: could not read samples");
fclose(f); fclose(f);
return -1; return -1;
@ -304,7 +306,7 @@ int CmdLegicSave(const char *Cmd)
} }
FILE *f = fopen(filename, "w"); FILE *f = fopen(filename, "w");
if(!f) { if (!f) {
PrintAndLog("couldn't open '%s'", Cmd+1); PrintAndLog("couldn't open '%s'", Cmd+1);
return -1; return -1;
} }
@ -345,7 +347,7 @@ int CmdLegicRfWrite(const char *Cmd)
{ {
UsbCommand c={CMD_WRITER_LEGIC_RF}; UsbCommand c={CMD_WRITER_LEGIC_RF};
int res = sscanf(Cmd, " 0x%" SCNx64 " 0x%" SCNx64, &c.arg[0], &c.arg[1]); int res = sscanf(Cmd, " 0x%" SCNx64 " 0x%" SCNx64, &c.arg[0], &c.arg[1]);
if(res != 2) { if (res != 2) {
PrintAndLog("Please specify the offset and length as two hex strings"); PrintAndLog("Please specify the offset and length as two hex strings");
return -1; return -1;
} }
@ -357,17 +359,17 @@ int CmdLegicRfFill(const char *Cmd)
{ {
UsbCommand cmd ={CMD_WRITER_LEGIC_RF}; UsbCommand cmd ={CMD_WRITER_LEGIC_RF};
int res = sscanf(Cmd, " 0x%" SCNx64 " 0x%" SCNx64 " 0x%" SCNx64, &cmd.arg[0], &cmd.arg[1], &cmd.arg[2]); int res = sscanf(Cmd, " 0x%" SCNx64 " 0x%" SCNx64 " 0x%" SCNx64, &cmd.arg[0], &cmd.arg[1], &cmd.arg[2]);
if(res != 3) { if (res != 3) {
PrintAndLog("Please specify the offset, length and value as two hex strings"); PrintAndLog("Please specify the offset, length and value as two hex strings");
return -1; return -1;
} }
int i; int i;
UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {0, 1, 0}}; UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {0, 1, 0}};
for(i = 0; i < 48; i++) { for (i = 0; i < 48; i++) {
c.d.asBytes[i] = cmd.arg[2]; c.d.asBytes[i] = cmd.arg[2];
} }
for(i = 0; i < 22; i++) { for (i = 0; i < 22; i++) {
c.arg[0] = i*48; c.arg[0] = i*48;
SendCommand(&c); SendCommand(&c);
WaitForResponse(CMD_ACK,NULL); WaitForResponse(CMD_ACK,NULL);

View file

@ -415,8 +415,8 @@ void annotateIso14443a(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
case ISO14443A_CMD_REQA: case ISO14443A_CMD_REQA:
snprintf(exp,size,"REQA"); snprintf(exp,size,"REQA");
break; break;
case ISO14443A_CMD_READBLOCK: snprintf(exp,size,"READBLOCK(%d)",cmd[1]); break; case MIFARE_CMD_READBLOCK: snprintf(exp,size,"READBLOCK(%d)",cmd[1]); break;
case ISO14443A_CMD_WRITEBLOCK: snprintf(exp,size,"WRITEBLOCK(%d)",cmd[1]); break; case MIFARE_CMD_WRITEBLOCK: snprintf(exp,size,"WRITEBLOCK(%d)",cmd[1]); break;
case ISO14443A_CMD_HALT: case ISO14443A_CMD_HALT:
snprintf(exp,size,"HALT"); snprintf(exp,size,"HALT");
MifareAuthState = masNone; MifareAuthState = masNone;

View file

@ -29,6 +29,7 @@
#include "hardnested/hardnested_bf_core.h" #include "hardnested/hardnested_bf_core.h"
#include "cliparser/cliparser.h" #include "cliparser/cliparser.h"
#include "cmdhf14a.h" #include "cmdhf14a.h"
#include "mifare/mifaredefault.h"
#include "mifare/mifare4.h" #include "mifare/mifare4.h"
#include "mifare/mad.h" #include "mifare/mad.h"
#include "mifare/ndef.h" #include "mifare/ndef.h"
@ -1515,8 +1516,11 @@ int CmdHF14AMfSim(const char *Cmd) {
break; break;
case 'u': case 'u':
case 'U': case 'U':
param_gethex_ex(Cmd, cmdp+1, uid, &uidlen); uidlen = 14;
switch(uidlen) { if (param_gethex_ex(Cmd, cmdp+1, uid, &uidlen)) {
return usage_hf14_mfsim();
}
switch (uidlen) {
case 14: flags = FLAG_7B_UID_IN_DATA; break; case 14: flags = FLAG_7B_UID_IN_DATA; break;
case 8: flags = FLAG_4B_UID_IN_DATA; break; case 8: flags = FLAG_4B_UID_IN_DATA; break;
default: return usage_hf14_mfsim(); default: return usage_hf14_mfsim();
@ -1951,31 +1955,37 @@ int CmdHF14AMfECFill(const char *Cmd)
return 0; return 0;
} }
int CmdHF14AMfEKeyPrn(const char *Cmd) int CmdHF14AMfEKeyPrn(const char *Cmd)
{ {
int i; int i;
uint8_t numSectors; uint8_t numSectors = 16;
uint8_t data[16]; uint8_t data[16];
uint64_t keyA, keyB; uint64_t keyA, keyB;
bool createDumpFile = false;
if (param_getchar(Cmd, 0) == 'h') { if (param_getchar(Cmd, 0) == 'h') {
PrintAndLog("It prints the keys loaded in the emulator memory"); PrintAndLog("It prints the keys loaded in the emulator memory");
PrintAndLog("Usage: hf mf ekeyprn [card memory]"); PrintAndLog("Usage: hf mf ekeyprn [card memory] [d]");
PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");
PrintAndLog(" [d] : write keys to binary file dumpkeys.bin");
PrintAndLog(""); PrintAndLog("");
PrintAndLog(" sample: hf mf ekeyprn 1"); PrintAndLog(" sample: hf mf ekeyprn 1");
return 0; return 0;
} }
char cmdp = param_getchar(Cmd, 0); uint8_t cmdp = 0;
while (param_getchar(Cmd, cmdp) != 0x00) {
switch (cmdp) { switch (param_getchar(Cmd, cmdp)) {
case '0' : numSectors = 5; break; case '0' : numSectors = 5; break;
case '1' : case '1' :
case '\0': numSectors = 16; break; case '\0': numSectors = 16; break;
case '2' : numSectors = 32; break; case '2' : numSectors = 32; break;
case '4' : numSectors = 40; break; case '4' : numSectors = 40; break;
default: numSectors = 16; case 'd' :
case 'D' : createDumpFile = true; break;
}
cmdp++;
} }
PrintAndLog("|---|----------------|----------------|"); PrintAndLog("|---|----------------|----------------|");
@ -1992,9 +2002,35 @@ int CmdHF14AMfEKeyPrn(const char *Cmd)
} }
PrintAndLog("|---|----------------|----------------|"); PrintAndLog("|---|----------------|----------------|");
// Create dump file
if (createDumpFile) {
FILE *fkeys;
if ((fkeys = fopen("dumpkeys.bin","wb")) == NULL) {
PrintAndLog("Could not create file dumpkeys.bin");
return 1;
}
PrintAndLog("Printing keys to binary file dumpkeys.bin...");
for(i = 0; i < numSectors; i++) {
if (mfEmlGetMem(data, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1)) {
PrintAndLog("error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1);
break;
}
fwrite(data+6, 1, 6, fkeys);
}
for(i = 0; i < numSectors; i++) {
if (mfEmlGetMem(data, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1)) {
PrintAndLog("error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1);
break;
}
fwrite(data+10, 1, 6, fkeys);
}
fclose(fkeys);
}
return 0; return 0;
} }
int CmdHF14AMfCSetUID(const char *Cmd) int CmdHF14AMfCSetUID(const char *Cmd)
{ {
uint8_t uid[8] = {0x00}; uint8_t uid[8] = {0x00};
@ -2693,9 +2729,9 @@ int CmdHF14AMfSniff(const char *Cmd){
//needs nt, ar, at, Data to decrypt //needs nt, ar, at, Data to decrypt
int CmdDecryptTraceCmds(const char *Cmd){ int CmdDecryptTraceCmds(const char *Cmd){
uint8_t data[50]; uint8_t data[50];
int len = 0; int len = 100;
param_gethex_ex(Cmd,3,data,&len); param_gethex_ex(Cmd, 3, data, &len);
return tryDecryptWord(param_get32ex(Cmd,0,0,16),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16),data,len/2); return tryDecryptWord(param_get32ex(Cmd, 0, 0, 16), param_get32ex(Cmd, 1, 0, 16), param_get32ex(Cmd, 2, 0, 16), data, len/2);
} }
int CmdHF14AMfAuth4(const char *cmd) { int CmdHF14AMfAuth4(const char *cmd) {

View file

@ -11,38 +11,6 @@
#ifndef CMDHFMF_H__ #ifndef CMDHFMF_H__
#define CMDHFMF_H__ #define CMDHFMF_H__
#include "mifare/mifaredefault.h"
extern int CmdHFMF(const char *Cmd); extern int CmdHFMF(const char *Cmd);
extern int CmdHFMF(const char *Cmd);
extern int CmdHF14AMfDbg(const char* cmd);
extern int CmdHF14AMfRdBl(const char* cmd);
extern int CmdHF14AMfURdBl(const char* cmd);
extern int CmdHF14AMfRdSc(const char* cmd);
extern int CmdHF14SMfURdCard(const char* cmd);
extern int CmdHF14AMfDump(const char* cmd);
extern int CmdHF14AMfRestore(const char* cmd);
extern int CmdHF14AMfWrBl(const char* cmd);
extern int CmdHF14AMfUWrBl(const char* cmd);
extern int CmdHF14AMfChk(const char* cmd);
extern int CmdHF14AMifare(const char* cmd);
extern int CmdHF14AMfNested(const char* cmd);
extern int CmdHF14AMfSniff(const char* cmd);
extern int CmdHF14AMf1kSim(const char* cmd);
extern int CmdHF14AMfEClear(const char* cmd);
extern int CmdHF14AMfEGet(const char* cmd);
extern int CmdHF14AMfESet(const char* cmd);
extern int CmdHF14AMfELoad(const char* cmd);
extern int CmdHF14AMfESave(const char* cmd);
extern int CmdHF14AMfECFill(const char* cmd);
extern int CmdHF14AMfEKeyPrn(const char* cmd);
extern int CmdHF14AMfCWipe(const char* cmd);
extern int CmdHF14AMfCSetUID(const char* cmd);
extern int CmdHF14AMfCSetBlk(const char* cmd);
extern int CmdHF14AMfCGetBlk(const char* cmd);
extern int CmdHF14AMfCGetSc(const char* cmd);
extern int CmdHF14AMfCLoad(const char* cmd);
extern int CmdHF14AMfCSave(const char* cmd);
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,54 +1,10 @@
#include "cmdhfmf.h"
#include "cmdhf14a.h"
#ifndef CMDHFMFU_H__ #ifndef CMDHFMFU_H__
#define CMDHFMFU_H__ #define CMDHFMFU_H__
int CmdHF14AMfUWrBl(const char *Cmd); #include <stdint.h>
int CmdHF14AMfURdBl(const char *Cmd);
//Crypto Cards extern int CmdHFMFUltra(const char *Cmd);
int CmdHF14AMfucAuth(const char *Cmd); extern uint32_t GetHF14AMfU_Type(void);
extern int ul_print_type(uint32_t tagtype, uint8_t spacer);
//general stuff
int CmdHF14AMfUDump(const char *Cmd);
int CmdHF14AMfUInfo(const char *Cmd);
uint32_t GetHF14AMfU_Type(void);
int ul_print_type(uint32_t tagtype, uint8_t spacer);
int usage_hf_mfu_dump(void);
int usage_hf_mfu_info(void);
int usage_hf_mfu_rdbl(void);
int usage_hf_mfu_wrbl(void);
int CmdHFMFUltra(const char *Cmd);
typedef enum TAGTYPE_UL {
UNKNOWN = 0x000000,
UL = 0x000001,
UL_C = 0x000002,
UL_EV1_48 = 0x000004,
UL_EV1_128 = 0x000008,
NTAG = 0x000010,
NTAG_203 = 0x000020,
NTAG_210 = 0x000040,
NTAG_212 = 0x000080,
NTAG_213 = 0x000100,
NTAG_215 = 0x000200,
NTAG_216 = 0x000400,
MY_D = 0x000800,
MY_D_NFC = 0x001000,
MY_D_MOVE = 0x002000,
MY_D_MOVE_NFC = 0x004000,
MY_D_MOVE_LEAN= 0x008000,
NTAG_I2C_1K = 0x010000,
NTAG_I2C_2K = 0x020000,
FUDAN_UL = 0x040000,
MAGIC = 0x080000,
UL_MAGIC = UL | MAGIC,
UL_C_MAGIC = UL_C | MAGIC,
UL_ERROR = 0xFFFFFF,
} TagTypeUL_t;
#endif #endif

View file

@ -232,6 +232,7 @@ int usage_lf_config(void)
PrintAndLog(" d <decim> Sets decimation. A value of N saves only 1 in N samples. Default: 1"); PrintAndLog(" d <decim> Sets decimation. A value of N saves only 1 in N samples. Default: 1");
PrintAndLog(" a [0|1] Averaging - if set, will average the stored sample value when decimating. Default: 1"); PrintAndLog(" a [0|1] Averaging - if set, will average the stored sample value when decimating. Default: 1");
PrintAndLog(" t <threshold> Sets trigger threshold. 0 means no threshold (range: 0-128)"); PrintAndLog(" t <threshold> Sets trigger threshold. 0 means no threshold (range: 0-128)");
PrintAndLog(" s <smplstoskip> Sets a number of samples to skip before capture. Default: 0");
PrintAndLog("Examples:"); PrintAndLog("Examples:");
PrintAndLog(" lf config b 8 L"); PrintAndLog(" lf config b 8 L");
PrintAndLog(" Samples at 125KHz, 8bps."); PrintAndLog(" Samples at 125KHz, 8bps.");
@ -255,6 +256,7 @@ int CmdLFSetConfig(const char *Cmd)
bool errors = false; bool errors = false;
int trigger_threshold =-1;//Means no change int trigger_threshold =-1;//Means no change
uint8_t unsigned_trigg = 0; uint8_t unsigned_trigg = 0;
int samples_to_skip = -1;
uint8_t cmdp =0; uint8_t cmdp =0;
while(param_getchar(Cmd, cmdp) != 0x00) while(param_getchar(Cmd, cmdp) != 0x00)
@ -295,6 +297,10 @@ int CmdLFSetConfig(const char *Cmd)
averaging = param_getchar(Cmd,cmdp+1) == '1'; averaging = param_getchar(Cmd,cmdp+1) == '1';
cmdp+=2; cmdp+=2;
break; break;
case 's':
samples_to_skip = param_get32ex(Cmd,cmdp+1,0,10);
cmdp+=2;
break;
default: default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = 1; errors = 1;
@ -316,7 +322,7 @@ int CmdLFSetConfig(const char *Cmd)
if(bps >> 4) bps = 8; if(bps >> 4) bps = 8;
sample_config config = { sample_config config = {
decimation,bps,averaging,divisor,trigger_threshold decimation,bps,averaging,divisor,trigger_threshold,samples_to_skip
}; };
//Averaging is a flag on high-bit of arg[1] //Averaging is a flag on high-bit of arg[1]
UsbCommand c = {CMD_SET_LF_SAMPLING_CONFIG}; UsbCommand c = {CMD_SET_LF_SAMPLING_CONFIG};

View file

@ -1161,6 +1161,119 @@ int CmdEM4x05WriteWord(const char *Cmd) {
return EM4x05WriteWord(addr, data, pwd, usePwd, swap, invert); return EM4x05WriteWord(addr, data, pwd, usePwd, swap, invert);
} }
int usage_lf_em_protect(void) {
PrintAndLog("Protect EM4x05. Tag must be on antenna. ");
PrintAndLog("");
PrintAndLog("Usage: lf em 4x05protect [h] d <data> p <pwd> [s] [i]");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" d <data> - data to write (hex)");
PrintAndLog(" p <pwd> - password (hex) (optional)");
PrintAndLog(" s - swap the data bit order before write");
PrintAndLog(" i - invert the data bits before write");
PrintAndLog("samples:");
PrintAndLog(" lf em 4x05protect d 11223344");
PrintAndLog(" lf em 4x05protect p deadc0de d 11223344 s i");
return 0;
}
int EM4x05Protect(uint32_t data, uint32_t pwd, bool usePwd, bool swap, bool invert) {
if (swap) data = SwapBits(data, 32);
if (invert) data ^= 0xFFFFFFFF;
if ( !usePwd ) {
PrintAndLog("Writing Protect data %08X", data);
} else {
PrintAndLog("Writing Protect data %08X using password %08X", data, pwd);
}
uint16_t flag = usePwd;
UsbCommand c = {CMD_EM4X_PROTECT, {flag, data, pwd}};
clearCommandBuffer();
SendCommand(&c);
UsbCommand resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)){
PrintAndLog("Error occurred, device did not respond during protect operation.");
return -1;
}
if ( !downloadSamplesEM() ) {
return -1;
}
//check response for 00001010 for write confirmation!
//attempt demod:
uint32_t dummy = 0;
int result = demodEM4x05resp(&dummy,false);
if (result == 1) {
PrintAndLog("Protect Verified");
} else {
PrintAndLog("Protect could not be verified");
}
return result;
}
int CmdEM4x05ProtectWrite(const char *Cmd) {
bool errors = false;
bool usePwd = false;
uint32_t data = 0xFFFFFFFF;
uint32_t pwd = 0xFFFFFFFF;
bool swap = false;
bool invert = false;
bool gotData = false;
char cmdp = 0;
while(param_getchar(Cmd, cmdp) != 0x00)
{
switch(param_getchar(Cmd, cmdp))
{
case 'h':
case 'H':
return usage_lf_em_write();
case 'd':
case 'D':
data = param_get32ex(Cmd, cmdp+1, 0, 16);
gotData = true;
cmdp += 2;
break;
case 'i':
case 'I':
invert = true;
cmdp++;
break;
case 'p':
case 'P':
pwd = param_get32ex(Cmd, cmdp+1, 1, 16);
if (pwd == 1) {
PrintAndLog("invalid pwd");
errors = true;
}
usePwd = true;
cmdp += 2;
break;
case 's':
case 'S':
swap = true;
cmdp++;
break;
default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
if(errors) break;
}
//Validations
if(errors) return usage_lf_em_protect();
if ( strlen(Cmd) == 0 ) return usage_lf_em_protect();
if (!gotData) {
PrintAndLog("You must enter the data you want to write");
return usage_lf_em_protect();
}
return EM4x05Protect(data, pwd, usePwd, swap, invert);
}
void printEM4x05config(uint32_t wordData) { void printEM4x05config(uint32_t wordData) {
uint16_t datarate = EM4x05_GET_BITRATE(wordData); uint16_t datarate = EM4x05_GET_BITRATE(wordData);
uint8_t encoder = ((wordData >> 6) & 0xF); uint8_t encoder = ((wordData >> 6) & 0xF);
@ -1345,6 +1458,7 @@ static command_t CommandTable[] =
{"4x05info", CmdEM4x05info, 0, "(pwd) -- Get info from EM4x05/EM4x69 tag"}, {"4x05info", CmdEM4x05info, 0, "(pwd) -- Get info from EM4x05/EM4x69 tag"},
{"4x05readword", CmdEM4x05ReadWord, 0, "<Word> (pwd) -- Read EM4x05/EM4x69 word data"}, {"4x05readword", CmdEM4x05ReadWord, 0, "<Word> (pwd) -- Read EM4x05/EM4x69 word data"},
{"4x05writeword", CmdEM4x05WriteWord, 0, "<Word> <data> (pwd) -- Write EM4x05/EM4x69 word data"}, {"4x05writeword", CmdEM4x05WriteWord, 0, "<Word> <data> (pwd) -- Write EM4x05/EM4x69 word data"},
{"4x05protect", CmdEM4x05ProtectWrite, 0, "<data> (pwd) -- Write Protection to EM4x05"},
{"4x50read", CmdEM4x50Read, 1, "demod data from EM4x50 tag from the graph buffer"}, {"4x50read", CmdEM4x50Read, 1, "demod data from EM4x50 tag from the graph buffer"},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };

View file

@ -180,24 +180,24 @@ int CmdLFPCF7931BruteForce(const char *Cmd){
uint8_t ctmp = param_getchar(Cmd, 0); uint8_t ctmp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_pcf7931_bruteforce(); if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_pcf7931_bruteforce();
uint64_t start_password = 0; uint8_t start_password[7] = {0};
uint8_t tries = 3; uint8_t tries = 3;
if (param_gethex(Cmd, 0, (uint8_t*)(&start_password), 14)) return usage_pcf7931_bruteforce(); if (param_gethex(Cmd, 0, start_password, 14)) return usage_pcf7931_bruteforce();
if (param_getdec(Cmd, 1, &tries)) return usage_pcf7931_bruteforce(); if (param_getdec(Cmd, 1, &tries)) return usage_pcf7931_bruteforce();
PrintAndLog("Bruteforcing from password: %02x %02x %02x %02x %02x %02x %02x", PrintAndLog("Bruteforcing from password: %02x %02x %02x %02x %02x %02x %02x",
start_password & 0xFF, start_password[0],
(start_password >> 8) & 0xFF, start_password[1],
(start_password >> 16) & 0xFF, start_password[2],
(start_password >> 24) & 0xFF, start_password[3],
(start_password >> 32) & 0xFF, start_password[4],
(start_password >> 48) & 0xFF, start_password[5],
(start_password >> 56) & 0xFF); start_password[6]);
PrintAndLog("Trying each password %d times", tries); PrintAndLog("Trying each password %d times", tries);
UsbCommand c = {CMD_PCF7931_BRUTEFORCE, {start_password, tries} }; UsbCommand c = {CMD_PCF7931_BRUTEFORCE, {bytes_to_num(start_password, 7), tries} };
c.d.asDwords[7] = (configPcf.OffsetWidth + 128); c.d.asDwords[7] = (configPcf.OffsetWidth + 128);
c.d.asDwords[8] = (configPcf.OffsetPosition + 128); c.d.asDwords[8] = (configPcf.OffsetPosition + 128);

View file

@ -67,6 +67,8 @@ int usage_t55xx_read(){
PrintAndLog(" p <password> - OPTIONAL password (8 hex characters)"); PrintAndLog(" p <password> - OPTIONAL password (8 hex characters)");
PrintAndLog(" o - OPTIONAL override safety check"); PrintAndLog(" o - OPTIONAL override safety check");
PrintAndLog(" 1 - OPTIONAL read Page 1 instead of Page 0"); PrintAndLog(" 1 - OPTIONAL read Page 1 instead of Page 0");
PrintAndLog(" r <mode> - OPTIONAL downlink encoding '0' fixed bit length (default), '1' long leading reference");
PrintAndLog(" '2' leading zero, '3' 1 of 4 coding reference");
PrintAndLog(" ****WARNING****"); PrintAndLog(" ****WARNING****");
PrintAndLog(" Use of read with password on a tag not configured for a pwd"); PrintAndLog(" Use of read with password on a tag not configured for a pwd");
PrintAndLog(" can damage the tag"); PrintAndLog(" can damage the tag");
@ -86,6 +88,8 @@ int usage_t55xx_write(){
PrintAndLog(" p <password> - OPTIONAL password 4bytes (8 hex characters)"); PrintAndLog(" p <password> - OPTIONAL password 4bytes (8 hex characters)");
PrintAndLog(" 1 - OPTIONAL write Page 1 instead of Page 0"); PrintAndLog(" 1 - OPTIONAL write Page 1 instead of Page 0");
PrintAndLog(" t - OPTIONAL test mode write - ****DANGER****"); PrintAndLog(" t - OPTIONAL test mode write - ****DANGER****");
PrintAndLog(" r <mode> - OPTIONAL downlink encoding '0' fixed bit length (default), '1' long leading reference");
PrintAndLog(" '2' leading zero, '3' 1 of 4 coding reference");
PrintAndLog(""); PrintAndLog("");
PrintAndLog("Examples:"); PrintAndLog("Examples:");
PrintAndLog(" lf t55xx write b 3 d 11223344 - write 11223344 to block 3"); PrintAndLog(" lf t55xx write b 3 d 11223344 - write 11223344 to block 3");
@ -132,6 +136,8 @@ int usage_t55xx_detect(){
PrintAndLog("Options:"); PrintAndLog("Options:");
PrintAndLog(" 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLog(" 1 - if set, use Graphbuffer otherwise read data from tag.");
PrintAndLog(" p <password> - OPTIONAL password (8 hex characters)"); PrintAndLog(" p <password> - OPTIONAL password (8 hex characters)");
PrintAndLog(" r <mode> - OPTIONAL downlink encoding '0' fixed bit length (default), '1' long leading reference");
PrintAndLog(" '2' leading zero, '3' 1 of 4 coding reference");
PrintAndLog(""); PrintAndLog("");
PrintAndLog("Examples:"); PrintAndLog("Examples:");
PrintAndLog(" lf t55xx detect"); PrintAndLog(" lf t55xx detect");
@ -172,13 +178,16 @@ int usage_t55xx_bruteforce(){
PrintAndLog(" password must be 4 bytes (8 hex symbols)"); PrintAndLog(" password must be 4 bytes (8 hex symbols)");
PrintAndLog("Options:"); PrintAndLog("Options:");
PrintAndLog(" h - this help"); PrintAndLog(" h - this help");
PrintAndLog(" r <mode> - OPTIONAL downlink encoding '0' fixed bit length (default)");
PrintAndLog(" '1' long leading reference, '2' leading zero ");
PrintAndLog(" '3' 1 of 4 coding reference, '4' special - try all downlink modes");
PrintAndLog(" <start_pwd> - 4 byte hex value to start pwd search at"); PrintAndLog(" <start_pwd> - 4 byte hex value to start pwd search at");
PrintAndLog(" <end_pwd> - 4 byte hex value to end pwd search at"); PrintAndLog(" <end_pwd> - 4 byte hex value to end pwd search at");
PrintAndLog(" i <*.dic> - loads a default keys dictionary file <*.dic>"); PrintAndLog(" i <*.dic> - loads a default keys dictionary file <*.dic>");
PrintAndLog(""); PrintAndLog("");
PrintAndLog("Examples:"); PrintAndLog("Examples:");
PrintAndLog(" lf t55xx bruteforce aaaaaaaa bbbbbbbb"); PrintAndLog(" lf t55xx bruteforce [r 2] aaaaaaaa bbbbbbbb");
PrintAndLog(" lf t55xx bruteforce i default_pwd.dic"); PrintAndLog(" lf t55xx bruteforce [r 2] i default_pwd.dic");
PrintAndLog(""); PrintAndLog("");
return 0; return 0;
} }
@ -302,21 +311,21 @@ int CmdT55xxSetConfig(const char *Cmd) {
} }
// No args // No args
if (cmdp == 0) return printConfiguration( config ); if (cmdp == 0) return printConfiguration( config);
//Validations //Validations
if (errors) return usage_t55xx_config(); if (errors) return usage_t55xx_config();
config.block0 = 0; config.block0 = 0;
return printConfiguration ( config ); return printConfiguration ( config);
} }
int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32_t password){ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32_t password, uint8_t downlink_mode){
//Password mode //Password mode
if ( usepwd ) { if ( usepwd ) {
// try reading the config block and verify that PWD bit is set before doing this! // try reading the config block and verify that PWD bit is set before doing this!
if ( !override ) { if ( !override ) {
if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0 ) ) return 0; if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0,downlink_mode ) ) return 0;
if ( !tryDetectModulation() ) { if ( !tryDetectModulation() ) {
PrintAndLog("Safety Check: Could not detect if PWD bit is set in config block. Exits."); PrintAndLog("Safety Check: Could not detect if PWD bit is set in config block. Exits.");
return 0; return 0;
@ -330,7 +339,7 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32
} }
} }
if (!AquireData(page1, block, usepwd, password) ) return 0; if (!AquireData(page1, block, usepwd, password,downlink_mode) ) return 0;
if (!DecodeT55xxBlock()) return 0; if (!DecodeT55xxBlock()) return 0;
char blk[10]={0}; char blk[10]={0};
@ -342,6 +351,8 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32
int CmdT55xxReadBlock(const char *Cmd) { int CmdT55xxReadBlock(const char *Cmd) {
uint8_t block = REGULAR_READ_MODE_BLOCK; uint8_t block = REGULAR_READ_MODE_BLOCK;
uint32_t password = 0; //default to blank Block 7 uint32_t password = 0; //default to blank Block 7
uint8_t downlink_mode = 0;
bool usepwd = false; bool usepwd = false;
bool override = false; bool override = false;
bool page1 = false; bool page1 = false;
@ -372,6 +383,12 @@ int CmdT55xxReadBlock(const char *Cmd) {
page1 = true; page1 = true;
cmdp++; cmdp++;
break; break;
case 'r':
case 'R':
downlink_mode = param_getchar(Cmd, cmdp+1) - '0';
if (downlink_mode > 3) downlink_mode = 0;
cmdp +=2;
break;
default: default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true; errors = true;
@ -386,7 +403,7 @@ int CmdT55xxReadBlock(const char *Cmd) {
} }
printT5xxHeader(page1); printT5xxHeader(page1);
return T55xxReadBlock(block, page1, usepwd, override, password); return T55xxReadBlock(block, page1, usepwd, override, password, downlink_mode);
} }
bool DecodeT55xxBlock(){ bool DecodeT55xxBlock(){
@ -459,12 +476,32 @@ bool DecodeT5555TraceBlock() {
return (bool) ASKDemod("64 0 1", false, false, 1); return (bool) ASKDemod("64 0 1", false, false, 1);
} }
void T55xx_Print_DownlinkMode (uint8_t downlink_mode)
{
char Msg[80];
sprintf (Msg,"Downlink Mode used : ");
switch (downlink_mode) {
case 0 : strcat (Msg,"default/fixed bit length"); break;
case 1 : strcat (Msg,"long leading reference (r 1)"); break;
case 2 : strcat (Msg,"leading zero reference (r 2)"); break;
case 3 : strcat (Msg,"1 of 4 coding reference (r 3)"); break;
default :
strcat (Msg,"default/fixed bit length"); break;
}
PrintAndLog (Msg);
}
int CmdT55xxDetect(const char *Cmd){ int CmdT55xxDetect(const char *Cmd){
bool errors = false; bool errors = false;
bool useGB = false; bool useGB = false;
bool usepwd = false; bool usepwd = false;
uint32_t password = 0; uint32_t password = 0;
uint8_t cmdp = 0; uint8_t cmdp = 0;
uint8_t downlink_mode = 0;
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch(param_getchar(Cmd, cmdp)) { switch(param_getchar(Cmd, cmdp)) {
@ -482,6 +519,12 @@ int CmdT55xxDetect(const char *Cmd){
useGB = true; useGB = true;
cmdp++; cmdp++;
break; break;
case 'r':
case 'R':
downlink_mode = param_getchar(Cmd, cmdp+1) - '0';
if (downlink_mode > 3) downlink_mode = 0;
cmdp +=2;
break;
default: default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true; errors = true;
@ -491,13 +534,16 @@ int CmdT55xxDetect(const char *Cmd){
if (errors) return usage_t55xx_detect(); if (errors) return usage_t55xx_detect();
if ( !useGB) { if ( !useGB) {
if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password) ) if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password,downlink_mode) )
return 0; return 0;
} }
if ( !tryDetectModulation() ) if ( !tryDetectModulation() )
PrintAndLog("Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'"); PrintAndLog("Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'");
else {
// Add downlink mode for reference.
T55xx_Print_DownlinkMode (downlink_mode);
}
return 1; return 1;
} }
@ -649,7 +695,8 @@ bool tryDetectModulation(){
config.block0 = tests[0].block0; config.block0 = tests[0].block0;
config.Q5 = tests[0].Q5; config.Q5 = tests[0].Q5;
config.ST = tests[0].ST; config.ST = tests[0].ST;
printConfiguration( config );
printConfiguration( config);
return true; return true;
} }
@ -657,7 +704,7 @@ bool tryDetectModulation(){
PrintAndLog("Found [%d] possible matches for modulation.",hits); PrintAndLog("Found [%d] possible matches for modulation.",hits);
for(int i=0; i<hits; ++i){ for(int i=0; i<hits; ++i){
PrintAndLog("--[%d]---------------", i+1); PrintAndLog("--[%d]---------------", i+1);
printConfiguration( tests[i] ); printConfiguration( tests[i]);
} }
} }
return false; return false;
@ -898,6 +945,8 @@ int CmdT55xxWriteBlock(const char *Cmd) {
uint8_t block = 0xFF; //default to invalid block uint8_t block = 0xFF; //default to invalid block
uint32_t data = 0; //default to blank Block uint32_t data = 0; //default to blank Block
uint32_t password = 0; //default to blank Block 7 uint32_t password = 0; //default to blank Block 7
uint32_t downlink_mode = 0;
bool usepwd = false; bool usepwd = false;
bool page1 = false; bool page1 = false;
bool gotdata = false; bool gotdata = false;
@ -935,6 +984,12 @@ int CmdT55xxWriteBlock(const char *Cmd) {
page1 = true; page1 = true;
cmdp++; cmdp++;
break; break;
case 'r':
case 'R':
downlink_mode = param_getchar(Cmd, cmdp+1) - '0';
if (downlink_mode > 3) downlink_mode = 0;
cmdp +=2;
break;
default: default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true; errors = true;
@ -952,6 +1007,7 @@ int CmdT55xxWriteBlock(const char *Cmd) {
UsbCommand resp; UsbCommand resp;
c.d.asBytes[0] = (page1) ? 0x2 : 0; c.d.asBytes[0] = (page1) ? 0x2 : 0;
c.d.asBytes[0] |= (testMode) ? 0x4 : 0; c.d.asBytes[0] |= (testMode) ? 0x4 : 0;
c.d.asBytes[0] |= (downlink_mode << 3);
char pwdStr[16] = {0}; char pwdStr[16] = {0};
snprintf(pwdStr, sizeof(pwdStr), "pwd: 0x%08X", password); snprintf(pwdStr, sizeof(pwdStr), "pwd: 0x%08X", password);
@ -963,6 +1019,7 @@ int CmdT55xxWriteBlock(const char *Cmd) {
c.arg[2] = password; c.arg[2] = password;
c.d.asBytes[0] |= 0x1; c.d.asBytes[0] |= 0x1;
} }
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){ if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){
@ -980,7 +1037,7 @@ int CmdT55xxReadTrace(const char *Cmd) {
return usage_t55xx_trace(); return usage_t55xx_trace();
if (strlen(Cmd)==0) if (strlen(Cmd)==0)
if ( !AquireData( T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password ) ) if ( !AquireData( T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password,0 ) )
return 0; return 0;
if ( config.Q5 ) { if ( config.Q5 ) {
@ -1144,7 +1201,7 @@ int CmdT55xxInfo(const char *Cmd){
return usage_t55xx_info(); return usage_t55xx_info();
if (strlen(Cmd)==0) if (strlen(Cmd)==0)
if ( !AquireData( T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, pwdmode, password ) ) if ( !AquireData( T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, pwdmode, password,0 ) )
return 1; return 1;
if (!DecodeT55xxBlock()) return 1; if (!DecodeT55xxBlock()) return 1;
@ -1212,20 +1269,21 @@ int CmdT55xxDump(const char *Cmd){
printT5xxHeader(0); printT5xxHeader(0);
for ( uint8_t i = 0; i <8; ++i) for ( uint8_t i = 0; i <8; ++i)
T55xxReadBlock(i, 0, usepwd, override, password); T55xxReadBlock(i, 0, usepwd, override, password,0);
printT5xxHeader(1); printT5xxHeader(1);
for ( uint8_t i = 0; i<4; i++) for ( uint8_t i = 0; i<4; i++)
T55xxReadBlock(i, 1, usepwd, override, password); T55xxReadBlock(i, 1, usepwd, override, password,0);
return 1; return 1;
} }
int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ){ int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password, uint8_t downlink_mode ){
// arg0 bitmodes: // arg0 bitmodes:
// bit0 = pwdmode // bit0 = pwdmode
// bit1 = page to read from // bit1 = page to read from
uint8_t arg0 = (page<<1) | pwdmode; uint8_t arg0 = (page<<1) | pwdmode;
arg0 |= (downlink_mode << 3);
UsbCommand c = {CMD_T55XX_READ_BLOCK, {arg0, block, password}}; UsbCommand c = {CMD_T55XX_READ_BLOCK, {arg0, block, password}};
clearCommandBuffer(); clearCommandBuffer();
@ -1403,9 +1461,23 @@ int CmdT55xxBruteForce(const char *Cmd) {
uint32_t start_password = 0x00000000; //start password uint32_t start_password = 0x00000000; //start password
uint32_t end_password = 0xFFFFFFFF; //end password uint32_t end_password = 0xFFFFFFFF; //end password
bool found = false; bool found = false;
uint8_t downlink_mode = 0;
bool try_all_dl_modes = false;
uint8_t dl_mode = 0;
uint8_t cmd_offset = 0;
int cmd_opt = 0;
char cmdp = param_getchar(Cmd, 0); char cmdp = param_getchar(Cmd, 0);
if (cmdp == 'h' || cmdp == 'H') return usage_t55xx_bruteforce(); if (cmdp == 'h' || cmdp == 'H') return usage_t55xx_bruteforce();
if (cmdp == 'r' || cmdp == 'R') {
downlink_mode = param_getchar(Cmd, 1) - '0'; // get 2nd option, as this is fixed order.
if (downlink_mode == 4) try_all_dl_modes = true;
if (downlink_mode > 3) downlink_mode = 0;
cmd_opt += 2; // To help start/end passwords for range to be found
cmd_offset += 4; // r <sp> x <sp> To help the string offset for filename start position in cmd
cmdp = param_getchar(Cmd, 2); // get 3rd option, as this is fixed order.
}
keyBlock = calloc(stKeyBlock, 6); keyBlock = calloc(stKeyBlock, 6);
if (keyBlock == NULL) return 1; if (keyBlock == NULL) return 1;
@ -1414,7 +1486,7 @@ int CmdT55xxBruteForce(const char *Cmd) {
int len = strlen(Cmd+2); int len = strlen(Cmd+2);
if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
memcpy(filename, Cmd+2, len); memcpy(filename, Cmd+2+cmd_offset, len);
FILE * f = fopen( filename , "r"); FILE * f = fopen( filename , "r");
@ -1480,8 +1552,11 @@ int CmdT55xxBruteForce(const char *Cmd) {
PrintAndLog("Testing %08X", testpwd); PrintAndLog("Testing %08X", testpwd);
if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, testpwd)) { // Try each downlink_mode if asked to
PrintAndLog("Aquireing data from device failed. Quitting"); // donwlink_mode will = 0 if > 3 or set to 0, so loop from 0 - 3
for (dl_mode = downlink_mode; dl_mode <= 3; dl_mode++){
if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, testpwd, dl_mode)) {
PrintAndLog("Acquiring data from device failed. Quitting");
free(keyBlock); free(keyBlock);
return 0; return 0;
} }
@ -1491,8 +1566,14 @@ int CmdT55xxBruteForce(const char *Cmd) {
if ( found ) { if ( found ) {
PrintAndLog("Found valid password: [%08X]", testpwd); PrintAndLog("Found valid password: [%08X]", testpwd);
free(keyBlock); free(keyBlock);
T55xx_Print_DownlinkMode (dl_mode);
return 0; return 0;
} }
if (!try_all_dl_modes) // Exit loop if not trying all downlink modes
dl_mode = 4;
}
} }
PrintAndLog("Password NOT found."); PrintAndLog("Password NOT found.");
free(keyBlock); free(keyBlock);
@ -1502,8 +1583,8 @@ int CmdT55xxBruteForce(const char *Cmd) {
// Try to read Block 7, first :) // Try to read Block 7, first :)
// incremental pwd range search // incremental pwd range search
start_password = param_get32ex(Cmd, 0, 0, 16); start_password = param_get32ex(Cmd, cmd_opt , 0, 16);
end_password = param_get32ex(Cmd, 1, 0, 16); end_password = param_get32ex(Cmd, cmd_opt+1 , 0, 16);
if ( start_password >= end_password ) { if ( start_password >= end_password ) {
free(keyBlock); free(keyBlock);
@ -1524,29 +1605,36 @@ int CmdT55xxBruteForce(const char *Cmd) {
free(keyBlock); free(keyBlock);
return 0; return 0;
} }
// Try each downlink_mode if asked to
if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, i)) { // donwlink_mode will = 0 if > 3 or set to 0, so loop from 0 - 3
PrintAndLog("Aquireing data from device failed. Quitting"); for (dl_mode = downlink_mode; dl_mode <= 3; dl_mode++){
if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, i,dl_mode)) {
PrintAndLog("Acquiring data from device failed. Quitting");
free(keyBlock); free(keyBlock);
return 0; return 0;
} }
found = tryDetectModulation(); found = tryDetectModulation();
if (found) break;
if (!try_all_dl_modes) // Exit loop if not trying all downlink modes
dl_mode = 4;
}
if (found) break; if (found) break;
i++; i++;
} }
PrintAndLog(""); if (found){
if (found)
PrintAndLog("Found valid password: [%08x]", i); PrintAndLog("Found valid password: [%08x]", i);
else T55xx_Print_DownlinkMode (downlink_mode);
}
else{
PrintAndLog("");
PrintAndLog("Password NOT found. Last tried: [%08x]", --i); PrintAndLog("Password NOT found. Last tried: [%08x]", --i);
}
free(keyBlock); free(keyBlock);
return 0; return 0;
} }
// note length of data returned is different for different chips. // note length of data returned is different for different chips.
// some return all page 1 (64 bits) and others return just that block (32 bits) // some return all page 1 (64 bits) and others return just that block (32 bits)
// unfortunately the 64 bits makes this more likely to get a false positive... // unfortunately the 64 bits makes this more likely to get a false positive...
@ -1558,7 +1646,7 @@ bool tryDetectP1(bool getData) {
bool st = true; bool st = true;
if ( getData ) { if ( getData ) {
if ( !AquireData(T55x7_PAGE1, 1, false, 0) ) if ( !AquireData(T55x7_PAGE1, 1, false, 0,0) )
return false; return false;
} }
@ -1687,7 +1775,7 @@ int CmdT55xxDetectPage1(const char *Cmd){
if (errors) return usage_t55xx_detectP1(); if (errors) return usage_t55xx_detectP1();
if ( !useGB ) { if ( !useGB ) {
if ( !AquireData(T55x7_PAGE1, 1, usepwd, password) ) if ( !AquireData(T55x7_PAGE1, 1, usepwd, password,0) )
return false; return false;
} }
bool success = tryDetectP1(false); bool success = tryDetectP1(false);

View file

@ -98,7 +98,7 @@ bool tryDetectModulation(void);
extern bool tryDetectP1(bool getData); extern bool tryDetectP1(bool getData);
bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5); bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5);
int special(const char *Cmd); int special(const char *Cmd);
int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ); int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password,uint8_t downlink_mode );
void printT55x7Trace( t55x7_tracedata_t data, uint8_t repeat ); void printT55x7Trace( t55x7_tracedata_t data, uint8_t repeat );
void printT5555Trace( t5555_tracedata_t data, uint8_t repeat ); void printT5555Trace( t5555_tracedata_t data, uint8_t repeat );

View file

@ -34,8 +34,8 @@ extern "C" {
bool g_useOverlays = false; bool g_useOverlays = false;
int g_absVMax = 0; int g_absVMax = 0;
int startMax; int startMax; // Maximum offset in the graph (right side of graph)
int PageWidth; int PageWidth; // How many samples are currently visible on this 'page' / graph
int unlockStart = 0; int unlockStart = 0;
void ProxGuiQT::ShowGraphWindow(void) void ProxGuiQT::ShowGraphWindow(void)
@ -509,8 +509,9 @@ void Plot::paintEvent(QPaintEvent *event)
if(CursorDPos > GraphTraceLen) if(CursorDPos > GraphTraceLen)
CursorDPos= 0; CursorDPos= 0;
QRect plotRect(WIDTH_AXES, 0, width()-WIDTH_AXES, height()-HEIGHT_INFO); QRect plotRect(WIDTH_AXES, 0, width() - WIDTH_AXES, height() - HEIGHT_INFO);
QRect infoRect(0, height()-HEIGHT_INFO, width(), HEIGHT_INFO); QRect infoRect(0, height() - HEIGHT_INFO, width(), HEIGHT_INFO);
PageWidth = plotRect.width() / GraphPixelsPerPoint;
//Grey background //Grey background
painter.fillRect(rect(), QColor(60, 60, 60)); painter.fillRect(rect(), QColor(60, 60, 60));
@ -616,7 +617,7 @@ void Plot::mouseMoveEvent(QMouseEvent *event)
void Plot::keyPressEvent(QKeyEvent *event) void Plot::keyPressEvent(QKeyEvent *event)
{ {
int offset; int offset; // Left/right movement offset (in sample size)
if(event->modifiers() & Qt::ShiftModifier) { if(event->modifiers() & Qt::ShiftModifier) {
if (PlotGridX) if (PlotGridX)
@ -671,20 +672,22 @@ void Plot::keyPressEvent(QKeyEvent *event)
case Qt::Key_H: case Qt::Key_H:
puts("Plot Window Keystrokes:\n"); puts("Plot Window Keystrokes:\n");
puts(" Key Action\n"); puts(" Key Action\n");
puts(" UP Zoom out");
puts(" DOWN Zoom in"); puts(" DOWN Zoom in");
puts(" G Toggle grid display"); puts(" G Toggle grid display");
puts(" H Show help"); puts(" H Show help");
puts(" L Toggle lock grid relative to samples"); puts(" L Toggle lock grid relative to samples");
puts(" Q Hide window");
puts(" HOME Move to the start of the graph");
puts(" END Move to the end of the graph");
puts(" LEFT Move left"); puts(" LEFT Move left");
puts(" <CTL>LEFT Move left 1 sample"); puts(" <CTL>LEFT Move left 1 sample");
puts(" <SHIFT>LEFT Page left"); puts(" <SHIFT>LEFT Page left");
puts(" LEFT-MOUSE-CLICK Set yellow cursor"); puts(" LEFT-MOUSE-CLICK Set yellow cursor");
puts(" Q Hide window");
puts(" RIGHT Move right"); puts(" RIGHT Move right");
puts(" <CTL>RIGHT Move right 1 sample"); puts(" <CTL>RIGHT Move right 1 sample");
puts(" <SHIFT>RIGHT Page right"); puts(" <SHIFT>RIGHT Page right");
puts(" RIGHT-MOUSE-CLICK Set purple cursor"); puts(" RIGHT-MOUSE-CLICK Set purple cursor");
puts(" UP Zoom out");
puts(""); puts("");
puts("Use client window 'data help' for more plot commands\n"); puts("Use client window 'data help' for more plot commands\n");
break; break;
@ -701,6 +704,14 @@ void Plot::keyPressEvent(QKeyEvent *event)
master->hide(); master->hide();
break; break;
case Qt::Key_Home:
GraphStart = 0;
break;
case Qt::Key_End:
GraphStart = startMax;
break;
default: default:
QWidget::keyPressEvent(event); QWidget::keyPressEvent(event);
return; return;

View file

@ -29,8 +29,8 @@ class Plot: public QWidget
{ {
private: private:
QWidget *master; QWidget *master;
int GraphStart; int GraphStart; // Starting point/offset for the left side of the graph
double GraphPixelsPerPoint; double GraphPixelsPerPoint; // How many visual pixels are between each sample point (x axis)
int CursorAPos; int CursorAPos;
int CursorBPos; int CursorBPos;
void PlotGraph(int *buffer, int len, QRect r,QRect r2, QPainter* painter, int graphNum); void PlotGraph(int *buffer, int len, QRect r,QRect r2, QPainter* painter, int graphNum);

View file

@ -117,9 +117,8 @@ void AddLogCurrentDT(char *fileName) {
AddLogLine(fileName, "\nanticollision: ", buff); AddLogLine(fileName, "\nanticollision: ", buff);
} }
void FillFileNameByUID(char *fileName, uint8_t * uid, char *ext, int byteCount) { void FillFileNameByUID(char *fileName, uint8_t *uid, char *ext, int byteCount) {
char * fnameptr = fileName; char * fnameptr = fileName;
memset(fileName, 0x00, 200);
for (int j = 0; j < byteCount; j++, fnameptr += 2) for (int j = 0; j < byteCount; j++, fnameptr += 2)
sprintf(fnameptr, "%02x", (unsigned int) uid[j]); sprintf(fnameptr, "%02x", (unsigned int) uid[j]);
@ -268,6 +267,10 @@ char *sprint_ascii_ex(const uint8_t *data, const size_t len, const size_t min_st
return buf; return buf;
} }
char *sprint_ascii(const uint8_t *data, const size_t len) {
return sprint_ascii_ex(data, len, 0);
}
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest) void num_to_bytes(uint64_t n, size_t len, uint8_t* dest)
{ {
while (len--) { while (len--) {
@ -319,22 +322,21 @@ uint32_t SwapBits(uint32_t value, int nrbits) {
uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize){ uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize){
static uint8_t buf[64]; static uint8_t buf[64];
memset(buf, 0x00, 64); memset(buf, 0x00, 64);
uint8_t *tmp = buf;
for (uint8_t block=0; block < (uint8_t)(len/blockSize); block++){ for (uint8_t block=0; block < (uint8_t)(len/blockSize); block++){
for (size_t i = 0; i < blockSize; i++){ for (size_t i = 0; i < blockSize; i++){
tmp[i+(blockSize*block)] = src[(blockSize-1-i)+(blockSize*block)]; buf[i+(blockSize*block)] = src[(blockSize-1-i)+(blockSize*block)];
} }
} }
return tmp; return buf;
} }
//assumes little endian //assumes little endian
char * printBits(size_t const size, void const * const ptr) char *printBits(size_t const size, void const * const ptr)
{ {
unsigned char *b = (unsigned char*) ptr; unsigned char *b = (unsigned char*) ptr;
unsigned char byte; unsigned char byte;
static char buf[1024]; static char buf[1024];
char * tmp = buf; char *tmp = buf;
int i, j; int i, j;
for (i=size-1;i>=0;i--) for (i=size-1;i>=0;i--)
@ -350,7 +352,7 @@ char * printBits(size_t const size, void const * const ptr)
return buf; return buf;
} }
char * printBitsPar(const uint8_t *b, size_t len) { char *printBitsPar(const uint8_t *b, size_t len) {
static char buf1[512] = {0}; static char buf1[512] = {0};
static char buf2[512] = {0}; static char buf2[512] = {0};
static char *buf; static char *buf;
@ -515,7 +517,8 @@ int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt)
return 0; return 0;
} }
int param_gethex_ex(const char *line, int paramnum, uint8_t * data, int *hexcnt)
int param_gethex_ex(const char *line, int paramnum, uint8_t *data, int *hexcnt)
{ {
int bg, en, temp, i; int bg, en, temp, i;
@ -524,6 +527,8 @@ int param_gethex_ex(const char *line, int paramnum, uint8_t * data, int *hexcnt)
if (param_getptr(line, &bg, &en, paramnum)) return 1; if (param_getptr(line, &bg, &en, paramnum)) return 1;
if (en - bg + 1 > *hexcnt) return 1;
*hexcnt = en - bg + 1; *hexcnt = en - bg + 1;
if (*hexcnt % 2) //error if not complete hex bytes if (*hexcnt % 2) //error if not complete hex bytes
return 1; return 1;

View file

@ -101,6 +101,7 @@ extern char *sprint_hex_inrow_ex(const uint8_t *data, const size_t len, const si
extern char *sprint_bin(const uint8_t * data, const size_t len); extern char *sprint_bin(const uint8_t * data, const size_t len);
extern char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t breaks); extern char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t breaks);
extern char *sprint_ascii_ex(const uint8_t *data, const size_t len, const size_t min_str_len); extern char *sprint_ascii_ex(const uint8_t *data, const size_t len, const size_t min_str_len);
extern char *sprint_ascii(const uint8_t *data, const size_t len);
extern void num_to_bytes(uint64_t n, size_t len, uint8_t* dest); extern void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
extern uint64_t bytes_to_num(uint8_t* src, size_t len); extern uint64_t bytes_to_num(uint8_t* src, size_t len);

View file

@ -105,15 +105,15 @@ NXP/Philips CUSTOM COMMANDS
#define ISO14443A_CMD_REQA 0x26 #define ISO14443A_CMD_REQA 0x26
#define ISO14443A_CMD_READBLOCK 0x30
#define ISO14443A_CMD_WUPA 0x52 #define ISO14443A_CMD_WUPA 0x52
#define ISO14443A_CMD_ANTICOLL_OR_SELECT 0x93 #define ISO14443A_CMD_ANTICOLL_OR_SELECT 0x93
#define ISO14443A_CMD_ANTICOLL_OR_SELECT_2 0x95 #define ISO14443A_CMD_ANTICOLL_OR_SELECT_2 0x95
#define ISO14443A_CMD_ANTICOLL_OR_SELECT_3 0x97 #define ISO14443A_CMD_ANTICOLL_OR_SELECT_3 0x97
#define ISO14443A_CMD_WRITEBLOCK 0xA0 // or 0xA2 ?
#define ISO14443A_CMD_HALT 0x50 #define ISO14443A_CMD_HALT 0x50
#define ISO14443A_CMD_RATS 0xE0 #define ISO14443A_CMD_RATS 0xE0
#define MIFARE_CMD_READBLOCK 0x30
#define MIFARE_CMD_WRITEBLOCK 0xA0
#define MIFARE_AUTH_KEYA 0x60 #define MIFARE_AUTH_KEYA 0x60
#define MIFARE_AUTH_KEYB 0x61 #define MIFARE_AUTH_KEYB 0x61
#define MIFARE_MAGICWUPC1 0x40 #define MIFARE_MAGICWUPC1 0x40
@ -127,23 +127,28 @@ NXP/Philips CUSTOM COMMANDS
#define MIFARE_EV1_PERSONAL_UID 0x40 #define MIFARE_EV1_PERSONAL_UID 0x40
#define MIFARE_EV1_SETMODE 0x43 #define MIFARE_EV1_SETMODE 0x43
#define MIFARE_ULC_WRITE 0xA2 #define MIFARE_ULC_WRITE 0xA2
//#define MIFARE_ULC__COMP_WRITE 0xA0 #define MIFARE_ULC_COMP_WRITE MIFARE_CMD_WRITEBLOCK
#define MIFARE_ULC_AUTH_1 0x1A #define MIFARE_ULC_AUTH_1 0x1A
#define MIFARE_ULC_AUTH_2 0xAF #define MIFARE_ULC_AUTH_2 0xAF
#define MIFARE_ULEV1_AUTH 0x1B #define MIFARE_ULEV1_AUTH 0x1B
#define MIFARE_ULEV1_VERSION 0x60 #define MIFARE_ULEV1_VERSION 0x60
#define MIFARE_ULEV1_FASTREAD 0x3A #define MIFARE_ULEV1_FASTREAD 0x3A
//#define MIFARE_ULEV1_WRITE 0xA2 #define MIFARE_ULEV1_WRITE 0xA2
//#define MIFARE_ULEV1_COMP_WRITE 0xA0 #define MIFARE_ULEV1_COMP_WRITE MIFARE_CMD_WRITEBLOCK
#define MIFARE_ULEV1_READ_CNT 0x39 #define MIFARE_ULEV1_READ_CNT 0x39
#define MIFARE_ULEV1_INCR_CNT 0xA5 #define MIFARE_ULEV1_INCR_CNT 0xA5
#define MIFARE_ULEV1_READSIG 0x3C #define MIFARE_ULEV1_READSIG 0x3C
#define MIFARE_ULEV1_CHECKTEAR 0x3E #define MIFARE_ULEV1_CHECKTEAR 0x3E
#define MIFARE_ULEV1_VCSL 0x4B #define MIFARE_ULEV1_VCSL 0x4B
// mifare 4bit card answers
#define CARD_ACK 0x0A // 1010 - ACK
#define CARD_NACK_NA 0x04 // 0100 - NACK, not allowed (command not allowed)
#define CARD_NACK_TR 0x05 // 0101 - NACK, transmission error
/** /**
06 00 = INITIATE 06 00 = INITIATE
0E xx = SELECT ID (xx = Chip-ID) 0E xx = SELECT ID (xx = Chip-ID)

View file

@ -41,6 +41,7 @@ typedef struct{
bool averaging; bool averaging;
int divisor; int divisor;
int trigger_threshold; int trigger_threshold;
int samples_to_skip;
} sample_config; } sample_config;
// For the bootloader // For the bootloader
@ -116,6 +117,7 @@ typedef struct{
#define CMD_T55XX_WAKEUP 0x0224 #define CMD_T55XX_WAKEUP 0x0224
#define CMD_COTAG 0x0225 #define CMD_COTAG 0x0225
#define CMD_PARADOX_CLONE_TAG 0x0226 #define CMD_PARADOX_CLONE_TAG 0x0226
#define CMD_EM4X_PROTECT 0x0228
// For the 13.56 MHz tags // For the 13.56 MHz tags
#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 0x0300 #define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 0x0300
@ -130,6 +132,7 @@ typedef struct{
#define CMD_ISO_15693_FIND_AFI 0x0315 #define CMD_ISO_15693_FIND_AFI 0x0315
#define CMD_ISO_15693_DEBUG 0x0316 #define CMD_ISO_15693_DEBUG 0x0316
#define CMD_LF_SNOOP_RAW_ADC_SAMPLES 0x0317 #define CMD_LF_SNOOP_RAW_ADC_SAMPLES 0x0317
#define CMD_CSETUID_ISO_15693 0x0318
// For Hitag2 transponders // For Hitag2 transponders
#define CMD_SNOOP_HITAG 0x0370 #define CMD_SNOOP_HITAG 0x0370

View file

@ -80,7 +80,7 @@ serial_port uart_open(const char* pcPortName)
if (sp == 0) return INVALID_SERIAL_PORT; if (sp == 0) return INVALID_SERIAL_PORT;
if (memcmp(pcPortName, "tcp:", 4) == 0) { if (memcmp(pcPortName, "tcp:", 4) == 0) {
struct addrinfo *addr, *rp; struct addrinfo *addr = NULL, *rp;
char *addrstr = strdup(pcPortName + 4); char *addrstr = strdup(pcPortName + 4);
if (addrstr == NULL) { if (addrstr == NULL) {
printf("Error: strdup\n"); printf("Error: strdup\n");
@ -98,7 +98,13 @@ serial_port uart_open(const char* pcPortName)
} else } else
portstr = "7901"; portstr = "7901";
int s = getaddrinfo(addrstr, portstr, NULL, &addr); struct addrinfo info;
memset (&info, 0, sizeof(info));
info.ai_socktype = SOCK_STREAM;
int s = getaddrinfo(addrstr, portstr, &info, &addr);
if (s != 0) { if (s != 0) {
printf("Error: getaddrinfo: %s\n", gai_strerror(s)); printf("Error: getaddrinfo: %s\n", gai_strerror(s));
return INVALID_SERIAL_PORT; return INVALID_SERIAL_PORT;