Merge pull request #33 from pwpiwi/master

Support for bigger iso14443 frames (including parity calculation)
unify hw tune and data tune
fix hf epa cnonces
adapt hf iclass list to new trace format
This commit is contained in:
pwpiwi 2014-12-20 21:56:12 +01:00
commit e688629475
20 changed files with 953 additions and 981 deletions

View file

@ -36,7 +36,8 @@
// is the order in which they go out on the wire.
//=============================================================================
uint8_t ToSend[512];
#define TOSEND_BUFFER_SIZE (9*MAX_FRAME_SIZE + 1 + 1 + 2) // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits
uint8_t ToSend[TOSEND_BUFFER_SIZE];
int ToSendMax;
static int ToSendBit;
struct common_area common_area __attribute__((section(".commonarea")));
@ -67,7 +68,7 @@ void ToSendStuffBit(int b)
ToSendBit++;
if(ToSendBit >= sizeof(ToSend)) {
if(ToSendMax >= sizeof(ToSend)) {
ToSendBit = 0;
DbpString("ToSendStuffBit overflowed!");
}
@ -195,15 +196,11 @@ int AvgAdc(int ch) // was static - merlok
void MeasureAntennaTuning(void)
{
uint8_t *dest = (uint8_t *)BigBuf+FREE_BUFFER_OFFSET;
uint8_t LF_Results[256];
int i, adcval = 0, peak = 0, peakv = 0, peakf = 0; //ptr = 0
int vLf125 = 0, vLf134 = 0, vHf = 0; // in mV
// UsbCommand c;
LED_B_ON();
DbpString("Measuring antenna characteristics, please wait...");
memset(dest,0,FREE_BUFFER_SIZE);
LED_B_ON();
/*
* Sweeps the useful LF range of the proxmark from
@ -216,7 +213,7 @@ void MeasureAntennaTuning(void)
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
for (i=255; i>19; i--) {
for (i=255; i>=19; i--) {
WDT_HIT();
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
SpinDelay(20);
@ -226,16 +223,18 @@ void MeasureAntennaTuning(void)
if (i==95) vLf125 = adcval; // voltage at 125Khz
if (i==89) vLf134 = adcval; // voltage at 134Khz
dest[i] = adcval>>8; // scale int to fit in byte for graphing purposes
if(dest[i] > peak) {
LF_Results[i] = adcval>>8; // scale int to fit in byte for graphing purposes
if(LF_Results[i] > peak) {
peakv = adcval;
peak = dest[i];
peak = LF_Results[i];
peakf = i;
//ptr = i;
}
}
LED_A_ON();
for (i=18; i >= 0; i--) LF_Results[i] = 0;
LED_A_ON();
// Let the FPGA drive the high-frequency antenna around 13.56 MHz.
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
@ -244,18 +243,11 @@ void MeasureAntennaTuning(void)
// can measure voltages up to 33000 mV
vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10;
// c.cmd = CMD_MEASURED_ANTENNA_TUNING;
// c.arg[0] = (vLf125 << 0) | (vLf134 << 16);
// c.arg[1] = vHf;
// c.arg[2] = peakf | (peakv << 16);
DbpString("Measuring complete, sending report back to host");
cmd_send(CMD_MEASURED_ANTENNA_TUNING,vLf125|(vLf134<<16),vHf,peakf|(peakv<<16),0,0);
// UsbSendPacket((uint8_t *)&c, sizeof(c));
cmd_send(CMD_MEASURED_ANTENNA_TUNING,vLf125|(vLf134<<16),vHf,peakf|(peakv<<16),LF_Results,256);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_A_OFF();
LED_B_OFF();
return;
LED_A_OFF();
LED_B_OFF();
return;
}
void MeasureAntennaTuningHf(void)

View file

@ -20,18 +20,22 @@
// The large multi-purpose buffer, typically used to hold A/D samples,
// maybe processed in some way.
uint32_t BigBuf[10000];
// BIG CHANGE - UNDERSTAND THIS BEFORE WE COMMIT
#define TRACE_OFFSET 0
#define TRACE_SIZE 3000
#define RECV_CMD_OFFSET 3032
#define RECV_CMD_SIZE 64
#define RECV_RES_OFFSET 3096
#define RECV_RES_SIZE 64
#define DMA_BUFFER_OFFSET 3160
#define DMA_BUFFER_SIZE 4096
#define FREE_BUFFER_OFFSET 7256
#define FREE_BUFFER_SIZE 2744
#define BIGBUF_SIZE 40000
uint32_t BigBuf[BIGBUF_SIZE / sizeof(uint32_t)];
#define TRACE_OFFSET 0
#define TRACE_SIZE 3000
#define RECV_CMD_OFFSET (TRACE_OFFSET + TRACE_SIZE)
#define MAX_FRAME_SIZE 256
#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 1)/ 8)
#define RECV_CMD_PAR_OFFSET (RECV_CMD_OFFSET + MAX_FRAME_SIZE)
#define RECV_RESP_OFFSET (RECV_CMD_PAR_OFFSET + MAX_PARITY_SIZE)
#define RECV_RESP_PAR_OFFSET (RECV_RESP_OFFSET + MAX_FRAME_SIZE)
#define CARD_MEMORY_OFFSET (RECV_RESP_PAR_OFFSET + MAX_PARITY_SIZE)
#define CARD_MEMORY_SIZE 4096
#define DMA_BUFFER_OFFSET CARD_MEMORY_OFFSET
#define DMA_BUFFER_SIZE CARD_MEMORY_SIZE
#define FREE_BUFFER_OFFSET (CARD_MEMORY_OFFSET + CARD_MEMORY_SIZE)
#define FREE_BUFFER_SIZE (BIGBUF_SIZE - FREE_BUFFER_OFFSET - 1)
extern const uint8_t OddByteParity[256];
extern uint8_t *trace; // = (uint8_t *) BigBuf;
@ -157,8 +161,8 @@ void RAMFUNC SnoopIso14443a(uint8_t param);
void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data);
void ReaderIso14443a(UsbCommand * c);
// Also used in iclass.c
bool RAMFUNC LogTrace(const uint8_t * btBytes, uint8_t iLen, uint32_t iSamples, uint32_t dwParity, bool readerToTag);
uint32_t GetParity(const uint8_t * pbtCmd, int iLen);
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t len, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *parity);
void iso14a_set_trigger(bool enable);
void iso14a_clear_trace();
void iso14a_set_tracing(bool enable);

View file

@ -108,9 +108,9 @@ size_t EPA_Parse_CardAccess(uint8_t *data,
if (data[index] == 0x31 || data[index] == 0x30) {
// enter the set (skip tag + length)
index += 2;
// extended length
// check for extended length
if ((data[index - 1] & 0x80) != 0) {
index += (data[index] & 0x7F);
index += (data[index-1] & 0x7F);
}
}
// OID
@ -434,7 +434,8 @@ int EPA_Setup()
// send the PPS request
ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL);
uint8_t pps_response[3];
return_code = ReaderReceive(pps_response);
uint8_t pps_response_par[1];
return_code = ReaderReceive(pps_response, pps_response_par);
if (return_code != 3 || pps_response[0] != 0xD0) {
return return_code == 0 ? 2 : return_code;
}

View file

@ -71,14 +71,13 @@ static struct {
int nOutOfCnt;
int OutOfCnt;
int syncBit;
int parityBits;
int samples;
int highCnt;
int swapper;
int counter;
int bitBuffer;
int dropPosition;
uint8_t *output;
uint8_t *output;
} Uart;
static RAMFUNC int OutOfNDecoding(int bit)
@ -137,11 +136,8 @@ static RAMFUNC int OutOfNDecoding(int bit)
if(Uart.byteCnt == 0) {
// Its not straightforward to show single EOFs
// So just leave it and do not return TRUE
Uart.output[Uart.byteCnt] = 0xf0;
Uart.output[0] = 0xf0;
Uart.byteCnt++;
// Calculate the parity bit for the client...
Uart.parityBits = 1;
}
else {
return TRUE;
@ -223,11 +219,6 @@ static RAMFUNC int OutOfNDecoding(int bit)
if(Uart.bitCnt == 8) {
Uart.output[Uart.byteCnt] = (Uart.shiftReg & 0xff);
Uart.byteCnt++;
// Calculate the parity bit for the client...
Uart.parityBits <<= 1;
Uart.parityBits ^= OddByteParity[(Uart.shiftReg & 0xff)];
Uart.bitCnt = 0;
Uart.shiftReg = 0;
}
@ -246,11 +237,6 @@ static RAMFUNC int OutOfNDecoding(int bit)
Uart.dropPosition--;
Uart.output[Uart.byteCnt] = (Uart.dropPosition & 0xff);
Uart.byteCnt++;
// Calculate the parity bit for the client...
Uart.parityBits <<= 1;
Uart.parityBits ^= OddByteParity[(Uart.dropPosition & 0xff)];
Uart.bitCnt = 0;
Uart.shiftReg = 0;
Uart.nOutOfCnt = 0;
@ -311,7 +297,6 @@ static RAMFUNC int OutOfNDecoding(int bit)
Uart.state = STATE_START_OF_COMMUNICATION;
Uart.bitCnt = 0;
Uart.byteCnt = 0;
Uart.parityBits = 0;
Uart.nOutOfCnt = 0;
Uart.OutOfCnt = 4; // Start at 1/4, could switch to 1/256
Uart.dropPosition = 0;
@ -353,7 +338,6 @@ static struct {
int bitCount;
int posCount;
int syncBit;
int parityBits;
uint16_t shiftReg;
int buffer;
int buffer2;
@ -367,7 +351,7 @@ static struct {
SUB_SECOND_HALF,
SUB_BOTH
} sub;
uint8_t *output;
uint8_t *output;
} Demod;
static RAMFUNC int ManchesterDecoding(int v)
@ -420,7 +404,6 @@ static RAMFUNC int ManchesterDecoding(int v)
Demod.sub = SUB_FIRST_HALF;
Demod.bitCount = 0;
Demod.shiftReg = 0;
Demod.parityBits = 0;
Demod.samples = 0;
if(Demod.posCount) {
//if(trigger) LED_A_OFF(); // Not useful in this case...
@ -485,8 +468,6 @@ static RAMFUNC int ManchesterDecoding(int v)
if(Demod.state == DEMOD_SOF_COMPLETE) {
Demod.output[Demod.len] = 0x0f;
Demod.len++;
Demod.parityBits <<= 1;
Demod.parityBits ^= OddByteParity[0x0f];
Demod.state = DEMOD_UNSYNCD;
// error = 0x0f;
return TRUE;
@ -567,11 +548,9 @@ static RAMFUNC int ManchesterDecoding(int v)
// Tag response does not need to be a complete byte!
if(Demod.len > 0 || Demod.bitCount > 0) {
if(Demod.bitCount > 1) { // was > 0, do not interpret last closing bit, is part of EOF
Demod.shiftReg >>= (9 - Demod.bitCount);
Demod.shiftReg >>= (9 - Demod.bitCount); // right align data
Demod.output[Demod.len] = Demod.shiftReg & 0xff;
Demod.len++;
// No parity bit, so just shift a 0
Demod.parityBits <<= 1;
}
Demod.state = DEMOD_UNSYNCD;
@ -608,11 +587,6 @@ static RAMFUNC int ManchesterDecoding(int v)
Demod.shiftReg >>= 1;
Demod.output[Demod.len] = (Demod.shiftReg & 0xff);
Demod.len++;
// FOR ISO15639 PARITY NOT SEND OTA, JUST CALCULATE IT FOR THE CLIENT
Demod.parityBits <<= 1;
Demod.parityBits ^= OddByteParity[(Demod.shiftReg & 0xff)];
Demod.bitCount = 0;
Demod.shiftReg = 0;
}
@ -669,8 +643,8 @@ void RAMFUNC SnoopIClass(void)
// So 32 should be enough!
uint8_t *readerToTagCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
// The response (tag -> reader) that we're receiving.
uint8_t *tagToReaderResponse = (((uint8_t *)BigBuf) + RECV_RES_OFFSET);
uint8_t *tagToReaderResponse = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// reset traceLen to 0
@ -769,10 +743,10 @@ void RAMFUNC SnoopIClass(void)
//if(!LogTrace(Uart.output,Uart.byteCnt, rsamples, Uart.parityBits,TRUE)) break;
//if(!LogTrace(NULL, 0, Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, 0, TRUE)) break;
if(tracing)
{
LogTrace(Uart.output,Uart.byteCnt, (GetCountSspClk()-time_0) << 4, Uart.parityBits,TRUE);
LogTrace(NULL, 0, (GetCountSspClk()-time_0) << 4, 0, TRUE);
if(tracing) {
uint8_t parity[MAX_PARITY_SIZE];
GetParity(Uart.output, Uart.byteCnt, parity);
LogTrace(Uart.output,Uart.byteCnt, (GetCountSspClk()-time_0) << 4, (GetCountSspClk()-time_0) << 4, parity, TRUE);
}
@ -793,10 +767,10 @@ void RAMFUNC SnoopIClass(void)
rsamples = samples - Demod.samples;
LED_B_ON();
if(tracing)
{
LogTrace(Demod.output,Demod.len, (GetCountSspClk()-time_0) << 4 , Demod.parityBits,FALSE);
LogTrace(NULL, 0, (GetCountSspClk()-time_0) << 4, 0, FALSE);
if(tracing) {
uint8_t parity[MAX_PARITY_SIZE];
GetParity(Demod.output, Demod.len, parity);
LogTrace(Demod.output, Demod.len, (GetCountSspClk()-time_0) << 4, (GetCountSspClk()-time_0) << 4, parity, FALSE);
}
@ -1079,7 +1053,7 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader
// + 1720..
uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
memset(receivedCmd, 0x44, RECV_CMD_SIZE);
memset(receivedCmd, 0x44, MAX_FRAME_SIZE);
int len;
// Prepare card messages
@ -1219,14 +1193,13 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader
}
if (tracing) {
LogTrace(receivedCmd,len, (r2t_time-time_0)<< 4, Uart.parityBits,TRUE);
LogTrace(NULL,0, (r2t_time-time_0) << 4, 0,TRUE);
uint8_t parity[MAX_PARITY_SIZE];
GetParity(receivedCmd, len, parity);
LogTrace(receivedCmd,len, (r2t_time-time_0)<< 4, (r2t_time-time_0) << 4, parity, TRUE);
if (respdata != NULL) {
LogTrace(respdata,respsize, (t2r_time-time_0) << 4,SwapBits(GetParity(respdata,respsize),respsize),FALSE);
LogTrace(NULL,0, (t2r_time-time_0) << 4,0,FALSE);
GetParity(respdata, respsize, parity);
LogTrace(respdata, respsize, (t2r_time-time_0) << 4, (t2r_time-time_0) << 4, parity, FALSE);
}
if(!tracing) {
DbpString("Trace full");
@ -1234,7 +1207,7 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader
}
}
memset(receivedCmd, 0x44, RECV_CMD_SIZE);
memset(receivedCmd, 0x44, MAX_FRAME_SIZE);
}
//Dbprintf("%x", cmdsRecvd);
@ -1391,21 +1364,24 @@ void CodeIClassCommand(const uint8_t * cmd, int len)
void ReaderTransmitIClass(uint8_t* frame, int len)
{
int wait = 0;
int samples = 0;
int par = 0;
int wait = 0;
int samples = 0;
// This is tied to other size changes
// uint8_t* frame_addr = ((uint8_t*)BigBuf) + 2024;
CodeIClassCommand(frame,len);
// This is tied to other size changes
// uint8_t* frame_addr = ((uint8_t*)BigBuf) + 2024;
CodeIClassCommand(frame,len);
// Select the card
TransmitIClassCommand(ToSend, ToSendMax, &samples, &wait);
if(trigger)
LED_A_ON();
// Select the card
TransmitIClassCommand(ToSend, ToSendMax, &samples, &wait);
if(trigger)
LED_A_ON();
// Store reader command in buffer
if (tracing) LogTrace(frame,len,rsamples,par,TRUE);
// Store reader command in buffer
if (tracing) {
uint8_t par[MAX_PARITY_SIZE];
GetParity(frame, len, par);
LogTrace(frame, len, rsamples, rsamples, par, TRUE);
}
}
//-----------------------------------------------------------------------------
@ -1464,7 +1440,11 @@ int ReaderReceiveIClass(uint8_t* receivedAnswer)
int samples = 0;
if (!GetIClassAnswer(receivedAnswer,160,&samples,0)) return FALSE;
rsamples += samples;
if (tracing) LogTrace(receivedAnswer,Demod.len,rsamples,Demod.parityBits,FALSE);
if (tracing) {
uint8_t parity[MAX_PARITY_SIZE];
GetParity(receivedAnswer, Demod.len, parity);
LogTrace(receivedAnswer,Demod.len,rsamples,rsamples,parity,FALSE);
}
if(samples == 0) return FALSE;
return Demod.len;
}
@ -1504,8 +1484,8 @@ void ReaderIClass(uint8_t arg0) {
uint8_t card_data[24]={0};
uint8_t last_csn[8]={0};
uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes
uint8_t *resp = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
int read_status= 0;
bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
@ -1595,8 +1575,8 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
int keyaccess;
} memory;
uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes
uint8_t* resp = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
setupIclassReader();
@ -1714,7 +1694,7 @@ void IClass_iso14443A_write(uint8_t arg0, uint8_t blockNo, uint8_t *data, uint8_
uint16_t crc = 0;
uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes
uint8_t* resp = (((uint8_t *)BigBuf) + 3560);
// Reset trace buffer
memset(trace, 0x44, RECV_CMD_OFFSET);

File diff suppressed because it is too large Load diff

View file

@ -15,13 +15,6 @@
#include "common.h"
#include "mifaresniff.h"
// mifare reader over DMA buffer (SnoopIso14443a())!!!
#define MIFARE_BUFF_OFFSET 3560 // \/ \/ \/
// card emulator memory
#define EML_RESPONSES 4000
#define CARD_MEMORY 6000
#define CARD_MEMORY_LEN 4096
typedef struct {
enum {
DEMOD_UNSYNCD,
@ -35,12 +28,14 @@ typedef struct {
uint16_t bitCount;
uint16_t collisionPos;
uint16_t syncBit;
uint32_t parityBits;
uint8_t parityBits;
uint8_t parityLen;
uint16_t shiftReg;
uint16_t samples;
uint16_t len;
uint32_t startTime, endTime;
uint8_t *output;
uint8_t *parity;
} tDemod;
typedef enum {
@ -66,32 +61,33 @@ typedef struct {
uint16_t byteCntMax;
uint16_t posCnt;
uint16_t syncBit;
uint32_t parityBits;
uint8_t parityBits;
uint8_t parityLen;
uint16_t highCnt;
uint16_t twoBits;
uint32_t startTime, endTime;
uint8_t *output;
uint8_t *parity;
} tUart;
extern byte_t oddparity (const byte_t bt);
extern uint32_t GetParity(const uint8_t *pbtCmd, int iLen);
extern void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par);
extern void AppendCrc14443a(uint8_t *data, int len);
extern void ReaderTransmit(uint8_t *frame, int len, uint32_t *timing);
extern void ReaderTransmitBitsPar(uint8_t *frame, int bits, uint32_t par, uint32_t *timing);
extern void ReaderTransmitPar(uint8_t *frame, int len, uint32_t par, uint32_t *timing);
extern int ReaderReceive(uint8_t *receivedAnswer);
extern int ReaderReceivePar(uint8_t *receivedAnswer, uint32_t *parptr);
extern void ReaderTransmit(uint8_t *frame, uint16_t len, uint32_t *timing);
extern void ReaderTransmitBitsPar(uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t *timing);
extern void ReaderTransmitPar(uint8_t *frame, uint16_t len, uint8_t *par, uint32_t *timing);
extern int ReaderReceive(uint8_t *receivedAnswer, uint8_t *par);
extern void iso14443a_setup(uint8_t fpga_minor_mode);
extern int iso14_apdu(uint8_t *cmd, size_t cmd_len, void *data);
extern int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data);
extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_data, uint32_t *cuid_ptr);
extern void iso14a_set_trigger(bool enable);
extern void iso14a_set_timeout(uint32_t timeout);
extern void iso14a_clear_tracelen();
extern void iso14a_clear_trace();
extern void iso14a_set_tracing(bool enable);
#endif /* __ISO14443A_H */

View file

@ -126,11 +126,8 @@ void MifareUReadBlock(uint8_t arg0,uint8_t *datain)
if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");
// add trace trailer
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);
LED_B_OFF();
@ -459,7 +456,7 @@ void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
// Return 1 if the nonce is invalid else return 0
int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, byte_t * parity) {
int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) {
return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \
(oddparity((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \
(oddparity((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0;
@ -486,7 +483,8 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
uint16_t davg;
static uint16_t dmin, dmax;
uint8_t uid[10];
uint32_t cuid, nt1, nt2, nttmp, nttest, par, ks1;
uint32_t cuid, nt1, nt2, nttmp, nttest, ks1;
uint8_t par[1];
uint32_t target_nt[2], target_ks[2];
uint8_t par_array[4];
@ -494,7 +492,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
struct Crypto1State mpcs = {0, 0};
struct Crypto1State *pcs;
pcs = &mpcs;
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint32_t auth1_time, auth2_time;
static uint16_t delta_time;
@ -610,19 +608,18 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
// nested authentication
auth2_time = auth1_time + delta_time;
len = mifare_sendcmd_shortex(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, &par, &auth2_time);
len = mifare_sendcmd_shortex(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, &auth2_time);
if (len != 4) {
if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth2 error len=%d", len);
continue;
};
nt2 = bytes_to_num(receivedAnswer, 4);
if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: Testing nt1=%08x nt2enc=%08x nt2par=%02x", i+1, nt1, nt2, par);
if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: Testing nt1=%08x nt2enc=%08x nt2par=%02x", i+1, nt1, nt2, par[0]);
// Parity validity check
for (j = 0; j < 4; j++) {
par_array[j] = (oddparity(receivedAnswer[j]) != ((par & 0x08) >> 3));
par = par << 1;
par_array[j] = (oddparity(receivedAnswer[j]) != ((par[0] >> (7-j)) & 0x01));
}
ncount = 0;
@ -657,10 +654,6 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
// ----------------------------- crypto1 destroy
crypto1_destroy(pcs);
// add trace trailer
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
byte_t buf[4 + 4 * 4];
memcpy(buf, &cuid, 4);
memcpy(buf+4, &target_nt[0], 4);
@ -896,8 +889,9 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
uint32_t cuid;
memset(uid, 0x00, 10);
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
if (workFlags & 0x08) {
// clear trace
iso14a_clear_trace();
@ -931,14 +925,14 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
// reset chip
if (needWipe){
ReaderTransmitBitsPar(wupC1,7,0, NULL);
if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {
ReaderTransmitBitsPar(wupC1,7,0, NULL);
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");
break;
};
ReaderTransmit(wipeC, sizeof(wipeC), NULL);
if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("wipeC error");
break;
};
@ -951,20 +945,20 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
// write block
if (workFlags & 0x02) {
ReaderTransmitBitsPar(wupC1,7,0, NULL);
if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {
ReaderTransmitBitsPar(wupC1,7,0, NULL);
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");
break;
};
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");
break;
};
}
if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("write block send command error");
break;
};
@ -973,7 +967,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
AppendCrc14443a(d_block, 16);
ReaderTransmit(d_block, sizeof(d_block), NULL);
if ((ReaderReceive(receivedAnswer) != 1) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("write block send data error");
break;
};
@ -1021,7 +1015,8 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
uint32_t cuid = 0;
memset(data, 0x00, 18);
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
if (workFlags & 0x08) {
// clear trace
@ -1043,20 +1038,20 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
while (true) {
if (workFlags & 0x02) {
ReaderTransmitBitsPar(wupC1,7,0, NULL);
if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");
break;
};
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");
break;
};
}
// read block
if ((mifare_sendcmd_short(NULL, 0, 0x30, blockNo, receivedAnswer, NULL) != 18)) {
if ((mifare_sendcmd_short(NULL, 0, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) {
if (MF_DBGLEVEL >= 1) Dbprintf("read block send command error");
break;
};

View file

@ -11,6 +11,7 @@
#include "mifaresniff.h"
#include "apps.h"
static int sniffState = SNF_INIT;
static uint8_t sniffUIDType;
static uint8_t sniffUID[8];
@ -37,7 +38,7 @@ bool MfSniffEnd(void){
return FALSE;
}
bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint32_t parity, uint16_t bitCnt, bool reader) {
bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, uint16_t bitCnt, bool reader) {
if (reader && (len == 1) && (bitCnt == 7)) { // reset on 7-Bit commands from reader
sniffState = SNF_INIT;
@ -114,16 +115,16 @@ bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint32_t parity, ui
sniffBuf[11] = sniffSAK;
sniffBuf[12] = 0xFF;
sniffBuf[13] = 0xFF;
LogTrace(sniffBuf, 14, 0, parity, true);
LogTrace(sniffBuf, 14, 0, 0, NULL, TRUE);
} // intentionally no break;
case SNF_CARD_CMD:{
LogTrace(data, len, 0, parity, true);
LogTrace(data, len, 0, 0, NULL, TRUE);
sniffState = SNF_CARD_RESP;
timerData = GetTickCount();
break;
}
case SNF_CARD_RESP:{
LogTrace(data, len, 0, parity, false);
LogTrace(data, len, 0, 0, NULL, FALSE);
sniffState = SNF_CARD_CMD;
timerData = GetTickCount();
break;

View file

@ -39,7 +39,7 @@
#define SNF_UID_7 0
bool MfSniffInit(void);
bool RAMFUNC MfSniffLogic(const uint8_t * data, uint16_t len, uint32_t parity, uint16_t bitCnt, bool reader);
bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, uint16_t bitCnt, bool reader);
bool RAMFUNC MfSniffSend(uint16_t maxTimeoutMs);
bool intMfSniffSend();
bool MfSniffEnd(void);

View file

@ -22,17 +22,14 @@
int MF_DBGLEVEL = MF_DBG_ALL;
// memory management
uint8_t* mifare_get_bigbufptr(void) {
return (((uint8_t *)BigBuf) + MIFARE_BUFF_OFFSET); // was 3560 - tied to other size changes
uint8_t* get_bigbufptr_recvrespbuf(void) {
return (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
}
uint8_t* eml_get_bigbufptr_sendbuf(void) {
uint8_t* get_bigbufptr_recvcmdbuf(void) {
return (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
}
uint8_t* eml_get_bigbufptr_recbuf(void) {
return (((uint8_t *)BigBuf) + MIFARE_BUFF_OFFSET);
}
uint8_t* eml_get_bigbufptr_cardmem(void) {
return (((uint8_t *)BigBuf) + CARD_MEMORY);
uint8_t* get_bigbufptr_emlcardmem(void) {
return (((uint8_t *)BigBuf) + CARD_MEMORY_OFFSET);
}
// crypto1 helpers
@ -53,15 +50,15 @@ void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len){
return;
}
void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, int len, uint32_t *par) {
void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par) {
uint8_t bt = 0;
int i;
uint32_t mltpl = 1 << (len - 1); // for len=18 it=0x20000
*par = 0;
par[0] = 0;
for (i = 0; i < len; i++) {
bt = data[i];
data[i] = crypto1_byte(pcs, 0x00, 0) ^ data[i];
*par = (*par >> 1) | ( ((filter(pcs->odd) ^ oddparity(bt)) & 0x01) * mltpl );
if((i&0x0007) == 0) par[i>>3] = 0;
par[i>>3] |= (((filter(pcs->odd) ^ oddparity(bt)) & 0x01)<<(7-(i&0x0007)));
}
return;
}
@ -77,18 +74,18 @@ uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data) {
}
// send commands
int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint32_t *timing)
int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing)
{
return mifare_sendcmd_shortex(pcs, crypted, cmd, data, answer, NULL, timing);
return mifare_sendcmd_shortex(pcs, crypted, cmd, data, answer, answer_parity, timing);
}
int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *timing)
int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing)
{
uint8_t dcmd[8];//, ecmd[4];
//uint32_t par=0;
uint8_t dcmd[8];//, ecmd[4];
//uint32_t par=0;
dcmd[0] = cmd;
dcmd[1] = data[0];
dcmd[0] = cmd;
dcmd[1] = data[0];
dcmd[2] = data[1];
dcmd[3] = data[2];
dcmd[4] = data[3];
@ -99,7 +96,7 @@ int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint
//memcpy(ecmd, dcmd, sizeof(dcmd));
ReaderTransmit(dcmd, sizeof(dcmd), NULL);
int len = ReaderReceive(answer);
int len = ReaderReceive(answer, answer_parity);
if(!len)
{
if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout.");
@ -108,11 +105,11 @@ int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint
return len;
}
int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint32_t * parptr, uint32_t *timing)
int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)
{
uint8_t dcmd[4], ecmd[4];
uint32_t pos, par, res;
uint16_t pos, res;
uint8_t par[1]; // 1 Byte parity is enough here
dcmd[0] = cmd;
dcmd[1] = data;
AppendCrc14443a(dcmd, 2);
@ -120,11 +117,11 @@ int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cm
memcpy(ecmd, dcmd, sizeof(dcmd));
if (crypted) {
par = 0;
par[0] = 0;
for (pos = 0; pos < 4; pos++)
{
ecmd[pos] = crypto1_byte(pcs, 0x00, 0) ^ dcmd[pos];
par = (par >> 1) | ( ((filter(pcs->odd) ^ oddparity(dcmd[pos])) & 0x01) * 0x08 );
par[0] |= (((filter(pcs->odd) ^ oddparity(dcmd[pos])) & 0x01) << (7-pos));
}
ReaderTransmitPar(ecmd, sizeof(ecmd), par, timing);
@ -133,10 +130,10 @@ int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cm
ReaderTransmit(dcmd, sizeof(dcmd), timing);
}
int len = ReaderReceivePar(answer, &par);
int len = ReaderReceive(answer, par);
if (answer_parity) *answer_parity = par[0];
if (parptr) *parptr = par;
if (crypted == CRYPT_ALL) {
if (len == 1) {
res = 0;
@ -157,33 +154,35 @@ int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cm
}
// mifare commands
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint64_t isNested)
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested)
{
return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL);
}
int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint64_t isNested, uint32_t * ntptr, uint32_t *timing)
int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing)
{
// variables
int len;
uint32_t pos;
uint8_t tmp4[4];
byte_t par = 0;
byte_t ar[4];
uint8_t par[1] = {0};
byte_t nr[4];
uint32_t nt, ntpp; // Supplied tag nonce
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// Transmit MIFARE_CLASSIC_AUTH
len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, timing);
if (MF_DBGLEVEL >= 4) Dbprintf("rand nonce len: %x", len);
len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, receivedAnswerPar, timing);
if (MF_DBGLEVEL >= 4) Dbprintf("rand tag nonce len: %x", len);
if (len != 4) return 1;
ar[0] = 0x55;
ar[1] = 0x41;
ar[2] = 0x49;
ar[3] = 0x92;
// "random" reader nonce:
nr[0] = 0x55;
nr[1] = 0x41;
nr[2] = 0x49;
nr[3] = 0x92;
// Save the tag nonce (nt)
nt = bytes_to_num(receivedAnswer, 4);
@ -211,12 +210,13 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN
if (ntptr)
*ntptr = nt;
par = 0;
// Generate (encrypted) nr+parity by loading it into the cipher (Nr)
par[0] = 0;
for (pos = 0; pos < 4; pos++)
{
mf_nr_ar[pos] = crypto1_byte(pcs, ar[pos], 0) ^ ar[pos];
par = (par >> 1) | ( ((filter(pcs->odd) ^ oddparity(ar[pos])) & 0x01) * 0x80 );
mf_nr_ar[pos] = crypto1_byte(pcs, nr[pos], 0) ^ nr[pos];
par[0] |= (((filter(pcs->odd) ^ oddparity(nr[pos])) & 0x01) << (7-pos));
}
// Skip 32 bits in pseudo random generator
@ -227,14 +227,14 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN
{
nt = prng_successor(nt,8);
mf_nr_ar[pos] = crypto1_byte(pcs,0x00,0) ^ (nt & 0xff);
par = (par >> 1)| ( ((filter(pcs->odd) ^ oddparity(nt & 0xff)) & 0x01) * 0x80 );
par[0] |= (((filter(pcs->odd) ^ oddparity(nt & 0xff)) & 0x01) << (7-pos));
}
// Transmit reader nonce and reader answer
ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL);
// Receive 4 bit answer
len = ReaderReceive(receivedAnswer);
// Receive 4 byte tag answer
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
if (!len)
{
if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout.");
@ -258,10 +258,11 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
int len;
uint8_t bt[2];
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// command MIFARE_CLASSIC_READBLOCK
len = mifare_sendcmd_short(pcs, 1, 0x30, blockNo, receivedAnswer, NULL);
len = mifare_sendcmd_short(pcs, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if (len == 1) {
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
return 1;
@ -285,13 +286,14 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
// variables
int len;
uint16_t len;
uint8_t bt[2];
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// command MIFARE_CLASSIC_READBLOCK
len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer,NULL);
len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if (len == 1) {
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
return 1;
@ -318,14 +320,15 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
// variables
int len, i;
uint32_t pos;
uint32_t par = 0;
uint8_t par[3] = {0}; // enough for 18 Bytes to send
byte_t res;
uint8_t d_block[18], d_block_enc[18];
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// command MIFARE_CLASSIC_WRITEBLOCK
len = mifare_sendcmd_short(pcs, 1, 0xA0, blockNo, receivedAnswer, NULL);
len = mifare_sendcmd_short(pcs, 1, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
@ -336,17 +339,16 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
AppendCrc14443a(d_block, 16);
// crypto
par = 0;
for (pos = 0; pos < 18; pos++)
{
d_block_enc[pos] = crypto1_byte(pcs, 0x00, 0) ^ d_block[pos];
par = (par >> 1) | ( ((filter(pcs->odd) ^ oddparity(d_block[pos])) & 0x01) * 0x20000 );
par[pos>>3] |= (((filter(pcs->odd) ^ oddparity(d_block[pos])) & 0x01) << (7 - (pos&0x0007)));
}
ReaderTransmitPar(d_block_enc, sizeof(d_block_enc), par, NULL);
// Receive the response
len = ReaderReceive(receivedAnswer);
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
res = 0;
for (i = 0; i < 4; i++)
@ -362,72 +364,74 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
// variables
int len;
uint32_t par = 0;
// variables
uint16_t len;
uint8_t par[3] = {0}; // enough for 18 parity bits
uint8_t d_block[18];
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t d_block[18];
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// command MIFARE_CLASSIC_WRITEBLOCK
len = mifare_sendcmd_short(NULL, 1, 0xA0, blockNo, receivedAnswer,NULL);
// command MIFARE_CLASSIC_WRITEBLOCK
len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);
return 1;
}
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);
return 1;
}
memset(d_block,'\0',18);
memcpy(d_block, blockData, 16);
AppendCrc14443a(d_block, 16);
AppendCrc14443a(d_block, 16);
ReaderTransmitPar(d_block, sizeof(d_block), par, NULL);
// Receive the response
len = ReaderReceive(receivedAnswer);
// Receive the response
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
return 2;
}
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
return 2;
}
return 0;
return 0;
}
int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
// variables
int len;
//uint32_t par = 0;
uint16_t len;
uint8_t d_block[8];
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t d_block[8];
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// command MIFARE_CLASSIC_WRITEBLOCK
// command MIFARE_CLASSIC_WRITEBLOCK
memset(d_block,'\0',8);
d_block[0]= blockNo;
memcpy(d_block+1,blockData,4);
AppendCrc14443a(d_block, 6);
//i know the data send here is correct
len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer,NULL);
len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer, receivedAnswerPar, NULL);
if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
return 1;
}
return 0;
if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
return 1;
}
return 0;
}
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
{
// variables
int len;
uint16_t len;
// Mifare HALT
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
len = mifare_sendcmd_short(pcs, pcs == NULL ? 0:1, 0x50, 0x00, receivedAnswer, NULL);
len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
if (len != 0) {
if (MF_DBGLEVEL >= 1) Dbprintf("halt error. response len: %x", len);
return 1;
@ -438,13 +442,13 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
int mifare_ultra_halt(uint32_t uid)
{
// variables
int len;
uint16_t len;
// Mifare HALT
uint8_t* receivedAnswer = mifare_get_bigbufptr();
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
len = mifare_sendcmd_short(NULL, 1, 0x50, 0x00, receivedAnswer, NULL);
len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
if (len != 0) {
if (MF_DBGLEVEL >= 1) Dbprintf("halt error. response len: %x", len);
return 1;
@ -476,25 +480,25 @@ uint8_t FirstBlockOfSector(uint8_t sectorNo)
// work with emulator memory
void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
uint8_t* emCARD = get_bigbufptr_emlcardmem();
memcpy(emCARD + blockNum * 16, data, blocksCount * 16);
}
void emlGetMem(uint8_t *data, int blockNum, int blocksCount) {
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
uint8_t* emCARD = get_bigbufptr_emlcardmem();
memcpy(data, emCARD + blockNum * 16, blocksCount * 16);
}
void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount) {
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
uint8_t* emCARD = get_bigbufptr_emlcardmem();
memcpy(data, emCARD + bytePtr, byteCount);
}
int emlCheckValBl(int blockNum) {
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
uint8_t* emCARD = get_bigbufptr_emlcardmem();
uint8_t* data = emCARD + blockNum * 16;
if ((data[0] != (data[4] ^ 0xff)) || (data[0] != data[8]) ||
@ -509,7 +513,7 @@ int emlCheckValBl(int blockNum) {
}
int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
uint8_t* emCARD = get_bigbufptr_emlcardmem();
uint8_t* data = emCARD + blockNum * 16;
if (emlCheckValBl(blockNum)) {
@ -523,7 +527,7 @@ int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {
}
int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) {
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
uint8_t* emCARD = get_bigbufptr_emlcardmem();
uint8_t* data = emCARD + blockNum * 16;
memcpy(data + 0, &blReg, 4);
@ -541,7 +545,7 @@ int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) {
uint64_t emlGetKey(int sectorNum, int keyType) {
uint8_t key[6];
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
uint8_t* emCARD = get_bigbufptr_emlcardmem();
memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6);
return bytes_to_num(key, 6);
@ -552,9 +556,9 @@ void emlClearMem(void) {
const uint8_t trailer[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x69, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
const uint8_t uid[] = {0xe6, 0x84, 0x87, 0xf3, 0x16, 0x88, 0x04, 0x00, 0x46, 0x8e, 0x45, 0x55, 0x4d, 0x70, 0x41, 0x04};
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
uint8_t* emCARD = get_bigbufptr_emlcardmem();
memset(emCARD, 0, CARD_MEMORY_LEN);
memset(emCARD, 0, CARD_MEMORY_SIZE);
// fill sectors trailer data
for(b = 3; b < 256; b<127?(b+=4):(b+=16)) {

View file

@ -16,7 +16,7 @@
#define CRYPT_NONE 0
#define CRYPT_ALL 1
#define CRYPT_REQUEST 2
#define AUTH_FIRST 0
#define AUTH_FIRST 0
#define AUTH_NESTED 2
// mifare 4bit card answers
@ -54,14 +54,12 @@ extern int MF_DBGLEVEL;
//functions
uint8_t* mifare_get_bigbufptr(void);
int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint32_t *timing);
int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t* amswer, uint8_t *timing);
int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint32_t * parptr, uint32_t *timing);
int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, \
uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint64_t isNested);
int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, \
uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint64_t isNested, uint32_t * ntptr, uint32_t *timing);
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested);
int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t * ntptr, uint32_t *timing);
int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData);
int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
@ -72,13 +70,13 @@ int mifare_ultra_halt(uint32_t uid);
// crypto functions
void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *receivedCmd, int len);
void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, int len, uint32_t *par);
void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par);
uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data);
// memory management
uint8_t* mifare_get_bigbufptr(void);
uint8_t* eml_get_bigbufptr_sendbuf(void);
uint8_t* eml_get_bigbufptr_recbuf(void);
uint8_t* get_bigbufptr_recvrespbuf(void);
uint8_t* get_bigbufptr_recvcmdbuf(void);
uint8_t* get_bigbufptr_emlcardmem(void);
// Mifare memory structure
uint8_t NumBlocksPerSector(uint8_t sectorNo);

View file

@ -481,24 +481,56 @@ int CmdSamples(const char *Cmd)
int CmdTuneSamples(const char *Cmd)
{
int cnt = 0;
int n = 255;
uint8_t got[255];
int timeout = 0;
printf("\nMeasuring antenna characteristics, please wait...");
PrintAndLog("Reading %d samples\n", n);
GetFromBigBuf(got,n,7256); // armsrc/apps.h: #define FREE_BUFFER_OFFSET 7256
WaitForResponse(CMD_ACK,NULL);
for (int j = 0; j < n; j++) {
GraphBuffer[cnt++] = ((int)got[j]) - 128;
}
UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING};
SendCommand(&c);
UsbCommand resp;
while(!WaitForResponseTimeout(CMD_MEASURED_ANTENNA_TUNING,&resp,1000)) {
timeout++;
printf(".");
if (timeout > 7) {
PrintAndLog("\nNo response from Proxmark. Aborting...");
return 1;
}
}
int peakv, peakf;
int vLf125, vLf134, vHf;
vLf125 = resp.arg[0] & 0xffff;
vLf134 = resp.arg[0] >> 16;
vHf = resp.arg[1] & 0xffff;;
peakf = resp.arg[2] & 0xffff;
peakv = resp.arg[2] >> 16;
PrintAndLog("");
PrintAndLog("# LF antenna: %5.2f V @ 125.00 kHz", vLf125/1000.0);
PrintAndLog("# LF antenna: %5.2f V @ 134.00 kHz", vLf134/1000.0);
PrintAndLog("# LF optimal: %5.2f V @%9.2f kHz", peakv/1000.0, 12000.0/(peakf+1));
PrintAndLog("# HF antenna: %5.2f V @ 13.56 MHz", vHf/1000.0);
if (peakv<2000)
PrintAndLog("# Your LF antenna is unusable.");
else if (peakv<10000)
PrintAndLog("# Your LF antenna is marginal.");
if (vHf<2000)
PrintAndLog("# Your HF antenna is unusable.");
else if (vHf<5000)
PrintAndLog("# Your HF antenna is marginal.");
for (int i = 0; i < 256; i++) {
GraphBuffer[i] = resp.d.asBytes[i] - 128;
}
PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n");
PrintAndLog("\n");
GraphTraceLen = n;
RepaintGraphWindow();
return 0;
PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n");
PrintAndLog("\n");
GraphTraceLen = 256;
ShowGraphWindow();
return 0;
}
int CmdLoad(const char *Cmd)
{
FILE *f = fopen(Cmd, "r");

View file

@ -43,136 +43,131 @@ int CmdHF14AList(const char *Cmd)
if (param == 'f') {
ShowWaitCycles = true;
}
uint8_t got[1920];
GetFromBigBuf(got,sizeof(got),0);
WaitForResponse(CMD_ACK,NULL);
// for the time being. Need better Bigbuf handling.
#define TRACE_SIZE 3000
uint8_t trace[TRACE_SIZE];
GetFromBigBuf(trace, TRACE_SIZE, 0);
WaitForResponse(CMD_ACK, NULL);
PrintAndLog("Recorded Activity");
PrintAndLog("");
PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer");
PrintAndLog("All times are in carrier periods (1/13.56Mhz)");
PrintAndLog("");
PrintAndLog(" Start | End | Src | Data");
PrintAndLog("-----------|-----------|-----|--------");
PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC ");
PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------------");
int i = 0;
uint32_t first_timestamp = 0;
uint16_t tracepos = 0;
uint16_t duration;
uint16_t data_len;
uint16_t parity_len;
bool isResponse;
uint32_t timestamp;
uint32_t EndOfTransmissionTimestamp = 0;
uint32_t first_timestamp;
uint32_t EndOfTransmissionTimestamp;
for (;;) {
if(i >= 1900) {
if(tracepos >= TRACE_SIZE) {
break;
}
bool isResponse;
timestamp = *((uint32_t *)(got+i));
if (timestamp & 0x80000000) {
timestamp &= 0x7fffffff;
timestamp = *((uint32_t *)(trace + tracepos));
if(tracepos == 0) {
first_timestamp = timestamp;
}
// Break and stick with current result if buffer was not completely full
if (timestamp == 0x44444444) break;
tracepos += 4;
duration = *((uint16_t *)(trace + tracepos));
tracepos += 2;
data_len = *((uint16_t *)(trace + tracepos));
tracepos += 2;
if (data_len & 0x8000) {
data_len &= 0x7fff;
isResponse = true;
} else {
isResponse = false;
}
if(i==0) {
first_timestamp = timestamp;
}
int parityBits = *((uint32_t *)(got+i+4));
parity_len = (data_len-1)/8 + 1;
int len = got[i+8];
if (len > 100) {
if (tracepos + data_len + parity_len >= TRACE_SIZE) {
break;
}
if (i + len >= 1900) {
break;
}
uint8_t *frame = (got+i+9);
// Break and stick with current result if buffer was not completely full
if (frame[0] == 0x44 && frame[1] == 0x44 && frame[2] == 0x44 && frame[3] == 0x44) break;
char line[1000] = "";
int j;
if (len) {
for (j = 0; j < len; j++) {
int oddparity = 0x01;
int k;
for (k=0;k<8;k++) {
oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
}
//if((parityBits >> (len - j - 1)) & 0x01) {
if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
sprintf(line+(j*4), "%02x! ", frame[j]);
} else {
sprintf(line+(j*4), "%02x ", frame[j]);
}
}
} else {
if (ShowWaitCycles) {
uint32_t next_timestamp = (*((uint32_t *)(got+i+9))) & 0x7fffffff;
sprintf(line, "fdt (Frame Delay Time): %d", (next_timestamp - timestamp));
}
}
char *crc;
crc = "";
if (len > 2) {
uint8_t b1, b2;
for (j = 0; j < (len - 1); j++) {
// gives problems... search for the reason..
/*if(frame[j] == 0xAA) {
switch(frame[j+1]) {
case 0x01:
crc = "[1] Two drops close after each other";
break;
case 0x02:
crc = "[2] Potential SOC with a drop in second half of bitperiod";
break;
case 0x03:
crc = "[3] Segment Z after segment X is not possible";
break;
case 0x04:
crc = "[4] Parity bit of a fully received byte was wrong";
break;
default:
crc = "[?] Unknown error";
break;
}
break;
}*/
}
if (strlen(crc)==0) {
ComputeCrc14443(CRC_14443_A, frame, len-2, &b1, &b2);
if (b1 != frame[len-2] || b2 != frame[len-1]) {
crc = (isResponse & (len < 6)) ? "" : " !crc";
} else {
crc = "";
}
}
} else {
crc = ""; // SHORT
}
i += (len + 9);
EndOfTransmissionTimestamp = (*((uint32_t *)(got+i))) & 0x7fffffff;
if (!ShowWaitCycles) i += 9;
PrintAndLog(" %9d | %9d | %s | %s %s",
(timestamp - first_timestamp),
(EndOfTransmissionTimestamp - first_timestamp),
(len?(isResponse ? "Tag" : "Rdr"):" "),
line, crc);
uint8_t *frame = trace + tracepos;
tracepos += data_len;
uint8_t *parityBytes = trace + tracepos;
tracepos += parity_len;
char line[16][110];
for (int j = 0; j < data_len; j++) {
int oddparity = 0x01;
int k;
for (k=0;k<8;k++) {
oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
}
uint8_t parityBits = parityBytes[j>>3];
if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
sprintf(line[j/16]+((j%16)*4), "%02x! ", frame[j]);
} else {
sprintf(line[j/16]+((j%16)*4), "%02x ", frame[j]);
}
}
char crc[5] = "";
if (data_len > 2) {
uint8_t b1, b2;
ComputeCrc14443(CRC_14443_A, frame, data_len-2, &b1, &b2);
if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
sprintf(crc, (isResponse & (data_len < 6)) ? "" : "!crc");
} else {
sprintf(crc, "");
}
}
EndOfTransmissionTimestamp = timestamp + duration;
int num_lines = (data_len - 1)/16 + 1;
for (int j = 0; j < num_lines; j++) {
if (j == 0) {
PrintAndLog(" %9d | %9d | %s | %-64s| %s",
(timestamp - first_timestamp),
(EndOfTransmissionTimestamp - first_timestamp),
(isResponse ? "Tag" : "Rdr"),
line[j],
(j == num_lines-1)?crc:"");
} else {
PrintAndLog(" | | | %-64s| %s",
line[j],
(j == num_lines-1)?crc:"");
}
}
bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
if (ShowWaitCycles && !isResponse && next_isResponse) {
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 0;
}

View file

@ -54,10 +54,10 @@ int CmdHFEPACollectPACENonces(const char *Cmd)
size_t nonce_length = resp.arg[1];
char *nonce = (char *) malloc(2 * nonce_length + 1);
for(int j = 0; j < nonce_length; j++) {
snprintf(nonce + (2 * j), 3, "%02X", resp.d.asBytes[j]);
sprintf(nonce + (2 * j), "%02X", resp.d.asBytes[j]);
}
// print nonce
PrintAndLog("Length: %d, Nonce: %s",resp.arg[1], nonce);
PrintAndLog("Length: %d, Nonce: %s", nonce_length, nonce);
}
if (i < n - 1) {
sleep(d);

View file

@ -44,10 +44,9 @@ int xorbits_8(uint8_t val)
int CmdHFiClassList(const char *Cmd)
{
bool ShowWaitCycles = false;
char param = param_getchar(Cmd, 0);
if (param != 0) {
PrintAndLog("List data in trace buffer.");
PrintAndLog("Usage: hf iclass list");
@ -56,247 +55,142 @@ int CmdHFiClassList(const char *Cmd)
return 0;
}
uint8_t got[1920];
GetFromBigBuf(got,sizeof(got),0);
WaitForResponse(CMD_ACK,NULL);
// for the time being. Need better Bigbuf handling.
#define TRACE_SIZE 3000
uint8_t trace[TRACE_SIZE];
GetFromBigBuf(trace, TRACE_SIZE, 0);
WaitForResponse(CMD_ACK, NULL);
PrintAndLog("Recorded Activity");
PrintAndLog("");
PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer");
PrintAndLog("All times are in carrier periods (1/13.56Mhz)");
PrintAndLog("");
PrintAndLog(" Start | End | Src | Data");
PrintAndLog("-----------|-----------|-----|--------");
PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC ");
PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------------");
int i;
uint32_t first_timestamp = 0;
uint16_t tracepos = 0;
uint16_t duration;
uint16_t data_len;
uint16_t parity_len;
bool isResponse;
uint32_t timestamp;
bool tagToReader;
uint32_t parityBits;
uint8_t len;
uint8_t *frame;
uint32_t EndOfTransmissionTimestamp = 0;
uint32_t first_timestamp;
uint32_t EndOfTransmissionTimestamp;
for (;;) {
if(tracepos >= TRACE_SIZE) {
break;
}
for( i=0; i < 1900;)
{
//First 32 bits contain
// isResponse (1 bit)
// timestamp (remaining)
//Then paritybits
//Then length
timestamp = *((uint32_t *)(got+i));
parityBits = *((uint32_t *)(got+i+4));
len = got[i+8];
frame = (got+i+9);
uint32_t next_timestamp = (*((uint32_t *)(got+i+9))) & 0x7fffffff;
tagToReader = timestamp & 0x80000000;
timestamp &= 0x7fffffff;
if(i==0) {
timestamp = *((uint32_t *)(trace + tracepos));
if(tracepos == 0) {
first_timestamp = timestamp;
}
// Break and stick with current result idf buffer was not completely full
if (frame[0] == 0x44 && frame[1] == 0x44 && frame[2] == 0x44 && frame[3] == 0x44) break;
// Break and stick with current result if buffer was not completely full
if (timestamp == 0x44444444) break;
char line[1000] = "";
if(len)//We have some data to display
{
int j,oddparity;
for(j = 0; j < len ; j++)
{
oddparity = 0x01 ^ xorbits_8(frame[j] & 0xFF);
if (tagToReader && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
sprintf(line+(j*4), "%02x! ", frame[j]);
} else {
sprintf(line+(j*4), "%02x ", frame[j]);
}
}
}else
{
if (ShowWaitCycles) {
sprintf(line, "fdt (Frame Delay Time): %d", (next_timestamp - timestamp));
}
tracepos += 4;
duration = *((uint16_t *)(trace + tracepos));
tracepos += 2;
data_len = *((uint16_t *)(trace + tracepos));
tracepos += 2;
if (data_len & 0x8000) {
data_len &= 0x7fff;
isResponse = true;
} else {
isResponse = false;
}
char *crc = "";
parity_len = (data_len-1)/8 + 1;
if(len > 2)
{
if (tracepos + data_len + parity_len >= TRACE_SIZE) {
break;
}
uint8_t *frame = trace + tracepos;
tracepos += data_len;
uint8_t *parityBytes = trace + tracepos;
tracepos += parity_len;
char line[16][110];
for (int j = 0; j < data_len; j++) {
int oddparity = 0x01;
int k;
for (k=0;k<8;k++) {
oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
}
uint8_t parityBits = parityBytes[j>>3];
if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
sprintf(line[j/16]+((j%16)*4), "%02x! ", frame[j]);
} else {
sprintf(line[j/16]+((j%16)*4), "%02x ", frame[j]);
}
}
char *crc = "";
if (data_len > 2) {
uint8_t b1, b2;
if(!tagToReader && len == 4) {
if(!isResponse && data_len == 4 ) {
// Rough guess that this is a command from the reader
// For iClass the command byte is not part of the CRC
ComputeCrc14443(CRC_ICLASS, &frame[1], len-3, &b1, &b2);
ComputeCrc14443(CRC_ICLASS, &frame[1], data_len-3, &b1, &b2);
if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
crc = "!crc";
}
}
else {
// For other data.. CRC might not be applicable (UPDATE commands etc.)
ComputeCrc14443(CRC_ICLASS, frame, len-2, &b1, &b2);
}
if (b1 != frame[len-2] || b2 != frame[len-1]) {
crc = (tagToReader & (len < 8)) ? "" : " !crc";
// For other data.. CRC might not be applicable (UPDATE commands etc.)
ComputeCrc14443(CRC_ICLASS, frame, data_len-2, &b1, &b2);
if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
crc = "!crc";
}
}
}
i += (len + 9);
EndOfTransmissionTimestamp = (*((uint32_t *)(got+i))) & 0x7fffffff;
EndOfTransmissionTimestamp = timestamp + duration;
int num_lines = (data_len - 1)/16 + 1;
for (int j = 0; j < num_lines; j++) {
if (j == 0) {
PrintAndLog(" %9d | %9d | %s | %-64s| %s",
(timestamp - first_timestamp),
(EndOfTransmissionTimestamp - first_timestamp),
(isResponse ? "Tag" : "Rdr"),
line[j],
(j == num_lines-1)?crc:"");
} else {
PrintAndLog(" | | | %-64s| %s",
line[j],
(j == num_lines-1)?crc:"");
}
}
// Not implemented for iclass on the ARM-side
//if (!ShowWaitCycles) i += 9;
PrintAndLog(" %9d | %9d | %s | %s %s",
(timestamp - first_timestamp),
(EndOfTransmissionTimestamp - first_timestamp),
(len?(tagToReader ? "Tag" : "Rdr"):" "),
line, crc);
bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
if (ShowWaitCycles && !isResponse && next_isResponse) {
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 0;
}
int CmdHFiClassListOld(const char *Cmd)
{
uint8_t got[1920];
GetFromBigBuf(got,sizeof(got),0);
PrintAndLog("recorded activity:");
PrintAndLog(" ETU :rssi: who bytes");
PrintAndLog("---------+----+----+-----------");
int i = 0;
int prev = -1;
for (;;) {
if(i >= 1900) {
break;
}
bool isResponse;
int timestamp = *((uint32_t *)(got+i));
if (timestamp & 0x80000000) {
timestamp &= 0x7fffffff;
isResponse = 1;
} else {
isResponse = 0;
}
int metric = 0;
int parityBits = *((uint32_t *)(got+i+4));
// 4 bytes of additional information...
// maximum of 32 additional parity bit information
//
// TODO:
// at each quarter bit period we can send power level (16 levels)
// or each half bit period in 256 levels.
int len = got[i+8];
if (len > 100) {
break;
}
if (i + len >= 1900) {
break;
}
uint8_t *frame = (got+i+9);
// Break and stick with current result if buffer was not completely full
if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
char line[1000] = "";
int j;
for (j = 0; j < len; j++) {
int oddparity = 0x01;
int k;
for (k=0;k<8;k++) {
oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
}
//if((parityBits >> (len - j - 1)) & 0x01) {
if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
sprintf(line+(j*4), "%02x! ", frame[j]);
}
else {
sprintf(line+(j*4), "%02x ", frame[j]);
}
}
char *crc;
crc = "";
if (len > 2) {
uint8_t b1, b2;
for (j = 0; j < (len - 1); j++) {
// gives problems... search for the reason..
/*if(frame[j] == 0xAA) {
switch(frame[j+1]) {
case 0x01:
crc = "[1] Two drops close after each other";
break;
case 0x02:
crc = "[2] Potential SOC with a drop in second half of bitperiod";
break;
case 0x03:
crc = "[3] Segment Z after segment X is not possible";
break;
case 0x04:
crc = "[4] Parity bit of a fully received byte was wrong";
break;
default:
crc = "[?] Unknown error";
break;
}
break;
}*/
}
if (strlen(crc)==0) {
if(!isResponse && len == 4) {
// Rough guess that this is a command from the reader
// For iClass the command byte is not part of the CRC
ComputeCrc14443(CRC_ICLASS, &frame[1], len-3, &b1, &b2);
}
else {
// For other data.. CRC might not be applicable (UPDATE commands etc.)
ComputeCrc14443(CRC_ICLASS, frame, len-2, &b1, &b2);
}
//printf("%1x %1x",(unsigned)b1,(unsigned)b2);
if (b1 != frame[len-2] || b2 != frame[len-1]) {
crc = (isResponse & (len < 8)) ? "" : " !crc";
} else {
crc = "";
}
}
} else {
crc = ""; // SHORT
}
char metricString[100];
if (isResponse) {
sprintf(metricString, "%3d", metric);
} else {
strcpy(metricString, " ");
}
PrintAndLog(" +%7d: %s: %s %s %s",
(prev < 0 ? 0 : (timestamp - prev)),
metricString,
(isResponse ? "TAG" : " "), line, crc);
prev = timestamp;
i += (len + 9);
}
return 0;
}
int CmdHFiClassSnoop(const char *Cmd)
{
UsbCommand c = {CMD_SNOOP_ICLASS};

View file

@ -1894,7 +1894,6 @@ int CmdHF14AMfSniff(const char *Cmd){
uint8_t atqa[2];
uint8_t sak;
bool isTag;
uint32_t parity;
uint8_t buf[3000];
uint8_t * bufPtr = buf;
memset(buf, 0x00, 3000);
@ -1961,14 +1960,17 @@ int CmdHF14AMfSniff(const char *Cmd){
printf(">\n");
PrintAndLog("received trace len: %d packages: %d", blockLen, pckNum);
num = 0;
while (bufPtr - buf + 9 < blockLen) {
isTag = bufPtr[3] & 0x80 ? true:false;
bufPtr += 4;
parity = *((uint32_t *)(bufPtr));
bufPtr += 4;
len = bufPtr[0];
bufPtr++;
if ((len == 14) && (bufPtr[0] == 0xff) && (bufPtr[1] == 0xff)) {
while (bufPtr - buf < blockLen) {
bufPtr += 6; // ignore void timing information
len = *((uint16_t *)bufPtr);
if(len & 0x8000) {
isTag = true;
len &= 0x7fff;
} else {
isTag = false;
}
bufPtr += 2;
if ((len == 14) && (bufPtr[0] == 0xff) && (bufPtr[1] == 0xff) && (bufPtr[12] == 0xff) && (bufPtr[13] == 0xff)) {
memcpy(uid, bufPtr + 2, 7);
memcpy(atqa, bufPtr + 2 + 7, 2);
uid_len = (atqa[0] & 0xC0) == 0x40 ? 7 : 4;
@ -1987,9 +1989,10 @@ int CmdHF14AMfSniff(const char *Cmd){
} else {
PrintAndLog("%s(%d):%s", isTag ? "TAG":"RDR", num, sprint_hex(bufPtr, len));
if (wantLogToFile) AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len);
if (wantDecrypt) mfTraceDecode(bufPtr, len, parity, wantSaveToEmlFile);
if (wantDecrypt) mfTraceDecode(bufPtr, len, wantSaveToEmlFile);
}
bufPtr += len;
bufPtr += ((len-1)/8+1); // ignore parity
num++;
}
}

View file

@ -18,6 +18,7 @@
#include "cmdparser.h"
#include "cmdhw.h"
#include "cmdmain.h"
#include "cmddata.h"
/* low-level hardware control */
@ -391,9 +392,7 @@ int CmdSetMux(const char *Cmd)
int CmdTune(const char *Cmd)
{
UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING};
SendCommand(&c);
return 0;
return CmdTuneSamples(Cmd);
}
int CmdVersion(const char *Cmd)

View file

@ -206,28 +206,28 @@ void UsbCommandReceived(UsbCommand *UC)
return;
} break;
case CMD_MEASURED_ANTENNA_TUNING: {
int peakv, peakf;
int vLf125, vLf134, vHf;
vLf125 = UC->arg[0] & 0xffff;
vLf134 = UC->arg[0] >> 16;
vHf = UC->arg[1] & 0xffff;;
peakf = UC->arg[2] & 0xffff;
peakv = UC->arg[2] >> 16;
PrintAndLog("");
PrintAndLog("# LF antenna: %5.2f V @ 125.00 kHz", vLf125/1000.0);
PrintAndLog("# LF antenna: %5.2f V @ 134.00 kHz", vLf134/1000.0);
PrintAndLog("# LF optimal: %5.2f V @%9.2f kHz", peakv/1000.0, 12000.0/(peakf+1));
PrintAndLog("# HF antenna: %5.2f V @ 13.56 MHz", vHf/1000.0);
if (peakv<2000)
PrintAndLog("# Your LF antenna is unusable.");
else if (peakv<10000)
PrintAndLog("# Your LF antenna is marginal.");
if (vHf<2000)
PrintAndLog("# Your HF antenna is unusable.");
else if (vHf<5000)
PrintAndLog("# Your HF antenna is marginal.");
} break;
// case CMD_MEASURED_ANTENNA_TUNING: {
// int peakv, peakf;
// int vLf125, vLf134, vHf;
// vLf125 = UC->arg[0] & 0xffff;
// vLf134 = UC->arg[0] >> 16;
// vHf = UC->arg[1] & 0xffff;;
// peakf = UC->arg[2] & 0xffff;
// peakv = UC->arg[2] >> 16;
// PrintAndLog("");
// PrintAndLog("# LF antenna: %5.2f V @ 125.00 kHz", vLf125/1000.0);
// PrintAndLog("# LF antenna: %5.2f V @ 134.00 kHz", vLf134/1000.0);
// PrintAndLog("# LF optimal: %5.2f V @%9.2f kHz", peakv/1000.0, 12000.0/(peakf+1));
// PrintAndLog("# HF antenna: %5.2f V @ 13.56 MHz", vHf/1000.0);
// if (peakv<2000)
// PrintAndLog("# Your LF antenna is unusable.");
// else if (peakv<10000)
// PrintAndLog("# Your LF antenna is marginal.");
// if (vHf<2000)
// PrintAndLog("# Your HF antenna is unusable.");
// else if (vHf<5000)
// PrintAndLog("# Your HF antenna is marginal.");
// } break;
case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: {
// printf("received samples: ");

View file

@ -238,7 +238,7 @@ int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
// "MAGIC" CARD
int mfCSetUID(uint8_t *uid, uint8_t *oldUID, int wantWipe) {
int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe) {
uint8_t block0[16];
memset(block0, 0, 16);
memcpy(block0, uid, 4);
@ -251,7 +251,7 @@ int mfCSetUID(uint8_t *uid, uint8_t *oldUID, int wantWipe) {
return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER);
}
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, int wantWipe, uint8_t params) {
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params) {
uint8_t isOK = 0;
UsbCommand c = {CMD_MIFARE_EML_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};
@ -310,12 +310,9 @@ uint32_t ks3;
uint32_t uid; // serial number
uint32_t nt; // tag challenge
uint32_t nt_par;
uint32_t nr_enc; // encrypted reader challenge
uint32_t ar_enc; // encrypted reader response
uint32_t nr_ar_par;
uint32_t at_enc; // encrypted tag response
uint32_t at_par;
int isTraceCardEmpty(void) {
return ((traceCard[0] == 0) && (traceCard[1] == 0) && (traceCard[2] == 0) && (traceCard[3] == 0));
@ -424,7 +421,7 @@ void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool i
}
int mfTraceDecode(uint8_t *data_src, int len, uint32_t parity, bool wantSaveToEmlFile) {
int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
uint8_t data[64];
if (traceState == TRACE_ERROR) return 1;
@ -527,7 +524,6 @@ int mfTraceDecode(uint8_t *data_src, int len, uint32_t parity, bool wantSaveToEm
traceState = TRACE_AUTH2;
nt = bytes_to_num(data, 4);
nt_par = parity;
return 0;
} else {
traceState = TRACE_ERROR;
@ -541,7 +537,6 @@ int mfTraceDecode(uint8_t *data_src, int len, uint32_t parity, bool wantSaveToEm
nr_enc = bytes_to_num(data, 4);
ar_enc = bytes_to_num(data + 4, 4);
nr_ar_par = parity;
return 0;
} else {
traceState = TRACE_ERROR;
@ -554,7 +549,6 @@ int mfTraceDecode(uint8_t *data_src, int len, uint32_t parity, bool wantSaveToEm
traceState = TRACE_IDLE;
at_enc = bytes_to_num(data, 4);
at_par = parity;
// decode key here)
ks2 = ar_enc ^ prng_successor(nt, 64);

View file

@ -56,12 +56,12 @@ int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * key
int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);
int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);
int mfCSetUID(uint8_t *uid, uint8_t *oldUID, int wantWipe);
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, int wantWipe, uint8_t params);
int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe);
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params);
int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params);
int mfTraceInit(uint8_t *tuid, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile);
int mfTraceDecode(uint8_t *data_src, int len, uint32_t parity, bool wantSaveToEmlFile);
int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile);
int isTraceCardEmpty(void);
int isBlockEmpty(int blockN);