Merge pull request #50 from RfidResearchGroup/master

Update
This commit is contained in:
mwalker33
2020-10-01 11:49:38 +10:00
committed by GitHub
155 changed files with 374055 additions and 328301 deletions
+3 -2
View File
@@ -3,8 +3,9 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased]
- Add lf t55xx chk e <EM4100> option. Checks calculated password based on the EM4100 id from some white cloners forumla by paleopterix (@mwalker33)
- Add lf t55xx sniff to allow extracting commands and passwords used be cloners. (@mwalker33)
- Add `hf 14b apdu` - send APDU over ISO14443B (@iceman1001)
- Add `lf t55xx chk e <EM4100> option` - Checks calculated password based on the EM4100 id from some white cloners forumla by paleopterix (@mwalker33)
- Add `lf t55xx sniff` to allow extracting commands and passwords used be cloners. (@mwalker33)
- Add options to `lf read`, `lf cmdread`, `lf sniff` for repeated acquisitions (@doegox)
- Change options of `lf read` to match `lf cmdread`, this affects historical `d` and `s` options (@doegox)
- Add `hf waveshare` to upload picture to Waveshare NFC-Powered e-Paper (@doegox)
+1 -1
View File
@@ -297,7 +297,7 @@ void tosend_stuffbit(int b) {
Dbprintf(_RED_("toSend overflow"));
return;
}
if (toSend.bit >= 8) {
toSend.max++;
toSend.buf[toSend.max] = 0;
+5 -5
View File
@@ -118,7 +118,7 @@ static int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response, uint16_t re
case 'a':
return iso14_apdu(apdu, (uint16_t) length, false, response, NULL);
case 'b':
return iso14443b_apdu(apdu, length, response, respmaxlen);
return iso14443b_apdu(apdu, length, false, response, respmaxlen);
default:
return 0;
}
@@ -225,10 +225,10 @@ int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length) {
// select the file EF.CardAccess
int rapdu_length = EPA_APDU((uint8_t *)apdu_select_binary_cardaccess,
sizeof(apdu_select_binary_cardaccess),
response_apdu,
sizeof(response_apdu)
);
sizeof(apdu_select_binary_cardaccess),
response_apdu,
sizeof(response_apdu)
);
if (rapdu_length < 6
|| response_apdu[rapdu_length - 4] != 0x90
+1 -1
View File
@@ -1748,7 +1748,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
// init as reader
lf_init(true, false);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
// Tag specific configuration settings (sof, timings, etc.)
// TODO HTS
/* if (htf <= HTS_LAST_CMD) {
+148 -98
View File
@@ -41,15 +41,18 @@
// defaults to 2000ms
#ifndef FWT_TIMEOUT_14B
# define FWT_TIMEOUT_14B 35312
# define FWT_TIMEOUT_14B 35312
#endif
// 1 tick == 1/13.56 mhz
// 1 us = 1.5 tick
// 330/848kHz = 1558us / 4 == 400us,
#define ISO14443B_READER_TIMEOUT 1700 //330
#define ISO14443B_READER_TIMEOUT 10000 //330
// 1024/3.39MHz = 302.1us between end of tag response and next reader cmd
#define DELAY_ISO14443B_VICC_TO_VCD_READER 600 // 1024
#define DELAY_ISO14443B_VCD_TO_VICC_READER 600// 1056
#define DELAY_ISO14443B_VICC_TO_VCD_READER (28*9) // 1024 ( counting from start of PICC EOF 14 ETU's)
#define DELAY_ISO14443B_VCD_TO_VICC_READER (28*9) // 1056
#ifndef RECEIVE_MASK
# define RECEIVE_MASK (DMA_BUFFER_SIZE - 1)
@@ -57,7 +60,7 @@
// Guard Time (per 14443-2)
#ifndef TR0
# define TR0 64 // TR0 max is 256/fs = 256/(848kHz) = 302us or 64 samples from FPGA
# define TR0 32 // TR0 max is 151/fs = 151/(848kHz) = 302us or 64 samples from FPGA
#endif
// Synchronization time (per 14443-2)
@@ -76,10 +79,9 @@ static void iso14b_set_timeout(uint32_t timeout);
static void iso14b_set_maxframesize(uint16_t size);
// the block number for the ISO14443-4 PCB (used with APDUs)
static uint8_t pcb_blocknum = 0;
static uint8_t iso14b_pcb_blocknum = 0;
static uint32_t iso14b_timeout = FWT_TIMEOUT_14B;
/* ISO 14443 B
*
* Reader to card | ASK - Amplitude Shift Keying Modulation (PCD to PICC for Type B) (NRZ-L encodig)
@@ -306,7 +308,6 @@ static void Demod14bInit(uint8_t *data, uint16_t max_len) {
Demod14bReset();
}
/*
* 9.4395 us = 1 ETU and clock is about 1.5 us
* 13560000Hz
@@ -740,7 +741,7 @@ void SimulateIso14443bTag(uint32_t pupi) {
*/
static RAMFUNC int Handle14443bSamplesFromTag(int ci, int cq) {
int v;
int v = 0;
// The soft decision on the bit uses an estimate of just the
// quadrant of the reference angle, not the exact angle.
@@ -757,7 +758,7 @@ static RAMFUNC int Handle14443bSamplesFromTag(int ci, int cq) {
} \
}
#define SUBCARRIER_DETECT_THRESHOLD 8
#define SUBCARRIER_DETECT_THRESHOLD 8
// Subcarrier amplitude v = sqrt(ci^2 + cq^2), approximated here by max(abs(ci),abs(cq)) + 1/2*min(abs(ci),abs(cq)))
#define AMPLITUDE(ci,cq) (MAX(ABS(ci),ABS(cq)) + (MIN(ABS(ci),ABS(cq))/2))
@@ -797,7 +798,7 @@ static RAMFUNC int Handle14443bSamplesFromTag(int ci, int cq) {
Demod.state = DEMOD_GOT_FALLING_EDGE_OF_SOF;
Demod.posCount = 0; // start of SOF sequence
} else {
if (Demod.posCount > 200 / 4) { // maximum length of TR1 = 200 1/fs
if (Demod.posCount > 200/4) { // maximum length of TR1 = 200 1/fs
Demod.state = DEMOD_UNSYNCD;
}
}
@@ -820,7 +821,7 @@ static RAMFUNC int Handle14443bSamplesFromTag(int ci, int cq) {
Demod.state = DEMOD_AWAITING_START_BIT;
}
} else {
if (Demod.posCount > 14 * 2) { // low phase of SOF too long (> 12 etu)
if (Demod.posCount > 12 * 2) { // low phase of SOF too long (> 12 etu)
Demod.state = DEMOD_UNSYNCD;
LED_C_OFF();
}
@@ -831,7 +832,7 @@ static RAMFUNC int Handle14443bSamplesFromTag(int ci, int cq) {
Demod.posCount++;
MAKE_SOFT_DECISION();
if (v > 0) {
if (Demod.posCount > 6 * 2) { // max 19us between characters = 16 1/fs, max 3 etu after low phase of SOF = 24 1/fs
if (Demod.posCount > 3 * 2) { // max 19us between characters = 16 1/fs, max 3 etu after low phase of SOF = 24 1/fs
LED_C_OFF();
if (Demod.bitCount == 0 && Demod.len == 0) { // received SOF only, this is valid for iClass/Picopass
return true;
@@ -873,7 +874,7 @@ static RAMFUNC int Handle14443bSamplesFromTag(int ci, int cq) {
Demod.bitCount = 0;
Demod.state = DEMOD_AWAITING_START_BIT;
} else {
Demod.state = DEMOD_UNSYNCD;
Demod.state = DEMOD_AWAITING_FALLING_EDGE_OF_SOF;
LED_C_OFF();
if (s == 0x000) {
// This is EOF (start, stop and all data bits == '0'
@@ -894,25 +895,18 @@ static RAMFUNC int Handle14443bSamplesFromTag(int ci, int cq) {
return false;
}
/*
* Demodulate the samples we received from the tag, also log to tracebuffer
*/
static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, int timeout, uint32_t *eof_time) {
int samples = 0, ret = 0;
// Set up the demodulator for tag -> reader responses.
Demod14bInit(response, max_len);
// wait for last transfer to complete
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)) {};
// And put the FPGA in the appropriate mode
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_848_KHZ | FPGA_HF_READER_MODE_RECEIVE_IQ);
// Setup and start DMA.
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
//FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
// The DMA buffer, used to stream samples from the FPGA
dmabuf16_t *dma = get_dma16();
@@ -924,6 +918,9 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, int timeo
uint32_t dma_start_time = 0;
uint16_t *upTo = dma->buf;
// Put FPGA in the appropriate mode
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_848_KHZ | FPGA_HF_READER_MODE_RECEIVE_IQ);
for (;;) {
volatile uint16_t behindBy = ((uint16_t *)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1);
@@ -971,7 +968,7 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, int timeo
if (Handle14443bSamplesFromTag(ci, cq)) {
*eof_time = dma_start_time + (samples * 16) - DELAY_TAG_TO_ARM; // end of EOF
*eof_time = dma_start_time + (samples ) - DELAY_TAG_TO_ARM; // end of EOF
if (Demod.len > Demod.max_len) {
ret = -2; // overflow
@@ -986,19 +983,17 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, int timeo
}
FpgaDisableSscDma();
if (ret < 0) {
return ret;
}
if (Demod.len > 0) {
uint32_t sof_time = *eof_time
- (Demod.len * 8 * 8 * 16) // time for byte transfers
- (32 * 16) // time for SOF transfer
- 0; // time for EOF transfer
- (Demod.len * (8 + 2)) // time for byte transfers
- (12) // time for SOF transfer
- (12); // time for EOF transfer
LogTrace(Demod.output, Demod.len, (sof_time * 4), (*eof_time * 4), NULL, false);
}
return Demod.len;
}
@@ -1011,6 +1006,7 @@ static void TransmitFor14443b_AsReader(uint32_t *start_time) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_SHALLOW_MOD);
// TR2 minimum 14 ETUs
if (*start_time < DELAY_ARM_TO_TAG) {
*start_time = DELAY_ARM_TO_TAG;
}
@@ -1018,21 +1014,20 @@ static void TransmitFor14443b_AsReader(uint32_t *start_time) {
*start_time = (*start_time - DELAY_ARM_TO_TAG) & 0xfffffff0;
if (GetCountSspClk() > *start_time) { // we may miss the intended time
*start_time = (GetCountSspClk() + 16) & 0xfffffff0; // next possible time
*start_time = (GetCountSspClk() + 32) & 0xfffffff0; // next possible time
}
// wait
while (GetCountSspClk() < *start_time) ;
while (GetCountSspClk() < *start_time);
LED_B_ON();
for (int c = 0; c < ts->max; c++) {
volatile uint8_t data = ts->buf[c];
for (int i = 0; i < 8; i++) {
uint16_t send_word = (data & 0x80) ? 0x0000 : 0xffff;
for (uint8_t i = 0; i < 8; i++) {
volatile uint16_t send_word = (data & 0x80) ? 0x0000 : 0xFFFF;
while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ;
AT91C_BASE_SSC->SSC_THR = send_word;
while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ;
@@ -1045,6 +1040,9 @@ static void TransmitFor14443b_AsReader(uint32_t *start_time) {
LED_B_OFF();
*start_time += DELAY_ARM_TO_TAG;
// wait for last transfer to complete
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)) {};
}
//-----------------------------------------------------------------------------
@@ -1061,32 +1059,38 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len) {
* - no modulation ONES
*
* 1 ETU == 1 BIT!
* TR0 - 8 ETUS minimum.
* TR0 - 8 ETU's minimum.
* TR0 - 32 ETU's maximum for ATQB only
* TR0 - FWT for all other commands
*
* QUESTION: how long is a 1 or 0 in pulses in the xcorr_848 mode?
* 1 "stuffbit" = 1ETU (9us)
*
* TR2 - After the PICC response, the PCD is required to wait the Frame Delay Time (TR2)
before transmission of the next command. The minimum frame delay time required for
all commands is 14 ETUs
*
*/
int i;
tosend_reset();
// Send SOF
// 10-11 ETUs of ZERO
for (int i = 0; i < 10; i++)
for (i = 0; i < 10; i++) {
tosend_stuffbit(0);
}
// 2-3 ETUs of ONE
tosend_stuffbit(1);
tosend_stuffbit(1);
// Sending cmd, LSB
// from here we add BITS
for (int i = 0; i < len; i++) {
for (i = 0; i < len; i++) {
// Start bit
tosend_stuffbit(0);
// Data bits
uint8_t b = cmd[i];
// Data bits
volatile uint8_t b = cmd[i];
tosend_stuffbit(b & 1);
tosend_stuffbit((b >> 1) & 1);
tosend_stuffbit((b >> 2) & 1);
@@ -1098,31 +1102,29 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len) {
// Stop bit
tosend_stuffbit(1);
// EGT extra guard time
// For PCD it ranges 0-57us (1etu = 9us)
// tosend_stuffbit(1);
// tosend_stuffbit(1);
// tosend_stuffbit(1);
// EGT extra guard time 1 ETU = 9us
// For PCD it ranges 0-57us === 0 - 6 ETU
// FOR PICC it ranges 0-19us == 0 - 2 ETU
}
// Send EOF
// 10-11 ETUs of ZERO
for (int i = 0; i < 10; i++)
for (i = 0; i < 10; i++) {
tosend_stuffbit(0);
}
// Transition time. TR0 - guard time
// 8ETUS minum?
// Per specification, Subcarrier must be stopped no later than 2 ETUs after EOF.
// I'm guessing this is for the FPGA to be able to send all bits before we switch to listening mode
tosend_stuffbit(1);
/* Transition time. TR0 - guard time
* TR0 - 8 ETU's minimum.
* TR0 - 32 ETU's maximum for ATQB only
* TR0 - FWT for all other commands
* 32,64,128,256,512, ... , 262144, 524288 ETU
*/
int pad = (12 + (len * 10) + 11) & 0x7;
// ensure that last byte is filled up
for (int i = 0; i < 8 ; ++i)
for (i = 0; i < 16 - pad; ++i)
tosend_stuffbit(1);
// TR1 - Synchronization time
// Convert from last character reference to length
tosend_t *ts = get_tosend();
ts->max++;
}
/*
@@ -1132,54 +1134,100 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len, uint32_t
tosend_t *ts = get_tosend();
CodeIso14443bAsReader(cmd, len);
TransmitFor14443b_AsReader(start_time);
*eof_time = *start_time + (32 * (8 * ts->max));
*eof_time = *start_time + (10 * ts->max) + 10 + 2 + 10;
LogTrace(cmd, len, *start_time, *eof_time, NULL, true);
}
/* Sends an APDU to the tag
* TODO: check CRC and preamble
*/
int iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response, uint16_t respmaxlen) {
int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, uint8_t *response, uint16_t respmaxlen) {
LED_A_ON();
uint8_t message_frame[message_length + 4];
// PCB
message_frame[0] = 0x0A | pcb_blocknum;
pcb_blocknum ^= 1;
// CID
message_frame[1] = 0;
// INF
memcpy(message_frame + 2, message, message_length);
// EDC (CRC)
AddCrc14B(message_frame, message_length + 2);
uint8_t real_cmd[msg_len + 4];
if (msg_len) {
// ISO 14443 APDU frame: PCB [CID] [NAD] APDU CRC PCB=0x02
real_cmd[0] = 0x02; // bnr, nad, cid, chn=0; i-block(0x00)
if (send_chaining) {
real_cmd[0] |= 0x10;
}
// put block number into the PCB
real_cmd[0] |= iso14b_pcb_blocknum;
memcpy(real_cmd + 1, msg, msg_len);
} else {
// R-block. ACK
real_cmd[0] = 0xA2; // r-block + ACK
real_cmd[0] |= iso14b_pcb_blocknum;
}
AddCrc14B(real_cmd, msg_len + 1);
// send
uint32_t start_time = 0;
uint32_t eof_time = 0;
CodeAndTransmit14443bAsReader(message_frame, sizeof(message_frame), &start_time, &eof_time);
// Get response?
if (response == NULL) {
LED_A_OFF();
return 0;
}
CodeAndTransmit14443bAsReader(real_cmd, msg_len + 3, &start_time, &eof_time);
eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER;
int retlen = Get14443bAnswerFromTag(response, respmaxlen, ISO14443B_READER_TIMEOUT, &eof_time);
int len = Get14443bAnswerFromTag(response, respmaxlen, ISO14443B_READER_TIMEOUT, &eof_time);
FpgaDisableTracing();
if (retlen < 3) {
LED_A_OFF();
return -1;
uint8_t *data_bytes = (uint8_t *) response;
if (len <= 0) {
return 0; //DATA LINK ERROR
} else {
// S-Block WTX
while (len && ((data_bytes[0] & 0xF2) == 0xF2)) {
uint32_t save_iso14b_timeout = iso14b_timeout;
// temporarily increase timeout
iso14b_set_timeout(MAX((data_bytes[1] & 0x3f) * save_iso14b_timeout, ISO14443B_READER_TIMEOUT));
// Transmit WTX back
// byte1 - WTXM [1..59]. command FWT = FWT * WTXM
data_bytes[1] = data_bytes[1] & 0x3f; // 2 high bits mandatory set to 0b
// now need to fix CRC.
AddCrc14B(data_bytes, len - 2);
// transmit S-Block
CodeAndTransmit14443bAsReader(data_bytes, len, &start_time, &eof_time);
// retrieve the result again (with increased timeout)
eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER;
len = Get14443bAnswerFromTag(response, respmaxlen, ISO14443B_READER_TIMEOUT, &eof_time);
FpgaDisableTracing();
data_bytes = response;
// restore timeout
iso14b_set_timeout(save_iso14b_timeout);
}
// if we received an I- or R(ACK)-Block with a block number equal to the
// current block number, toggle the current block number
if (len >= 3 // PCB + CRC = 3 bytes
&& ((data_bytes[0] & 0xC0) == 0 // I-Block
|| (data_bytes[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0
&& (data_bytes[0] & 0x01) == iso14b_pcb_blocknum) { // equal block numbers
iso14b_pcb_blocknum ^= 1;
}
// if we received I-block with chaining we need to send ACK and receive another block of data
if (response)
*response = data_bytes[0];
// crc check
if (len >= 3 && !check_crc(CRC_14443_B, data_bytes, len)) {
return -1;
}
}
// VALIDATE CRC
if (!check_crc(CRC_14443_B, response, retlen)) {
if (DBGLEVEL > DBG_DEBUG) DbpString("CRC fail");
return -2;
if (len) {
// cut frame byte
len -= 1;
// memmove(data_bytes, data_bytes + 1, len);
for (int i = 0; i < len; i++)
data_bytes[i] = data_bytes[i + 1];
}
return retlen;
return len;
}
/**
@@ -1272,7 +1320,10 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) {
int iso14443b_select_card(iso14b_card_select_t *card) {
// WUPB command (including CRC)
// Note: WUPB wakes up all tags, REQB doesn't wake up tags in HALT state
static const uint8_t wupb[] = { ISO14443B_REQB, 0x00, 0x08, 0x39, 0x73 };
// WUTB or REQB is denoted in the third byte, lower nibble. 0 vs 8
//static const uint8_t wupb[] = { ISO14443B_REQB, 0x00, 0x08, 0x39, 0x73 };
static const uint8_t wupb[] = { ISO14443B_REQB, 0x00, 0x00, 0x71, 0xff };
// ATTRIB command (with space for CRC)
uint8_t attrib[] = { ISO14443B_ATTRIB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00};
@@ -1350,7 +1401,7 @@ int iso14443b_select_card(iso14b_card_select_t *card) {
}
}
// reset PCB block number
pcb_blocknum = 0;
iso14b_pcb_blocknum = 0;
return 0;
}
@@ -1683,6 +1734,7 @@ void SendRawCommand14443B_Ex(PacketCommandNG *c) {
size_t len = c->oldarg[1] & 0xffff;
uint32_t timeout = c->oldarg[2];
uint8_t *cmd = c->data.asBytes;
uint8_t buf[PM3_CMD_DATA_SIZE] = {0x00};
if (DBGLEVEL > DBG_DEBUG) Dbprintf("14b raw: param, %04x", param);
@@ -1719,9 +1771,9 @@ void SendRawCommand14443B_Ex(PacketCommandNG *c) {
}
if ((param & ISO14B_APDU) == ISO14B_APDU) {
uint8_t buf[100] = {0};
status = iso14443b_apdu(cmd, len, buf, sizeof(buf));
reply_mix(CMD_HF_ISO14443B_COMMAND, status, status, 0, buf, status);
status = iso14443b_apdu(cmd, len, (param & ISO14B_SEND_CHAINING), buf, sizeof(buf));
sendlen = MIN(Demod.len, PM3_CMD_DATA_SIZE);
reply_mix(CMD_HF_ISO14443B_COMMAND, status, status, 0, buf, sendlen);
}
if ((param & ISO14B_RAW) == ISO14B_RAW) {
@@ -1729,8 +1781,6 @@ void SendRawCommand14443B_Ex(PacketCommandNG *c) {
AddCrc14B(cmd, len);
len += 2;
}
uint8_t buf[100] = {0};
uint32_t start_time = 0;
uint32_t eof_time = 0;
CodeAndTransmit14443bAsReader(cmd, len, &start_time, &eof_time);
+1 -1
View File
@@ -27,7 +27,7 @@
#endif
void iso14443b_setup(void);
int iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response, uint16_t respmaxlen);
int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, uint8_t *response, uint16_t respmaxlen);
int iso14443b_select_card(iso14b_card_select_t *card);
int iso14443b_select_card_srx(iso14b_card_select_t *card);
+1 -1
View File
@@ -465,7 +465,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint16_t period_0, uint
} else if (*command == '1') {
TurnReadLFOn(period_1);
} else {
for (uint8_t i=0; i < LF_CMDREAD_MAX_EXTRA_SYMBOLS; i++) {
for (uint8_t i = 0; i < LF_CMDREAD_MAX_EXTRA_SYMBOLS; i++) {
if (*command == symbol_extra[i]) {
TurnReadLFOn(period_extra[i]);
break;
+1 -1
View File
@@ -332,7 +332,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, in
if (verbose) {
if (checked == -1) {
Dbprintf("lf sampling aborted");
} else if ((cancel_counter == cancel_after) && (cancel_after > 0)){
} else if ((cancel_counter == cancel_after) && (cancel_after > 0)) {
Dbprintf("lf sampling cancelled after %u", cancel_counter);
}
+61 -9
View File
@@ -11,10 +11,25 @@
#include "cliparser.h"
#include <string.h>
#include <stdlib.h>
#include <util.h> // Get color constants
#include <ui.h> // get PrintAndLogEx
#ifndef ARRAYLEN
# define ARRAYLEN(x) (sizeof(x)/sizeof((x)[0]))
#endif
// Custom Colors
// To default the color return s
#define _SectionTagColor_(s) _GREEN_(s)
#define _ExampleColor_(s) _YELLOW_(s)
#define _CommandColor_(s) _RED_(s)
#define _DescriptionColor_(s) _CYAN_(s)
#define _ArgColor_(s) s
#define _ArgHelpColor_(s) s
// End Custom Colors
// Option width set to 30 to allow option descriptions to align. approx line 74
// Example width set to 50 to allow help descriptions to align. approx line 93
int CLIParserInit(CLIParserContext **ctx, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp) {
*ctx = malloc(sizeof(CLIParserContext));
if (!*ctx) {
@@ -40,7 +55,7 @@ int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargta
/* verify the argtable[] entries were allocated sucessfully */
if (arg_nullcheck(ctx->argtable) != 0) {
/* NULL entries were detected, some allocations must have failed */
printf("ERROR: Insufficient memory\n");
PrintAndLogEx(ERR, "ERROR: Insufficient memory\n");
fflush(stdout);
return 2;
}
@@ -49,14 +64,50 @@ int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargta
/* special case: '--help' takes precedence over error reporting */
if ((argc < 2 && !allowEmptyExec) || ((struct arg_lit *)(ctx->argtable)[0])->count > 0) { // help must be the first record
printf("Usage: %s", ctx->programName);
arg_print_syntaxv(stdout, ctx->argtable, "\n");
if (ctx->programHint)
printf("%s\n\n", ctx->programHint);
arg_print_glossary(stdout, ctx->argtable, " %-20s %s\n");
printf("\n");
if (ctx->programHelp)
printf("%s \n", ctx->programHelp);
PrintAndLogEx(NORMAL, "\n"_DescriptionColor_("%s"), ctx->programHint);
PrintAndLogEx(NORMAL, "\n"_SectionTagColor_("usage:"));
PrintAndLogEx(NORMAL, " "_CommandColor_("%s")NOLF, ctx->programName);
arg_print_syntaxv(stdout, ctx->argtable, "\n\n");
PrintAndLogEx(NORMAL, _SectionTagColor_("options:"));
arg_print_glossary(stdout, ctx->argtable, " "_ArgColor_("%-30s")" "_ArgHelpColor_("%s")"\n");
PrintAndLogEx(NORMAL, "");
if (ctx->programHelp) {
PrintAndLogEx(NORMAL, _SectionTagColor_("examples/notes:"));
char *buf = NULL;
int idx = 0;
buf = realloc(buf, strlen(ctx->programHelp) + 1); // more then enough as we are splitting
char *p2; // pointer to split example from comment.
int egWidth = 30;
for (int i = 0; i <= strlen(ctx->programHelp); i++) { // <= so to get string terminator.
buf[idx++] = ctx->programHelp[i];
if ((ctx->programHelp[i] == '\n') || (ctx->programHelp[i] == 0x00)) {
buf[idx - 1] = 0x00;
p2 = strstr(buf, "->"); // See if the example has a comment.
if (p2 != NULL) {
*(p2 - 1) = 0x00;
if (strlen(buf) > 28)
egWidth = strlen(buf) + 5;
else
egWidth = 30;
PrintAndLogEx(NORMAL, " "_ExampleColor_("%-*s")" %s", egWidth, buf, p2);
} else {
PrintAndLogEx(NORMAL, " "_ExampleColor_("%-*s"), egWidth, buf);
}
idx = 0;
}
}
PrintAndLogEx(NORMAL, "");
free(buf);
}
fflush(stdout);
return 1;
@@ -66,7 +117,7 @@ int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargta
if (nerrors > 0) {
/* Display the error details contained in the arg_end struct.*/
arg_print_errors(stdout, ((struct arg_end *)(ctx->argtable)[vargtableLen - 1]), ctx->programName);
printf("Try '%s --help' for more information.\n", ctx->programName);
PrintAndLogEx(WARNING, "Try '%s --help' for more information.\n", ctx->programName);
fflush(stdout);
return 3;
}
@@ -74,6 +125,7 @@ int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargta
return 0;
}
enum ParserState {
PS_FIRST,
PS_ARGUMENT,
+1 -1
View File
@@ -14,7 +14,7 @@
#include <stdlib.h>
#include "util.h"
#define arg_param_begin arg_lit0("hH", "help", "This help")
#define arg_param_begin arg_lit0("h", "help", "This help")
#define arg_param_end arg_end(20)
#define arg_getsize(a) (sizeof(a) / sizeof(a[0]))
+13 -11
View File
@@ -93,8 +93,10 @@ Command = {
o.data = data
return o
end,
parse = function (packet)
local count, cmd, arg1, arg2, arg3, data = bin.unpack('LLLLH511', packet)
parse = function(packet)
local count, cmd, arg1, arg2, arg3, data = bin.unpack('LLLL', packet)
local length = #packet - count + 1
count, data = bin.unpack('H'..length, packet, count)
return Command:new{cmd = cmd, arg1 = arg1, arg2 = arg2, arg3 = arg3, data = data}
end
}
@@ -121,26 +123,28 @@ end
-- @param command - the usb packet to send
-- @param ignoreresponse - if set to true, we don't read the device answer packet
-- which is usually recipe for fail. If not sent, the host will wait 2s for a
-- response of type CMD_ACK
-- response of type CMD_ACK or like NG use the CMD as ack..
-- @return packet,nil if successful
-- nil, errormessage if unsuccessful
function Command:sendMIX( ignore_response, timeout )
function Command:sendMIX( ignore_response, timeout, use_cmd_ack)
if timeout == nil then timeout = TIMEOUT end
local data = self.data
local cmd = self.cmd
local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3
local err, msg = core.SendCommandMIX(cmd, arg1, arg2, arg3, data)
if err == nil then return err, msg end
if ignore_response then return true, nil end
if timeout == nil then timeout = TIMEOUT end
local ack = _commands.CMD_ACK
if use_cmd_ack then
ack = cmd
end
local response, msg = core.WaitForResponseTimeout(_commands.CMD_ACK, timeout)
local response, msg = core.WaitForResponseTimeout(ack, timeout)
if response == nil then
return nil, 'Error, waiting for response timed out :: '..msg
end
-- lets digest
data = nil
cmd = nil
@@ -157,15 +161,13 @@ function Command:sendMIX( ignore_response, timeout )
return packed, nil;
end
function Command:sendNG( ignore_response, timeout )
if timeout == nil then timeout = TIMEOUT end
local data = self.data
local cmd = self.cmd
local err, msg = core.SendCommandNG(cmd, data)
if err == nil then return nil, msg end
if ignore_response then return true, nil end
if timeout == nil then timeout = TIMEOUT end
local response, msg = core.WaitForResponseTimeout(cmd, timeout)
if response == nil then
return nil, 'Error, waiting for response timed out :: '..msg
+12 -12
View File
@@ -15,17 +15,18 @@ local cmds = require('commands')
local utils = require('utils')
-- Shouldn't take longer than 2.5 seconds
local TIMEOUT = 2500
local TIMEOUT = 2000
local ISO14B_COMMAND = {
ISO14B_CONNECT = 1,
ISO14B_DISCONNECT = 2,
ISO14B_APDU = 4,
ISO14B_RAW = 8,
ISO14B_CONNECT = 0x1,
ISO14B_DISCONNECT = 0x2,
ISO14B_APDU = 0x4,
ISO14B_RAW = 0x8,
ISO14B_REQUEST_TRIGGER = 0x10,
ISO14B_APPEND_CRC = 0x20,
ISO14B_SELECT_STD = 0x40,
ISO14B_SELECT_SR = 0x80,
ISO14B_SET_TIMEOUT = 0x100,
}
local function parse14443b(data)
@@ -74,9 +75,11 @@ local function read14443b(disconnect)
arg1 = flags
}
local result, err = command:sendMIX()
info = nil
local result, err = command:sendMIX(false, TIMEOUT, true)
if result then
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL', result)
if arg0 == 0 then
data = string.sub(result, count)
info, err = parse14443b(data)
@@ -88,12 +91,10 @@ local function read14443b(disconnect)
end
if err then
print(err)
return nil, err
end
return info
return info, nil
end
---
-- Waits for a mifare card to be placed within the vicinity of the reader.
-- @return if successful: an table containing card info
@@ -102,12 +103,11 @@ local function waitFor14443b()
print('Waiting for card... press Enter to quit')
while not core.kbd_enter_pressed() do
res, err = read14443b(false)
if res then return res end
if res then return res, err end
-- err means that there was no response from card
end
return nil, 'Aborted by user'
end
---
-- turns on the HF field.
local function connect14443b()
+6 -6
View File
@@ -11,10 +11,10 @@ This is a script to allow raw 14443a commands to be sent and received.
]]
example = [[
# 1. Connect and don't disconnect
script run hf_14a_raw -p
script run hf_14a_raw -k
# 2. Send mf auth, read response (nonce)
script run hf_14a_raw -o -x 6000F57b -p
script run hf_14a_raw -o -x 6000F57b -k
# 3. disconnect
script run hf_14a_raw -o
@@ -26,10 +26,10 @@ usage = [[
script run hf_14a_raw -x 6000F57b
]]
arguments = [[
-o do not connect - use this only if you previously used -p to stay connected
-o do not connect - use this only if you previously used -k to stay connected
-r do not read response
-c calculate and append CRC
-p stay connected - dont inactivate the field
-k stay connected - dont inactivate the field
-x <payload> Data to send (NO SPACES!)
-d Debug flag
-t Topaz mode
@@ -187,8 +187,8 @@ function selftest()
DEBUG = true
dbg('Performing test')
main()
main('-p')
main(' -o -x 6000F57b -p')
main('-k')
main(' -o -x 6000F57b -k')
main('-o')
main('-x 6000F57b')
dbg('Tests done')
+4 -4
View File
@@ -135,13 +135,13 @@ function main(args)
end
-- Original loop
-- core.console("hf 14a raw -a -p -b 7 45")
-- local cmd_select = string.format("hf 14a raw -c -p 9370%s", serial_number)
-- core.console("hf 14a raw -a -k -b 7 45")
-- local cmd_select = string.format("hf 14a raw -c -k 9370%s", serial_number)
-- core.console(cmd_select)
-- for i = 0, 254 do
-- local cmd_rd_blk = string.format("hf 14a raw -c -p 30 %02x", i)
-- local cmd_rd_blk = string.format("hf 14a raw -c -k 30 %02x", i)
-- core.console(cmd_rd_blk)
-- core.console("hf 14a raw -p 80")
-- core.console("hf 14a raw -k 80")
-- end
-- core.console("hf 14a raw -r")
+40 -24
View File
@@ -7,7 +7,7 @@ local ansicolors = require('ansicolors')
copyright = ''
author = 'Iceman'
version = 'v1.0.2'
version = 'v1.0.4'
desc = [[
This is a script to communicate with a CALYSPO / 14443b tag using the '14b raw' commands
]]
@@ -31,11 +31,12 @@ device-side.
local function calypso_parse(result)
local r = Command.parse(result)
local len = r.arg2 * 2
r.data = string.sub(r.data, 0, len);
print('GOT:', r.data)
if r.arg1 == 0 then
return r, nil
if r.arg1 >= 0 then
local len = r.arg2 * 2
if len > 0 then
r.data = string.sub(r.data, 0, len);
return r, nil
end
end
return nil,nil
end
@@ -123,12 +124,19 @@ local function calypso_send_cmd_raw(data, ignoreresponse )
arg2 = #data/2, -- LEN of data, half the length of the ASCII-string hex string
data = data} -- data bytes (commands etc)
result, err = command:sendMIX(ignoreresponse)
local use_cmd_ack = true
result, err = command:sendMIX(ignoreresponse, 2000, use_cmd_ack)
if result then
local r = calypso_parse(result)
return r, nil
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL', result)
if arg0 >= 0 then
return calypso_parse(result)
else
err = 'card response failed'
end
else
err = 'No response from card'
end
return respone, err
return result, err
end
---
-- calypso_card_num : Reads card number from ATR and
@@ -136,23 +144,22 @@ end
local function calypso_card_num(card)
if not card then return end
local card_num = tonumber( card.uid:sub(1,8),16 )
print('Card UID', card.uid)
print('Card Number', card_num)
print('')
print('Card UID ' ..ansicolors.green..card.uid:format('%x')..ansicolors.reset)
print('Card Number ' ..ansicolors.green..string.format('%u', card_num)..ansicolors.reset)
print('-----------------------')
end
---
-- analyse CALYPSO apdu status bytes.
local function calypso_apdu_status(apdu)
-- last two is CRC
-- next two is APDU status bytes.
local status = false
local mess = 'FAIL'
local sw = apdu:sub( #apdu-7, #apdu-4)
desc, err = iso7816.tostring(sw)
print ('SW', sw, desc, err )
status = ( sw == '9000' )
return status
--print ('SW', sw, desc, err )
local status = ( sw == '9000' )
return status, desc, err
end
local _calypso_cmds = {
@@ -215,7 +222,7 @@ function main(args)
if o == 'b' then bytes = a end
end
lib14b.connect()
-- lib14b.connect()
-- Select 14b tag.
card, err = lib14b.waitFor14443b()
@@ -241,14 +248,23 @@ function main(args)
--for i = 1,10 do
--result, err = calypso_send_cmd_raw('0294a40800043f000002',false) --select ICC file
for i, apdu in spairs(_calypso_cmds) do
print('>>', i )
print('>> '..ansicolors.yellow..i..ansicolors.reset)
apdu = apdu:gsub('%s+', '')
result, err = calypso_send_cmd_raw(apdu , false)
if result then
calypso_apdu_status(result.data)
print('<<', result.data )
if err then
print('<< '..err)
else
print('<< no answer')
if result then
local status, desc, err = calypso_apdu_status(result.data)
local d = result.data:sub(3, (#result.data - 8))
if status then
print('<< '..d..' ('..ansicolors.green..'ok'..ansicolors.reset..')')
else
print('<< '..d..' '..ansicolors.red..err..ansicolors.reset )
end
else
print('<< no answer')
end
end
end
lib14b.disconnect()
+10 -10
View File
@@ -59,24 +59,24 @@ end
local function cmdUltralight()
return {
[0] = 'hf 14a raw -p -a -b 7 40',
[1] = 'hf 14a raw -p -a 43',
[0] = 'hf 14a raw -k -a -b 7 40',
[1] = 'hf 14a raw -k -a 43',
[2] = 'hf 14a raw -c -a A2005380712A',
[3] = 'hf 14a raw -p -a -b 7 40',
[4] = 'hf 14a raw -p -a 43',
[3] = 'hf 14a raw -k -a -b 7 40',
[4] = 'hf 14a raw -k -a 43',
[5] = 'hf 14a raw -c -a A2010200D980',
[6] = 'hf 14a raw -p -a -b 7 40',
[7] = 'hf 14a raw -p -a 43',
[6] = 'hf 14a raw -k -a -b 7 40',
[7] = 'hf 14a raw -k -a 43',
[8] = 'hf 14a raw -c -a A2025B480000',
[9] = 'hf 14a raw -c -a 5000',
}
end
local function cmdClassic()
return {
[0] = 'hf 14a raw -p -a -b 7 40',
[1] = 'hf 14a raw -p -a 43',
[2] = 'hf 14a raw -c -p -a A000',
[3] = 'hf 14a raw -c -p -a 01020304049802000000000000001001',
[0] = 'hf 14a raw -k -a -b 7 40',
[1] = 'hf 14a raw -k -a 43',
[2] = 'hf 14a raw -c -k -a A000',
[3] = 'hf 14a raw -c -k -a 01020304049802000000000000001001',
[4] = 'hf 14a raw -c -a 5000',
}
end
+10 -10
View File
@@ -70,18 +70,18 @@ function magicUID(b0, b1, b2)
print('Using backdoor Magic tag function')
-- write block 0
core.console('hf 14a raw -p -a -b 7 40')
core.console('hf 14a raw -p -a 43')
core.console('hf 14a raw -k -a -b 7 40')
core.console('hf 14a raw -k -a 43')
core.console('hf 14a raw -c -a A200'..b0)
-- write block 1
core.console('hf 14a raw -p -a -b 7 40')
core.console('hf 14a raw -p -a 43')
core.console('hf 14a raw -k -a -b 7 40')
core.console('hf 14a raw -k -a 43')
core.console('hf 14a raw -c -a A201'..b1)
-- write block 2
core.console('hf 14a raw -p -a -b 7 40')
core.console('hf 14a raw -p -a 43')
core.console('hf 14a raw -k -a -b 7 40')
core.console('hf 14a raw -k -a 43')
core.console('hf 14a raw -c -a A202'..b2)
end
--
@@ -90,16 +90,16 @@ function brickableUID(b0, b1, b2)
print('Using BRICKABLE Magic tag function')
core.console('hf 14a raw -p -s -3')
core.console('hf 14a raw -k -s -3')
-- write block 0
core.console('hf 14a raw -p -c A200'..b0)
core.console('hf 14a raw -k -c A200'..b0)
-- write block 1
core.console('hf 14a raw -p -c A201'..b1)
core.console('hf 14a raw -k -c A201'..b1)
-- write block 2
core.console('hf 14a raw -p -c A202'..b2)
core.console('hf 14a raw -k -c A202'..b2)
end
---
-- The main entry point
+5 -6
View File
@@ -660,7 +660,7 @@ static int Cmdaskmandemod(const char *Cmd) {
Cmd++;
} else if (Cmd[1] == 's') {
st = true;
Cmd+=2;
Cmd += 2;
}
int clk = 0;
int invert = 0;
@@ -2264,15 +2264,14 @@ static int CmdDataNDEF(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "data ndef",
"Decode and print NFC Data Exchange Format (NDEF)",
"Samples:\n"
_YELLOW_("\tdata ndef -d 9101085402656e48656c6c6f5101085402656e576f726c64\n")
_YELLOW_("\tdata ndef -d 0103d020240203e02c040300fe\n")
"data ndef -d 9101085402656e48656c6c6f5101085402656e576f726c64\n"
"data ndef -d 0103d020240203e02c040300fe\n"
);
void *argtable[] = {
arg_param_begin,
arg_strx0("dD", "data", "<hex>", "NDEF data to decode"),
arg_lit0("vV", "verbose", "verbose mode"),
arg_strx0("d", "data", "<hex>", "NDEF data to decode"),
arg_lit0("v", "verbose", "verbose mode"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
+51 -54
View File
@@ -246,11 +246,11 @@ static int usage_hf_14a_sniff(void) {
return PM3_SUCCESS;
}
static int usage_hf_14a_raw(void) {
PrintAndLogEx(NORMAL, "Usage: hf 14a raw [-h] [-r] [-c] [-p] [-a] [-T] [-t] <milliseconds> [-b] <number of bits> <0A 0B 0C ... hex>");
PrintAndLogEx(NORMAL, "Usage: hf 14a raw [-h] [-r] [-c] [-k] [-a] [-T] [-t] <milliseconds> [-b] <number of bits> <0A 0B 0C ... hex>");
PrintAndLogEx(NORMAL, " -h this help");
PrintAndLogEx(NORMAL, " -r do not read response");
PrintAndLogEx(NORMAL, " -c calculate and append CRC");
PrintAndLogEx(NORMAL, " -p leave the signal field ON after receive");
PrintAndLogEx(NORMAL, " -k keep signal field ON after receive");
PrintAndLogEx(NORMAL, " -a active signal field ON without select");
PrintAndLogEx(NORMAL, " -s active signal field ON with select");
PrintAndLogEx(NORMAL, " -b number of bits to send. Useful for send partial byte");
@@ -563,13 +563,13 @@ static int CmdHF14AInfo(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 14a info",
"This command makes more extensive tests against a ISO14443a tag in order to collect information",
"Sample:\n\thf 14a info -nsv - shows full information about the card\n");
"hf 14a info -nsv -> shows full information about the card\n");
void *argtable[] = {
arg_param_begin,
arg_lit0("vV", "verbose", "adds some information to results"),
arg_lit0("nN", "nacktest", "test for nack bug"),
arg_lit0("sS", "aidsearch", "checks if AIDs from aidlist.json is present on the card and prints information about found AIDs"),
arg_lit0("v", "verbose", "adds some information to results"),
arg_lit0("n", "nacktest", "test for nack bug"),
arg_lit0("s", "aidsearch", "checks if AIDs from aidlist.json is present on the card and prints information about found AIDs"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@@ -1080,20 +1080,20 @@ static int CmdHF14AAPDU(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 14a apdu",
"Sends an ISO 7816-4 APDU via ISO 14443-4 block transmission protocol (T=CL). works with all apdu types from ISO 7816-4:2013",
"Sample:\n\thf 14a apdu -st 00A404000E325041592E5359532E444446303100\n"
"\thf 14a apdu -sd 00A404000E325041592E5359532E444446303100 - decode apdu\n"
"\thf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -l 256 - encode standard apdu\n"
"\thf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -el 65536 - encode extended apdu\n");
"hf 14a apdu -st 00A404000E325041592E5359532E444446303100\n"
"hf 14a apdu -sd 00A404000E325041592E5359532E444446303100 -> decode apdu\n"
"hf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -l 256 -> encode standard apdu\n"
"hf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -el 65536 -> encode extended apdu\n");
void *argtable[] = {
arg_param_begin,
arg_lit0("sS", "select", "activate field and select card"),
arg_lit0("kK", "keep", "leave the signal field ON after receive response"),
arg_lit0("tT", "tlv", "executes TLV decoder if it possible"),
arg_lit0("dD", "decapdu", "decode apdu request if it possible"),
arg_str0("mM", "make", "<head (CLA INS P1 P2) hex>", "make apdu with head from this field and data from data field. Must be 4 bytes length: <CLA INS P1 P2>"),
arg_lit0("eE", "extended", "make extended length apdu if `m` parameter included"),
arg_int0("lL", "le", "<Le (int)>", "Le apdu parameter if `m` parameter included"),
arg_lit0("s", "select", "activate field and select card"),
arg_lit0("k", "keep", "leave the signal field ON after receive response"),
arg_lit0("t", "tlv", "executes TLV decoder if it possible"),
arg_lit0("d", "decapdu", "decode apdu request if it possible"),
arg_str0("m", "make", "<head (CLA INS P1 P2) hex>", "make apdu with head from this field and data from data field. Must be 4 bytes length: <CLA INS P1 P2>"),
arg_lit0("e", "extended", "make extended length apdu if `m` parameter included"),
arg_int0("l", "le", "<Le (int)>", "Le apdu parameter if `m` parameter included"),
arg_strx1(NULL, NULL, "<APDU (hex) | data (hex)>", "data if `m` parameter included"),
arg_param_end
};
@@ -1186,7 +1186,7 @@ static int CmdHF14AAPDU(const char *Cmd) {
static int CmdHF14ACmdRaw(const char *Cmd) {
bool reply = 1;
bool crc = false;
bool power = false;
bool keep_field_on = false;
bool active = false;
bool active_select = false;
bool no_rats = false;
@@ -1218,8 +1218,8 @@ static int CmdHF14ACmdRaw(const char *Cmd) {
case 'c':
crc = true;
break;
case 'p':
power = true;
case 'k':
keep_field_on = true;
break;
case 'a':
active = true;
@@ -1306,7 +1306,7 @@ static int CmdHF14ACmdRaw(const char *Cmd) {
argtimeout = 13560000 / 1000 / (8 * 16) * timeout; // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us)
}
if (power) {
if (keep_field_on) {
flags |= ISO14A_NO_DISCONNECT;
}
@@ -1369,8 +1369,7 @@ static int CmdHF14AAntiFuzz(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 14a antifuzz",
"Tries to fuzz the ISO14443a anticollision phase",
"Usage:\n"
"\thf 14a antifuzz -4\n");
"hf 14a antifuzz -4\n");
void *argtable[] = {
arg_param_begin,
@@ -1398,9 +1397,8 @@ static int CmdHF14AChaining(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 14a chaining",
"Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.",
"Usage:\n"
"\thf 14a chaining disable -> disable chaining\n"
"\thf 14a chaining -> show chaining enable/disable state\n");
"hf 14a chaining disable -> disable chaining\n"
"hf 14a chaining -> show chaining enable/disable state\n");
void *argtable[] = {
arg_param_begin,
@@ -1425,38 +1423,10 @@ static int CmdHF14AChaining(const char *Cmd) {
return 0;
}
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"list", CmdHF14AList, AlwaysAvailable, "List ISO 14443-a history"},
{"info", CmdHF14AInfo, IfPm3Iso14443a, "Tag information"},
{"reader", CmdHF14AReader, IfPm3Iso14443a, "Act like an ISO14443-a reader"},
{"cuids", CmdHF14ACUIDs, IfPm3Iso14443a, "<n> Collect n>0 ISO14443-a UIDs in one go"},
{"sim", CmdHF14ASim, IfPm3Iso14443a, "<UID> -- Simulate ISO 14443-a tag"},
{"sniff", CmdHF14ASniff, IfPm3Iso14443a, "sniff ISO 14443-a traffic"},
{"apdu", CmdHF14AAPDU, IfPm3Iso14443a, "Send ISO 14443-4 APDU to tag"},
{"chaining", CmdHF14AChaining, IfPm3Iso14443a, "Control ISO 14443-4 input chaining"},
{"raw", CmdHF14ACmdRaw, IfPm3Iso14443a, "Send raw hex data to tag"},
{"antifuzz", CmdHF14AAntiFuzz, IfPm3Iso14443a, "Fuzzing the anticollision phase. Warning! Readers may react strange"},
{"config", CmdHf14AConfig, IfPm3Iso14443a, "Configure 14a settings (use with caution)"},
{NULL, NULL, NULL, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return PM3_SUCCESS;
}
int CmdHF14A(const char *Cmd) {
clearCommandBuffer();
return CmdsParse(CommandTable, Cmd);
}
static void printTag(const char *tag) {
PrintAndLogEx(SUCCESS, " " _YELLOW_("%s"), tag);
}
typedef enum {
MTNONE = 0,
MTCLASSIC = 1,
@@ -2032,3 +2002,30 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
DropField();
return select_status;
}
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"list", CmdHF14AList, AlwaysAvailable, "List ISO 14443-a history"},
{"info", CmdHF14AInfo, IfPm3Iso14443a, "Tag information"},
{"reader", CmdHF14AReader, IfPm3Iso14443a, "Act like an ISO14443-a reader"},
{"cuids", CmdHF14ACUIDs, IfPm3Iso14443a, "<n> Collect n>0 ISO14443-a UIDs in one go"},
{"sim", CmdHF14ASim, IfPm3Iso14443a, "<UID> -- Simulate ISO 14443-a tag"},
{"sniff", CmdHF14ASniff, IfPm3Iso14443a, "sniff ISO 14443-a traffic"},
{"apdu", CmdHF14AAPDU, IfPm3Iso14443a, "Send ISO 14443-4 APDU to tag"},
{"chaining", CmdHF14AChaining, IfPm3Iso14443a, "Control ISO 14443-4 input chaining"},
{"raw", CmdHF14ACmdRaw, IfPm3Iso14443a, "Send raw hex data to tag"},
{"antifuzz", CmdHF14AAntiFuzz, IfPm3Iso14443a, "Fuzzing the anticollision phase. Warning! Readers may react strange"},
{"config", CmdHf14AConfig, IfPm3Iso14443a, "Configure 14a settings (use with caution)"},
{NULL, NULL, NULL, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return PM3_SUCCESS;
}
int CmdHF14A(const char *Cmd) {
clearCommandBuffer();
return CmdsParse(CommandTable, Cmd);
}
+427 -86
View File
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More