mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-22 06:13:27 -07:00
Merge branch 'master' into originality_check
This commit is contained in:
commit
3a159d1df0
36 changed files with 2521 additions and 1928 deletions
|
@ -16,6 +16,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
|||
- `hf 15 sim` now works as expected (piwi)
|
||||
|
||||
### 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
|
||||
- Added `hf emv scan` - commands for scan EMV card and dump data to json file (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 Mifare Mini, Mifare 2K and 4K support to `hf mf sim` (piwi)
|
||||
- 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]
|
||||
|
||||
|
|
|
@ -30,9 +30,10 @@ following locations:
|
|||
* [RyscCorp](https://proxmark3.com/) (US)
|
||||
* [Hackerwarehouse](https://hackerwarehouse.com/) (US)
|
||||
* [Elechouse](http://www.elechouse.com/) (HK)
|
||||
* [Lab401](https://lab401.com/) (FR)
|
||||
* [Lab401](https://lab401.com/) (HK)
|
||||
* [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
|
||||
something like this together with a reasonable yield. A run of around
|
||||
|
|
|
@ -1088,6 +1088,9 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
|||
case CMD_EM4X_WRITE_WORD:
|
||||
EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2]);
|
||||
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
|
||||
CmdAWIDdemodFSK(c->arg[0], 0, 0, 1);
|
||||
break;
|
||||
|
@ -1155,9 +1158,14 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
|||
case CMD_READER_ISO_15693:
|
||||
ReaderIso15693(c->arg[0]);
|
||||
break;
|
||||
|
||||
case CMD_SIMTAG_ISO_15693:
|
||||
SimTagIso15693(c->arg[0], c->d.asBytes);
|
||||
break;
|
||||
|
||||
case CMD_CSETUID_ISO_15693:
|
||||
SetTag15693Uid(c->d.asBytes);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_LEGICRF
|
||||
|
|
|
@ -89,6 +89,7 @@ void TurnReadLFOn();
|
|||
//void T55xxReadTrace(void);
|
||||
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
|
||||
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);
|
||||
|
||||
/// 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);
|
||||
int DesfireAPDU(uint8_t *cmd, size_t cmd_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
|
||||
|
|
|
@ -1963,7 +1963,10 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) {
|
|||
uint8_t *dataout = BigBuf_malloc(255*8);
|
||||
if (dataout == NULL){
|
||||
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;
|
||||
}
|
||||
memset(dataout,0xFF,255*8);
|
||||
|
|
|
@ -1591,6 +1591,85 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint
|
|||
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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ void ReaderIso15693(uint32_t parameter);
|
|||
void SimTagIso15693(uint32_t parameter, uint8_t *uid);
|
||||
void BruteforceIso15693Afi(uint32_t speed);
|
||||
void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t data[]);
|
||||
void SetTag15693Uid(uint8_t *uid);
|
||||
void SetDebugIso15693(uint32_t flag);
|
||||
|
||||
#endif
|
||||
|
|
435
armsrc/lfops.c
435
armsrc/lfops.c
|
@ -1198,12 +1198,79 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
|||
* and enlarge the gap ones.
|
||||
* 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 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_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
|
||||
|
||||
*/
|
||||
/* 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) {
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
// 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
|
||||
void T55xxWriteBit(int bit) {
|
||||
if (!bit)
|
||||
TurnReadLFOn(WRITE_0);
|
||||
else
|
||||
TurnReadLFOn(WRITE_1);
|
||||
void T55xxWriteBit(int bit, T55xx_Timing *Timings) {
|
||||
|
||||
// If bit = 4 Send Long Leading Reference which is 138 + WRITE_0
|
||||
// Dbprintf ("Bits : %d",bit);
|
||||
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);
|
||||
WaitUS(WRITE_GAP);
|
||||
WaitUS(Timings->WRITE_GAP);
|
||||
}
|
||||
|
||||
// Send T5577 reset command then read stream (see if we can identify the start of the stream)
|
||||
void T55xxResetRead(void) {
|
||||
LED_A_ON();
|
||||
//clear buffer now so it does not interfere with timing later
|
||||
BigBuf_Clear_keep_EM();
|
||||
// Function to abstract an Arbitrary length byte array to store bit pattern.
|
||||
// bit_array - Array to hold data/bit pattern
|
||||
// start_offset - bit location to start storing new bits.
|
||||
// data - upto 32 bits of data to store
|
||||
// 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
|
||||
LFSetupFPGAForADC(95, true);
|
||||
StartTicks();
|
||||
// make sure tag is fully powered up...
|
||||
WaitMS(5);
|
||||
|
||||
// Trigger T55x7 in mode.
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
WaitUS(START_GAP);
|
||||
WaitUS(Timing->START_GAP);
|
||||
|
||||
// reset tag - op code 00
|
||||
T55xxWriteBit(0);
|
||||
T55xxWriteBit(0);
|
||||
// If long leading 0 send long reference pulse
|
||||
if (downlink_mode == T55xx_DLMode_LLR)
|
||||
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
|
||||
DoPartialAcquisition(0, true, BigBuf_max_traceLen(), 0);
|
||||
|
@ -1252,42 +1462,23 @@ void T55xxResetRead(void) {
|
|||
}
|
||||
|
||||
// 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) {
|
||||
/*
|
||||
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 testMode = ((arg & 0x04) == 0x04);
|
||||
arg &= (0xff ^ 0x40); // Called for a write, so ensure it is clear/0
|
||||
|
||||
LED_A_ON ();
|
||||
bool PwdMode = arg & 0x1;
|
||||
uint8_t Page = (arg & 0x2)>>1;
|
||||
bool testMode = arg & 0x4;
|
||||
uint32_t i = 0;
|
||||
|
||||
// Set up FPGA, 125kHz
|
||||
LFSetupFPGAForADC(95, true);
|
||||
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");
|
||||
// Std Opcode 10
|
||||
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);
|
||||
T55xx_SendCMD (Data, Block, Pwd, arg) ;//, false);
|
||||
|
||||
// Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550,
|
||||
// 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);
|
||||
}
|
||||
|
||||
// turn field off
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Read one card block in page [page]
|
||||
void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
|
||||
LED_A_ON();
|
||||
bool PwdMode = arg0 & 0x1;
|
||||
uint8_t Page = (arg0 & 0x2) >> 1;
|
||||
uint32_t i = 0;
|
||||
bool RegReadMode = (Block == 0xFF);//regular read mode
|
||||
void T55xxReadBlock (uint16_t arg0, uint8_t Block, uint32_t Pwd) {//, struct T55xx_Timing *Timing) {
|
||||
|
||||
//clear buffer now so it does not interfere with timing later
|
||||
BigBuf_Clear_ext(false);
|
||||
LED_A_ON();
|
||||
|
||||
/*
|
||||
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
|
||||
Block &= 0x7;
|
||||
|
||||
// Set up FPGA, 125kHz to power up the tag
|
||||
LFSetupFPGAForADC(95, true);
|
||||
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);
|
||||
//clear buffer now so it does not interfere with timing later
|
||||
BigBuf_Clear_ext(false);
|
||||
|
||||
// Opcode 1[page]
|
||||
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);
|
||||
T55xx_SendCMD (0, Block, Pwd, arg0); //, true);
|
||||
|
||||
// Turn field on to read the response
|
||||
// 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
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
|
||||
LED_A_OFF();
|
||||
}
|
||||
|
||||
void T55xxWakeUp(uint32_t Pwd){
|
||||
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
|
||||
LFSetupFPGAForADC(95, true);
|
||||
StartTicks();
|
||||
// make sure tag is fully powered up...
|
||||
WaitMS(5);
|
||||
// r* 10 (00) <pwd> r* for llr , L0 and 1/4 - (00) for L0 and 1/4 - All handled in SendCMD
|
||||
// So, default Opcode 10 and pwd.
|
||||
uint8_t arg = 0x01 | 0x40 | 0x20; //Password Read Call no data | reg_read no block
|
||||
|
||||
// Trigger T55x7 Direct Access Mode
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
WaitUS(START_GAP);
|
||||
// Add in downlink_mode when ready
|
||||
// arg |= 0x00; // dlmode << 3 (00 default - 08 leading 0 - 10 Fixed - 18 1 of 4 )
|
||||
|
||||
// Opcode 10
|
||||
T55xxWriteBit(1);
|
||||
T55xxWriteBit(0); //Page 0
|
||||
|
||||
// Send Pwd
|
||||
for (i = 0x80000000; i != 0; i >>= 1)
|
||||
T55xxWriteBit(Pwd & i);
|
||||
T55xx_SendCMD (0, 0, Pwd, arg); //, true);
|
||||
|
||||
// Turn and leave field on to let the begin repeating transmission
|
||||
TurnReadLFOn(20*1000);
|
||||
|
@ -1414,7 +1592,8 @@ void T55xxWakeUp(uint32_t Pwd){
|
|||
void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) {
|
||||
// write last block first and config block last (if included)
|
||||
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_READ 0x9
|
||||
#define FWD_CMD_DISABLE 0x5
|
||||
#define FWD_CMD_PROTECT 0x3
|
||||
|
||||
uint8_t forwardLink_data[64]; //array of forwarded bits
|
||||
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
|
||||
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
|
||||
if(((*fwd_write_ptr++) & 1) == 1)
|
||||
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
|
||||
WaitUS(23*8); //23 cycles off (8us each)
|
||||
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) {
|
||||
|
||||
bool PwdMode = (flag & 0xF);
|
||||
bool PwdMode = (flag & 0x1);
|
||||
uint8_t Address = (flag >> 8) & 0xFF;
|
||||
uint8_t fwd_bit_count;
|
||||
|
||||
|
@ -1813,6 +1993,39 @@ void EM4xWriteWord(uint32_t flag, uint32_t Data, uint32_t Pwd) {
|
|||
LED_A_OFF();
|
||||
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.
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "usb_cdc.h" // for usb_poll_validate_length
|
||||
#include "fpgaloader.h"
|
||||
|
||||
sample_config config = { 1, 8, 1, 95, 0 } ;
|
||||
sample_config config = { 1, 8, 1, 95, 0, 0 } ;
|
||||
|
||||
void printConfig()
|
||||
{
|
||||
|
@ -24,6 +24,7 @@ void printConfig()
|
|||
Dbprintf(" [d] decimation: %d ", config.decimation);
|
||||
Dbprintf(" [a] averaging: %d ", config.averaging);
|
||||
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,
|
||||
* 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
|
||||
* @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->decimation!= 0) config.decimation= sc->decimation;
|
||||
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;
|
||||
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
|
||||
* @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();
|
||||
|
@ -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_saved =0 ;
|
||||
uint32_t cancel_counter = 0;
|
||||
uint32_t samples_skipped = 0;
|
||||
|
||||
while(!BUTTON_PRESS() && !usb_poll_validate_length() ) {
|
||||
WDT_HIT();
|
||||
|
@ -160,6 +163,10 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
|
|||
continue;
|
||||
}
|
||||
trigger_threshold = 0;
|
||||
if (samples_to_skip > samples_skipped) {
|
||||
samples_skipped++;
|
||||
continue;
|
||||
}
|
||||
sample_total_numbers++;
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -228,11 +235,12 @@ uint32_t DoAcquisition_config(bool silent, int sample_size)
|
|||
,config.trigger_threshold
|
||||
,silent
|
||||
,sample_size
|
||||
,0);
|
||||
,0
|
||||
,config.samples_to_skip);
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -23,24 +23,42 @@
|
|||
#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
|
||||
|
||||
/*
|
||||
// the block number for the ISO14443-4 PCB
|
||||
static uint8_t pcb_blocknum = 0;
|
||||
// Deselect card by sending a s-block. the crc is precalced for speed
|
||||
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.
|
||||
// read block
|
||||
//-----------------------------------------------------------------------------
|
||||
void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||
{
|
||||
// params
|
||||
LED_A_ON();
|
||||
|
||||
uint8_t blockNo = arg0;
|
||||
uint8_t keyType = arg1;
|
||||
uint64_t ui64Key = 0;
|
||||
ui64Key = bytes_to_num(datain, 6);
|
||||
|
||||
// variables
|
||||
byte_t isOK = 0;
|
||||
byte_t dataoutbuf[16];
|
||||
uint8_t uid[10];
|
||||
|
@ -53,10 +71,6 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
|||
|
||||
clear_trace();
|
||||
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
|
||||
while (true) {
|
||||
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||
|
@ -97,14 +111,11 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
|||
|
||||
void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
|
||||
|
||||
LED_A_ON();
|
||||
bool turnOffField = (arg0 == 1);
|
||||
|
||||
LED_A_ON(); LED_B_OFF(); LED_C_OFF();
|
||||
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
clear_trace();
|
||||
|
||||
if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
|
||||
OnError(0);
|
||||
|
@ -119,9 +130,11 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
|
|||
|
||||
if (turnOffField) {
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
LED_D_OFF();
|
||||
}
|
||||
|
||||
cmd_send(CMD_ACK,1,0,0,0,0);
|
||||
LED_A_OFF();
|
||||
}
|
||||
|
||||
// Arg0 = BlockNo,
|
||||
|
@ -129,17 +142,15 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
|
|||
// datain = PWD bytes,
|
||||
void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
|
||||
{
|
||||
LED_A_ON();
|
||||
|
||||
uint8_t blockNo = arg0;
|
||||
byte_t dataout[16] = {0x00};
|
||||
bool useKey = (arg1 == 1); //UL_C
|
||||
bool usePwd = (arg1 == 2); //UL_EV1/NTAG
|
||||
|
||||
LEDsoff();
|
||||
LED_A_ON();
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
clear_trace();
|
||||
|
||||
int len = iso14443a_select_card(NULL, NULL, NULL, true, 0, true);
|
||||
if(!len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len);
|
||||
|
@ -183,7 +194,8 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
|
|||
|
||||
cmd_send(CMD_ACK,1,0,0,dataout,16);
|
||||
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
|
||||
void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
|
||||
{
|
||||
LEDsoff();
|
||||
LED_A_ON();
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
// free eventually allocated BigBuf memory
|
||||
BigBuf_free();
|
||||
clear_trace();
|
||||
|
||||
// params
|
||||
uint8_t blockNo = arg0;
|
||||
|
@ -340,14 +350,14 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
|
|||
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);
|
||||
LEDsoff();
|
||||
LED_D_OFF();
|
||||
BigBuf_free();
|
||||
LED_A_OFF();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1598,17 +1608,3 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){
|
|||
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();
|
||||
}
|
||||
|
|
|
@ -542,8 +542,8 @@ void MifareSim(uint8_t flags, uint8_t exitAfterNReads, uint8_t cardsize, uint8_t
|
|||
break;
|
||||
}
|
||||
|
||||
if(receivedCmd_dec[0] == ISO14443A_CMD_READBLOCK
|
||||
|| receivedCmd_dec[0] == ISO14443A_CMD_WRITEBLOCK
|
||||
if(receivedCmd_dec[0] == MIFARE_CMD_READBLOCK
|
||||
|| receivedCmd_dec[0] == MIFARE_CMD_WRITEBLOCK
|
||||
|| receivedCmd_dec[0] == MIFARE_CMD_INC
|
||||
|| receivedCmd_dec[0] == MIFARE_CMD_DEC
|
||||
|| 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];
|
||||
emlGetMem(response, blockNo, 1);
|
||||
if (IsSectorTrailer(blockNo)) {
|
||||
|
@ -593,7 +593,7 @@ void MifareSim(uint8_t flags, uint8_t exitAfterNReads, uint8_t cardsize, uint8_t
|
|||
break;
|
||||
}
|
||||
|
||||
if (receivedCmd_dec[0] == ISO14443A_CMD_WRITEBLOCK) {
|
||||
if (receivedCmd_dec[0] == MIFARE_CMD_WRITEBLOCK) {
|
||||
uint8_t blockNo = receivedCmd_dec[1];
|
||||
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK));
|
||||
FpgaDisableTracing();
|
||||
|
|
|
@ -451,7 +451,7 @@ int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData)
|
|||
return result;
|
||||
}
|
||||
|
||||
memcpy(blockData, receivedAnswer, 14);
|
||||
memcpy(blockData, receivedAnswer, 16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,11 +25,6 @@
|
|||
#define AUTH_FIRST 0
|
||||
#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
|
||||
#define MF_MINFIELDV 4000
|
||||
|
||||
|
|
|
@ -401,13 +401,7 @@ void BruteForcePCF7931(uint64_t password, uint8_t tries, uint16_t init_delay, in
|
|||
return;
|
||||
}
|
||||
|
||||
pass_array[0] = password & 0xFF;
|
||||
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;
|
||||
num_to_bytes(password, 7, pass_array);
|
||||
|
||||
Dbprintf("Trying: %02x %02x %02x %02x %02x %02x %02x ...",
|
||||
pass_array[0],
|
||||
|
|
|
@ -16,13 +16,14 @@
|
|||
#include <stdbool.h>
|
||||
#include "mifare.h"
|
||||
|
||||
int CmdHF14A(const char *Cmd);
|
||||
int CmdHF14AList(const char *Cmd);
|
||||
int CmdHF14AMifare(const char *Cmd);
|
||||
int CmdHF14AReader(const char *Cmd);
|
||||
extern int CmdHF14A(const char *Cmd);
|
||||
extern int CmdHF14AMfDbg(const char* cmd);
|
||||
extern int CmdHF14AList(const char *Cmd);
|
||||
extern int CmdHF14AMifare(const char *Cmd);
|
||||
extern int CmdHF14AReader(const char *Cmd);
|
||||
extern int CmdHF14AInfo(const char *Cmd);
|
||||
int CmdHF14ASim(const char *Cmd);
|
||||
int CmdHF14ASnoop(const char *Cmd);
|
||||
extern int CmdHF14ASim(const char *Cmd);
|
||||
extern int CmdHF14ASnoop(const char *Cmd);
|
||||
|
||||
extern void DropField();
|
||||
|
||||
|
|
|
@ -382,6 +382,7 @@ static command_t CommandTable15[] =
|
|||
{"cmd", CmdHF15Cmd, 0, "Send direct commands to ISO15693 tag"},
|
||||
{"findafi", CmdHF15Afi, 0, "Brute force AFI 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}
|
||||
};
|
||||
|
||||
|
@ -954,6 +955,92 @@ int CmdHF15CmdWrite(const char *Cmd) {
|
|||
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[] =
|
||||
|
@ -968,6 +1055,7 @@ static command_t CommandTable15Cmd[] =
|
|||
{"readmulti",CmdHF15CmdReadmulti, 0, "Reads multiple Blocks"},
|
||||
{"sysinfo",CmdHF15CmdSysinfo, 0, "Get Card Information"},
|
||||
{"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"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
|
|
@ -22,6 +22,7 @@ int CmdHF15Reader(const char *Cmd);
|
|||
int CmdHF15Sim(const char *Cmd);
|
||||
int CmdHF15Record(const char *Cmd);
|
||||
int CmdHF15Cmd(const char*Cmd);
|
||||
int CmdHF15CSetUID(const char *Cmd);
|
||||
int CmdHF15CmdHelp(const char*Cmd);
|
||||
int CmdHF15Help(const char*Cmd);
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "usb_cmd.h"
|
||||
#include "cmdhfmfu.h"
|
||||
#include "util_posix.h"
|
||||
#include "cmdhf14a.h" // DropField()
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
|
|
|
@ -218,8 +218,10 @@ int CmdLegicRFRead(const char *Cmd)
|
|||
UsbCommand resp;
|
||||
WaitForResponse(CMD_ACK,&resp);
|
||||
switch (resp.arg[0]) {
|
||||
legic_card_select_t card;
|
||||
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);
|
||||
break;
|
||||
case 1:
|
||||
|
|
|
@ -415,8 +415,8 @@ void annotateIso14443a(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
|||
case ISO14443A_CMD_REQA:
|
||||
snprintf(exp,size,"REQA");
|
||||
break;
|
||||
case ISO14443A_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_READBLOCK: snprintf(exp,size,"READBLOCK(%d)",cmd[1]); break;
|
||||
case MIFARE_CMD_WRITEBLOCK: snprintf(exp,size,"WRITEBLOCK(%d)",cmd[1]); break;
|
||||
case ISO14443A_CMD_HALT:
|
||||
snprintf(exp,size,"HALT");
|
||||
MifareAuthState = masNone;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "hardnested/hardnested_bf_core.h"
|
||||
#include "cliparser/cliparser.h"
|
||||
#include "cmdhf14a.h"
|
||||
#include "mifare/mifaredefault.h"
|
||||
#include "mifare/mifare4.h"
|
||||
#include "mifare/mad.h"
|
||||
#include "mifare/ndef.h"
|
||||
|
@ -1515,7 +1516,10 @@ int CmdHF14AMfSim(const char *Cmd) {
|
|||
break;
|
||||
case 'u':
|
||||
case 'U':
|
||||
param_gethex_ex(Cmd, cmdp+1, uid, &uidlen);
|
||||
uidlen = 14;
|
||||
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 8: flags = FLAG_4B_UID_IN_DATA; break;
|
||||
|
@ -1951,31 +1955,37 @@ int CmdHF14AMfECFill(const char *Cmd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CmdHF14AMfEKeyPrn(const char *Cmd)
|
||||
{
|
||||
int i;
|
||||
uint8_t numSectors;
|
||||
uint8_t numSectors = 16;
|
||||
uint8_t data[16];
|
||||
uint64_t keyA, keyB;
|
||||
bool createDumpFile = false;
|
||||
|
||||
if (param_getchar(Cmd, 0) == 'h') {
|
||||
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(" [d] : write keys to binary file dumpkeys.bin");
|
||||
PrintAndLog("");
|
||||
PrintAndLog(" sample: hf mf ekeyprn 1");
|
||||
return 0;
|
||||
}
|
||||
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
|
||||
switch (cmdp) {
|
||||
uint8_t cmdp = 0;
|
||||
while (param_getchar(Cmd, cmdp) != 0x00) {
|
||||
switch (param_getchar(Cmd, cmdp)) {
|
||||
case '0' : numSectors = 5; break;
|
||||
case '1' :
|
||||
case '\0': numSectors = 16; break;
|
||||
case '2' : numSectors = 32; break;
|
||||
case '4' : numSectors = 40; break;
|
||||
default: numSectors = 16;
|
||||
case 'd' :
|
||||
case 'D' : createDumpFile = true; break;
|
||||
}
|
||||
cmdp++;
|
||||
}
|
||||
|
||||
PrintAndLog("|---|----------------|----------------|");
|
||||
|
@ -1992,9 +2002,35 @@ int CmdHF14AMfEKeyPrn(const char *Cmd)
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
int CmdHF14AMfCSetUID(const char *Cmd)
|
||||
{
|
||||
uint8_t uid[8] = {0x00};
|
||||
|
@ -2693,7 +2729,7 @@ int CmdHF14AMfSniff(const char *Cmd){
|
|||
//needs nt, ar, at, Data to decrypt
|
||||
int CmdDecryptTraceCmds(const char *Cmd){
|
||||
uint8_t data[50];
|
||||
int len = 0;
|
||||
int len = 100;
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -11,38 +11,6 @@
|
|||
#ifndef CMDHFMF_H__
|
||||
#define CMDHFMF_H__
|
||||
|
||||
#include "mifare/mifaredefault.h"
|
||||
|
||||
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
|
||||
|
|
1573
client/cmdhfmfu.c
1573
client/cmdhfmfu.c
File diff suppressed because it is too large
Load diff
|
@ -1,54 +1,10 @@
|
|||
#include "cmdhfmf.h"
|
||||
#include "cmdhf14a.h"
|
||||
|
||||
#ifndef CMDHFMFU_H__
|
||||
#define CMDHFMFU_H__
|
||||
|
||||
int CmdHF14AMfUWrBl(const char *Cmd);
|
||||
int CmdHF14AMfURdBl(const char *Cmd);
|
||||
#include <stdint.h>
|
||||
|
||||
//Crypto Cards
|
||||
int CmdHF14AMfucAuth(const char *Cmd);
|
||||
|
||||
//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;
|
||||
extern int CmdHFMFUltra(const char *Cmd);
|
||||
extern uint32_t GetHF14AMfU_Type(void);
|
||||
extern int ul_print_type(uint32_t tagtype, uint8_t spacer);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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(" 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(" s <smplstoskip> Sets a number of samples to skip before capture. Default: 0");
|
||||
PrintAndLog("Examples:");
|
||||
PrintAndLog(" lf config b 8 L");
|
||||
PrintAndLog(" Samples at 125KHz, 8bps.");
|
||||
|
@ -255,6 +256,7 @@ int CmdLFSetConfig(const char *Cmd)
|
|||
bool errors = false;
|
||||
int trigger_threshold =-1;//Means no change
|
||||
uint8_t unsigned_trigg = 0;
|
||||
int samples_to_skip = -1;
|
||||
|
||||
uint8_t cmdp =0;
|
||||
while(param_getchar(Cmd, cmdp) != 0x00)
|
||||
|
@ -295,6 +297,10 @@ int CmdLFSetConfig(const char *Cmd)
|
|||
averaging = param_getchar(Cmd,cmdp+1) == '1';
|
||||
cmdp+=2;
|
||||
break;
|
||||
case 's':
|
||||
samples_to_skip = param_get32ex(Cmd,cmdp+1,0,10);
|
||||
cmdp+=2;
|
||||
break;
|
||||
default:
|
||||
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = 1;
|
||||
|
@ -316,7 +322,7 @@ int CmdLFSetConfig(const char *Cmd)
|
|||
if(bps >> 4) bps = 8;
|
||||
|
||||
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]
|
||||
UsbCommand c = {CMD_SET_LF_SAMPLING_CONFIG};
|
||||
|
|
|
@ -1161,6 +1161,119 @@ int CmdEM4x05WriteWord(const char *Cmd) {
|
|||
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) {
|
||||
uint16_t datarate = EM4x05_GET_BITRATE(wordData);
|
||||
uint8_t encoder = ((wordData >> 6) & 0xF);
|
||||
|
@ -1345,6 +1458,7 @@ static command_t CommandTable[] =
|
|||
{"4x05info", CmdEM4x05info, 0, "(pwd) -- Get info from EM4x05/EM4x69 tag"},
|
||||
{"4x05readword", CmdEM4x05ReadWord, 0, "<Word> (pwd) -- Read 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"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
|
|
@ -180,24 +180,24 @@ int CmdLFPCF7931BruteForce(const char *Cmd){
|
|||
uint8_t ctmp = param_getchar(Cmd, 0);
|
||||
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;
|
||||
|
||||
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();
|
||||
|
||||
PrintAndLog("Bruteforcing from password: %02x %02x %02x %02x %02x %02x %02x",
|
||||
start_password & 0xFF,
|
||||
(start_password >> 8) & 0xFF,
|
||||
(start_password >> 16) & 0xFF,
|
||||
(start_password >> 24) & 0xFF,
|
||||
(start_password >> 32) & 0xFF,
|
||||
(start_password >> 48) & 0xFF,
|
||||
(start_password >> 56) & 0xFF);
|
||||
start_password[0],
|
||||
start_password[1],
|
||||
start_password[2],
|
||||
start_password[3],
|
||||
start_password[4],
|
||||
start_password[5],
|
||||
start_password[6]);
|
||||
|
||||
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[8] = (configPcf.OffsetPosition + 128);
|
||||
|
|
|
@ -67,6 +67,8 @@ int usage_t55xx_read(){
|
|||
PrintAndLog(" p <password> - OPTIONAL password (8 hex characters)");
|
||||
PrintAndLog(" o - OPTIONAL override safety check");
|
||||
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(" Use of read with password on a tag not configured for a pwd");
|
||||
PrintAndLog(" can damage the tag");
|
||||
|
@ -86,6 +88,8 @@ int usage_t55xx_write(){
|
|||
PrintAndLog(" p <password> - OPTIONAL password 4bytes (8 hex characters)");
|
||||
PrintAndLog(" 1 - OPTIONAL write Page 1 instead of Page 0");
|
||||
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("Examples:");
|
||||
PrintAndLog(" lf t55xx write b 3 d 11223344 - write 11223344 to block 3");
|
||||
|
@ -132,6 +136,8 @@ int usage_t55xx_detect(){
|
|||
PrintAndLog("Options:");
|
||||
PrintAndLog(" 1 - if set, use Graphbuffer otherwise read data from tag.");
|
||||
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("Examples:");
|
||||
PrintAndLog(" lf t55xx detect");
|
||||
|
@ -172,13 +178,16 @@ int usage_t55xx_bruteforce(){
|
|||
PrintAndLog(" password must be 4 bytes (8 hex symbols)");
|
||||
PrintAndLog("Options:");
|
||||
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(" <end_pwd> - 4 byte hex value to end pwd search at");
|
||||
PrintAndLog(" i <*.dic> - loads a default keys dictionary file <*.dic>");
|
||||
PrintAndLog("");
|
||||
PrintAndLog("Examples:");
|
||||
PrintAndLog(" lf t55xx bruteforce aaaaaaaa bbbbbbbb");
|
||||
PrintAndLog(" lf t55xx bruteforce i default_pwd.dic");
|
||||
PrintAndLog(" lf t55xx bruteforce [r 2] aaaaaaaa bbbbbbbb");
|
||||
PrintAndLog(" lf t55xx bruteforce [r 2] i default_pwd.dic");
|
||||
PrintAndLog("");
|
||||
return 0;
|
||||
}
|
||||
|
@ -311,12 +320,12 @@ int CmdT55xxSetConfig(const char *Cmd) {
|
|||
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
|
||||
if ( usepwd ) {
|
||||
// try reading the config block and verify that PWD bit is set before doing this!
|
||||
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() ) {
|
||||
PrintAndLog("Safety Check: Could not detect if PWD bit is set in config block. Exits.");
|
||||
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;
|
||||
|
||||
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) {
|
||||
uint8_t block = REGULAR_READ_MODE_BLOCK;
|
||||
uint32_t password = 0; //default to blank Block 7
|
||||
uint8_t downlink_mode = 0;
|
||||
|
||||
bool usepwd = false;
|
||||
bool override = false;
|
||||
bool page1 = false;
|
||||
|
@ -372,6 +383,12 @@ int CmdT55xxReadBlock(const char *Cmd) {
|
|||
page1 = true;
|
||||
cmdp++;
|
||||
break;
|
||||
case 'r':
|
||||
case 'R':
|
||||
downlink_mode = param_getchar(Cmd, cmdp+1) - '0';
|
||||
if (downlink_mode > 3) downlink_mode = 0;
|
||||
cmdp +=2;
|
||||
break;
|
||||
default:
|
||||
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = true;
|
||||
|
@ -386,7 +403,7 @@ int CmdT55xxReadBlock(const char *Cmd) {
|
|||
}
|
||||
|
||||
printT5xxHeader(page1);
|
||||
return T55xxReadBlock(block, page1, usepwd, override, password);
|
||||
return T55xxReadBlock(block, page1, usepwd, override, password, downlink_mode);
|
||||
}
|
||||
|
||||
bool DecodeT55xxBlock(){
|
||||
|
@ -459,12 +476,32 @@ bool DecodeT5555TraceBlock() {
|
|||
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){
|
||||
bool errors = false;
|
||||
bool useGB = false;
|
||||
bool usepwd = false;
|
||||
uint32_t password = 0;
|
||||
uint8_t cmdp = 0;
|
||||
uint8_t downlink_mode = 0;
|
||||
|
||||
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch(param_getchar(Cmd, cmdp)) {
|
||||
|
@ -482,6 +519,12 @@ int CmdT55xxDetect(const char *Cmd){
|
|||
useGB = true;
|
||||
cmdp++;
|
||||
break;
|
||||
case 'r':
|
||||
case 'R':
|
||||
downlink_mode = param_getchar(Cmd, cmdp+1) - '0';
|
||||
if (downlink_mode > 3) downlink_mode = 0;
|
||||
cmdp +=2;
|
||||
break;
|
||||
default:
|
||||
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = true;
|
||||
|
@ -491,13 +534,16 @@ int CmdT55xxDetect(const char *Cmd){
|
|||
if (errors) return usage_t55xx_detect();
|
||||
|
||||
if ( !useGB) {
|
||||
if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password) )
|
||||
if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password,downlink_mode) )
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( !tryDetectModulation() )
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -649,6 +695,7 @@ bool tryDetectModulation(){
|
|||
config.block0 = tests[0].block0;
|
||||
config.Q5 = tests[0].Q5;
|
||||
config.ST = tests[0].ST;
|
||||
|
||||
printConfiguration( config);
|
||||
return true;
|
||||
}
|
||||
|
@ -898,6 +945,8 @@ int CmdT55xxWriteBlock(const char *Cmd) {
|
|||
uint8_t block = 0xFF; //default to invalid block
|
||||
uint32_t data = 0; //default to blank Block
|
||||
uint32_t password = 0; //default to blank Block 7
|
||||
uint32_t downlink_mode = 0;
|
||||
|
||||
bool usepwd = false;
|
||||
bool page1 = false;
|
||||
bool gotdata = false;
|
||||
|
@ -935,6 +984,12 @@ int CmdT55xxWriteBlock(const char *Cmd) {
|
|||
page1 = true;
|
||||
cmdp++;
|
||||
break;
|
||||
case 'r':
|
||||
case 'R':
|
||||
downlink_mode = param_getchar(Cmd, cmdp+1) - '0';
|
||||
if (downlink_mode > 3) downlink_mode = 0;
|
||||
cmdp +=2;
|
||||
break;
|
||||
default:
|
||||
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = true;
|
||||
|
@ -952,6 +1007,7 @@ int CmdT55xxWriteBlock(const char *Cmd) {
|
|||
UsbCommand resp;
|
||||
c.d.asBytes[0] = (page1) ? 0x2 : 0;
|
||||
c.d.asBytes[0] |= (testMode) ? 0x4 : 0;
|
||||
c.d.asBytes[0] |= (downlink_mode << 3);
|
||||
|
||||
char pwdStr[16] = {0};
|
||||
snprintf(pwdStr, sizeof(pwdStr), "pwd: 0x%08X", password);
|
||||
|
@ -963,6 +1019,7 @@ int CmdT55xxWriteBlock(const char *Cmd) {
|
|||
c.arg[2] = password;
|
||||
c.d.asBytes[0] |= 0x1;
|
||||
}
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){
|
||||
|
@ -980,7 +1037,7 @@ int CmdT55xxReadTrace(const char *Cmd) {
|
|||
return usage_t55xx_trace();
|
||||
|
||||
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;
|
||||
|
||||
if ( config.Q5 ) {
|
||||
|
@ -1144,7 +1201,7 @@ int CmdT55xxInfo(const char *Cmd){
|
|||
return usage_t55xx_info();
|
||||
|
||||
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;
|
||||
|
||||
if (!DecodeT55xxBlock()) return 1;
|
||||
|
@ -1212,20 +1269,21 @@ int CmdT55xxDump(const char *Cmd){
|
|||
|
||||
printT5xxHeader(0);
|
||||
for ( uint8_t i = 0; i <8; ++i)
|
||||
T55xxReadBlock(i, 0, usepwd, override, password);
|
||||
T55xxReadBlock(i, 0, usepwd, override, password,0);
|
||||
|
||||
printT5xxHeader(1);
|
||||
for ( uint8_t i = 0; i<4; i++)
|
||||
T55xxReadBlock(i, 1, usepwd, override, password);
|
||||
T55xxReadBlock(i, 1, usepwd, override, password,0);
|
||||
|
||||
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:
|
||||
// bit0 = pwdmode
|
||||
// bit1 = page to read from
|
||||
uint8_t arg0 = (page<<1) | pwdmode;
|
||||
arg0 |= (downlink_mode << 3);
|
||||
UsbCommand c = {CMD_T55XX_READ_BLOCK, {arg0, block, password}};
|
||||
|
||||
clearCommandBuffer();
|
||||
|
@ -1403,9 +1461,23 @@ int CmdT55xxBruteForce(const char *Cmd) {
|
|||
uint32_t start_password = 0x00000000; //start password
|
||||
uint32_t end_password = 0xFFFFFFFF; //end password
|
||||
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);
|
||||
|
||||
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);
|
||||
if (keyBlock == NULL) return 1;
|
||||
|
@ -1414,7 +1486,7 @@ int CmdT55xxBruteForce(const char *Cmd) {
|
|||
|
||||
int len = strlen(Cmd+2);
|
||||
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");
|
||||
|
||||
|
@ -1480,8 +1552,11 @@ int CmdT55xxBruteForce(const char *Cmd) {
|
|||
|
||||
PrintAndLog("Testing %08X", testpwd);
|
||||
|
||||
if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, testpwd)) {
|
||||
PrintAndLog("Aquireing data from device failed. Quitting");
|
||||
// Try each downlink_mode if asked to
|
||||
// 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);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1491,8 +1566,14 @@ int CmdT55xxBruteForce(const char *Cmd) {
|
|||
if ( found ) {
|
||||
PrintAndLog("Found valid password: [%08X]", testpwd);
|
||||
free(keyBlock);
|
||||
|
||||
T55xx_Print_DownlinkMode (dl_mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (!try_all_dl_modes) // Exit loop if not trying all downlink modes
|
||||
dl_mode = 4;
|
||||
}
|
||||
}
|
||||
PrintAndLog("Password NOT found.");
|
||||
free(keyBlock);
|
||||
|
@ -1502,8 +1583,8 @@ int CmdT55xxBruteForce(const char *Cmd) {
|
|||
// Try to read Block 7, first :)
|
||||
|
||||
// incremental pwd range search
|
||||
start_password = param_get32ex(Cmd, 0, 0, 16);
|
||||
end_password = param_get32ex(Cmd, 1, 0, 16);
|
||||
start_password = param_get32ex(Cmd, cmd_opt , 0, 16);
|
||||
end_password = param_get32ex(Cmd, cmd_opt+1 , 0, 16);
|
||||
|
||||
if ( start_password >= end_password ) {
|
||||
free(keyBlock);
|
||||
|
@ -1524,29 +1605,36 @@ int CmdT55xxBruteForce(const char *Cmd) {
|
|||
free(keyBlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, i)) {
|
||||
PrintAndLog("Aquireing data from device failed. Quitting");
|
||||
// Try each downlink_mode if asked to
|
||||
// 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, i,dl_mode)) {
|
||||
PrintAndLog("Acquiring data from device failed. Quitting");
|
||||
free(keyBlock);
|
||||
return 0;
|
||||
}
|
||||
found = tryDetectModulation();
|
||||
|
||||
if (found) break;
|
||||
if (!try_all_dl_modes) // Exit loop if not trying all downlink modes
|
||||
dl_mode = 4;
|
||||
}
|
||||
if (found) break;
|
||||
i++;
|
||||
}
|
||||
|
||||
PrintAndLog("");
|
||||
|
||||
if (found)
|
||||
if (found){
|
||||
PrintAndLog("Found valid password: [%08x]", i);
|
||||
else
|
||||
T55xx_Print_DownlinkMode (downlink_mode);
|
||||
}
|
||||
else{
|
||||
PrintAndLog("");
|
||||
PrintAndLog("Password NOT found. Last tried: [%08x]", --i);
|
||||
}
|
||||
|
||||
free(keyBlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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)
|
||||
// unfortunately the 64 bits makes this more likely to get a false positive...
|
||||
|
@ -1558,7 +1646,7 @@ bool tryDetectP1(bool getData) {
|
|||
bool st = true;
|
||||
|
||||
if ( getData ) {
|
||||
if ( !AquireData(T55x7_PAGE1, 1, false, 0) )
|
||||
if ( !AquireData(T55x7_PAGE1, 1, false, 0,0) )
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1687,7 +1775,7 @@ int CmdT55xxDetectPage1(const char *Cmd){
|
|||
if (errors) return usage_t55xx_detectP1();
|
||||
|
||||
if ( !useGB ) {
|
||||
if ( !AquireData(T55x7_PAGE1, 1, usepwd, password) )
|
||||
if ( !AquireData(T55x7_PAGE1, 1, usepwd, password,0) )
|
||||
return false;
|
||||
}
|
||||
bool success = tryDetectP1(false);
|
||||
|
|
|
@ -98,7 +98,7 @@ bool tryDetectModulation(void);
|
|||
extern bool tryDetectP1(bool getData);
|
||||
bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5);
|
||||
int special(const char *Cmd);
|
||||
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 printT5555Trace( t5555_tracedata_t data, uint8_t repeat );
|
||||
|
|
|
@ -34,8 +34,8 @@ extern "C" {
|
|||
|
||||
bool g_useOverlays = false;
|
||||
int g_absVMax = 0;
|
||||
int startMax;
|
||||
int PageWidth;
|
||||
int startMax; // Maximum offset in the graph (right side of graph)
|
||||
int PageWidth; // How many samples are currently visible on this 'page' / graph
|
||||
int unlockStart = 0;
|
||||
|
||||
void ProxGuiQT::ShowGraphWindow(void)
|
||||
|
@ -511,6 +511,7 @@ void Plot::paintEvent(QPaintEvent *event)
|
|||
|
||||
QRect plotRect(WIDTH_AXES, 0, width() - WIDTH_AXES, height() - HEIGHT_INFO);
|
||||
QRect infoRect(0, height() - HEIGHT_INFO, width(), HEIGHT_INFO);
|
||||
PageWidth = plotRect.width() / GraphPixelsPerPoint;
|
||||
|
||||
//Grey background
|
||||
painter.fillRect(rect(), QColor(60, 60, 60));
|
||||
|
@ -616,7 +617,7 @@ void Plot::mouseMoveEvent(QMouseEvent *event)
|
|||
|
||||
void Plot::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
int offset;
|
||||
int offset; // Left/right movement offset (in sample size)
|
||||
|
||||
if(event->modifiers() & Qt::ShiftModifier) {
|
||||
if (PlotGridX)
|
||||
|
@ -671,20 +672,22 @@ void Plot::keyPressEvent(QKeyEvent *event)
|
|||
case Qt::Key_H:
|
||||
puts("Plot Window Keystrokes:\n");
|
||||
puts(" Key Action\n");
|
||||
puts(" UP Zoom out");
|
||||
puts(" DOWN Zoom in");
|
||||
puts(" G Toggle grid display");
|
||||
puts(" H Show help");
|
||||
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(" <CTL>LEFT Move left 1 sample");
|
||||
puts(" <SHIFT>LEFT Page left");
|
||||
puts(" LEFT-MOUSE-CLICK Set yellow cursor");
|
||||
puts(" Q Hide window");
|
||||
puts(" RIGHT Move right");
|
||||
puts(" <CTL>RIGHT Move right 1 sample");
|
||||
puts(" <SHIFT>RIGHT Page right");
|
||||
puts(" RIGHT-MOUSE-CLICK Set purple cursor");
|
||||
puts(" UP Zoom out");
|
||||
puts("");
|
||||
puts("Use client window 'data help' for more plot commands\n");
|
||||
break;
|
||||
|
@ -701,6 +704,14 @@ void Plot::keyPressEvent(QKeyEvent *event)
|
|||
master->hide();
|
||||
break;
|
||||
|
||||
case Qt::Key_Home:
|
||||
GraphStart = 0;
|
||||
break;
|
||||
|
||||
case Qt::Key_End:
|
||||
GraphStart = startMax;
|
||||
break;
|
||||
|
||||
default:
|
||||
QWidget::keyPressEvent(event);
|
||||
return;
|
||||
|
|
|
@ -29,8 +29,8 @@ class Plot: public QWidget
|
|||
{
|
||||
private:
|
||||
QWidget *master;
|
||||
int GraphStart;
|
||||
double GraphPixelsPerPoint;
|
||||
int GraphStart; // Starting point/offset for the left side of the graph
|
||||
double GraphPixelsPerPoint; // How many visual pixels are between each sample point (x axis)
|
||||
int CursorAPos;
|
||||
int CursorBPos;
|
||||
void PlotGraph(int *buffer, int len, QRect r,QRect r2, QPainter* painter, int graphNum);
|
||||
|
|
|
@ -119,7 +119,6 @@ void AddLogCurrentDT(char *fileName) {
|
|||
|
||||
void FillFileNameByUID(char *fileName, uint8_t *uid, char *ext, int byteCount) {
|
||||
char * fnameptr = fileName;
|
||||
memset(fileName, 0x00, 200);
|
||||
|
||||
for (int j = 0; j < byteCount; j++, fnameptr += 2)
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
while (len--) {
|
||||
|
@ -319,13 +322,12 @@ uint32_t SwapBits(uint32_t value, int nrbits) {
|
|||
uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize){
|
||||
static uint8_t buf[64];
|
||||
memset(buf, 0x00, 64);
|
||||
uint8_t *tmp = buf;
|
||||
for (uint8_t block=0; block < (uint8_t)(len/blockSize); block++){
|
||||
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
|
||||
|
@ -515,6 +517,7 @@ int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int param_gethex_ex(const char *line, int paramnum, uint8_t *data, int *hexcnt)
|
||||
{
|
||||
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 (en - bg + 1 > *hexcnt) return 1;
|
||||
|
||||
*hexcnt = en - bg + 1;
|
||||
if (*hexcnt % 2) //error if not complete hex bytes
|
||||
return 1;
|
||||
|
|
|
@ -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_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(const uint8_t *data, const size_t len);
|
||||
|
||||
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);
|
||||
|
|
|
@ -105,15 +105,15 @@ NXP/Philips CUSTOM COMMANDS
|
|||
|
||||
|
||||
#define ISO14443A_CMD_REQA 0x26
|
||||
#define ISO14443A_CMD_READBLOCK 0x30
|
||||
#define ISO14443A_CMD_WUPA 0x52
|
||||
#define ISO14443A_CMD_ANTICOLL_OR_SELECT 0x93
|
||||
#define ISO14443A_CMD_ANTICOLL_OR_SELECT_2 0x95
|
||||
#define ISO14443A_CMD_ANTICOLL_OR_SELECT_3 0x97
|
||||
#define ISO14443A_CMD_WRITEBLOCK 0xA0 // or 0xA2 ?
|
||||
#define ISO14443A_CMD_HALT 0x50
|
||||
#define ISO14443A_CMD_RATS 0xE0
|
||||
|
||||
#define MIFARE_CMD_READBLOCK 0x30
|
||||
#define MIFARE_CMD_WRITEBLOCK 0xA0
|
||||
#define MIFARE_AUTH_KEYA 0x60
|
||||
#define MIFARE_AUTH_KEYB 0x61
|
||||
#define MIFARE_MAGICWUPC1 0x40
|
||||
|
@ -127,23 +127,28 @@ NXP/Philips CUSTOM COMMANDS
|
|||
#define MIFARE_EV1_PERSONAL_UID 0x40
|
||||
#define MIFARE_EV1_SETMODE 0x43
|
||||
|
||||
|
||||
#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_2 0xAF
|
||||
|
||||
#define MIFARE_ULEV1_AUTH 0x1B
|
||||
#define MIFARE_ULEV1_VERSION 0x60
|
||||
#define MIFARE_ULEV1_FASTREAD 0x3A
|
||||
//#define MIFARE_ULEV1_WRITE 0xA2
|
||||
//#define MIFARE_ULEV1_COMP_WRITE 0xA0
|
||||
#define MIFARE_ULEV1_WRITE 0xA2
|
||||
#define MIFARE_ULEV1_COMP_WRITE MIFARE_CMD_WRITEBLOCK
|
||||
#define MIFARE_ULEV1_READ_CNT 0x39
|
||||
#define MIFARE_ULEV1_INCR_CNT 0xA5
|
||||
#define MIFARE_ULEV1_READSIG 0x3C
|
||||
#define MIFARE_ULEV1_CHECKTEAR 0x3E
|
||||
#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
|
||||
0E xx = SELECT ID (xx = Chip-ID)
|
||||
|
|
|
@ -41,6 +41,7 @@ typedef struct{
|
|||
bool averaging;
|
||||
int divisor;
|
||||
int trigger_threshold;
|
||||
int samples_to_skip;
|
||||
} sample_config;
|
||||
|
||||
// For the bootloader
|
||||
|
@ -116,6 +117,7 @@ typedef struct{
|
|||
#define CMD_T55XX_WAKEUP 0x0224
|
||||
#define CMD_COTAG 0x0225
|
||||
#define CMD_PARADOX_CLONE_TAG 0x0226
|
||||
#define CMD_EM4X_PROTECT 0x0228
|
||||
|
||||
// For the 13.56 MHz tags
|
||||
#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_DEBUG 0x0316
|
||||
#define CMD_LF_SNOOP_RAW_ADC_SAMPLES 0x0317
|
||||
#define CMD_CSETUID_ISO_15693 0x0318
|
||||
|
||||
// For Hitag2 transponders
|
||||
#define CMD_SNOOP_HITAG 0x0370
|
||||
|
|
|
@ -80,7 +80,7 @@ serial_port uart_open(const char* pcPortName)
|
|||
if (sp == 0) return INVALID_SERIAL_PORT;
|
||||
|
||||
if (memcmp(pcPortName, "tcp:", 4) == 0) {
|
||||
struct addrinfo *addr, *rp;
|
||||
struct addrinfo *addr = NULL, *rp;
|
||||
char *addrstr = strdup(pcPortName + 4);
|
||||
if (addrstr == NULL) {
|
||||
printf("Error: strdup\n");
|
||||
|
@ -98,7 +98,13 @@ serial_port uart_open(const char* pcPortName)
|
|||
} else
|
||||
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) {
|
||||
printf("Error: getaddrinfo: %s\n", gai_strerror(s));
|
||||
return INVALID_SERIAL_PORT;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue