@@ -314,11 +314,69 @@ static int CmdFlashMemSpiFFSDump(const char *Cmd) {
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int flashmem_spiffs_load(uint8_t *destfn, uint8_t *data, size_t datalen) {
|
||||
|
||||
int ret_val = PM3_SUCCESS;
|
||||
|
||||
// We want to mount before multiple operation so the lazy writes/append will not
|
||||
// trigger a mount + umount each loop iteration (lazy ops device side)
|
||||
SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0);
|
||||
|
||||
// Send to device
|
||||
uint32_t bytes_sent = 0;
|
||||
uint32_t bytes_remaining = datalen;
|
||||
uint32_t append = 0;
|
||||
|
||||
// fast push mode
|
||||
conn.block_after_ACK = true;
|
||||
|
||||
while (bytes_remaining > 0) {
|
||||
uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining);
|
||||
|
||||
clearCommandBuffer();
|
||||
|
||||
char fdata[32 + bytes_in_packet];
|
||||
memset(fdata, 0, sizeof(fdata));
|
||||
memcpy(fdata, destfn, 32);
|
||||
memcpy(fdata + 32, data + bytes_sent, bytes_in_packet);
|
||||
|
||||
if (bytes_sent > 0)
|
||||
append = 1;
|
||||
|
||||
SendCommandOLD(CMD_SPIFFS_WRITE, append, bytes_in_packet, 0, fdata, 32 + bytes_in_packet);
|
||||
|
||||
bytes_remaining -= bytes_in_packet;
|
||||
bytes_sent += bytes_in_packet;
|
||||
|
||||
PacketResponseNG resp;
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||
ret_val = PM3_ETIMEOUT;
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t isok = resp.oldarg[0] & 0xFF;
|
||||
if (!isok) {
|
||||
PrintAndLogEx(FAILED, "Flash write fail [offset %u]", bytes_sent);
|
||||
ret_val = PM3_EFLASH;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// turn off fast push mode
|
||||
conn.block_after_ACK = false;
|
||||
|
||||
// We want to unmount after these to set things back to normal but more than this
|
||||
// unmouting ensure that SPIFFS CACHES are all flushed so our file is actually written on memory
|
||||
SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static int CmdFlashMemSpiFFSLoad(const char *Cmd) {
|
||||
|
||||
uint32_t append = 0;
|
||||
char filename[FILE_PATH_SIZE] = {0};
|
||||
char destfilename[32] = {0};
|
||||
uint8_t destfilename[32] = {0};
|
||||
bool errors = false;
|
||||
uint8_t cmdp = 0;
|
||||
|
||||
@@ -334,8 +392,8 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) {
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'o':
|
||||
param_getstr(Cmd, cmdp + 1, destfilename, 32);
|
||||
if (strlen(destfilename) == 0) {
|
||||
param_getstr(Cmd, cmdp + 1, (char*)destfilename, 32);
|
||||
if (strlen((char*)destfilename) == 0) {
|
||||
PrintAndLogEx(FAILED, "Destination Filename missing or invalid");
|
||||
errors = true;
|
||||
}
|
||||
@@ -362,63 +420,14 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) {
|
||||
return PM3_EFILE;
|
||||
}
|
||||
|
||||
// We want to mount before multiple operation so the lazy writes/append will not
|
||||
// trigger a mount + umount each loop iteration (lazy ops device side)
|
||||
SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0);
|
||||
|
||||
// Send to device
|
||||
uint32_t bytes_sent = 0;
|
||||
uint32_t bytes_remaining = datalen;
|
||||
|
||||
// fast push mode
|
||||
conn.block_after_ACK = true;
|
||||
|
||||
// SendCommandMIX(CMD_SPIFFS_COPY, 0, 0, 0, (uint8_t *)data, 65);
|
||||
|
||||
while (bytes_remaining > 0) {
|
||||
uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining);
|
||||
|
||||
clearCommandBuffer();
|
||||
|
||||
char fdata[32 + bytes_in_packet];
|
||||
memset(fdata, 0, sizeof(fdata));
|
||||
memcpy(fdata, destfilename, 32);
|
||||
memcpy(fdata + 32, data + bytes_sent, bytes_in_packet);
|
||||
// sprintf(fdata, "%s%s", destfilename, data + bytes_sent);
|
||||
|
||||
if (bytes_sent > 0)
|
||||
append = 1;
|
||||
|
||||
SendCommandOLD(CMD_SPIFFS_WRITE, append, bytes_in_packet, 0, fdata, 32 + bytes_in_packet);
|
||||
|
||||
bytes_remaining -= bytes_in_packet;
|
||||
bytes_sent += bytes_in_packet;
|
||||
|
||||
PacketResponseNG resp;
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||
conn.block_after_ACK = false;
|
||||
free(data);
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
uint8_t isok = resp.oldarg[0] & 0xFF;
|
||||
if (!isok) {
|
||||
conn.block_after_ACK = false;
|
||||
PrintAndLogEx(FAILED, "Flash write fail [offset %u]", bytes_sent);
|
||||
free(data);
|
||||
return PM3_EFLASH;
|
||||
}
|
||||
}
|
||||
|
||||
conn.block_after_ACK = false;
|
||||
res = flashmem_spiffs_load(destfilename, data, datalen);
|
||||
|
||||
free(data);
|
||||
PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%zu") "bytes to file "_GREEN_("%s"), datalen, destfilename);
|
||||
|
||||
// We want to unmount after these to set things back to normal but more than this
|
||||
// unmouting ensure that SPIFFS CACHES are all flushed so our file is actually written on memory
|
||||
SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0);
|
||||
return PM3_SUCCESS;
|
||||
|
||||
if ( res == PM3_SUCCESS )
|
||||
PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%zu") "bytes to file "_GREEN_("%s"), datalen, destfilename);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
|
||||
@@ -14,5 +14,6 @@
|
||||
#include "common.h"
|
||||
|
||||
int CmdFlashMemSpiFFS(const char *Cmd);
|
||||
int flashmem_spiffs_load(uint8_t *destfn, uint8_t *data, size_t datalen);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -85,8 +85,6 @@ int CmdHFSearch(const char *Cmd) {
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_hf_search();
|
||||
|
||||
PrintAndLogEx(INFO, "Checking for known tags...");
|
||||
|
||||
PROMPT_CLEARLINE;
|
||||
PrintAndLogEx(INPLACE, "Searching for ThinFilm tag...");
|
||||
if (IfPm3NfcBarcode()) {
|
||||
@@ -170,9 +168,8 @@ int CmdHFSearch(const char *Cmd) {
|
||||
}
|
||||
|
||||
PROMPT_CLEARLINE;
|
||||
PrintAndLogEx(INPLACE, "done");
|
||||
PrintAndLogEx(INPLACE, _RED_("No known/supported 13.56 MHz tags found"));
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(FAILED, _RED_("No known/supported 13.56 MHz tags found"));
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
@@ -272,15 +269,16 @@ static command_t CommandTable[] = {
|
||||
{"15", CmdHF15, AlwaysAvailable, "{ ISO15693 RFIDs... }"},
|
||||
{"epa", CmdHFEPA, AlwaysAvailable, "{ German Identification Card... }"},
|
||||
{"felica", CmdHFFelica, AlwaysAvailable, "{ ISO18092 / Felica RFIDs... }"},
|
||||
{"legic", CmdHFLegic, AlwaysAvailable, "{ LEGIC RFIDs... }"},
|
||||
{"fido", CmdHFFido, AlwaysAvailable, "{ FIDO and FIDO2 authenticators... }"},
|
||||
{"iclass", CmdHFiClass, AlwaysAvailable, "{ ICLASS RFIDs... }"},
|
||||
{"legic", CmdHFLegic, AlwaysAvailable, "{ LEGIC RFIDs... }"},
|
||||
{"lto", CmdHFLTO, AlwaysAvailable, "{ LTO Cartridge Memory RFIDs... }"},
|
||||
{"mf", CmdHFMF, AlwaysAvailable, "{ MIFARE RFIDs... }"},
|
||||
{"mfp", CmdHFMFP, AlwaysAvailable, "{ MIFARE Plus RFIDs... }"},
|
||||
{"mfu", CmdHFMFUltra, AlwaysAvailable, "{ MIFARE Ultralight RFIDs... }"},
|
||||
{"mfdes", CmdHFMFDes, AlwaysAvailable, "{ MIFARE Desfire RFIDs... }"},
|
||||
{"topaz", CmdHFTopaz, AlwaysAvailable, "{ TOPAZ (NFC Type 1) RFIDs... }"},
|
||||
{"fido", CmdHFFido, AlwaysAvailable, "{ FIDO and FIDO2 authenticators... }"},
|
||||
{"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"},
|
||||
{"topaz", CmdHFTopaz, AlwaysAvailable, "{ TOPAZ (NFC Type 1) RFIDs... }"},
|
||||
{"list", CmdTraceList, AlwaysAvailable, "List protocol data in trace buffer"},
|
||||
{"plot", CmdHFPlot, IfPm3Hfplot, "Plot signal"},
|
||||
{"tune", CmdHFTune, IfPm3Present, "Continuously measure HF antenna tuning"},
|
||||
|
||||
@@ -2805,6 +2805,7 @@ int readIclass(bool loop, bool verbose) {
|
||||
FLAG_ICLASS_READER_CONF | FLAG_ICLASS_READER_ONLY_ONCE |
|
||||
FLAG_ICLASS_READER_ONE_TRY;
|
||||
|
||||
uint32_t res = PM3_ETIMEOUT;
|
||||
// loop in client not device - else on windows have a communication error
|
||||
while (!kbd_enter_pressed()) {
|
||||
|
||||
@@ -2876,6 +2877,6 @@ int readIclass(bool loop, bool verbose) {
|
||||
if (!loop) break;
|
||||
}
|
||||
DropField();
|
||||
return PM3_SUCCESS;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -1101,10 +1101,10 @@ void annotateLTO(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
|
||||
snprintf(exp, size, "REQ Standard");
|
||||
break;
|
||||
case LTO_SELECT:
|
||||
snprintf(exp, size, "SELECT");
|
||||
break;
|
||||
case LTO_SELECT_1:
|
||||
snprintf(exp, size, "SELECT_1");
|
||||
if (cmd[1] == 0x70)
|
||||
snprintf(exp, size, "SELECT_UID-2");
|
||||
else if (cmd[1] == 0x20)
|
||||
snprintf(exp, size, "SELECT");
|
||||
break;
|
||||
case LTO_REQ_ALL:
|
||||
snprintf(exp, size, "REQ All");
|
||||
|
||||
@@ -42,9 +42,17 @@ static void lto_switch_on_field(void) {
|
||||
}
|
||||
|
||||
// send a raw LTO-CM command, returns the length of the response (0 in case of error)
|
||||
static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t *response_len, bool verbose) {
|
||||
static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t *response_len, bool addcrc, bool verbose) {
|
||||
|
||||
SendCommandOLD(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, len, 0, cmd, len);
|
||||
uint64_t arg0 = ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS;
|
||||
uint32_t arg1 = (len == 1) ? (7 << 16) : 0;
|
||||
arg1 |= len;
|
||||
|
||||
if (addcrc) {
|
||||
arg0 |= ISO14A_APPEND_CRC;
|
||||
}
|
||||
|
||||
SendCommandOLD(CMD_HF_ISO14443A_READER, arg0, arg1, 0, cmd, len);
|
||||
PacketResponseNG resp;
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
@@ -55,7 +63,6 @@ static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16
|
||||
if (resp.oldarg[0] == *response_len) {
|
||||
*response_len = resp.oldarg[0];
|
||||
|
||||
PrintAndLogEx(INFO, "%s", sprint_hex(resp.data.asBytes, *response_len));
|
||||
if (*response_len > 0) {
|
||||
memcpy(response, resp.data.asBytes, *response_len);
|
||||
}
|
||||
@@ -66,7 +73,6 @@ static int lto_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint16
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// select a LTO-CM tag. Send WUPA and RID.
|
||||
static int lto_select(uint8_t *id_response, uint8_t id_len, bool verbose) {
|
||||
// Todo: implement anticollision
|
||||
@@ -75,26 +81,27 @@ static int lto_select(uint8_t *id_response, uint8_t id_len, bool verbose) {
|
||||
uint16_t resp_len;
|
||||
uint8_t wupa_cmd[] = {LTO_REQ_STANDARD};
|
||||
uint8_t select_cmd[] = {LTO_SELECT, 0x20};
|
||||
uint8_t select_1_cmd[] = {LTO_SELECT_1, 0x70, 0, 0, 0, 0, 0};
|
||||
uint8_t select_1_cmd[] = {LTO_SELECT, 0x70, 0, 0, 0, 0, 0};
|
||||
|
||||
lto_switch_on_field();
|
||||
|
||||
resp_len = 2;
|
||||
int status = lto_send_cmd_raw(wupa_cmd, sizeof(wupa_cmd), resp, &resp_len, verbose);
|
||||
int status = lto_send_cmd_raw(wupa_cmd, sizeof(wupa_cmd), resp, &resp_len, false, verbose);
|
||||
if (status == PM3_ETIMEOUT || status == PM3_ESOFT) {
|
||||
lto_switch_off_field();
|
||||
return PM3_ESOFT; // WUPA failed
|
||||
}
|
||||
|
||||
resp_len = id_len;
|
||||
status = lto_send_cmd_raw(select_cmd, sizeof(select_cmd), id_response, &resp_len, verbose);
|
||||
status = lto_send_cmd_raw(select_cmd, sizeof(select_cmd), id_response, &resp_len, false, verbose);
|
||||
if (status == PM3_ETIMEOUT || status == PM3_ESOFT) {
|
||||
lto_switch_off_field();
|
||||
return PM3_EWRONGANSVER; // SELECT failed
|
||||
}
|
||||
|
||||
memcpy(select_1_cmd + 2, id_response, sizeof(select_1_cmd) - 2);
|
||||
resp_len = 1;
|
||||
status = lto_send_cmd_raw(select_1_cmd, sizeof(select_1_cmd), resp, &resp_len, verbose);
|
||||
status = lto_send_cmd_raw(select_1_cmd, sizeof(select_1_cmd), resp, &resp_len, true, verbose);
|
||||
if (status == PM3_ETIMEOUT || status == PM3_ESOFT || resp[0] != 0x0A) {
|
||||
lto_switch_off_field();
|
||||
return PM3_EWRONGANSVER; // SELECT failed
|
||||
@@ -104,7 +111,6 @@ static int lto_select(uint8_t *id_response, uint8_t id_len, bool verbose) {
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int CmdHfLTOInfo(const char *Cmd) {
|
||||
|
||||
uint8_t cmdp = 0;
|
||||
@@ -126,7 +132,7 @@ static int CmdHfLTOInfo(const char *Cmd) {
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
return infoLTO(true);
|
||||
return infoLTO(false);
|
||||
}
|
||||
|
||||
int infoLTO(bool verbose) {
|
||||
@@ -134,18 +140,20 @@ int infoLTO(bool verbose) {
|
||||
clearCommandBuffer();
|
||||
|
||||
uint8_t serial_number[5];
|
||||
uint8_t serial_len = 0;
|
||||
|
||||
uint8_t serial_len = sizeof(serial_number);
|
||||
int ret_val = lto_select(serial_number, serial_len, verbose);
|
||||
|
||||
lto_switch_off_field();
|
||||
/*
|
||||
|
||||
-- "hf 14a raw -a -p -b 7 45"
|
||||
-- "hf 14a raw -c -p 9320"
|
||||
-- "hf 14a raw -c -p 9370%s", serial_number
|
||||
-- "disconnect"
|
||||
if (ret_val == PM3_SUCCESS) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(SUCCESS, " UID : " _YELLOW_("%s"), sprint_hex_inrow(serial_number, sizeof(serial_number)));
|
||||
PrintAndLogEx(SUCCESS, "TYPE : ");
|
||||
// todo: add printing of all configuration
|
||||
} else {
|
||||
if (verbose) PrintAndLogEx(WARNING, "LTO-CM card select failed");
|
||||
}
|
||||
|
||||
/* read block:
|
||||
|
||||
SendCommandNG(CMD_HF_THINFILM_READ, NULL, 0);
|
||||
PacketResponseNG resp;
|
||||
|
||||
@@ -339,7 +339,7 @@ int CmdLFCommandRead(const char *Cmd) {
|
||||
// bitbang mode
|
||||
if (payload.delay == 0) {
|
||||
if (payload.zeros < 7 || payload.ones < 7) {
|
||||
PrintAndLogEx(WARNING, "Warning periods cannot be less than 7us in bit bang mode");
|
||||
PrintAndLogEx(WARNING, "warning periods cannot be less than 7us in bit bang mode");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
}
|
||||
@@ -347,15 +347,14 @@ int CmdLFCommandRead(const char *Cmd) {
|
||||
//Validations
|
||||
if (errors || cmdp == 0) return usage_lf_cmdread();
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Sending");
|
||||
PrintAndLogEx(SUCCESS, "sending");
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_LF_MOD_THEN_ACQ_RAW_ADC, (uint8_t *)&payload, 8 + datalen);
|
||||
|
||||
printf("\n");
|
||||
|
||||
PacketResponseNG resp;
|
||||
|
||||
uint8_t i = 10;
|
||||
// 20sec wait loop
|
||||
while (!WaitForResponseTimeout(CMD_LF_MOD_THEN_ACQ_RAW_ADC, &resp, 2000) && i != 0) {
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
@@ -365,15 +364,15 @@ int CmdLFCommandRead(const char *Cmd) {
|
||||
|
||||
if (resp.status == PM3_SUCCESS) {
|
||||
if (i) {
|
||||
PrintAndLogEx(SUCCESS, "Downloading response signal data");
|
||||
getSamples(0, false);
|
||||
PrintAndLogEx(SUCCESS, "downloading response signal data");
|
||||
getSamples(0, true);
|
||||
return PM3_SUCCESS;
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
}
|
||||
PrintAndLogEx(WARNING, "Command failed.");
|
||||
PrintAndLogEx(WARNING, "command failed.");
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
@@ -1214,17 +1213,18 @@ int CmdLFfind(const char *Cmd) {
|
||||
|
||||
// only run these tests if device is online
|
||||
if (isOnline) {
|
||||
|
||||
if (IfPm3Hitag()) {
|
||||
if (readHitagUid()) {
|
||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") "found!");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
// only run if graphbuffer is just noise as it should be for hitag
|
||||
// The improved noise detection will find Cotag.
|
||||
if (getSignalProperties()->isnoise) {
|
||||
|
||||
if (IfPm3Hitag()) {
|
||||
if (readHitagUid()) {
|
||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") "found!");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (readMotorolaUid()) {
|
||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Motorola FlexPass ID") "found!");
|
||||
return PM3_SUCCESS;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "commonutil.h"
|
||||
#include "hitag.h"
|
||||
#include "fileutils.h" // savefile
|
||||
#include "protocols.h" // defines
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
@@ -35,7 +36,7 @@ static int usage_hitag_sniff(void) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " lf hitag sniff");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
static int usage_hitag_sim(void) {
|
||||
PrintAndLogEx(NORMAL, "Simulate " _YELLOW_("Hitag2 / HitagS")" transponder");
|
||||
@@ -49,7 +50,7 @@ static int usage_hitag_sim(void) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " lf hitag sim 2 b lf-hitag-dump");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
static int usage_hitag_info(void) {
|
||||
PrintAndLogEx(NORMAL, "Usage: lf hitag info [h] p <pwd>");
|
||||
@@ -58,7 +59,7 @@ static int usage_hitag_info(void) {
|
||||
PrintAndLogEx(NORMAL, " p <pwd> password");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " lf hitag info");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
/*
|
||||
static int usage_hitag_dump(void) {
|
||||
@@ -71,7 +72,7 @@ static int usage_hitag_dump(void) {
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " lf hitag dump f mydump");
|
||||
PrintAndLogEx(NORMAL, " lf hitag dump p 4D494B52 f mydump");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
*/
|
||||
static int usage_hitag_reader(void) {
|
||||
@@ -85,12 +86,12 @@ static int usage_hitag_reader(void) {
|
||||
PrintAndLogEx(NORMAL, " Hitag1 (1*)");
|
||||
PrintAndLogEx(NORMAL, " Not implemented");
|
||||
PrintAndLogEx(NORMAL, " Hitag2 (2*)");
|
||||
PrintAndLogEx(NORMAL, " 21 <password> Read all pages, password mode. Default: 4D494B52 (\"MIKR\")");
|
||||
PrintAndLogEx(NORMAL, " 21 <password> Read all pages, password mode. Default: " _YELLOW_("4D494B52") "(\"MIKR\")");
|
||||
PrintAndLogEx(NORMAL, " 22 <nr> <ar> Read all pages, challenge mode");
|
||||
PrintAndLogEx(NORMAL, " 23 <key> Read all pages, crypto mode. Key format: ISK high + ISK low. Default: 4F4E4D494B52 (\"ONMIKR\")");
|
||||
PrintAndLogEx(NORMAL, " 23 <key> Read all pages, crypto mode. Key format: ISK high + ISK low. Default: " _YELLOW_("4F4E4D494B52") "(\"ONMIKR\")");
|
||||
PrintAndLogEx(NORMAL, " 25 Test recorded authentications");
|
||||
PrintAndLogEx(NORMAL, " 26 Just read UID");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
static int usage_hitag_writer(void) {
|
||||
PrintAndLogEx(NORMAL, "Hitag writer functions");
|
||||
@@ -106,7 +107,7 @@ static int usage_hitag_writer(void) {
|
||||
PrintAndLogEx(NORMAL, " 24 <key> <page> <byte0...byte3> Write page, crypto mode. Key format: ISK high + ISK low.");
|
||||
PrintAndLogEx(NORMAL, " Default: 4F4E4D494B52 (\"ONMIKR\"). Set key=0 for no auth");
|
||||
PrintAndLogEx(NORMAL, " 27 <password> <page> <byte0...byte3> Write page, password mode. Default: 4D494B52 (\"MIKR\")");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
static int usage_hitag_checkchallenges(void) {
|
||||
PrintAndLogEx(NORMAL, "Check challenges, load a file with save hitag crypto challenges and test them all.");
|
||||
@@ -119,19 +120,19 @@ static int usage_hitag_checkchallenges(void) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " lf hitag cc f lf-hitag-challenges");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdLFHitagList(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdTraceList("hitag");
|
||||
return 0;
|
||||
CmdTraceList("hitag2");
|
||||
return PM3_SUCCESS;
|
||||
|
||||
/*
|
||||
uint8_t *got = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t));
|
||||
if (!got) {
|
||||
PrintAndLogEx(WARNING, "Cannot allocate memory for trace");
|
||||
return 2;
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
|
||||
// Query for the actual size of the trace
|
||||
@@ -139,7 +140,7 @@ static int CmdLFHitagList(const char *Cmd) {
|
||||
if (!GetFromDevice(BIG_BUF, got, PM3_CMD_DATA_SIZE, 0, NULL, 0, &response, 2500, false)) {
|
||||
PrintAndLogEx(WARNING, "command execution time out");
|
||||
free(got);
|
||||
return 2;
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
uint16_t traceLen = response.arg[2];
|
||||
@@ -148,13 +149,13 @@ static int CmdLFHitagList(const char *Cmd) {
|
||||
if (p == NULL) {
|
||||
PrintAndLogEx(WARNING, "Cannot allocate memory for trace");
|
||||
free(got);
|
||||
return 2;
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
got = p;
|
||||
if (!GetFromDevice(BIG_BUF, got, traceLen, 0, NULL, 0, NULL, 2500, false)) {
|
||||
PrintAndLogEx(WARNING, "command execution time out");
|
||||
free(got);
|
||||
return 2;
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,7 +252,7 @@ static int CmdLFHitagList(const char *Cmd) {
|
||||
}
|
||||
|
||||
free(got);
|
||||
return 0;
|
||||
return PM3_SUCCES;
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -262,7 +263,7 @@ static int CmdLFHitagSniff(const char *Cmd) {
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_LF_HITAG_SNIFF, NULL, 0);
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdLFHitagSim(const char *Cmd) {
|
||||
@@ -343,7 +344,7 @@ static int CmdLFHitagSim(const char *Cmd) {
|
||||
}
|
||||
|
||||
free(data);
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static void printHitagConfiguration(uint8_t config) {
|
||||
@@ -483,21 +484,20 @@ static int CmdLFHitagInfo(const char *Cmd) {
|
||||
// read UID
|
||||
uint32_t uid = 0;
|
||||
if (getHitagUid(&uid) == false)
|
||||
return 1;
|
||||
return PM3_ESOFT;
|
||||
|
||||
PrintAndLogEx(SUCCESS, "UID: %08X", uid);
|
||||
PrintAndLogEx(SUCCESS, "UID: " _YELLOW_("%08X"), uid);
|
||||
|
||||
// how to detemine Hitag types?
|
||||
// read block3, get configuration byte.
|
||||
PrintAndLogEx(FAILED, _RED_("TODO: This is a hardcoded example!"));
|
||||
|
||||
// common configurations.
|
||||
printHitagConfiguration(0x06);
|
||||
// printHitagConfiguration(0x06);
|
||||
//printHitagConfiguration( 0x0E );
|
||||
//printHitagConfiguration( 0x02 );
|
||||
//printHitagConfiguration( 0x00 );
|
||||
//printHitagConfiguration( 0x04 );
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// TODO: iceman
|
||||
@@ -550,21 +550,22 @@ static int CmdLFHitagReader(const char *Cmd) {
|
||||
}
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandOLD(cmd, htf, 0, 0, &htd, sizeof(htd));
|
||||
SendCommandMIX(cmd, htf, 0, 0, &htd, sizeof(htd));
|
||||
PacketResponseNG resp;
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) {
|
||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||
return 1;
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
if (resp.oldarg[0] == false) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - hitag failed");
|
||||
return 1;
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
uint32_t id = bytes_to_num(resp.data.asBytes, 4);
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Valid Hitag2 tag found - UID: %08x", id);
|
||||
PrintAndLogEx(SUCCESS, " UID: " _YELLOW_("%08x"), id);
|
||||
|
||||
if (htf != RHT2F_UID_ONLY) {
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Dumping tag memory...");
|
||||
@@ -575,6 +576,8 @@ static int CmdLFHitagReader(const char *Cmd) {
|
||||
fnameptr += sprintf(fnameptr, "lf-hitag-");
|
||||
FillFileNameByUID(fnameptr, data, "-dump", 4);
|
||||
|
||||
|
||||
|
||||
saveFile(filename, ".bin", data, 48);
|
||||
saveFileEML(filename, data, 48, 4);
|
||||
saveFileJSON(filename, jsfHitag, data, 48);
|
||||
@@ -582,7 +585,7 @@ static int CmdLFHitagReader(const char *Cmd) {
|
||||
// block3, 1 byte
|
||||
printHitagConfiguration(data[4 * 3]);
|
||||
}
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdLFHitagCheckChallenges(const char *Cmd) {
|
||||
@@ -631,7 +634,7 @@ static int CmdLFHitagCheckChallenges(const char *Cmd) {
|
||||
SendCommandMIX(CMD_LF_HITAGS_TEST_TRACES, 0, 0, 0, NULL, 0);
|
||||
|
||||
free(data);
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdLFHitagWriter(const char *Cmd) {
|
||||
@@ -675,14 +678,14 @@ static int CmdLFHitagWriter(const char *Cmd) {
|
||||
PacketResponseNG resp;
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) {
|
||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||
return 1;
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
if (resp.oldarg[0] == false) {
|
||||
PrintAndLogEx(DEBUG, "DEBUG: Error - hitag write failed");
|
||||
return 1;
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -692,10 +695,50 @@ static int CmdLFHitagDump(const char *Cmd) {
|
||||
|
||||
char ctmp = tolower(param_getchar(Cmd, 0));
|
||||
if (ctmp == 'h') return usage_hitag_dump();
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
*/
|
||||
|
||||
// Annotate HITAG protocol
|
||||
void annotateHitag1(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
|
||||
}
|
||||
|
||||
void annotateHitag2(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
|
||||
|
||||
uint8_t cmdbits = (cmd[0] & 0xC0) >> 6;
|
||||
|
||||
if (cmdsize == 1) {
|
||||
if (cmdbits == HITAG2_START_AUTH) {
|
||||
snprintf(exp, size, "START AUTH");
|
||||
return;
|
||||
}
|
||||
if (cmdbits == HITAG2_HALT) {
|
||||
snprintf(exp, size, "HALT");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmdsize == 2) {
|
||||
if (cmdbits == HITAG2_START_AUTH) {
|
||||
// C 1 C 0
|
||||
// 1100 0 00 1 1100 000
|
||||
uint8_t page = (cmd[0] & 0x38) >> 3;
|
||||
uint8_t inv_page = ((cmd[0] & 0x1) << 2) | ((cmd[1] & 0xC0) >> 6);
|
||||
snprintf(exp, size, "READ page(%x) %x", page, inv_page);
|
||||
return;
|
||||
}
|
||||
if (cmdbits == HITAG2_WRITE_PAGE) {
|
||||
uint8_t page = (cmd[0] & 0x38) >> 3;
|
||||
uint8_t inv_page = ((cmd[0] & 0x1) << 2) | ((cmd[1] & 0xC0) >> 6);
|
||||
snprintf(exp, size, "WRITE page(%x) %x", page, inv_page);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void annotateHitagS(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help" },
|
||||
{"list", CmdLFHitagList, IfPm3Hitag, "List Hitag trace history" },
|
||||
@@ -711,7 +754,7 @@ static command_t CommandTable[] = {
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int CmdLFHitag(const char *Cmd) {
|
||||
@@ -720,5 +763,5 @@ int CmdLFHitag(const char *Cmd) {
|
||||
}
|
||||
|
||||
int readHitagUid(void) {
|
||||
return CmdLFHitagReader("26") == 0;
|
||||
return (CmdLFHitagReader("26") == PM3_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -16,5 +16,7 @@
|
||||
int CmdLFHitag(const char *Cmd);
|
||||
|
||||
int readHitagUid(void);
|
||||
|
||||
void annotateHitag1(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize);
|
||||
void annotateHitag2(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize);
|
||||
void annotateHitagS(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize);
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "cmdhflist.h" // annotations
|
||||
#include "comms.h" // for sending cmds to device. GetFromBigBuf
|
||||
#include "fileutils.h" // for saveFile
|
||||
#include "cmdlfhitag.h" // annotate hitag
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
@@ -45,7 +46,9 @@ static int usage_trace_list() {
|
||||
PrintAndLogEx(NORMAL, " iclass - interpret data as iclass communications");
|
||||
PrintAndLogEx(NORMAL, " legic - interpret data as LEGIC communications");
|
||||
PrintAndLogEx(NORMAL, " felica - interpret data as ISO18092 / FeliCa communications");
|
||||
PrintAndLogEx(NORMAL, " hitag - interpret data as Hitag2 / HitagS communications");
|
||||
PrintAndLogEx(NORMAL, " hitag1 - interpret data as Hitag1 communications");
|
||||
PrintAndLogEx(NORMAL, " hitag2 - interpret data as Hitag2 communications");
|
||||
PrintAndLogEx(NORMAL, " hitags - interpret data as HitagS communications");
|
||||
PrintAndLogEx(NORMAL, " lto - interpret data as LTO-CM communications");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
@@ -281,7 +284,9 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
||||
crcStatus = iso15693_CRC_check(frame, data_len);
|
||||
break;
|
||||
case ISO_7816_4:
|
||||
case PROTO_HITAG:
|
||||
case PROTO_HITAG1:
|
||||
case PROTO_HITAG2:
|
||||
case PROTO_HITAGS:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -301,7 +306,9 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
||||
&& protocol != ISO_15693
|
||||
&& protocol != ICLASS
|
||||
&& protocol != ISO_7816_4
|
||||
&& protocol != PROTO_HITAG
|
||||
&& protocol != PROTO_HITAG1
|
||||
&& protocol != PROTO_HITAG2
|
||||
&& protocol != PROTO_HITAGS
|
||||
&& protocol != THINFILM
|
||||
&& protocol != FELICA
|
||||
&& protocol != LTO
|
||||
@@ -385,6 +392,15 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
||||
case LTO:
|
||||
annotateLTO(explanation, sizeof(explanation), frame, data_len);
|
||||
break;
|
||||
case PROTO_HITAG1:
|
||||
annotateHitag1(explanation, sizeof(explanation), frame, data_len);
|
||||
break;
|
||||
case PROTO_HITAG2:
|
||||
annotateHitag2(explanation, sizeof(explanation), frame, data_len);
|
||||
break;
|
||||
case PROTO_HITAGS:
|
||||
annotateHitagS(explanation, sizeof(explanation), frame, data_len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -593,7 +609,9 @@ int CmdTraceList(const char *Cmd) {
|
||||
else if (strcmp(type, "15") == 0) protocol = ISO_15693;
|
||||
else if (strcmp(type, "felica") == 0) protocol = FELICA;
|
||||
else if (strcmp(type, "mf") == 0) protocol = PROTO_MIFARE;
|
||||
else if (strcmp(type, "hitag") == 0) protocol = PROTO_HITAG;
|
||||
else if (strcmp(type, "hitag1") == 0) protocol = PROTO_HITAG1;
|
||||
else if (strcmp(type, "hitag2") == 0) protocol = PROTO_HITAG2;
|
||||
else if (strcmp(type, "hitags") == 0) protocol = PROTO_HITAGS;
|
||||
else if (strcmp(type, "thinfilm") == 0) protocol = THINFILM;
|
||||
else if (strcmp(type, "lto") == 0) protocol = LTO;
|
||||
else if (strcmp(type, "raw") == 0) protocol = -1; //No crc, no annotations
|
||||
@@ -644,8 +662,7 @@ int CmdTraceList(const char *Cmd) {
|
||||
}
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Recorded Activity (TraceLen = %lu bytes)", traceLen);
|
||||
PrintAndLogEx(INFO, "");
|
||||
PrintAndLogEx(SUCCESS, "Recorded activity (trace len = " _YELLOW_("%lu") "bytes)", traceLen);
|
||||
|
||||
/*
|
||||
if (protocol == FELICA) {
|
||||
@@ -657,27 +674,27 @@ int CmdTraceList(const char *Cmd) {
|
||||
tracepos = printHexLine(tracepos, traceLen, trace, protocol);
|
||||
}
|
||||
} else {
|
||||
PrintAndLogEx(NORMAL, "Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer");
|
||||
PrintAndLogEx(INFO, _YELLOW_("Start") "= Start of Start Bit, " _YELLOW_("End") "= End of last modulation. " _YELLOW_("Src") "= Source of Transfer");
|
||||
if (protocol == ISO_14443A || protocol == PROTO_MIFARE || protocol == MFDES || protocol == TOPAZ || protocol == LTO)
|
||||
PrintAndLogEx(NORMAL, "ISO14443A - All times are in carrier periods (1/13.56MHz)");
|
||||
PrintAndLogEx(INFO, "ISO14443A - All times are in carrier periods (1/13.56MHz)");
|
||||
if (protocol == THINFILM)
|
||||
PrintAndLogEx(NORMAL, "Thinfilm - All times are in carrier periods (1/13.56MHz)");
|
||||
PrintAndLogEx(INFO, "Thinfilm - All times are in carrier periods (1/13.56MHz)");
|
||||
if (protocol == ICLASS)
|
||||
PrintAndLogEx(NORMAL, "iClass - Timings are not as accurate");
|
||||
PrintAndLogEx(INFO, "iClass - Timings are not as accurate");
|
||||
if (protocol == LEGIC)
|
||||
PrintAndLogEx(NORMAL, "LEGIC - Reader Mode: Timings are in ticks (1us == 1.5ticks)\n"
|
||||
PrintAndLogEx(INFO, "LEGIC - Reader Mode: Timings are in ticks (1us == 1.5ticks)\n"
|
||||
" Tag Mode: Timings are in sub carrier periods (1/212 kHz == 4.7us)");
|
||||
if (protocol == ISO_14443B)
|
||||
PrintAndLogEx(NORMAL, "ISO14443B"); // Timings ?
|
||||
PrintAndLogEx(INFO, "ISO14443B"); // Timings ?
|
||||
if (protocol == ISO_15693)
|
||||
PrintAndLogEx(NORMAL, "ISO15693 - Timings are not as accurate");
|
||||
PrintAndLogEx(INFO, "ISO15693 - Timings are not as accurate");
|
||||
if (protocol == ISO_7816_4)
|
||||
PrintAndLogEx(NORMAL, "ISO7816-4 / Smartcard - Timings N/A yet");
|
||||
if (protocol == PROTO_HITAG)
|
||||
PrintAndLogEx(NORMAL, "Hitag2 / HitagS - Timings in ETU (8us)");
|
||||
PrintAndLogEx(INFO, "ISO7816-4 / Smartcard - Timings N/A yet");
|
||||
if (protocol == PROTO_HITAG1 || protocol == PROTO_HITAG2 || protocol == PROTO_HITAGS)
|
||||
PrintAndLogEx(INFO, "Hitag1 / Hitag2 / HitagS - Timings in ETU (8us)");
|
||||
if (protocol == FELICA)
|
||||
PrintAndLogEx(NORMAL, "ISO18092 / FeliCa - Timings are not as accurate");
|
||||
|
||||
PrintAndLogEx(INFO, "ISO18092 / FeliCa - Timings are not as accurate");
|
||||
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, " Start | End | Src | Data (! denotes parity error) | CRC | Annotation");
|
||||
PrintAndLogEx(NORMAL, "------------+------------+-----+-------------------------------------------------------------------------+-----+--------------------");
|
||||
|
||||
@@ -125,15 +125,16 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
|
||||
}
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "found " _YELLOW_("%u") "candidate key%s\n", keycount, (keycount > 1) ? "s." : ".");
|
||||
PrintAndLogEx(SUCCESS, "found " _YELLOW_("%u") "candidate key%s", keycount, (keycount > 1) ? "s." : ".");
|
||||
|
||||
*key = UINT64_C(-1);
|
||||
uint8_t keyBlock[PM3_CMD_DATA_SIZE];
|
||||
uint32_t max_keys = KEYS_IN_BLOCK;
|
||||
for (uint32_t i = 0; i < keycount; i += max_keys) {
|
||||
|
||||
uint32_t size = keycount - i > max_keys ? max_keys : keycount - i;
|
||||
for (uint32_t j = 0; j < size; j++) {
|
||||
uint8_t size = keycount - i > max_keys ? max_keys : keycount - i;
|
||||
register uint8_t j;
|
||||
for (j = 0; j < size; j++) {
|
||||
if (par_list == 0) {
|
||||
num_to_bytes(last_keylist[i * max_keys + j], 6, keyBlock + (j * 6));
|
||||
} else {
|
||||
@@ -159,6 +160,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
|
||||
free(keylist);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int mfCheckKeys(uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t *keyBlock, uint64_t *key) {
|
||||
*key = -1;
|
||||
clearCommandBuffer();
|
||||
@@ -308,7 +310,7 @@ int mfKeyBrute(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint64_t *resultk
|
||||
}
|
||||
|
||||
// Compare 16 Bits out of cryptostate
|
||||
static int Compare16Bits(const void *a, const void *b) {
|
||||
inline static int Compare16Bits(const void *a, const void *b) {
|
||||
if ((*(uint64_t *)b & 0x00ff000000ff0000) == (*(uint64_t *)a & 0x00ff000000ff0000)) return 0;
|
||||
if ((*(uint64_t *)b & 0x00ff000000ff0000) > (*(uint64_t *)a & 0x00ff000000ff0000)) return 1;
|
||||
return -1;
|
||||
@@ -330,13 +332,14 @@ __attribute__((force_align_arg_pointer))
|
||||
|
||||
statelist->len = p1 - statelist->head.slhead;
|
||||
statelist->tail.sltail = --p1;
|
||||
|
||||
qsort(statelist->head.slhead, statelist->len, sizeof(uint64_t), Compare16Bits);
|
||||
|
||||
return statelist->head.slhead;
|
||||
}
|
||||
|
||||
int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKey, bool calibrate) {
|
||||
uint16_t i;
|
||||
|
||||
uint32_t uid;
|
||||
StateList_t statelists[2];
|
||||
struct Crypto1State *p1, *p2, *p3, *p4;
|
||||
@@ -385,7 +388,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo,
|
||||
|
||||
memcpy(&uid, package->cuid, sizeof(package->cuid));
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
statelists[i].blockNo = package->block;
|
||||
statelists[i].keyType = package->keytype;
|
||||
statelists[i].uid = uid;
|
||||
@@ -402,11 +405,11 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo,
|
||||
pthread_t thread_id[2];
|
||||
|
||||
// create and run worker threads
|
||||
for (i = 0; i < 2; i++)
|
||||
for (uint8_t i = 0; i < 2; i++)
|
||||
pthread_create(thread_id + i, NULL, nested_worker_thread, &statelists[i]);
|
||||
|
||||
// wait for threads to terminate:
|
||||
for (i = 0; i < 2; i++)
|
||||
for (uint8_t i = 0; i < 2; i++)
|
||||
pthread_join(thread_id[i], (void *)&statelists[i].head.slhead);
|
||||
|
||||
// the first 16 Bits of the cryptostate already contain part of our key.
|
||||
@@ -457,6 +460,8 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo,
|
||||
uint32_t keycnt = statelists[0].len;
|
||||
if (keycnt == 0) goto out;
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Found " _YELLOW_("%u") "candidate keys", keycnt);
|
||||
|
||||
memset(resultKey, 0, 6);
|
||||
uint64_t key64 = -1;
|
||||
|
||||
@@ -464,11 +469,14 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo,
|
||||
uint32_t max_keys = keycnt > KEYS_IN_BLOCK ? KEYS_IN_BLOCK : keycnt;
|
||||
uint8_t keyBlock[PM3_CMD_DATA_SIZE] = {0x00};
|
||||
|
||||
for (i = 0; i < keycnt; i += max_keys) {
|
||||
uint64_t start_time = msclock();
|
||||
|
||||
int size = keycnt - i > max_keys ? max_keys : keycnt - i;
|
||||
for (uint32_t i = 0; i < keycnt; i += max_keys) {
|
||||
|
||||
for (int j = 0; j < size; j++) {
|
||||
uint8_t size = keycnt - i > max_keys ? max_keys : keycnt - i;
|
||||
|
||||
register uint8_t j;
|
||||
for (j = 0; j < size; j++) {
|
||||
crypto1_get_lfsr(statelists[0].head.slhead + i, &key64);
|
||||
num_to_bytes(key64, 6, keyBlock + j * 6);
|
||||
}
|
||||
@@ -485,6 +493,13 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo,
|
||||
);
|
||||
return -5;
|
||||
}
|
||||
|
||||
float bruteforce_per_second = (float)KEYS_IN_BLOCK / (float)(msclock() - start_time) * 1000.0;
|
||||
start_time = msclock();
|
||||
|
||||
if ( i + 1 % 10 == 0)
|
||||
PrintAndLogEx(INFO, " %8d keys left | %5.1f keys/sec | worst case %6.1f seconds remaining", keycnt - i, bruteforce_per_second, (keycnt-i) / bruteforce_per_second);
|
||||
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -499,7 +514,7 @@ out:
|
||||
}
|
||||
|
||||
int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKey) {
|
||||
uint16_t i;
|
||||
|
||||
uint32_t uid;
|
||||
StateList_t statelists[1];
|
||||
struct Crypto1State *p1, *p3;
|
||||
@@ -589,16 +604,18 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl
|
||||
uint32_t max_keys_slice = keycnt > KEYS_IN_BLOCK ? KEYS_IN_BLOCK : keycnt;
|
||||
uint8_t keyBlock[PM3_CMD_DATA_SIZE] = {0x00};
|
||||
|
||||
for (i = 0; i < keycnt; i += max_keys_slice) {
|
||||
uint64_t start_time = msclock();
|
||||
for (uint32_t i = 0; i < keycnt; i += max_keys_slice) {
|
||||
|
||||
PrintAndLogEx(INFO, "Testing %u / %u ", i, keycnt);
|
||||
// PrintAndLogEx(INFO, "Testing %u / %u ", i, keycnt);
|
||||
|
||||
key64 = 0;
|
||||
|
||||
int size = keycnt - i > max_keys_slice ? max_keys_slice : keycnt - i;
|
||||
uint8_t size = keycnt - i > max_keys_slice ? max_keys_slice : keycnt - i;
|
||||
|
||||
// copy x keys to device.
|
||||
for (int j = 0; j < size; j++) {
|
||||
register uint8_t j;
|
||||
for (j = 0; j < size; j++) {
|
||||
crypto1_get_lfsr(statelists[0].head.slhead + i + j, &key64);
|
||||
num_to_bytes(key64, 6, keyBlock + j * 6);
|
||||
}
|
||||
@@ -617,6 +634,12 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl
|
||||
);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
float bruteforce_per_second = (float)KEYS_IN_BLOCK / (float)(msclock() - start_time) * 1000.0;
|
||||
start_time = msclock();
|
||||
|
||||
if ( i+1 % 10 == 0)
|
||||
PrintAndLogEx(INFO, " %8d keys left | %5.1f keys/sec | worst case %6.1f seconds remaining", keycnt - i, bruteforce_per_second, (keycnt-i) / bruteforce_per_second);
|
||||
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
Reference in New Issue
Block a user