mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Merge branch 'master' of https://github.com/Proxmark/proxmark3
Conflicts: armsrc/lfops.c client/cmddata.c client/cmdlf.c client/cmdlft55xx.c client/cmdlft55xx.h client/scripts/test_t55x7_bi.lua
This commit is contained in:
+9
-6
@@ -171,18 +171,19 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
|
||||
traceLen += iLen;
|
||||
|
||||
// parity bytes
|
||||
if (parity != NULL && iLen != 0) {
|
||||
if (iLen != 0) {
|
||||
if (parity != NULL) {
|
||||
memcpy(trace + traceLen, parity, num_paritybytes);
|
||||
} else {
|
||||
memset(trace + traceLen, 0x00, num_paritybytes);
|
||||
}
|
||||
}
|
||||
traceLen += num_paritybytes;
|
||||
|
||||
if(traceLen +4 < max_traceLen)
|
||||
{ //If it hadn't been cleared, for whatever reason..
|
||||
memset(trace+traceLen,0x44, 4);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int readerToTag)
|
||||
{
|
||||
/**
|
||||
@@ -224,6 +225,8 @@ int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwP
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Emulator memory
|
||||
uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length){
|
||||
uint8_t* mem = BigBuf_get_EM_addr();
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ SRC_LF = lfops.c hitag2.c lfsampling.c
|
||||
SRC_ISO15693 = iso15693.c iso15693tools.c
|
||||
SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c
|
||||
SRC_ISO14443b = iso14443.c
|
||||
SRC_CRAPTO1 = crapto1.c crypto1.c des.c aes.c
|
||||
SRC_CRAPTO1 = crapto1.c crypto1.c des.c aes.c desfire_key.c desfire_crypto.c mifaredesfire.c
|
||||
SRC_CRC = iso14443crc.c crc.c crc16.c crc32.c
|
||||
|
||||
THUMBSRC = start.c \
|
||||
|
||||
+1
-1
@@ -647,7 +647,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||
setSamplingConfig((sample_config *) c->d.asBytes);
|
||||
break;
|
||||
case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
|
||||
cmd_send(CMD_ACK,SampleLF(),0,0,0,0);
|
||||
cmd_send(CMD_ACK,SampleLF(c->arg[0]),0,0,0,0);
|
||||
break;
|
||||
case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
|
||||
ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
|
||||
|
||||
+19
-1
@@ -21,6 +21,13 @@
|
||||
#include "../common/crc32.h"
|
||||
#include "BigBuf.h"
|
||||
#include "../include/hitag2.h"
|
||||
#include "../include/mifare.h"
|
||||
//#include <openssl/des.h>
|
||||
//#include <openssl/aes.h>
|
||||
//#include "des.h"
|
||||
//#include "aes.h"
|
||||
#include "desfire.h"
|
||||
|
||||
|
||||
extern const uint8_t OddByteParity[256];
|
||||
extern int rsamples; // = 0;
|
||||
@@ -170,7 +177,7 @@ void EPA_PACE_Collect_Nonce(UsbCommand * c);
|
||||
void ReaderMifare(bool first_try);
|
||||
int32_t dist_nt(uint32_t nt1, uint32_t nt2);
|
||||
void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *data);
|
||||
void MifareUReadBlock(uint8_t arg0,uint8_t *datain);
|
||||
void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
|
||||
void MifareUC_Auth1(uint8_t arg0, uint8_t *datain);
|
||||
void MifareUC_Auth2(uint32_t arg0, uint8_t *datain);
|
||||
void MifareUReadCard(uint8_t arg0, int Pages, uint8_t *datain);
|
||||
@@ -207,6 +214,17 @@ void OnError(uint8_t reason);
|
||||
|
||||
|
||||
|
||||
// desfire_crypto.h
|
||||
void *mifare_cryto_preprocess_data (desfiretag_t tag, void *data, size_t *nbytes, off_t offset, int communication_settings);
|
||||
void *mifare_cryto_postprocess_data (desfiretag_t tag, void *data, ssize_t *nbytes, int communication_settings);
|
||||
void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size);
|
||||
void mifare_cypher_blocks_chained (desfiretag_t tag, desfirekey_t key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation);
|
||||
size_t key_block_size (const desfirekey_t key);
|
||||
size_t padded_data_length (const size_t nbytes, const size_t block_size);
|
||||
size_t maced_data_length (const desfirekey_t key, const size_t nbytes);
|
||||
size_t enciphered_data_length (const desfiretag_t tag, const size_t nbytes, int communication_settings);
|
||||
void cmac_generate_subkeys (desfirekey_t key);
|
||||
void cmac (const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac);
|
||||
|
||||
|
||||
/// iso15693.h
|
||||
|
||||
+82
-39
@@ -213,6 +213,12 @@ void AppendCrc14443a(uint8_t* data, int len)
|
||||
ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1);
|
||||
}
|
||||
|
||||
void AppendCrc14443b(uint8_t* data, int len)
|
||||
{
|
||||
ComputeCrc14443(CRC_14443_B,data,len,data+len,data+len+1);
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// ISO 14443 Type A - Miller decoder
|
||||
//=============================================================================
|
||||
@@ -232,13 +238,17 @@ void AppendCrc14443a(uint8_t* data, int len)
|
||||
static tUart Uart;
|
||||
|
||||
// Lookup-Table to decide if 4 raw bits are a modulation.
|
||||
// We accept two or three consecutive "0" in any position with the rest "1"
|
||||
// We accept the following:
|
||||
// 0001 - a 3 tick wide pause
|
||||
// 0011 - a 2 tick wide pause, or a three tick wide pause shifted left
|
||||
// 0111 - a 2 tick wide pause shifted left
|
||||
// 1001 - a 2 tick wide pause shifted right
|
||||
const bool Mod_Miller_LUT[] = {
|
||||
TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE,
|
||||
TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE
|
||||
FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE,
|
||||
FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
|
||||
};
|
||||
#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x00F0) >> 4])
|
||||
#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x000F)])
|
||||
#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4])
|
||||
#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)])
|
||||
|
||||
void UartReset()
|
||||
{
|
||||
@@ -248,8 +258,6 @@ void UartReset()
|
||||
Uart.parityLen = 0; // number of decoded parity bytes
|
||||
Uart.shiftReg = 0; // shiftreg to hold decoded data bits
|
||||
Uart.parityBits = 0; // holds 8 parity bits
|
||||
Uart.twoBits = 0x0000; // buffer for 2 Bits
|
||||
Uart.highCnt = 0;
|
||||
Uart.startTime = 0;
|
||||
Uart.endTime = 0;
|
||||
}
|
||||
@@ -258,6 +266,7 @@ void UartInit(uint8_t *data, uint8_t *parity)
|
||||
{
|
||||
Uart.output = data;
|
||||
Uart.parity = parity;
|
||||
Uart.fourBits = 0x00000000; // clear the buffer for 4 Bits
|
||||
UartReset();
|
||||
}
|
||||
|
||||
@@ -265,40 +274,37 @@ void UartInit(uint8_t *data, uint8_t *parity)
|
||||
static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
|
||||
{
|
||||
|
||||
Uart.twoBits = (Uart.twoBits << 8) | bit;
|
||||
Uart.fourBits = (Uart.fourBits << 8) | bit;
|
||||
|
||||
if (Uart.state == STATE_UNSYNCD) { // not yet synced
|
||||
|
||||
if (Uart.highCnt < 2) { // wait for a stable unmodulated signal
|
||||
if (Uart.twoBits == 0xffff) {
|
||||
Uart.highCnt++;
|
||||
} else {
|
||||
Uart.highCnt = 0;
|
||||
}
|
||||
} else {
|
||||
Uart.syncBit = 0xFFFF; // not set
|
||||
// we look for a ...1111111100x11111xxxxxx pattern (the start bit)
|
||||
if ((Uart.twoBits & 0xDF00) == 0x1F00) Uart.syncBit = 8; // mask is 11x11111 xxxxxxxx,
|
||||
// check for 00x11111 xxxxxxxx
|
||||
else if ((Uart.twoBits & 0xEF80) == 0x8F80) Uart.syncBit = 7; // both masks shifted right one bit, left padded with '1'
|
||||
else if ((Uart.twoBits & 0xF7C0) == 0xC7C0) Uart.syncBit = 6; // ...
|
||||
else if ((Uart.twoBits & 0xFBE0) == 0xE3E0) Uart.syncBit = 5;
|
||||
else if ((Uart.twoBits & 0xFDF0) == 0xF1F0) Uart.syncBit = 4;
|
||||
else if ((Uart.twoBits & 0xFEF8) == 0xF8F8) Uart.syncBit = 3;
|
||||
else if ((Uart.twoBits & 0xFF7C) == 0xFC7C) Uart.syncBit = 2;
|
||||
else if ((Uart.twoBits & 0xFFBE) == 0xFE3E) Uart.syncBit = 1;
|
||||
if (Uart.syncBit != 0xFFFF) { // found a sync bit
|
||||
Uart.syncBit = 9999; // not set
|
||||
// The start bit is one ore more Sequence Y followed by a Sequence Z (... 11111111 00x11111). We need to distinguish from
|
||||
// Sequence X followed by Sequence Y followed by Sequence Z (111100x1 11111111 00x11111)
|
||||
// we therefore look for a ...xx11111111111100x11111xxxxxx... pattern
|
||||
// (12 '1's followed by 2 '0's, eventually followed by another '0', followed by 5 '1's)
|
||||
#define ISO14443A_STARTBIT_MASK 0x07FFEF80 // mask is 00000111 11111111 11101111 10000000
|
||||
#define ISO14443A_STARTBIT_PATTERN 0x07FF8F80 // pattern is 00000111 11111111 10001111 10000000
|
||||
if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 0)) == ISO14443A_STARTBIT_PATTERN >> 0) Uart.syncBit = 7;
|
||||
else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 1)) == ISO14443A_STARTBIT_PATTERN >> 1) Uart.syncBit = 6;
|
||||
else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 2)) == ISO14443A_STARTBIT_PATTERN >> 2) Uart.syncBit = 5;
|
||||
else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 3)) == ISO14443A_STARTBIT_PATTERN >> 3) Uart.syncBit = 4;
|
||||
else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 4)) == ISO14443A_STARTBIT_PATTERN >> 4) Uart.syncBit = 3;
|
||||
else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 5)) == ISO14443A_STARTBIT_PATTERN >> 5) Uart.syncBit = 2;
|
||||
else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 6)) == ISO14443A_STARTBIT_PATTERN >> 6) Uart.syncBit = 1;
|
||||
else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 7)) == ISO14443A_STARTBIT_PATTERN >> 7) Uart.syncBit = 0;
|
||||
|
||||
if (Uart.syncBit != 9999) { // found a sync bit
|
||||
Uart.startTime = non_real_time?non_real_time:(GetCountSspClk() & 0xfffffff8);
|
||||
Uart.startTime -= Uart.syncBit;
|
||||
Uart.endTime = Uart.startTime;
|
||||
Uart.state = STATE_START_OF_COMMUNICATION;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (IsMillerModulationNibble1(Uart.twoBits >> Uart.syncBit)) {
|
||||
if (IsMillerModulationNibble2(Uart.twoBits >> Uart.syncBit)) { // Modulation in both halves - error
|
||||
if (IsMillerModulationNibble1(Uart.fourBits >> Uart.syncBit)) {
|
||||
if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) { // Modulation in both halves - error
|
||||
UartReset();
|
||||
} else { // Modulation in first half = Sequence Z = logic "0"
|
||||
if (Uart.state == STATE_MILLER_X) { // error - must not follow after X
|
||||
@@ -322,7 +328,7 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (IsMillerModulationNibble2(Uart.twoBits >> Uart.syncBit)) { // Modulation second half = Sequence X = logic "1"
|
||||
if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) { // Modulation second half = Sequence X = logic "1"
|
||||
Uart.bitCount++;
|
||||
Uart.shiftReg = (Uart.shiftReg >> 1) | 0x100; // add a 1 to the shiftreg
|
||||
Uart.state = STATE_MILLER_X;
|
||||
@@ -358,12 +364,10 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
|
||||
return TRUE; // we are finished with decoding the raw data sequence
|
||||
} else {
|
||||
UartReset(); // Nothing received - start over
|
||||
Uart.highCnt = 1;
|
||||
}
|
||||
}
|
||||
if (Uart.state == STATE_START_OF_COMMUNICATION) { // error - must not follow directly after SOC
|
||||
UartReset();
|
||||
Uart.highCnt = 1;
|
||||
} else { // a logic "0"
|
||||
Uart.bitCount++;
|
||||
Uart.shiftReg = (Uart.shiftReg >> 1); // add a 0 to the shiftreg
|
||||
@@ -680,6 +684,9 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||
|
||||
// And ready to receive another response.
|
||||
DemodReset();
|
||||
// And reset the Miller decoder including itS (now outdated) input buffer
|
||||
UartInit(receivedCmd, receivedCmdPar);
|
||||
|
||||
LED_C_OFF();
|
||||
}
|
||||
TagIsActive = (Demod.state != DEMOD_UNSYNCD);
|
||||
@@ -1337,7 +1344,7 @@ void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8
|
||||
}
|
||||
|
||||
// Only transmit parity bit if we transmitted a complete byte
|
||||
if (j == 8) {
|
||||
if (j == 8 && parity != NULL) {
|
||||
// Get the parity bit
|
||||
if (parity[i>>3] & (0x80 >> (i&0x0007))) {
|
||||
// Sequence X
|
||||
@@ -1631,6 +1638,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t *timing)
|
||||
{
|
||||
CodeIso14443aBitsAsReaderPar(frame, bits, par);
|
||||
@@ -1646,11 +1654,13 @@ void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ReaderTransmitPar(uint8_t* frame, uint16_t len, uint8_t *par, uint32_t *timing)
|
||||
{
|
||||
ReaderTransmitBitsPar(frame, len*8, par, timing);
|
||||
}
|
||||
|
||||
|
||||
void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing)
|
||||
{
|
||||
// Generate parity and redirect
|
||||
@@ -1659,6 +1669,7 @@ void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing)
|
||||
ReaderTransmitBitsPar(frame, len, par, timing);
|
||||
}
|
||||
|
||||
|
||||
void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing)
|
||||
{
|
||||
// Generate parity and redirect
|
||||
@@ -1719,6 +1730,11 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
|
||||
memset(uid_ptr,0,10);
|
||||
}
|
||||
|
||||
// check for proprietary anticollision:
|
||||
if ((resp[0] & 0x1F) == 0) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
// OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in
|
||||
// which case we need to make a cascade 2 request and select - this is a long UID
|
||||
// While the UID is not complete, the 3nd bit (from the right) is set in the SAK.
|
||||
@@ -1851,7 +1867,7 @@ void iso14443a_setup(uint8_t fpga_minor_mode) {
|
||||
DemodReset();
|
||||
UartReset();
|
||||
NextTransferTime = 2*DELAY_ARM2AIR_AS_READER;
|
||||
iso14a_set_timeout(1050); // 10ms default
|
||||
iso14a_set_timeout(50*106); // 10ms default
|
||||
}
|
||||
|
||||
int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) {
|
||||
@@ -1927,15 +1943,38 @@ void ReaderIso14443a(UsbCommand *c)
|
||||
|
||||
if(param & ISO14A_RAW) {
|
||||
if(param & ISO14A_APPEND_CRC) {
|
||||
if(param & ISO14A_TOPAZMODE) {
|
||||
AppendCrc14443b(cmd,len);
|
||||
} else {
|
||||
AppendCrc14443a(cmd,len);
|
||||
}
|
||||
len += 2;
|
||||
if (lenbits) lenbits += 16;
|
||||
}
|
||||
if(lenbits>0) {
|
||||
if(lenbits>0) { // want to send a specific number of bits (e.g. short commands)
|
||||
if(param & ISO14A_TOPAZMODE) {
|
||||
int bits_to_send = lenbits;
|
||||
uint16_t i = 0;
|
||||
ReaderTransmitBitsPar(&cmd[i++], MIN(bits_to_send, 7), NULL, NULL); // first byte is always short (7bits) and no parity
|
||||
bits_to_send -= 7;
|
||||
while (bits_to_send > 0) {
|
||||
ReaderTransmitBitsPar(&cmd[i++], MIN(bits_to_send, 8), NULL, NULL); // following bytes are 8 bit and no parity
|
||||
bits_to_send -= 8;
|
||||
}
|
||||
} else {
|
||||
GetParity(cmd, lenbits/8, par);
|
||||
ReaderTransmitBitsPar(cmd, lenbits, par, NULL);
|
||||
ReaderTransmitBitsPar(cmd, lenbits, par, NULL); // bytes are 8 bit with odd parity
|
||||
}
|
||||
} else { // want to send complete bytes only
|
||||
if(param & ISO14A_TOPAZMODE) {
|
||||
uint16_t i = 0;
|
||||
ReaderTransmitBitsPar(&cmd[i++], 7, NULL, NULL); // first byte: 7 bits, no paritiy
|
||||
while (i < len) {
|
||||
ReaderTransmitBitsPar(&cmd[i++], 8, NULL, NULL); // following bytes: 8 bits, no paritiy
|
||||
}
|
||||
} else {
|
||||
ReaderTransmit(cmd,len, NULL);
|
||||
ReaderTransmit(cmd,len, NULL); // 8 bits, odd parity
|
||||
}
|
||||
}
|
||||
arg0 = ReaderReceive(buf, par);
|
||||
cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
|
||||
@@ -2302,6 +2341,8 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||
}
|
||||
if(cardSTATE == MFEMUL_NOFIELD) continue;
|
||||
|
||||
//Now, get data
|
||||
|
||||
res = EmGetCmd(receivedCmd, &len, receivedCmd_par);
|
||||
if (res == 2) { //Field is off!
|
||||
cardSTATE = MFEMUL_NOFIELD;
|
||||
@@ -2805,7 +2846,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||
if (MfSniffLogic(receivedCmd, Uart.len, Uart.parity, Uart.bitCount, TRUE)) break;
|
||||
|
||||
/* And ready to receive another command. */
|
||||
UartReset();
|
||||
UartInit(receivedCmd, receivedCmdPar);
|
||||
|
||||
/* And also reset the demod code */
|
||||
DemodReset();
|
||||
@@ -2822,6 +2863,8 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||
|
||||
// And ready to receive another response.
|
||||
DemodReset();
|
||||
// And reset the Miller decoder including its (now outdated) input buffer
|
||||
UartInit(receivedCmd, receivedCmdPar);
|
||||
}
|
||||
TagIsActive = (Demod.state != DEMOD_UNSYNCD);
|
||||
}
|
||||
|
||||
+2
-3
@@ -57,15 +57,14 @@ typedef struct {
|
||||
// DROP_FIRST_HALF,
|
||||
} state;
|
||||
uint16_t shiftReg;
|
||||
uint16_t bitCount;
|
||||
int16_t bitCount;
|
||||
uint16_t len;
|
||||
uint16_t byteCntMax;
|
||||
uint16_t posCnt;
|
||||
uint16_t syncBit;
|
||||
uint8_t parityBits;
|
||||
uint8_t parityLen;
|
||||
uint16_t highCnt;
|
||||
uint16_t twoBits;
|
||||
uint32_t fourBits;
|
||||
uint32_t startTime, endTime;
|
||||
uint8_t *output;
|
||||
uint8_t *parity;
|
||||
|
||||
+40
-31
@@ -1085,11 +1085,11 @@ void T55xxWriteBit(int bit)
|
||||
// Write one card block in page 0, no lock
|
||||
void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint32_t i = 0;
|
||||
|
||||
// Set up FPGA, 125kHz
|
||||
// Wait for config.. (192+8190xPOW)x8 == 67ms
|
||||
LFSetupFPGAForADC(0, true);
|
||||
// Set up FPGA, 125kHz
|
||||
// Wait for config.. (192+8190xPOW)x8 == 67ms
|
||||
LFSetupFPGAForADC(0, true);
|
||||
|
||||
// Now start writting
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
@@ -1122,20 +1122,28 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
}
|
||||
|
||||
void TurnReadLFOn(){
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
// Give it a bit of time for the resonant antenna to settle.
|
||||
SpinDelayUs(8*150);
|
||||
}
|
||||
|
||||
|
||||
// Read one card block in page 0
|
||||
void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
uint16_t bufferlength = BigBuf_max_traceLen();
|
||||
if ( bufferlength > T55xx_SAMPLES_SIZE )
|
||||
bufferlength = T55xx_SAMPLES_SIZE;
|
||||
if ( bufferlength > T55xx_SAMPLES_SIZE )
|
||||
bufferlength = T55xx_SAMPLES_SIZE;
|
||||
|
||||
memset(dest, 0x80, bufferlength);
|
||||
|
||||
// Set up FPGA, 125kHz
|
||||
// Wait for config.. (192+8190xPOW)x8 == 67ms
|
||||
LFSetupFPGAForADC(0, true);
|
||||
// Clear destination buffer before sending the command
|
||||
memset(dest, 0x80, bufferlength);
|
||||
|
||||
// Set up FPGA, 125kHz
|
||||
// Wait for config.. (192+8190xPOW)x8 == 67ms
|
||||
LFSetupFPGAForADC(0, true);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelayUs(START_GAP);
|
||||
|
||||
@@ -1154,40 +1162,40 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
|
||||
T55xxWriteBit(Block & i);
|
||||
|
||||
// Turn field on to read the response
|
||||
TurnReadLFOn();
|
||||
|
||||
TurnReadLFOn();
|
||||
// Now do the acquisition
|
||||
i = 0;
|
||||
for(;;) {
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x43;
|
||||
LED_D_ON();
|
||||
LED_D_ON();
|
||||
}
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
++i;
|
||||
LED_D_OFF();
|
||||
if (i >= bufferlength) break;
|
||||
i++;
|
||||
LED_D_OFF();
|
||||
if (i >= bufferlength) break;
|
||||
}
|
||||
}
|
||||
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
||||
LED_D_OFF();
|
||||
}
|
||||
|
||||
// Read card traceability data (page 1)
|
||||
void T55xxReadTrace(void){
|
||||
|
||||
uint32_t i = 0;
|
||||
|
||||
uint32_t i = 0;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
uint16_t bufferlength = BigBuf_max_traceLen();
|
||||
if ( bufferlength > T55xx_SAMPLES_SIZE )
|
||||
bufferlength = T55xx_SAMPLES_SIZE;
|
||||
if ( bufferlength > T55xx_SAMPLES_SIZE )
|
||||
bufferlength= T55xx_SAMPLES_SIZE;
|
||||
|
||||
memset(dest, 0x80, bufferlength);
|
||||
|
||||
LFSetupFPGAForADC(0, true);
|
||||
// Clear destination buffer before sending the command
|
||||
memset(dest, 0x80, bufferlength);
|
||||
|
||||
LFSetupFPGAForADC(0, true);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelayUs(START_GAP);
|
||||
|
||||
@@ -1196,24 +1204,25 @@ void T55xxReadTrace(void){
|
||||
T55xxWriteBit(1); //Page 1
|
||||
|
||||
// Turn field on to read the response
|
||||
TurnReadLFOn();
|
||||
TurnReadLFOn();
|
||||
|
||||
// Now do the acquisition
|
||||
for(;;) {
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x43;
|
||||
LED_D_ON();
|
||||
LED_D_ON();
|
||||
}
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
++i;
|
||||
LED_D_OFF();
|
||||
|
||||
if (i >= bufferlength) break;
|
||||
i++;
|
||||
LED_D_OFF();
|
||||
|
||||
if (i >= bufferlength) break;
|
||||
}
|
||||
}
|
||||
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
||||
LED_D_OFF();
|
||||
}
|
||||
|
||||
+6
-6
@@ -224,21 +224,21 @@ uint32_t DoAcquisition_config( bool silent)
|
||||
,silent);
|
||||
}
|
||||
|
||||
uint32_t ReadLF(bool activeField)
|
||||
uint32_t ReadLF(bool activeField, bool silent)
|
||||
{
|
||||
printConfig();
|
||||
if (!silent) printConfig();
|
||||
LFSetupFPGAForADC(config.divisor, activeField);
|
||||
// Now call the acquisition routine
|
||||
return DoAcquisition_config(false);
|
||||
return DoAcquisition_config(silent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the FPGA for reader-mode (field on), and acquires the samples.
|
||||
* @return number of bits sampled
|
||||
**/
|
||||
uint32_t SampleLF()
|
||||
uint32_t SampleLF(bool printCfg)
|
||||
{
|
||||
return ReadLF(true);
|
||||
return ReadLF(true, printCfg);
|
||||
}
|
||||
/**
|
||||
* Initializes the FPGA for snoop-mode (field off), and acquires the samples.
|
||||
@@ -247,5 +247,5 @@ uint32_t SampleLF()
|
||||
|
||||
uint32_t SnoopLF()
|
||||
{
|
||||
return ReadLF(false);
|
||||
return ReadLF(false, true);
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* Initializes the FPGA for reader-mode (field on), and acquires the samples.
|
||||
* @return number of bits sampled
|
||||
**/
|
||||
uint32_t SampleLF();
|
||||
uint32_t SampleLF(bool silent);
|
||||
|
||||
/**
|
||||
* Initializes the FPGA for snoop-mode (field off), and acquires the samples.
|
||||
|
||||
+89
-20
@@ -16,7 +16,8 @@
|
||||
#include "mifarecmd.h"
|
||||
#include "apps.h"
|
||||
#include "util.h"
|
||||
|
||||
//#include "../client/loclass/des.h"
|
||||
#include "des.h"
|
||||
#include "crc.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -104,14 +105,14 @@ void MifareUC_Auth1(uint8_t arg0, uint8_t *datain){
|
||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Can't select card");
|
||||
//OnError(0);
|
||||
OnError(0);
|
||||
return;
|
||||
};
|
||||
|
||||
if(mifare_ultra_auth1(cuid, dataoutbuf)){
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Authentication part1: Fail.");
|
||||
//OnError(1);
|
||||
OnError(1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -138,7 +139,7 @@ void MifareUC_Auth2(uint32_t arg0, uint8_t *datain){
|
||||
if(mifare_ultra_auth2(cuid, key, dataoutbuf)){
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Authentication part2: Fail...");
|
||||
//OnError(1);
|
||||
OnError(1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -151,13 +152,21 @@ void MifareUC_Auth2(uint32_t arg0, uint8_t *datain){
|
||||
LEDsoff();
|
||||
}
|
||||
|
||||
void MifareUReadBlock(uint8_t arg0,uint8_t *datain)
|
||||
void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
|
||||
{
|
||||
uint8_t blockNo = arg0;
|
||||
byte_t dataout[16] = {0x00};
|
||||
uint8_t uid[10] = {0x00};
|
||||
uint8_t key[8] = {0x00};
|
||||
uint32_t cuid;
|
||||
|
||||
bool usePwd = false;
|
||||
|
||||
usePwd = (arg1 == 1);
|
||||
|
||||
// use password
|
||||
if ( usePwd )
|
||||
memcpy(key, datain, 8);
|
||||
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
@@ -167,22 +176,82 @@ void MifareUReadBlock(uint8_t arg0,uint8_t *datain)
|
||||
|
||||
int len = iso14443a_select_card(uid, NULL, &cuid);
|
||||
if(!len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
|
||||
//OnError(1);
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len);
|
||||
OnError(1);
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
// authenticate here.
|
||||
if ( usePwd ) {
|
||||
|
||||
uint8_t a[8] = { 0x01 };
|
||||
uint8_t b[8] = { 0x00 };
|
||||
uint8_t enc_b[8] = { 0x00 };
|
||||
uint8_t ab[16] = { 0x00 };
|
||||
|
||||
uint8_t transKey[8] = { 0x00 };
|
||||
|
||||
uint16_t len;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL);
|
||||
if (len == 1) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
|
||||
OnError(1);
|
||||
return;
|
||||
}
|
||||
|
||||
// memcpy(dataout, receivedAnswer, 11);
|
||||
|
||||
// tag nonce.
|
||||
memcpy(enc_b,receivedAnswer+1,8);
|
||||
|
||||
// decrypt nonce.
|
||||
des_dec(enc_b, b, key );
|
||||
|
||||
Dbprintf("enc_B: %02x %02x %02x %02x %02x %02x %02x %02x", enc_b[0],enc_b[1],enc_b[2],enc_b[3],enc_b[4],enc_b[5],enc_b[6],enc_b[7] );
|
||||
|
||||
rol(b,8);
|
||||
|
||||
memcpy(ab ,a,8);
|
||||
memcpy(ab+8,b,8);
|
||||
|
||||
Dbprintf("AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[0],ab[1],ab[2],ab[3],ab[4],ab[5],ab[6],ab[7] );
|
||||
Dbprintf("AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[8],ab[9],ab[10],ab[11],ab[12],ab[13],ab[14],ab[15] );
|
||||
|
||||
// encrypt
|
||||
des_enc(ab, ab, key);
|
||||
|
||||
Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[0],ab[1],ab[2],ab[3],ab[4],ab[5],ab[6],ab[7] );
|
||||
Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[8],ab[9],ab[10],ab[11],ab[12],ab[13],ab[14],ab[15] );
|
||||
|
||||
len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, ab, receivedAnswer, receivedAnswerPar, NULL);
|
||||
if (len == 1) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
|
||||
OnError(1);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
memcpy(transKey, receivedAnswer+1, 8);
|
||||
Dbprintf("TRANSACTIONKEY: %02x %02x %02x %02x %02x %02x %02x %02x", transKey[0],transKey[1],transKey[2],transKey[3],
|
||||
transKey[4],transKey[5],transKey[6],transKey[7] );
|
||||
}
|
||||
|
||||
len = mifare_ultra_readblock(cuid, blockNo, dataout);
|
||||
if(len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error");
|
||||
//OnError(2);
|
||||
OnError(2);
|
||||
return;
|
||||
};
|
||||
|
||||
len = mifare_ultra_halt(cuid);
|
||||
if(len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");
|
||||
//OnError(3);
|
||||
OnError(3);
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -261,8 +330,8 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||
|
||||
void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)
|
||||
{
|
||||
// params
|
||||
uint8_t sectorNo = arg0;
|
||||
// params
|
||||
uint8_t sectorNo = arg0;
|
||||
int Pages = arg1;
|
||||
int count_Pages = 0;
|
||||
byte_t dataout[176] = {0x00};;
|
||||
@@ -283,8 +352,8 @@ void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)
|
||||
|
||||
if (!len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Can't select card");
|
||||
//OnError(1);
|
||||
Dbprintf("Can't select card (RC:%d)",len);
|
||||
OnError(1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -295,7 +364,7 @@ void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)
|
||||
if (len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Read block %d error",i);
|
||||
//OnError(2);
|
||||
OnError(2);
|
||||
return;
|
||||
} else {
|
||||
count_Pages++;
|
||||
@@ -306,7 +375,7 @@ void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)
|
||||
if (len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Halt error");
|
||||
//OnError(3);
|
||||
OnError(3);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1143,14 +1212,14 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
|
||||
if(!len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Can't select card");
|
||||
//OnError(1);
|
||||
OnError(1);
|
||||
return;
|
||||
};
|
||||
|
||||
if(mifare_desfire_des_auth1(cuid, dataout)){
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Authentication part1: Fail.");
|
||||
//OnError(4);
|
||||
OnError(4);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1173,7 +1242,7 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){
|
||||
if( isOK) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED)
|
||||
Dbprintf("Authentication part2: Failed");
|
||||
//OnError(4);
|
||||
OnError(4);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "mifaredesfire.h"
|
||||
#include "des.h"
|
||||
#include "BigBuf.h"
|
||||
|
||||
#define MAX_APPLICATION_COUNT 28
|
||||
#define MAX_FILE_COUNT 16
|
||||
@@ -23,7 +24,7 @@ bool InitDesfireCard(){
|
||||
|
||||
iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf;
|
||||
|
||||
iso14a_set_tracing(TRUE);
|
||||
set_tracing(TRUE);
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
int len = iso14443a_select_card(NULL,card,NULL);
|
||||
@@ -65,7 +66,7 @@ void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){
|
||||
}
|
||||
|
||||
if ( flags & CLEARTRACE ){
|
||||
iso14a_clear_trace();
|
||||
clear_trace();
|
||||
}
|
||||
|
||||
if ( flags & INIT ){
|
||||
@@ -109,8 +110,8 @@ void MifareDesfireGetInformation(){
|
||||
PCB == 0x0A because sending CID byte.
|
||||
CID == 0x00 first card?
|
||||
*/
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
clear_trace();
|
||||
set_tracing(TRUE);
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
// card select - information
|
||||
@@ -434,8 +435,8 @@ int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){
|
||||
size_t wrappedLen = 0;
|
||||
uint8_t wCmd[USB_CMD_DATA_SIZE] = {0};
|
||||
|
||||
uint8_t *resp = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET;
|
||||
uint8_t *resp_par = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
|
||||
uint8_t resp[MAX_FRAME_SIZE];
|
||||
uint8_t par[MAX_PARITY_SIZE];
|
||||
|
||||
wrappedLen = CreateAPDU( cmd, cmd_len, wCmd);
|
||||
|
||||
@@ -444,7 +445,7 @@ int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){
|
||||
}
|
||||
ReaderTransmit( wCmd, wrappedLen, NULL);
|
||||
|
||||
len = ReaderReceive(resp, resp_par);
|
||||
len = ReaderReceive(resp, par);
|
||||
|
||||
if( len == 0x00 ){
|
||||
if (MF_DBGLEVEL >= 4) {
|
||||
|
||||
@@ -94,6 +94,8 @@ CMDSRCS = nonce2key/crapto1.c\
|
||||
cmdhficlass.c \
|
||||
cmdhfmf.c \
|
||||
cmdhfmfu.c \
|
||||
cmdhfmfdes.c \
|
||||
cmdhftopaz.c \
|
||||
cmdhw.c \
|
||||
cmdlf.c \
|
||||
cmdlfio.c \
|
||||
|
||||
+210
-206
File diff suppressed because it is too large
Load Diff
@@ -64,12 +64,16 @@ int CmdThreshold(const char *Cmd);
|
||||
int CmdDirectionalThreshold(const char *Cmd);
|
||||
int CmdZerocrossings(const char *Cmd);
|
||||
int CmdIndalaDecode(const char *Cmd);
|
||||
int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo);
|
||||
int ASKbiphaseDemod(const char *Cmd, bool verbose);
|
||||
int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch);
|
||||
int ASKrawDemod(const char *Cmd, bool verbose);
|
||||
int FSKrawDemod(const char *Cmd, bool verbose);
|
||||
int PSKDemod(const char *Cmd, bool verbose);
|
||||
int NRZrawDemod(const char *Cmd, bool verbose);
|
||||
void printEM410x(uint32_t hi, uint64_t id);
|
||||
int getSamples(const char *Cmd, bool silent);
|
||||
|
||||
|
||||
#define MAX_DEMOD_BUF_LEN (1024*128)
|
||||
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
|
||||
|
||||
+177
-62
@@ -23,6 +23,8 @@
|
||||
#include "cmdhficlass.h"
|
||||
#include "cmdhfmf.h"
|
||||
#include "cmdhfmfu.h"
|
||||
#include "cmdhfmfdes.h"
|
||||
#include "cmdhftopaz.h"
|
||||
#include "protocols.h"
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
@@ -141,6 +143,26 @@ void annotateIso15693(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void annotateTopaz(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
||||
{
|
||||
switch(cmd[0]) {
|
||||
case TOPAZ_REQA :snprintf(exp, size, "REQA");break;
|
||||
case TOPAZ_WUPA :snprintf(exp, size, "WUPA");break;
|
||||
case TOPAZ_RID :snprintf(exp, size, "RID");break;
|
||||
case TOPAZ_RALL :snprintf(exp, size, "RALL");break;
|
||||
case TOPAZ_READ :snprintf(exp, size, "READ");break;
|
||||
case TOPAZ_WRITE_E :snprintf(exp, size, "WRITE-E");break;
|
||||
case TOPAZ_WRITE_NE :snprintf(exp, size, "WRITE-NE");break;
|
||||
case TOPAZ_RSEG :snprintf(exp, size, "RSEG");break;
|
||||
case TOPAZ_READ8 :snprintf(exp, size, "READ8");break;
|
||||
case TOPAZ_WRITE_E8 :snprintf(exp, size, "WRITE-E8");break;
|
||||
case TOPAZ_WRITE_NE8 :snprintf(exp, size, "WRITE-NE8");break;
|
||||
default: snprintf(exp,size,"?"); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
06 00 = INITIATE
|
||||
0E xx = SELECT ID (xx = Chip-ID)
|
||||
@@ -172,7 +194,34 @@ void annotateIso14443b(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief iso14443B_CRC_Ok Checks CRC in command or response
|
||||
* @brief iso14443A_CRC_check Checks CRC in command or response
|
||||
* @param isResponse
|
||||
* @param data
|
||||
* @param len
|
||||
* @return 0 : CRC-command, CRC not ok
|
||||
* 1 : CRC-command, CRC ok
|
||||
* 2 : Not crc-command
|
||||
*/
|
||||
|
||||
uint8_t iso14443A_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
|
||||
{
|
||||
uint8_t b1,b2;
|
||||
|
||||
if(len <= 2) return 2;
|
||||
|
||||
if(isResponse & (len < 6)) return 2;
|
||||
|
||||
ComputeCrc14443(CRC_14443_A, data, len-2, &b1, &b2);
|
||||
if (b1 != data[len-2] || b2 != data[len-1]) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief iso14443B_CRC_check Checks CRC in command or response
|
||||
* @param isResponse
|
||||
* @param data
|
||||
* @param len
|
||||
@@ -190,8 +239,9 @@ uint8_t iso14443B_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
|
||||
ComputeCrc14443(CRC_14443_B, data, len-2, &b1, &b2);
|
||||
if(b1 != data[len-2] || b2 != data[len-1]) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -255,11 +305,66 @@ uint8_t iclass_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles)
|
||||
|
||||
bool is_last_record(uint16_t tracepos, uint8_t *trace, uint16_t traceLen)
|
||||
{
|
||||
return(tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) >= traceLen);
|
||||
}
|
||||
|
||||
|
||||
bool next_record_is_response(uint16_t tracepos, uint8_t *trace)
|
||||
{
|
||||
uint16_t next_records_datalen = *((uint16_t *)(trace + tracepos + sizeof(uint32_t) + sizeof(uint16_t)));
|
||||
|
||||
return(next_records_datalen & 0x8000);
|
||||
}
|
||||
|
||||
|
||||
bool merge_topaz_reader_frames(uint32_t timestamp, uint32_t *duration, uint16_t *tracepos, uint16_t traceLen, uint8_t *trace, uint8_t *frame, uint8_t *topaz_reader_command, uint16_t *data_len)
|
||||
{
|
||||
|
||||
#define MAX_TOPAZ_READER_CMD_LEN 16
|
||||
|
||||
uint32_t last_timestamp = timestamp + *duration;
|
||||
|
||||
if ((*data_len != 1) || (frame[0] == TOPAZ_WUPA) || (frame[0] == TOPAZ_REQA)) return false;
|
||||
|
||||
memcpy(topaz_reader_command, frame, *data_len);
|
||||
|
||||
while (!is_last_record(*tracepos, trace, traceLen) && !next_record_is_response(*tracepos, trace)) {
|
||||
uint32_t next_timestamp = *((uint32_t *)(trace + *tracepos));
|
||||
*tracepos += sizeof(uint32_t);
|
||||
uint16_t next_duration = *((uint16_t *)(trace + *tracepos));
|
||||
*tracepos += sizeof(uint16_t);
|
||||
uint16_t next_data_len = *((uint16_t *)(trace + *tracepos)) & 0x7FFF;
|
||||
*tracepos += sizeof(uint16_t);
|
||||
uint8_t *next_frame = (trace + *tracepos);
|
||||
*tracepos += next_data_len;
|
||||
if ((next_data_len == 1) && (*data_len + next_data_len <= MAX_TOPAZ_READER_CMD_LEN)) {
|
||||
memcpy(topaz_reader_command + *data_len, next_frame, next_data_len);
|
||||
*data_len += next_data_len;
|
||||
last_timestamp = next_timestamp + next_duration;
|
||||
} else {
|
||||
// rewind and exit
|
||||
*tracepos = *tracepos - next_data_len - sizeof(uint16_t) - sizeof(uint16_t) - sizeof(uint32_t);
|
||||
break;
|
||||
}
|
||||
uint16_t next_parity_len = (next_data_len-1)/8 + 1;
|
||||
*tracepos += next_parity_len;
|
||||
}
|
||||
|
||||
*duration = last_timestamp - timestamp;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles, bool markCRCBytes)
|
||||
{
|
||||
bool isResponse;
|
||||
uint16_t duration, data_len, parity_len;
|
||||
|
||||
uint16_t data_len, parity_len;
|
||||
uint32_t duration;
|
||||
uint8_t topaz_reader_command[9];
|
||||
uint32_t timestamp, first_timestamp, EndOfTransmissionTimestamp;
|
||||
char explanation[30] = {0};
|
||||
|
||||
@@ -290,29 +395,31 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
||||
uint8_t *parityBytes = trace + tracepos;
|
||||
tracepos += parity_len;
|
||||
|
||||
if (protocol == TOPAZ && !isResponse) {
|
||||
// topaz reader commands come in 1 or 9 separate frames with 7 or 8 Bits each.
|
||||
// merge them:
|
||||
if (merge_topaz_reader_frames(timestamp, &duration, &tracepos, traceLen, trace, frame, topaz_reader_command, &data_len)) {
|
||||
frame = topaz_reader_command;
|
||||
}
|
||||
}
|
||||
|
||||
//Check the CRC status
|
||||
uint8_t crcStatus = 2;
|
||||
|
||||
if (data_len > 2) {
|
||||
uint8_t b1, b2;
|
||||
if(protocol == ICLASS)
|
||||
{
|
||||
switch (protocol) {
|
||||
case ICLASS:
|
||||
crcStatus = iclass_CRC_check(isResponse, frame, data_len);
|
||||
|
||||
}else if (protocol == ISO_14443B)
|
||||
{
|
||||
break;
|
||||
case ISO_14443B:
|
||||
case TOPAZ:
|
||||
crcStatus = iso14443B_CRC_check(isResponse, frame, data_len);
|
||||
}
|
||||
else if (protocol == ISO_14443A){//Iso 14443a
|
||||
|
||||
ComputeCrc14443(CRC_14443_A, frame, data_len-2, &b1, &b2);
|
||||
|
||||
if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
|
||||
if(!(isResponse & (data_len < 6)))
|
||||
{
|
||||
crcStatus = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ISO_14443A:
|
||||
crcStatus = iso14443A_CRC_check(isResponse, frame, data_len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
//0 CRC-command, CRC not ok
|
||||
@@ -334,19 +441,22 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
||||
uint8_t parityBits = parityBytes[j>>3];
|
||||
if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
|
||||
snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]);
|
||||
|
||||
} else {
|
||||
snprintf(line[j/16]+(( j % 16) * 4),110, "%02x ", frame[j]);
|
||||
}
|
||||
|
||||
}
|
||||
if(crcStatus == 1)
|
||||
|
||||
if (markCRCBytes) {
|
||||
if(crcStatus == 0 || crcStatus == 1)
|
||||
{//CRC-command
|
||||
char *pos1 = line[(data_len-2)/16]+(((data_len-2) % 16) * 4)-1;
|
||||
char *pos1 = line[(data_len-2)/16]+(((data_len-2) % 16) * 4);
|
||||
(*pos1) = '[';
|
||||
char *pos2 = line[(data_len)/16]+(((data_len) % 16) * 4)-2;
|
||||
(*pos2) = ']';
|
||||
char *pos2 = line[(data_len)/16]+(((data_len) % 16) * 4);
|
||||
sprintf(pos2, "%c", ']');
|
||||
}
|
||||
}
|
||||
|
||||
if(data_len == 0)
|
||||
{
|
||||
if(data_len == 0){
|
||||
@@ -361,18 +471,19 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
||||
|
||||
if(!isResponse)
|
||||
{
|
||||
if(protocol == ICLASS)
|
||||
annotateIclass(explanation,sizeof(explanation),frame,data_len);
|
||||
else if (protocol == ISO_14443A)
|
||||
annotateIso14443a(explanation,sizeof(explanation),frame,data_len);
|
||||
else if(protocol == ISO_14443B)
|
||||
annotateIso14443b(explanation,sizeof(explanation),frame,data_len);
|
||||
switch(protocol) {
|
||||
case ICLASS: annotateIclass(explanation,sizeof(explanation),frame,data_len); break;
|
||||
case ISO_14443A: annotateIso14443a(explanation,sizeof(explanation),frame,data_len); break;
|
||||
case ISO_14443B: annotateIso14443b(explanation,sizeof(explanation),frame,data_len); break;
|
||||
case TOPAZ: annotateTopaz(explanation,sizeof(explanation),frame,data_len); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
int num_lines = MIN((data_len - 1)/16 + 1, 16);
|
||||
for (int j = 0; j < num_lines ; j++) {
|
||||
if (j == 0) {
|
||||
PrintAndLog(" %9d | %9d | %s | %-64s| %s| %s",
|
||||
PrintAndLog(" %10d | %10d | %s |%-64s | %s| %s",
|
||||
(timestamp - first_timestamp),
|
||||
(EndOfTransmissionTimestamp - first_timestamp),
|
||||
(isResponse ? "Tag" : "Rdr"),
|
||||
@@ -387,20 +498,16 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
||||
}
|
||||
}
|
||||
|
||||
if (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen) return traceLen;
|
||||
if (is_last_record(tracepos, trace, traceLen)) return traceLen;
|
||||
|
||||
bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
|
||||
|
||||
if (showWaitCycles && !isResponse && next_isResponse) {
|
||||
if (showWaitCycles && !isResponse && next_record_is_response(tracepos, trace)) {
|
||||
uint32_t next_timestamp = *((uint32_t *)(trace + tracepos));
|
||||
if (next_timestamp != 0x44444444) {
|
||||
PrintAndLog(" %9d | %9d | %s | fdt (Frame Delay Time): %d",
|
||||
(EndOfTransmissionTimestamp - first_timestamp),
|
||||
(next_timestamp - first_timestamp),
|
||||
" ",
|
||||
(next_timestamp - EndOfTransmissionTimestamp));
|
||||
}
|
||||
}
|
||||
|
||||
return tracepos;
|
||||
}
|
||||
@@ -409,34 +516,35 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
||||
int CmdHFList(const char *Cmd)
|
||||
{
|
||||
bool showWaitCycles = false;
|
||||
bool markCRCBytes = false;
|
||||
char type[40] = {0};
|
||||
int tlen = param_getstr(Cmd,0,type);
|
||||
char param = param_getchar(Cmd, 1);
|
||||
char param1 = param_getchar(Cmd, 1);
|
||||
char param2 = param_getchar(Cmd, 2);
|
||||
bool errors = false;
|
||||
uint8_t protocol = 0;
|
||||
//Validate params
|
||||
if(tlen == 0)
|
||||
{
|
||||
|
||||
if(tlen == 0) {
|
||||
errors = true;
|
||||
}
|
||||
if(param == 'h' || (param !=0 && param != 'f'))
|
||||
{
|
||||
|
||||
if(param1 == 'h'
|
||||
|| (param1 != 0 && param1 != 'f' && param1 != 'c')
|
||||
|| (param2 != 0 && param2 != 'f' && param2 != 'c')) {
|
||||
errors = true;
|
||||
}
|
||||
if(!errors)
|
||||
{
|
||||
if(strcmp(type, "iclass") == 0)
|
||||
{
|
||||
|
||||
if(!errors) {
|
||||
if(strcmp(type, "iclass") == 0) {
|
||||
protocol = ICLASS;
|
||||
}else if(strcmp(type, "14a") == 0)
|
||||
{
|
||||
} else if(strcmp(type, "14a") == 0) {
|
||||
protocol = ISO_14443A;
|
||||
}
|
||||
else if(strcmp(type, "14b") == 0)
|
||||
{
|
||||
} else if(strcmp(type, "14b") == 0) {
|
||||
protocol = ISO_14443B;
|
||||
}else if(strcmp(type,"raw")== 0)
|
||||
{
|
||||
} else if(strcmp(type,"topaz")== 0) {
|
||||
protocol = TOPAZ;
|
||||
} else if(strcmp(type,"raw")== 0) {
|
||||
protocol = -1;//No crc, no annotations
|
||||
}else{
|
||||
errors = true;
|
||||
@@ -445,13 +553,15 @@ int CmdHFList(const char *Cmd)
|
||||
|
||||
if (errors) {
|
||||
PrintAndLog("List protocol data in trace buffer.");
|
||||
PrintAndLog("Usage: hf list <protocol> [f]");
|
||||
PrintAndLog("Usage: hf list <protocol> [f][c]");
|
||||
PrintAndLog(" f - show frame delay times as well");
|
||||
PrintAndLog(" c - mark CRC bytes");
|
||||
PrintAndLog("Supported <protocol> values:");
|
||||
PrintAndLog(" raw - just show raw data without annotations");
|
||||
PrintAndLog(" 14a - interpret data as iso14443a communications");
|
||||
PrintAndLog(" 14b - interpret data as iso14443b communications");
|
||||
PrintAndLog(" iclass - interpret data as iclass communications");
|
||||
PrintAndLog(" topaz - interpret data as topaz communications");
|
||||
PrintAndLog("");
|
||||
PrintAndLog("example: hf list 14a f");
|
||||
PrintAndLog("example: hf list iclass");
|
||||
@@ -459,10 +569,13 @@ int CmdHFList(const char *Cmd)
|
||||
}
|
||||
|
||||
|
||||
if (param == 'f') {
|
||||
if (param1 == 'f' || param2 == 'f') {
|
||||
showWaitCycles = true;
|
||||
}
|
||||
|
||||
if (param1 == 'c' || param2 == 'c') {
|
||||
markCRCBytes = true;
|
||||
}
|
||||
|
||||
uint8_t *trace;
|
||||
uint16_t tracepos = 0;
|
||||
@@ -496,7 +609,7 @@ int CmdHFList(const char *Cmd)
|
||||
|
||||
while(tracepos < traceLen)
|
||||
{
|
||||
tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles);
|
||||
tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles, markCRCBytes);
|
||||
}
|
||||
|
||||
free(trace);
|
||||
@@ -514,9 +627,11 @@ static command_t CommandTable[] =
|
||||
{"legic", CmdHFLegic, 0, "{ LEGIC RFIDs... }"},
|
||||
{"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"},
|
||||
{"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"},
|
||||
{"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"},
|
||||
{"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"},
|
||||
{"list", CmdHFList, 1, "List protocol data in trace buffer"},
|
||||
{"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"},
|
||||
{"mfdes", CmdHFMFDes, 1, "{ MIFARE Desfire RFIDs... }"},
|
||||
{"topaz", CmdHFTopaz, 1, "{ TOPAZ (NFC Type 1) RFIDs... }"},
|
||||
{"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"},
|
||||
{"list", CmdHFList, 1, "List protocol data in trace buffer"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
||||
+44
-14
@@ -140,7 +140,7 @@ int CmdHF14AReader(const char *Cmd)
|
||||
iso14a_card_select_t card;
|
||||
memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
|
||||
|
||||
uint64_t select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS
|
||||
uint64_t select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
|
||||
|
||||
if(select_status == 0) {
|
||||
PrintAndLog("iso14443a card select failed");
|
||||
@@ -152,6 +152,18 @@ int CmdHF14AReader(const char *Cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(select_status == 3) {
|
||||
PrintAndLog("Card doesn't support standard iso14443-3 anticollision");
|
||||
PrintAndLog("ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
|
||||
// disconnect
|
||||
c.arg[0] = 0;
|
||||
c.arg[1] = 0;
|
||||
c.arg[2] = 0;
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
PrintAndLog("ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
|
||||
PrintAndLog(" UID : %s", sprint_hex(card.uid, card.uidlen));
|
||||
PrintAndLog(" SAK : %02x [%d]", card.sak, resp.arg[0]);
|
||||
@@ -497,16 +509,18 @@ int CmdHF14ASnoop(const char *Cmd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CmdHF14ACmdRaw(const char *cmd) {
|
||||
UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}};
|
||||
uint8_t reply=1;
|
||||
uint8_t crc=0;
|
||||
uint8_t power=0;
|
||||
uint8_t active=0;
|
||||
uint8_t active_select=0;
|
||||
bool reply=1;
|
||||
bool crc = FALSE;
|
||||
bool power = FALSE;
|
||||
bool active = FALSE;
|
||||
bool active_select = FALSE;
|
||||
uint16_t numbits=0;
|
||||
bool bTimeout = FALSE;
|
||||
uint32_t timeout=0;
|
||||
uint8_t bTimeout=0;
|
||||
bool topazmode = FALSE;
|
||||
char buf[5]="";
|
||||
int i=0;
|
||||
uint8_t data[USB_CMD_DATA_SIZE];
|
||||
@@ -522,9 +536,11 @@ int CmdHF14ACmdRaw(const char *cmd) {
|
||||
PrintAndLog(" -s active signal field ON with select");
|
||||
PrintAndLog(" -b number of bits to send. Useful for send partial byte");
|
||||
PrintAndLog(" -t timeout in ms");
|
||||
PrintAndLog(" -T use Topaz protocol to send command");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// strip
|
||||
while (*cmd==' ' || *cmd=='\t') cmd++;
|
||||
|
||||
@@ -533,19 +549,19 @@ int CmdHF14ACmdRaw(const char *cmd) {
|
||||
if (cmd[i]=='-') {
|
||||
switch (cmd[i+1]) {
|
||||
case 'r':
|
||||
reply=0;
|
||||
reply = FALSE;
|
||||
break;
|
||||
case 'c':
|
||||
crc=1;
|
||||
crc = TRUE;
|
||||
break;
|
||||
case 'p':
|
||||
power=1;
|
||||
power = TRUE;
|
||||
break;
|
||||
case 'a':
|
||||
active=1;
|
||||
active = TRUE;
|
||||
break;
|
||||
case 's':
|
||||
active_select=1;
|
||||
active_select = TRUE;
|
||||
break;
|
||||
case 'b':
|
||||
sscanf(cmd+i+2,"%d",&temp);
|
||||
@@ -555,13 +571,16 @@ int CmdHF14ACmdRaw(const char *cmd) {
|
||||
i-=2;
|
||||
break;
|
||||
case 't':
|
||||
bTimeout=1;
|
||||
bTimeout = TRUE;
|
||||
sscanf(cmd+i+2,"%d",&temp);
|
||||
timeout = temp;
|
||||
i+=3;
|
||||
while(cmd[i]!=' ' && cmd[i]!='\0') { i++; }
|
||||
i-=2;
|
||||
break;
|
||||
case 'T':
|
||||
topazmode = TRUE;
|
||||
break;
|
||||
default:
|
||||
PrintAndLog("Invalid option");
|
||||
return 0;
|
||||
@@ -591,10 +610,15 @@ int CmdHF14ACmdRaw(const char *cmd) {
|
||||
PrintAndLog("Invalid char on input");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(crc && datalen>0 && datalen<sizeof(data)-2)
|
||||
{
|
||||
uint8_t first, second;
|
||||
if (topazmode) {
|
||||
ComputeCrc14443(CRC_14443_B, data, datalen, &first, &second);
|
||||
} else {
|
||||
ComputeCrc14443(CRC_14443_A, data, datalen, &first, &second);
|
||||
}
|
||||
data[datalen++] = first;
|
||||
data[datalen++] = second;
|
||||
}
|
||||
@@ -607,7 +631,7 @@ int CmdHF14ACmdRaw(const char *cmd) {
|
||||
}
|
||||
|
||||
if(bTimeout){
|
||||
#define MAX_TIMEOUT 40542464 // (2^32-1) * (8*16) / 13560000Hz * 1000ms/s =
|
||||
#define MAX_TIMEOUT 40542464 // = (2^32-1) * (8*16) / 13560000Hz * 1000ms/s
|
||||
c.arg[0] |= ISO14A_SET_TIMEOUT;
|
||||
if(timeout > MAX_TIMEOUT) {
|
||||
timeout = MAX_TIMEOUT;
|
||||
@@ -615,11 +639,16 @@ int CmdHF14ACmdRaw(const char *cmd) {
|
||||
}
|
||||
c.arg[2] = 13560000 / 1000 / (8*16) * timeout; // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us)
|
||||
}
|
||||
|
||||
if(power)
|
||||
c.arg[0] |= ISO14A_NO_DISCONNECT;
|
||||
|
||||
if(datalen>0)
|
||||
c.arg[0] |= ISO14A_RAW;
|
||||
|
||||
if(topazmode)
|
||||
c.arg[0] |= ISO14A_TOPAZMODE;
|
||||
|
||||
// Max buffer is USB_CMD_DATA_SIZE
|
||||
c.arg[1] = (datalen & 0xFFFF) | (numbits << 16);
|
||||
memcpy(c.d.asBytes,data,datalen);
|
||||
@@ -635,6 +664,7 @@ int CmdHF14ACmdRaw(const char *cmd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void waitCmd(uint8_t iSelect)
|
||||
{
|
||||
uint8_t *recv;
|
||||
|
||||
+4
-3
@@ -12,7 +12,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <openssl/des.h>
|
||||
//#include <openssl/des.h>
|
||||
#include "loclass/des.h"
|
||||
#include "cmdmain.h"
|
||||
#include "proxmark3.h"
|
||||
#include "../include/common.h"
|
||||
@@ -236,7 +237,7 @@ char * GetCardSizeStr( uint8_t fsize ){
|
||||
uint16_t lsize = 1 << (fsize >>1);
|
||||
|
||||
// is LSB set?
|
||||
if ( fsize & (1 << 0 ) )
|
||||
if ( fsize & 1 )
|
||||
sprintf(retStr, "0x%02X (%d - %d bytes)",fsize, usize, lsize);
|
||||
else
|
||||
sprintf(retStr, "0x%02X (%d bytes)", fsize, lsize);
|
||||
@@ -251,7 +252,7 @@ char * GetProtocolStr(uint8_t id){
|
||||
if ( id == 0x05)
|
||||
sprintf(retStr,"0x%02X (ISO 14443-3, 14443-4)", id);
|
||||
else
|
||||
sprintf(retStr,"0x%02X", id);
|
||||
sprintf(retStr,"0x%02X (Unknown)", id);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
+18
-6
@@ -7,7 +7,6 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// High frequency MIFARE ULTRALIGHT (C) commands
|
||||
//-----------------------------------------------------------------------------
|
||||
//#include <openssl/des.h>
|
||||
#include "loclass/des.h"
|
||||
#include "cmdhfmfu.h"
|
||||
#include "cmdhfmf.h"
|
||||
@@ -391,7 +390,7 @@ int CmdHF14AMfucAuth(const char *Cmd){
|
||||
//Change key to user defined one
|
||||
if (cmdp == 'k' || cmdp == 'K'){
|
||||
keyNo = param_get8(Cmd, 1);
|
||||
if(keyNo >= 4) errors = true;
|
||||
if(keyNo > 4) errors = true;
|
||||
}
|
||||
|
||||
if (cmdp == 'h' || cmdp == 'H') {
|
||||
@@ -430,7 +429,6 @@ int CmdHF14AMfucAuth(const char *Cmd){
|
||||
uint8_t * data= resp.d.asBytes;
|
||||
|
||||
if (isOK){
|
||||
PrintAndLog("enc(RndB):%s", sprint_hex(data+1, 8));
|
||||
memcpy(enc_random_b,data+1,8);
|
||||
} else {
|
||||
PrintAndLog("Auth failed");
|
||||
@@ -440,10 +438,7 @@ int CmdHF14AMfucAuth(const char *Cmd){
|
||||
PrintAndLog("Command execute timeout");
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t iv[8] = { 0 };
|
||||
// Do we need random ? Right now we use all ones, is that random enough ?
|
||||
// DES_random_key(&RndA);
|
||||
|
||||
PrintAndLog(" RndA :%s",sprint_hex(random_a, 8));
|
||||
PrintAndLog(" e_RndB:%s",sprint_hex(enc_random_b, 8));
|
||||
@@ -490,6 +485,23 @@ int CmdHF14AMfucAuth(const char *Cmd){
|
||||
|
||||
if (isOK){
|
||||
PrintAndLog("enc(RndA'):%s", sprint_hex(data2+1, 8));
|
||||
|
||||
uint8_t foo[8] = { 0 };
|
||||
uint8_t bar[8] = { 0 };
|
||||
memcpy(foo, data2+1, 8);
|
||||
des3_set2key_enc(&ctx, key);
|
||||
|
||||
des3_crypt_cbc(&ctx // des3_context *ctx
|
||||
, DES_DECRYPT // int mode
|
||||
, 8 // size_t length
|
||||
, enc_random_b // unsigned char iv[8]
|
||||
, foo // const unsigned char *input
|
||||
, bar // unsigned char *output
|
||||
);
|
||||
|
||||
PrintAndLog("BAR:%s",sprint_hex(bar, 8));
|
||||
|
||||
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
|
||||
+4
-1
@@ -1,6 +1,9 @@
|
||||
#include "cmdhfmf.h"
|
||||
#include "cmdhf14a.h"
|
||||
|
||||
#ifndef CMDHFMFU_H__
|
||||
#define CMDHFMFU_H__
|
||||
|
||||
//standard ultralight
|
||||
int CmdHF14AMfUWrBl(const char *Cmd);
|
||||
int CmdHF14AMfURdBl(const char *Cmd);
|
||||
@@ -14,6 +17,6 @@ int CmdHF14AMfucAuth(const char *Cmd);
|
||||
int CmdHF14AMfUDump(const char *Cmd);
|
||||
void rol (uint8_t *data, const size_t len);
|
||||
|
||||
|
||||
int CmdHFMFUltra(const char *Cmd);
|
||||
int CmdHF14AMfUInfo(const char *Cmd);
|
||||
#endif
|
||||
|
||||
+17
-10
@@ -362,6 +362,7 @@ int usage_lf_read()
|
||||
PrintAndLog("Usage: lf read");
|
||||
PrintAndLog("Options: ");
|
||||
PrintAndLog(" h This help");
|
||||
PrintAndLog(" s silent run no printout");
|
||||
PrintAndLog("This function takes no arguments. ");
|
||||
PrintAndLog("Use 'lf config' to set parameters.");
|
||||
return 0;
|
||||
@@ -481,13 +482,15 @@ int CmdLFSetConfig(const char *Cmd)
|
||||
int CmdLFRead(const char *Cmd)
|
||||
{
|
||||
|
||||
uint8_t cmdp =0;
|
||||
if(param_getchar(Cmd, cmdp) == 'h')
|
||||
uint8_t cmdp = 0;
|
||||
bool arg1 = false;
|
||||
if (param_getchar(Cmd, cmdp) == 'h')
|
||||
{
|
||||
return usage_lf_read();
|
||||
}
|
||||
if (param_getchar(Cmd, cmdp) == 's') arg1 = true; //suppress print
|
||||
//And ship it to device
|
||||
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K};
|
||||
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {arg1,0,0}};
|
||||
SendCommand(&c);
|
||||
//WaitForResponse(CMD_ACK,NULL);
|
||||
if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
|
||||
@@ -1041,57 +1044,61 @@ int CmdLFfind(const char *Cmd)
|
||||
return 0;
|
||||
}
|
||||
if (cmdp == 'u' || cmdp == 'U') testRaw = 'u';
|
||||
|
||||
|
||||
PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag");
|
||||
PrintAndLog("False Positives ARE possible\n");
|
||||
PrintAndLog("\nChecking for known tags:\n");
|
||||
|
||||
|
||||
ans=CmdFSKdemodIO("");
|
||||
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid IO Prox ID Found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
ans=CmdFSKdemodPyramid("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid Pyramid ID Found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
ans=CmdFSKdemodParadox("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid Paradox ID Found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
ans=CmdFSKdemodAWID("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid AWID ID Found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
ans=CmdFSKdemodHID("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid HID Prox ID Found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
//add psk and indala
|
||||
ans=CmdIndalaDecode("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid Indala ID Found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ans=CmdAskEM410xDemod("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid EM410x ID Found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ans=CmdG_Prox_II_Demod("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid G Prox II ID Found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLog("\nNo Known Tags Found!\n");
|
||||
if (testRaw=='u' || testRaw=='U'){
|
||||
//test unknown tag formats (raw mode)
|
||||
@@ -1170,7 +1177,7 @@ static command_t CommandTable[] =
|
||||
{"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"},
|
||||
{"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
|
||||
{"indalaclone", CmdIndalaClone, 0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"},
|
||||
{"read", CmdLFRead, 0, "Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
|
||||
{"read", CmdLFRead, 0, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
|
||||
{"search", CmdLFfind, 1, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) - 'u' to search for unknown tags"},
|
||||
{"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"},
|
||||
{"simask", CmdLFaskSim, 0, "[clock] [invert <1|0>] [manchester/raw <'m'|'r'>] [msg separator 's'] [d <hexdata>] -- Simulate LF ASK tag from demodbuffer or input"},
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user