step one of bounds checking all responses when receiving ISO14443A frames... because @doegox find a missbehaving IC clone.....

This commit is contained in:
iceman1001 2024-09-05 17:52:10 +02:00
commit 9c181dd83d
13 changed files with 156 additions and 139 deletions

View file

@ -84,7 +84,7 @@ static void RAMFUNC SniffAndStore(uint8_t param) {
bool ReaderIsActive = false;
// Set up the demodulator for tag -> reader responses.
Demod14aInit(receivedResp, receivedRespPar);
Demod14aInit(receivedResp, MAX_FRAME_SIZE, receivedRespPar);
// Set up the demodulator for the reader -> tag commands
Uart14aInit(receivedCmd, receivedCmdPar);

View file

@ -162,7 +162,7 @@ static void become_reader(void) {
AddCrc14A(toCard, rx->len);
ReaderTransmit(toCard, rx->len + 2, NULL);
tx->len = ReaderReceive(tx->dat, parity);
tx->len = ReaderReceive(tx->dat, sizeof(tx->dat), parity);
if (tx->len == 0) {
tx->len = sizeof(magicERR);
memcpy(tx->dat, magicERR, sizeof(magicERR));

View file

@ -995,13 +995,13 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
// reset chip
if (needWipe) {
ReaderTransmitBitsPar(wupC1, 7, 0, NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
DbprintfEx(FLAG_NEWLINE, "wupC1 error");
break;
};
ReaderTransmit(wipeC, sizeof(wipeC), NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
DbprintfEx(FLAG_NEWLINE, "wipeC error");
break;
};
@ -1016,19 +1016,19 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
// write block
if (workFlags & 0x02) {
ReaderTransmitBitsPar(wupC1, 7, 0, NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
DbprintfEx(FLAG_NEWLINE, "wupC1 error");
break;
};
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
DbprintfEx(FLAG_NEWLINE, "wupC2 errorv");
break;
};
}
if ((mifare_sendcmd_short(NULL, CRYPT_NONE, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) ||
if ((mifare_sendcmd_short(NULL, CRYPT_NONE, 0xA0, blockNo, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, NULL) != 1) ||
(receivedAnswer[0] != 0x0a)) {
DbprintfEx(FLAG_NEWLINE, "write block send command error");
break;
@ -1037,7 +1037,7 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
memcpy(d_block, datain, 16);
AddCrc14A(d_block, 16);
ReaderTransmit(d_block, sizeof(d_block), NULL);
if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {
DbprintfEx(FLAG_NEWLINE, "write block send data error");
break;
};

View file

@ -145,7 +145,7 @@ static int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response, uint16_t re
switch (iso_type) {
case 'a':
#ifdef WITH_ISO14443a
return iso14_apdu(apdu, (uint16_t) length, false, response, NULL);
return iso14_apdu(apdu, (uint16_t) length, false, response, respmaxlen, NULL);
#else
(void) apdu;
(void) length;
@ -581,7 +581,7 @@ static int EPA_Setup(void) {
uint8_t pps_response_par[1];
// send the PPS request
ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL);
return_code = ReaderReceive(pps_response, pps_response_par);
return_code = ReaderReceive(pps_response, sizeof(pps_response), pps_response_par);
if (return_code != 3 || pps_response[0] != 0xD0) {
return return_code == 0 ? 2 : return_code;
}

View file

@ -2188,7 +2188,7 @@ void iClass_Recover(iclass_recover_req_t *msg) {
if (res == false) {
Dbprintf(_RED_("Unable to select card! Stopping."));
goto out;
}else {
} else {
DbpString(_GREEN_("Card selected successfully!"));
}
@ -2200,7 +2200,7 @@ void iClass_Recover(iclass_recover_req_t *msg) {
if (res == false) {
Dbprintf(_RED_("Unable to authenticate with AA2 using K2! Stopping."));
goto out;
}else{
} else {
DbpString(_GREEN_("AA2 authentication with K2 successful!"));
}
@ -2232,7 +2232,7 @@ void iClass_Recover(iclass_recover_req_t *msg) {
if (res == false) {
Dbprintf(_RED_("Unable to authenticate on AA1 using macs! Stopping."));
goto out;
}else {
} else {
DbpString(_GREEN_("Authenticated with AA1 with macs!"));
}

View file

@ -474,8 +474,9 @@ void Demod14aReset(void) {
Demod.samples = 0;
}
void Demod14aInit(uint8_t *data, uint8_t *par) {
Demod.output = data;
void Demod14aInit(uint8_t *d, uint16_t n, uint8_t *par) {
Demod.output_len = n;
Demod.output = d;
Demod.parity = par;
Demod14aReset();
}
@ -683,7 +684,7 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
bool ReaderIsActive = false;
// Set up the demodulator for tag -> reader responses.
Demod14aInit(receivedResp, receivedRespPar);
Demod14aInit(receivedResp, MAX_FRAME_SIZE, receivedRespPar);
// Set up the demodulator for the reader -> tag commands
Uart14aInit(receivedCmd, receivedCmdPar);
@ -2301,7 +2302,7 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start
// If a response is captured return TRUE
// If it takes too long return FALSE
//-----------------------------------------------------------------------------
bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *received_len) {
bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint16_t resp_len, uint8_t *received_len) {
if (g_hf_field_active == false) {
Dbprintf("Warning: HF field is off, ignoring GetIso14443aAnswerFromTag_Thinfilm command");
@ -2315,7 +2316,7 @@ bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *rec
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN);
// Now get the answer from the card
Demod14aInit(receivedResponse, NULL);
Demod14aInit(receivedResponse, resp_len, NULL);
// clear RXRDY:
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
@ -2353,7 +2354,7 @@ bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *rec
// If a response is captured return TRUE
// If it takes too long return FALSE
//-----------------------------------------------------------------------------
static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset) {
static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint16_t resp_len, uint8_t *receivedResponsePar, uint16_t offset) {
if (g_hf_field_active == false) {
Dbprintf("Warning: HF field is off");
return false;
@ -2366,7 +2367,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN);
// Now get the answer from the card
Demod14aInit(receivedResponse, receivedResponsePar);
Demod14aInit(receivedResponse, resp_len, receivedResponsePar);
// clear RXRDY:
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
@ -2423,16 +2424,16 @@ void ReaderTransmit(uint8_t *frame, uint16_t len, uint32_t *timing) {
ReaderTransmitBitsPar(frame, len * 8, parity_array, timing);
}
static uint16_t ReaderReceiveOffset(uint8_t *receivedAnswer, uint16_t offset, uint8_t *par) {
if (GetIso14443aAnswerFromTag(receivedAnswer, par, offset) == false) {
static uint16_t ReaderReceiveOffset(uint8_t *receivedAnswer, uint16_t answer_len, uint16_t offset, uint8_t *par) {
if (GetIso14443aAnswerFromTag(receivedAnswer, answer_len, par, offset) == false) {
return 0;
}
LogTrace(receivedAnswer, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, par, false);
return Demod.len;
}
uint16_t ReaderReceive(uint8_t *receivedAnswer, uint8_t *par) {
if (GetIso14443aAnswerFromTag(receivedAnswer, par, 0) == false) {
uint16_t ReaderReceive(uint8_t *receivedAnswer, uint16_t answer_len, uint8_t *par) {
if (GetIso14443aAnswerFromTag(receivedAnswer, answer_len, par, 0) == false) {
return 0;
}
LogTrace(receivedAnswer, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, par, false);
@ -2544,7 +2545,7 @@ static void iso14a_set_ATS_times(const uint8_t *ats) {
}
static int GetATQA(uint8_t *resp, uint8_t *resp_par, iso14a_polling_parameters_t *polling_parameters) {
static int GetATQA(uint8_t *resp, uint16_t resp_len, uint8_t *resp_par, iso14a_polling_parameters_t *polling_parameters) {
#define WUPA_RETRY_TIMEOUT 10
uint32_t save_iso14a_timeout = iso14a_get_timeout();
@ -2571,7 +2572,7 @@ static int GetATQA(uint8_t *resp, uint8_t *resp_par, iso14a_polling_parameters_t
}
// Receive the ATQA
len = ReaderReceive(resp, resp_par);
len = ReaderReceive(resp, resp_len, resp_par);
// We set the start_time here otherwise in some cases we miss the window and only ever try once
if (first_try) {
@ -2616,7 +2617,7 @@ int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint
p_card->ats_len = 0;
}
if (GetATQA(resp, parity_array, polling_parameters) == 0) {
if (GetATQA(resp, sizeof(resp), parity_array, polling_parameters) == 0) {
return 0;
}
@ -2633,7 +2634,7 @@ int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint
// Read real UID
uint8_t fudan_read[] = { 0x30, 0x01, 0x8B, 0xB9};
ReaderTransmit(fudan_read, sizeof(fudan_read), NULL);
if (!ReaderReceive(resp, parity_array)) {
if (ReaderReceive(resp, sizeof(resp), parity_array) == 0) {
if (g_dbglevel >= DBG_INFO) Dbprintf("Card didn't answer to select all");
return 0;
}
@ -2641,11 +2642,11 @@ int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint
memcpy(p_card->uid, resp, 4);
// select again?
if (GetATQA(resp, parity_array, &WUPA_POLLING_PARAMETERS) == 0) {
if (GetATQA(resp, sizeof(resp), parity_array, &WUPA_POLLING_PARAMETERS) == 0) {
return 0;
}
if (GetATQA(resp, parity_array, &WUPA_POLLING_PARAMETERS) == 0) {
if (GetATQA(resp, sizeof(resp), parity_array, &WUPA_POLLING_PARAMETERS) == 0) {
return 0;
}
@ -2685,7 +2686,7 @@ int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint
// SELECT_ALL
ReaderTransmit(sel_all, sizeof(sel_all), NULL);
if (!ReaderReceive(resp, parity_array)) {
if (ReaderReceive(resp, sizeof(resp), parity_array) == 0) {
if (g_dbglevel >= DBG_INFO) Dbprintf("Card didn't answer to CL%i select all", cascade_level + 1);
return 0;
}
@ -2715,7 +2716,7 @@ int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint
collision_answer_offset = uid_resp_bits % 8;
ReaderTransmitBits(sel_uid, 16 + uid_resp_bits, NULL);
if (!ReaderReceiveOffset(resp, collision_answer_offset, parity_array)) {
if (ReaderReceiveOffset(resp, sizeof(resp), collision_answer_offset, parity_array) == 0) {
return 0;
}
}
@ -2773,7 +2774,7 @@ int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint
ReaderTransmit(sel_uid, sizeof(sel_uid), NULL);
// Receive the SAK
if (!ReaderReceive(resp, parity_array)) {
if (ReaderReceive(resp, sizeof(resp), parity_array) == 0) {
if (g_dbglevel >= DBG_INFO) Dbprintf("Card didn't answer to select");
return 0;
}
@ -2837,7 +2838,7 @@ int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint
uint8_t rats[] = { ISO14443A_CMD_RATS, 0x80, 0x31, 0x73 }; // FSD=256, FSDI=8, CID=0
ReaderTransmit(rats, sizeof(rats), NULL);
int len = ReaderReceive(resp, parity_array);
int len = ReaderReceive(resp, sizeof(resp), parity_array);
if (len == 0) {
return 0;
}
@ -2864,7 +2865,7 @@ int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades) {
uint8_t sak = 0x04; // cascade uid
int cascade_level = 0;
if (GetATQA(resp, resp_par, &WUPA_POLLING_PARAMETERS) == 0) {
if (GetATQA(resp, sizeof(resp), resp_par, &WUPA_POLLING_PARAMETERS) == 0) {
return 0;
}
@ -2891,7 +2892,7 @@ int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades) {
ReaderTransmit(sel_uid, sizeof(sel_uid), NULL);
// Receive the SAK
if (!ReaderReceive(resp, resp_par)) {
if (ReaderReceive(resp, sizeof(resp), resp_par) == 0) {
return 0;
}
@ -2964,7 +2965,7 @@ b8 b7 b6 b5 b4 b3 b2 b1
b5,b6 = 00 - DESELECT
11 - WTX
*/
int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint8_t *res) {
int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint16_t data_len, uint8_t *res) {
uint8_t *real_cmd = BigBuf_calloc(cmd_len + 4);
if (cmd_len) {
@ -2985,7 +2986,7 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, u
ReaderTransmit(real_cmd, cmd_len + 3, NULL);
size_t len = ReaderReceive(data, parity_array);
size_t len = ReaderReceive(data, data_len, parity_array);
uint8_t *data_bytes = (uint8_t *) data;
if (!len) {
@ -3005,7 +3006,7 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, u
// transmit S-Block
ReaderTransmit(data_bytes, len, NULL);
// retrieve the result again (with increased timeout)
len = ReaderReceive(data, parity_array);
len = ReaderReceive(data, data_len, parity_array);
data_bytes = data;
// restore timeout
iso14a_set_timeout(save_iso14a_timeout);
@ -3114,6 +3115,7 @@ void ReaderIso14443a(PacketCommandNG *c) {
len,
((param & ISO14A_SEND_CHAINING) == ISO14A_SEND_CHAINING),
buf,
sizeof(buf),
&res
);
FpgaDisableTracing();
@ -3186,13 +3188,13 @@ void ReaderIso14443a(PacketCommandNG *c) {
FpgaDisableTracing();
reply_mix(CMD_ACK, 0, 0, 0, NULL, 0);
} else {
arg0 = ReaderReceive(buf, parity_array);
arg0 = ReaderReceive(buf, sizeof(buf), parity_array);
FpgaDisableTracing();
reply_mix(CMD_ACK, arg0, 0, 0, buf, sizeof(buf));
}
} else {
arg0 = ReaderReceive(buf, parity_array);
arg0 = ReaderReceive(buf, sizeof(buf), parity_array);
FpgaDisableTracing();
reply_mix(CMD_ACK, arg0, 0, 0, buf, sizeof(buf));
}
@ -3204,7 +3206,7 @@ void ReaderIso14443a(PacketCommandNG *c) {
FpgaDisableTracing();
reply_mix(CMD_ACK, 0, 0, 0, NULL, 0);
} else {
arg0 = ReaderReceive(buf, parity_array);
arg0 = ReaderReceive(buf, sizeof(buf), parity_array);
FpgaDisableTracing();
reply_mix(CMD_ACK, arg0, 0, 0, buf, sizeof(buf));
}
@ -3382,7 +3384,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time);
// Receive the (4 Byte) "random" TAG nonce
if (ReaderReceive(receivedAnswer, receivedAnswerPar) != 4)
if (ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) != 4)
continue;
previous_nt = nt;
@ -3392,7 +3394,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL);
// Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding
int resp_res = ReaderReceive(receivedAnswer, receivedAnswerPar);
int resp_res = ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar);
if (resp_res == 1)
received_nack = true;
else if (resp_res == 4) {
@ -3663,8 +3665,9 @@ void DetectNACKbug(void) {
ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time);
// Receive the (4 Byte) "random" TAG nonce
if (!ReaderReceive(receivedAnswer, receivedAnswerPar))
if (ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) {
continue;
}
previous_nt = nt;
nt = bytes_to_num(receivedAnswer, 4);
@ -3673,7 +3676,7 @@ void DetectNACKbug(void) {
ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL);
// Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding
if (ReaderReceive(receivedAnswer, receivedAnswerPar)) {
if (ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar)) {
received_nack = true;
num_nacks++;
// ALWAYS leak Detection. Well, we could be lucky and get a response nack on first try.

View file

@ -56,6 +56,7 @@ typedef struct {
uint16_t samples;
uint16_t len;
uint32_t startTime, endTime;
uint16_t output_len;
uint8_t *output;
uint8_t *parity;
} tDemod14a;
@ -130,7 +131,7 @@ void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par);
tDemod14a *GetDemod14a(void);
void Demod14aReset(void);
void Demod14aInit(uint8_t *data, uint8_t *par);
void Demod14aInit(uint8_t *d, uint16_t n, uint8_t *par);
tUart14a *GetUart14a(void);
void Uart14aReset(void);
void Uart14aInit(uint8_t *data, uint8_t *par);
@ -146,10 +147,10 @@ void ReaderIso14443a(PacketCommandNG *c);
void ReaderTransmit(uint8_t *frame, uint16_t len, uint32_t *timing);
void ReaderTransmitBitsPar(uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t *timing);
void ReaderTransmitPar(uint8_t *frame, uint16_t len, uint8_t *par, uint32_t *timing);
uint16_t ReaderReceive(uint8_t *receivedAnswer, uint8_t *par);
uint16_t ReaderReceive(uint8_t *receivedAnswer, uint16_t answer_len, uint8_t *par);
void iso14443a_setup(uint8_t fpga_minor_mode);
int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint8_t *res);
int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint16_t data_len, uint8_t *res);
int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats);
int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats, iso14a_polling_parameters_t *polling_parameters);
int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades);
@ -173,7 +174,7 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start
void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype);
void DetectNACKbug(void);
bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *received_len);
bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint16_t resp_len, uint8_t *received_len);
extern iso14a_polling_parameters_t WUPA_POLLING_PARAMETERS;
extern iso14a_polling_parameters_t REQA_POLLING_PARAMETERS;

View file

@ -95,31 +95,31 @@ static bool mifare_wakeup_auth(struct Crypto1State *pcs, MifareWakeupType wakeup
break;
case MF_WAKE_GEN1A:
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupC1 error");
return false;
}
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_INFO) Dbprintf("Assuming Magic Gen 1B tag. [wupC2 failed]");
}
break;
case MF_WAKE_GEN1B:
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupC1 error");
return false;
}
break;
case MF_WAKE_GDM_ALT:
ReaderTransmitBitsPar(wupGDM1, 7, NULL, NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupGDM1 error");
return false;
}
ReaderTransmit(wupGDM2, sizeof(wupGDM2), NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_INFO) Dbprintf("wupGDM2 error");
// maybe this is fine on some tags?
}
@ -532,7 +532,7 @@ void MifareValue(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) {
}
// send transfer (commit the change)
len = mifare_sendcmd_short(pcs, 1, MIFARE_CMD_TRANSFER, (transferBlk != 0) ? transferBlk : blockNo, receivedAnswer, NULL, NULL);
len = mifare_sendcmd_short(pcs, 1, MIFARE_CMD_TRANSFER, (transferBlk != 0) ? transferBlk : blockNo, receivedAnswer, sizeof(receivedAnswer), NULL, NULL);
if (len != 1 && receivedAnswer[0] != 0x0A) { // 0x0a - ACK
if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error in transfer: %02x", receivedAnswer[0]);
break;
@ -852,7 +852,7 @@ void MifareAcquireNonces(uint32_t arg0, uint32_t flags) {
uint8_t dcmd[4] = {0x60 + (keyType & 0x01), blockNo, 0x00, 0x00};
AddCrc14A(dcmd, 2);
ReaderTransmit(dcmd, sizeof(dcmd), NULL);
int len = ReaderReceive(answer, par);
int len = ReaderReceive(answer, sizeof(answer), par);
// wait for the card to become ready again
CHK_TIMEOUT();
@ -975,7 +975,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
}
// nested authentication
uint16_t len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + (targetKeyType & 0xF), targetBlockNo, receivedAnswer, par_enc, NULL);
uint16_t len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + (targetKeyType & 0xF), targetBlockNo, receivedAnswer, sizeof(receivedAnswer), par_enc, NULL);
// wait for the card to become ready again
CHK_TIMEOUT();
@ -1124,7 +1124,7 @@ void MifareAcquireStaticEncryptedNonces(uint32_t flags, uint8_t *key) {
}
// nested authentication
uint16_t len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + keyType + 4, blockNo, receivedAnswer, par_enc, NULL);
uint16_t len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + keyType + 4, blockNo, receivedAnswer, sizeof(receivedAnswer), par_enc, NULL);
if (len != 4) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("AcquireStaticEncryptedNonces: Auth2 error len=%d", len);
isOK = PM3_ESOFT;
@ -1150,7 +1150,7 @@ void MifareAcquireStaticEncryptedNonces(uint32_t flags, uint8_t *key) {
};
// nested authentication on regular keytype
len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + keyType, blockNo, receivedAnswer, par_enc, NULL);
len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + keyType, blockNo, receivedAnswer, sizeof(receivedAnswer), par_enc, NULL);
if (len != 4) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("AcquireStaticEncryptedNonces: Auth2 error len=%d", len);
isOK = PM3_ESOFT;
@ -1364,7 +1364,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8
// nested authentication
auth2_time = auth1_time + delta_time;
len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + (targetKeyType & 0xF), targetBlockNo, receivedAnswer, par, &auth2_time);
len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + (targetKeyType & 0xF), targetBlockNo, receivedAnswer, sizeof(receivedAnswer), par, &auth2_time);
if (len != 4) {
if (g_dbglevel >= DBG_INFO) Dbprintf("Nested: Auth2 error len=%d", len);
continue;
@ -1489,7 +1489,7 @@ void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo,
target_nt[1] = prng_successor(nt1, 320);
}
len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + (targetKeyType & 0xF), targetBlockNo, receivedAnswer, par, NULL);
len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + (targetKeyType & 0xF), targetBlockNo, receivedAnswer, sizeof(receivedAnswer), par, NULL);
if (len != 4) {
continue;
};
@ -1514,7 +1514,7 @@ void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo,
continue;
};
len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + (targetKeyType & 0xF), targetBlockNo, receivedAnswer, par, NULL);
len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + (targetKeyType & 0xF), targetBlockNo, receivedAnswer, sizeof(receivedAnswer), par, NULL);
if (len != 4) {
continue;
};
@ -2244,7 +2244,7 @@ void MifarePersonalizeUID(uint8_t keyType, uint8_t perso_option, uint64_t key) {
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
int len = mifare_sendcmd_short(pcs, true, MIFARE_EV1_PERSONAL_UID, perso_option, receivedAnswer, receivedAnswerPar, NULL);
int len = mifare_sendcmd_short(pcs, true, MIFARE_EV1_PERSONAL_UID, perso_option, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, NULL);
if (len != 1 || receivedAnswer[0] != CARD_ACK) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
break;
@ -2513,7 +2513,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
// wipe tag, fill it with zeros
if (workFlags & MAGIC_WIPE) {
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupC1 error");
errormsg = MAGIC_WIPE;
break;
@ -2526,7 +2526,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
iso14a_set_timeout(21190);
ReaderTransmit(wipeC, sizeof(wipeC), NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("wipeC error");
errormsg = MAGIC_WIPE;
break;
@ -2539,7 +2539,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
// write block
if (workFlags & MAGIC_WUPC) {
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupC1 error");
errormsg = MAGIC_WUPC;
break;
@ -2547,7 +2547,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
if (!is1b) {
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_INFO) Dbprintf("Assuming Magic Gen 1B tag. [wupC2 failed]");
is1b = true;
continue;
@ -2555,7 +2555,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
}
}
if ((mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
if ((mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("write block send command error");
errormsg = 4;
break;
@ -2565,14 +2565,15 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
AddCrc14A(data, 16);
ReaderTransmit(data, sizeof(data), NULL);
if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("write block send data error");
errormsg = 0;
break;
}
if (workFlags & MAGIC_HALT)
if (workFlags & MAGIC_HALT) {
mifare_classic_halt(NULL);
}
isOK = true;
break;
@ -2623,15 +2624,15 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
while (true) {
if (workFlags & MAGIC_WUPC) {
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupC1 error");
errormsg = MAGIC_WUPC;
break;
}
if (!is1b) {
if (is1b == false) {
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_INFO) Dbprintf("Assuming Magic Gen 1B tag. [wupC2 failed]");
is1b = true;
continue;
@ -2640,7 +2641,7 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
}
// read block
if ((mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != MAX_MIFARE_FRAME_SIZE)) {
if ((mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, NULL) != MAX_MIFARE_FRAME_SIZE)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("read block send command error");
errormsg = 0;
break;
@ -2649,25 +2650,29 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
memcpy(data, receivedAnswer, sizeof(data));
// send HALT
if (workFlags & MAGIC_HALT)
if (workFlags & MAGIC_HALT) {
mifare_classic_halt(NULL);
}
isOK = true;
break;
}
// if MAGIC_DATAIN, the data stays on device side.
if (workFlags & MAGIC_DATAIN) {
if (isOK)
if (isOK) {
memcpy(datain, data, sizeof(data));
}
} else {
if (isOK)
if (isOK) {
reply_old(CMD_ACK, 1, 0, 0, data, sizeof(data));
else
} else {
OnErrorMagic(errormsg);
}
}
if (workFlags & MAGIC_OFF)
if (workFlags & MAGIC_OFF) {
OnSuccessMagic();
}
iso14a_set_timeout(timeout);
}
@ -2702,18 +2707,18 @@ void MifareCIdent(bool is_mfc, uint8_t keytype, uint8_t *key) {
// Generation 1 test
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
if (ReaderReceive(rec, recpar) && (rec[0] == 0x0A)) {
if (ReaderReceive(rec, 1, recpar) && (rec[0] == 0x0A)) {
flag = MAGIC_FLAG_GEN_1A;
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
uint16_t tmp = ReaderReceive(rec, recpar);
uint16_t tmp = ReaderReceive(rec, 1, recpar);
if ((tmp && (rec[0] != 0x0A)) || (tmp == 0)) {
flag = MAGIC_FLAG_GEN_1B;
}
// check for GDM config
ReaderTransmit(gen4gdmGetConf, sizeof(gen4gdmGetConf), NULL);
res = ReaderReceive(buf, par);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res > 1) {
flag |= MAGIC_FLAG_GDM_WUP_40;
}
@ -2727,7 +2732,7 @@ void MifareCIdent(bool is_mfc, uint8_t keytype, uint8_t *key) {
// Get config should return 30 or 32 bytes
AddCrc14A(gen4GetConf, sizeof(gen4GetConf) - 2);
ReaderTransmit(gen4GetConf, sizeof(gen4GetConf), NULL);
res = ReaderReceive(buf, par);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res == 32 || res == 34) {
flag |= MAGIC_FLAG_GEN_4GTU;
}
@ -2743,7 +2748,7 @@ void MifareCIdent(bool is_mfc, uint8_t keytype, uint8_t *key) {
}
ReaderTransmit(rats, sizeof(rats), NULL);
res = ReaderReceive(buf, par);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res) {
if (memcmp(buf, "\x09\x78\x00\x91\x02\xDA\xBC\x19\x10", 9) == 0) {
@ -2778,7 +2783,7 @@ void MifareCIdent(bool is_mfc, uint8_t keytype, uint8_t *key) {
// test for super card
ReaderTransmit(superGen1, sizeof(superGen1), NULL);
res = ReaderReceive(buf, par);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res == 22) {
uint8_t isGen = MAGIC_FLAG_SUPER_GEN1;
@ -2788,7 +2793,7 @@ void MifareCIdent(bool is_mfc, uint8_t keytype, uint8_t *key) {
iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
ReaderTransmit(rdbl00, sizeof(rdbl00), NULL);
res = ReaderReceive(buf, par);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res == 18) {
isGen = MAGIC_FLAG_SUPER_GEN2;
}
@ -2804,7 +2809,7 @@ void MifareCIdent(bool is_mfc, uint8_t keytype, uint8_t *key) {
res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
if (res == 2) {
ReaderTransmit(rdblf0, sizeof(rdblf0), NULL);
res = ReaderReceive(buf, par);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res == 18) {
flag |= MAGIC_FLAG_NTAG21X;
}
@ -2828,7 +2833,7 @@ void MifareCIdent(bool is_mfc, uint8_t keytype, uint8_t *key) {
uint64_t tmpkey = bytes_to_num(key, 6);
if (mifare_classic_authex(pcs, cuid, 0, keytype, tmpkey, AUTH_FIRST, NULL, NULL) == 0) {
if ((mifare_sendcmd_short(pcs, 1, ISO14443A_CMD_WRITEBLOCK, 0, buf, par, NULL) == 1) && (buf[0] == 0x0A)) {
if ((mifare_sendcmd_short(pcs, 1, ISO14443A_CMD_WRITEBLOCK, 0, buf, PM3_CMD_DATA_SIZE, par, NULL) == 1) && (buf[0] == 0x0A)) {
flag |= MAGIC_FLAG_GEN_2;
// turn off immediately to ensure nothing ever accidentally writes to the block
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@ -2844,7 +2849,7 @@ void MifareCIdent(bool is_mfc, uint8_t keytype, uint8_t *key) {
res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
if (res) {
ReaderTransmit(rdbl00, sizeof(rdbl00), NULL);
res = ReaderReceive(buf, par);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res == 18) {
flag |= MAGIC_FLAG_GEN_3;
}
@ -2856,7 +2861,7 @@ void MifareCIdent(bool is_mfc, uint8_t keytype, uint8_t *key) {
res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
if (res) {
ReaderTransmit(gen4gdmAuth, sizeof(gen4gdmAuth), NULL);
res = ReaderReceive(buf, par);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res == 4) {
flag |= MAGIC_FLAG_GDM_AUTH;
}
@ -2877,7 +2882,7 @@ void MifareCIdent(bool is_mfc, uint8_t keytype, uint8_t *key) {
// GDM alt magic wakeup (20)
ReaderTransmitBitsPar(wupGDM1, 7, NULL, NULL);
if (ReaderReceive(rec, recpar) && (rec[0] == 0x0a)) {
if (ReaderReceive(rec, 1, recpar) && (rec[0] == 0x0a)) {
flag |= MAGIC_FLAG_GDM_WUP_20;
}
@ -2916,7 +2921,7 @@ void MifareHasStaticNonce(void) {
uint8_t rec[4] = {0x00};
uint8_t recpar[1] = {0x00};
// Transmit MIFARE_CLASSIC_AUTH 0x60, block 0
int len = mifare_sendcmd_short(pcs, false, MIFARE_AUTH_KEYA, 0, rec, recpar, NULL);
int len = mifare_sendcmd_short(pcs, false, MIFARE_AUTH_KEYA, 0, rec, sizeof(rec), recpar, NULL);
if (len != 4) {
retval = PM3_ESOFT;
goto OUT;
@ -3108,7 +3113,7 @@ int DoGen3Cmd(uint8_t *cmd, uint8_t cmd_len) {
iso14a_set_timeout(13560000 / 1000 / (8 * 16) * 2000); // 2 seconds timeout
ReaderTransmit(cmd, cmd_len, NULL);
int res = ReaderReceive(buf, par);
int res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res == 4 && memcmp(buf, "\x90\x00\xfd\x07", 4) == 0) {
// timeout for card memory reset
SpinDelay(1000);
@ -3160,7 +3165,9 @@ void MifareGen3Blk(uint8_t block_len, uint8_t *block) {
int retval = PM3_SUCCESS;
uint8_t block_cmd[5] = { 0x90, 0xf0, 0xcc, 0xcc, 0x10 };
uint8_t *cmd = BigBuf_calloc(sizeof(block_cmd) + MAX_MIFARE_FRAME_SIZE);
uint8_t cmdlen = sizeof(block_cmd) + MAX_MIFARE_FRAME_SIZE;
uint8_t *cmd = BigBuf_calloc(cmdlen);
iso14a_card_select_t *card_info = (iso14a_card_select_t *) BigBuf_calloc(sizeof(iso14a_card_select_t));
LEDsoff();
@ -3175,7 +3182,7 @@ void MifareGen3Blk(uint8_t block_len, uint8_t *block) {
bool doReselect = false;
if (block_len < MIFARE_BLOCK_SIZE) {
if ((mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_READBLOCK, 0, &cmd[sizeof(block_cmd)], NULL, NULL) != MAX_MIFARE_FRAME_SIZE)) {
if ((mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_READBLOCK, 0, &cmd[sizeof(block_cmd)], MAX_MIFARE_FRAME_SIZE, NULL, NULL) != MAX_MIFARE_FRAME_SIZE)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Read manufacturer block failed");
retval = PM3_ESOFT;
goto OUT;
@ -3291,7 +3298,7 @@ void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd, uint8_t workFlags) {
AddCrc14A(cmd, sizeof(cmd) - 2);
ReaderTransmit(cmd, sizeof(cmd), NULL);
res = ReaderReceive(buf, par);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res != 18) {
retval = PM3_ESOFT;
@ -3376,7 +3383,7 @@ void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t work
AddCrc14A(cmd, sizeof(cmd) - 2);
ReaderTransmit(cmd, sizeof(cmd), NULL);
res = ReaderReceive(buf, par);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if ((res != 4) || (memcmp(buf, "\x90\x00\xfd\x07", 4) != 0)) {
retval = PM3_ESOFT;
@ -3438,7 +3445,7 @@ void MifareSetMod(uint8_t *datain) {
}
int respLen;
if (((respLen = mifare_sendcmd_short(pcs, CRYPT_ALL, MIFARE_EV1_SETMOD, mod, buf, par, NULL)) != 1) || (buf[0] != 0x0a)) {
if (((respLen = mifare_sendcmd_short(pcs, CRYPT_ALL, MIFARE_EV1_SETMOD, mod, buf, MAX_MIFARE_FRAME_SIZE, par, NULL)) != 1) || (buf[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("SetMod error; response[0]: %hhX, len: %d", buf[0], respLen);
break;
}

View file

@ -676,7 +676,7 @@ int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout) {
ReaderTransmit(wCmd, wrappedLen, NULL);
len = ReaderReceive(resp, par);
len = ReaderReceive(resp, sizeof(resp), par);
if (!len) {
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("fukked");
return false; //DATA LINK ERROR

View file

@ -77,25 +77,26 @@ uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data) {
}
// send X byte basic commands
uint16_t mifare_sendcmd(uint8_t cmd, uint8_t *data, uint8_t data_size, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) {
uint16_t mifare_sendcmd(uint8_t cmd, uint8_t *data, uint8_t data_size, uint8_t *answer, uint16_t answer_len, uint8_t *answer_parity, uint32_t *timing) {
uint8_t dcmd[data_size + 3];
dcmd[0] = cmd;
if (data_size > 0)
if (data_size > 0) {
memcpy(dcmd + 1, data, data_size);
}
AddCrc14A(dcmd, data_size + 1);
ReaderTransmit(dcmd, sizeof(dcmd), timing);
uint16_t len = ReaderReceive(answer, answer_parity);
uint16_t len = ReaderReceive(answer, answer_len, answer_parity);
if (len == 0) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("%02X Cmd failed. Card timeout.", cmd);
len = ReaderReceive(answer, answer_parity);
len = ReaderReceive(answer, answer_len, answer_parity);
}
return len;
}
// send 2 byte commands
uint16_t 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) {
uint16_t mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint16_t answer_len, uint8_t *answer_parity, uint32_t *timing) {
uint16_t pos;
uint8_t dcmd[4] = {cmd, data, 0x00, 0x00};
uint8_t ecmd[4] = {0x00, 0x00, 0x00, 0x00};
@ -114,7 +115,7 @@ uint16_t mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t
ReaderTransmit(dcmd, sizeof(dcmd), timing);
}
uint16_t len = ReaderReceive(answer, par);
uint16_t len = ReaderReceive(answer, answer_len, par);
if (answer_parity) {
*answer_parity = par[0];
@ -153,7 +154,7 @@ int mifare_classic_authex_cmd(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
// Transmit MIFARE_CLASSIC_AUTH, 0x60 for key A, 0x61 for key B, or 0x80 for GDM backdoor
int len = mifare_sendcmd_short(pcs, isNested, cmd, blockNo, receivedAnswer, receivedAnswerPar, timing);
int len = mifare_sendcmd_short(pcs, isNested, cmd, blockNo, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, timing);
if (len != 4) return 1;
// Save the tag nonce (nt)
@ -253,7 +254,7 @@ int mifare_classic_authex_cmd(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
iso14a_set_timeout(106);
// Receive 4 byte tag answer
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
len = ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar);
iso14a_set_timeout(save_timeout);
@ -279,7 +280,7 @@ int mifare_classic_readblock_ex(struct Crypto1State *pcs, uint8_t blockNo, uint8
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
uint16_t len = mifare_sendcmd_short(pcs, 1, iso_byte, blockNo, receivedAnswer, receivedAnswerPar, NULL);
uint16_t len = mifare_sendcmd_short(pcs, 1, iso_byte, blockNo, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, NULL);
if (len == 1) {
if (g_dbglevel >= DBG_ERROR) {
Dbprintf("Block " _YELLOW_("%3d") " Cmd 0x%02x Cmd Error %02x", blockNo, iso_byte, receivedAnswer[0]);
@ -317,7 +318,7 @@ int mifare_ul_ev1_auth(uint8_t *keybytes, uint8_t *pack) {
if (g_dbglevel >= DBG_EXTENDED)
Dbprintf("EV1 Auth : %02x%02x%02x%02x", key[0], key[1], key[2], key[3]);
len = mifare_sendcmd(MIFARE_ULEV1_AUTH, key, sizeof(key), resp, respPar, NULL);
len = mifare_sendcmd(MIFARE_ULEV1_AUTH, key, sizeof(key), resp, sizeof(resp), respPar, NULL);
if (len != 4) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x %u", resp[0], len);
@ -347,7 +348,7 @@ int mifare_ultra_auth(uint8_t *keybytes) {
uint8_t respPar[3] = {0, 0, 0};
// REQUEST AUTHENTICATION
len = mifare_sendcmd_short(NULL, CRYPT_NONE, MIFARE_ULC_AUTH_1, 0x00, resp, respPar, NULL);
len = mifare_sendcmd_short(NULL, CRYPT_NONE, MIFARE_ULC_AUTH_1, 0x00, resp, sizeof(resp), respPar, NULL);
if (len != 11) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]);
return 0;
@ -379,7 +380,7 @@ int mifare_ultra_auth(uint8_t *keybytes) {
// encrypt out, in, length, key, iv
tdes_nxp_send(rnd_ab, rnd_ab, sizeof(rnd_ab), key, enc_random_b, 2);
len = mifare_sendcmd(MIFARE_ULC_AUTH_2, rnd_ab, sizeof(rnd_ab), resp, respPar, NULL);
len = mifare_sendcmd(MIFARE_ULC_AUTH_2, rnd_ab, sizeof(rnd_ab), resp, sizeof(resp), respPar, NULL);
if (len != 11) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]);
return 0;
@ -441,7 +442,7 @@ int mifare_ultra_aes_auth(uint8_t keyno, uint8_t *keybytes) {
mbedtls_aes_setkey_dec(&actx, key, 128);
// Send REQUEST AUTHENTICATION / receive tag nonce
len = mifare_sendcmd_short(NULL, CRYPT_NONE, MIFARE_ULAES_AUTH_1, keyno, resp, respPar, NULL);
len = mifare_sendcmd_short(NULL, CRYPT_NONE, MIFARE_ULAES_AUTH_1, keyno, resp, sizeof(resp), respPar, NULL);
if (len != 19) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x - expected 19 got " _RED_("%u"), resp[0], len);
return 0;
@ -471,7 +472,7 @@ int mifare_ultra_aes_auth(uint8_t keyno, uint8_t *keybytes) {
mbedtls_aes_crypt_cbc(&actx, MBEDTLS_AES_ENCRYPT, sizeof(enc_rnd_ab), IV, rnd_ab, enc_rnd_ab);
// send & recieve
len = mifare_sendcmd(MIFARE_ULAES_AUTH_2, enc_rnd_ab, sizeof(enc_rnd_ab), resp, respPar, NULL);
len = mifare_sendcmd(MIFARE_ULAES_AUTH_2, enc_rnd_ab, sizeof(enc_rnd_ab), resp, sizeof(resp), respPar, NULL);
if (len != 19) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x - expected 19 got " _RED_("%u"), resp[0], len);
return 0;
@ -508,7 +509,7 @@ static int mifare_ultra_readblockEx(uint8_t blockNo, uint8_t *blockData) {
uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00};
uint8_t receivedAnswerPar[MAX_PARITY_SIZE] = {0x00};
len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);
len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, NULL);
if (len == 1) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
return 1;
@ -558,7 +559,7 @@ int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint8_t blockNo, uint
// cmd is ISO14443A_CMD_WRITEBLOCK for normal tags, but could also be
// MIFARE_MAGIC_GDM_WRITEBLOCK or MIFARE_MAGIC_GDM_WRITE_CFG for certain magic tags
uint16_t len = mifare_sendcmd_short(pcs, 1, cmd, blockNo, receivedAnswer, receivedAnswerPar, NULL);
uint16_t len = mifare_sendcmd_short(pcs, 1, cmd, blockNo, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, NULL);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
if (g_dbglevel >= DBG_INFO) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
@ -588,7 +589,7 @@ int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint8_t blockNo, uint
return PM3_ETEAROFF;
} else {
// Receive the response
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
len = ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar);
uint8_t res = 0;
if (pcs) {
@ -626,7 +627,7 @@ int mifare_classic_value(struct Crypto1State *pcs, uint8_t blockNo, uint8_t *blo
command = MIFARE_CMD_RESTORE;
// Send increment or decrement command
len = mifare_sendcmd_short(pcs, 1, command, blockNo, receivedAnswer, receivedAnswerPar, NULL);
len = mifare_sendcmd_short(pcs, 1, command, blockNo, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, NULL);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
if (g_dbglevel >= DBG_INFO) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
@ -645,7 +646,7 @@ int mifare_classic_value(struct Crypto1State *pcs, uint8_t blockNo, uint8_t *blo
ReaderTransmitPar(d_block_enc, 6, par, NULL);
// Receive the response NO Response means OK ... i.e. NOT NACK
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
len = ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar);
if (len != 0) { // Something not right, len == 0 (no response is ok as its waiting for transfer
uint8_t res = 0;
@ -671,7 +672,7 @@ int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData) {
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);
len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, NULL);
if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
if (g_dbglevel >= DBG_INFO) {
@ -686,7 +687,7 @@ int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData) {
ReaderTransmit(d_block, sizeof(d_block), NULL);
// Receive the response
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
len = ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar);
if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
if (g_dbglevel >= DBG_INFO) {
@ -706,7 +707,7 @@ int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) {
// command MIFARE_CLASSIC_WRITEBLOCK
memcpy(block + 1, blockData, 4);
len = mifare_sendcmd(MIFARE_ULC_WRITE, block, sizeof(block), receivedAnswer, receivedAnswerPar, NULL);
len = mifare_sendcmd(MIFARE_ULC_WRITE, block, sizeof(block), receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, NULL);
if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
if (g_dbglevel >= DBG_INFO) {
@ -719,7 +720,7 @@ int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) {
int mifare_classic_halt(struct Crypto1State *pcs) {
uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00};
uint16_t len = mifare_sendcmd_short(pcs, (pcs == NULL) ? CRYPT_NONE : CRYPT_ALL, ISO14443A_CMD_HALT, 0x00, receivedAnswer, NULL, NULL);
uint16_t len = mifare_sendcmd_short(pcs, (pcs == NULL) ? CRYPT_NONE : CRYPT_ALL, ISO14443A_CMD_HALT, 0x00, receivedAnswer, sizeof(receivedAnswer), NULL, NULL);
if (len != 0) {
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("halt warning. response len: %x", len);
return 1;
@ -841,12 +842,12 @@ bool IsSectorTrailer(uint8_t blockNo) {
}
// Mifare desfire commands
int mifare_sendcmd_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_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint16_t answer_len, uint8_t *answer_parity, uint32_t *timing) {
uint8_t dcmd[5] = {cmd, data[0], data[1], 0x00, 0x00};
AddCrc14A(dcmd, 3);
ReaderTransmit(dcmd, sizeof(dcmd), NULL);
int len = ReaderReceive(answer, answer_parity);
int len = ReaderReceive(answer, answer_len, answer_parity);
if (!len) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Authentication failed. Card timeout.");
return 1;
@ -854,14 +855,14 @@ int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cm
return len;
}
int mifare_sendcmd_special2(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_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint16_t answer_len, uint8_t *answer_parity, uint32_t *timing) {
uint8_t dcmd[20] = {0x00};
dcmd[0] = cmd;
memcpy(dcmd + 1, data, 17);
AddCrc14A(dcmd, 18);
ReaderTransmit(dcmd, sizeof(dcmd), NULL);
int len = ReaderReceive(answer, answer_parity);
int len = ReaderReceive(answer, answer_len, answer_parity);
if (!len) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Authentication failed. Card timeout.");
return 1;
@ -877,7 +878,7 @@ int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData) {
uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00};
uint8_t receivedAnswerPar[MAX_PARITY_SIZE] = {0x00};
len = mifare_sendcmd_special(NULL, 1, 0x02, data, receivedAnswer, receivedAnswerPar, NULL);
len = mifare_sendcmd_special(NULL, 1, 0x02, data, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, NULL);
if (len == 1) {
if (g_dbglevel >= DBG_INFO) {
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
@ -907,7 +908,7 @@ int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData) {
uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00};
uint8_t receivedAnswerPar[MAX_PARITY_SIZE] = {0x00};
len = mifare_sendcmd_special2(NULL, 1, 0x03, data, receivedAnswer, receivedAnswerPar, NULL);
len = mifare_sendcmd_special2(NULL, 1, 0x03, data, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, NULL);
if ((receivedAnswer[0] == 0x03) && (receivedAnswer[1] == 0xae)) {
if (g_dbglevel >= DBG_ERROR) {

View file

@ -68,8 +68,9 @@
#endif
//functions
uint16_t mifare_sendcmd(uint8_t cmd, uint8_t *data, uint8_t data_size, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing);
uint16_t 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);
uint16_t mifare_sendcmd(uint8_t cmd, uint8_t *data, uint8_t data_size, uint8_t *answer, uint16_t answer_len, uint8_t *answer_parity, uint32_t *timing);
uint16_t mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data,
uint8_t *answer, uint16_t answer_len, uint8_t *answer_parity, uint32_t *timing);
// mifare classic
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested);
@ -94,8 +95,8 @@ int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData);
int mifare_ultra_halt(void);
// desfire
int mifare_sendcmd_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_special2(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_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint16_t answer_len, uint8_t *answer_parity, uint32_t *timing);
int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint16_t answer_len, uint8_t *answer_parity, uint32_t *timing);
int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData);
int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData);

View file

@ -46,7 +46,7 @@ void ReadThinFilm(void) {
uint8_t buf[36] = {0x00};
// power on and listen for answer.
bool status = GetIso14443aAnswerFromTag_Thinfilm(buf, &len);
bool status = GetIso14443aAnswerFromTag_Thinfilm(buf, sizeof(buf), &len);
reply_ng(CMD_HF_THINFILM_READ, status ? PM3_SUCCESS : PM3_ENODATA, buf, len);
hf_field_off();

View file

@ -5056,9 +5056,13 @@
"--addauth auth(blk)-auth(blk)-auth(blk2)",
"--incblk2 auth(blk)-auth(blk2)-auth(blk2+4)-...",
"--corruptnrar corrupt {nR}{aR}, but with correct parity",
"--corruptnrarparity correct {nR}{aR}, but with corrupted parity"
"--corruptnrarparity correct {nR}{aR}, but with corrupted parity",
"",
"FM11RF08S specific options: Incompatible with above options, except -k; output in JSON",
"--collect_fm11rf08s collect all nT/{nT}/par_err.",
"--collect_fm11rf08s_with_data collect all nT/{nT}/par_err and data blocks."
],
"usage": "hf mf isen [-hab] [--blk <dec>] [-c <dec>] [-k <hex>] [--blk2 <dec>] [--a2] [--b2] [--c2 <dec>] [--key2 <hex>] [-n <dec>] [--reset] [--hardreset] [--addread] [--addauth] [--incblk2] [--corruptnrar] [--corruptnrarparity]"
"usage": "hf mf isen [-hab] [--blk <dec>] [-c <dec>] [-k <hex>] [--blk2 <dec>] [--a2] [--b2] [--c2 <dec>] [--key2 <hex>] [-n <dec>] [--reset] [--hardreset] [--addread] [--addauth] [--incblk2] [--corruptnrar] [--corruptnrarparity] FM11RF08S specific options: [--collect_fm11rf08s] [--collect_fm11rf08s_with_data]"
},
"hf mf mad": {
"command": "hf mf mad",
@ -9725,7 +9729,7 @@
"command": "lf hitag hts read",
"description": "Read Hitag S memory. Crypto mode: - key format ISK high + ISK low - default key 4F4E4D494B52 (ONMIKR)",
"notes": [
"lf hitag s read -> Hitag S, plain mode",
"lf hitag hts read -> Hitag S, plain mode",
"lf hitag hts read --nrar 0102030411223344 -> Hitag S, challenge mode",
"lf hitag hts read --crypto -> Hitag S, crypto mode, def key",
"lf hitag hts read -k 4F4E4D494B52 -> Hitag S, crypto mode"
@ -9743,7 +9747,7 @@
"command": "lf hitag hts write",
"description": "Write a page in Hitag S memory. Crypto mode: - key format ISK high + ISK low - default key 4F4E4D494B52 (ONMIKR)",
"notes": [
"lf hitag write -p 6 -d 01020304 -> Hitag S, plain mode",
"lf hitag hts write -p 6 -d 01020304 -> Hitag S, plain mode",
"lf hitag hts write -p 6 -d 01020304 --nrar 0102030411223344 -> Hitag S, challenge mode",
"lf hitag hts write -p 6 -d 01020304 --crypto -> Hitag S, crypto mode, default key",
"lf hitag hts write -p 6 -d 01020304 -k 4F4E4D494B52 -> Hitag S, crypto mode"
@ -12881,6 +12885,6 @@
"metadata": {
"commands_extracted": 743,
"extracted_by": "PM3Help2JSON v1.00",
"extracted_on": "2024-08-29T10:28:11"
"extracted_on": "2024-09-05T15:50:04"
}
}