From 9c181dd83dc7cc45c4b4cd2da9db1dc5dbce0372 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 5 Sep 2024 17:52:10 +0200 Subject: [PATCH] step one of bounds checking all responses when receiving ISO14443A frames... because @doegox find a missbehaving IC clone..... --- armsrc/Standalone/hf_bog.c | 2 +- armsrc/Standalone/hf_cardhopper.c | 2 +- armsrc/Standalone/hf_colin.c | 12 ++-- armsrc/epa.c | 4 +- armsrc/iclass.c | 6 +- armsrc/iso14443a.c | 69 ++++++++++---------- armsrc/iso14443a.h | 9 +-- armsrc/mifarecmd.c | 105 ++++++++++++++++-------------- armsrc/mifaredesfire.c | 2 +- armsrc/mifareutil.c | 59 ++++++++--------- armsrc/mifareutil.h | 9 +-- armsrc/thinfilm.c | 2 +- doc/commands.json | 14 ++-- 13 files changed, 156 insertions(+), 139 deletions(-) diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index 2f28c409c..9e458a2cf 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -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); diff --git a/armsrc/Standalone/hf_cardhopper.c b/armsrc/Standalone/hf_cardhopper.c index 45181b0d9..21b162cfb 100644 --- a/armsrc/Standalone/hf_cardhopper.c +++ b/armsrc/Standalone/hf_cardhopper.c @@ -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)); diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 044d3aba3..143f97c4f 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -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; }; diff --git a/armsrc/epa.c b/armsrc/epa.c index 8406f6168..aa0f87230 100644 --- a/armsrc/epa.c +++ b/armsrc/epa.c @@ -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; } diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 72b5ca8f2..3d83e54bc 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -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!")); } diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index c0ad1aaec..ef8bea8c3 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -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. diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index 37913b029..3b3053def 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -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; diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index f2b669593..d4152cfb6 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -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; } diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index a04d5d915..8326327db 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -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 diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index c95d9a316..0ad60d2d4 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -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) { diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index fb4da4543..b1ae83021 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -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); diff --git a/armsrc/thinfilm.c b/armsrc/thinfilm.c index bdc4d7d11..150189f8f 100644 --- a/armsrc/thinfilm.c +++ b/armsrc/thinfilm.c @@ -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(); diff --git a/doc/commands.json b/doc/commands.json index 86150f560..878c7bca8 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -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 ] [-c ] [-k ] [--blk2 ] [--a2] [--b2] [--c2 ] [--key2 ] [-n ] [--reset] [--hardreset] [--addread] [--addauth] [--incblk2] [--corruptnrar] [--corruptnrarparity]" + "usage": "hf mf isen [-hab] [--blk ] [-c ] [-k ] [--blk2 ] [--a2] [--b2] [--c2 ] [--key2 ] [-n ] [--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" } }