// Nested\r
//----------------------------------------------\r
\r
-static void parseParamTDS(const char *Cmd, const uint8_t indx, bool *paramT, bool *paramD, uint8_t *timeout) {\r
+static void parseParamTDS(const char *Cmd, const uint8_t indx, bool *paramT, bool *paramD, uint16_t *timeout) {\r
char ctmp3[4] = {0};\r
int len = param_getlength(Cmd, indx);\r
if (len > 0 && len < 4){\r
\r
// slow and very slow\r
if (ctmp3[0] == 's' || ctmp3[0] == 'S' || ctmp3[1] == 's' || ctmp3[1] == 'S') {\r
- *timeout = 11; // slow\r
+ *timeout = MF_CHKKEYS_SLOWTIMEOUT; // slow\r
\r
if (!paramS1 && (ctmp3[1] == 's' || ctmp3[1] == 'S')) {\r
- *timeout = 53; // very slow\r
+ *timeout = MF_CHKKEYS_VERYSLOWTIMEOUT; // very slow\r
}\r
if (paramS1 && (ctmp3[2] == 's' || ctmp3[2] == 'S')) {\r
- *timeout = 53; // very slow\r
+ *timeout = MF_CHKKEYS_VERYSLOWTIMEOUT; // very slow\r
}\r
}\r
}\r
}\r
\r
-int CmdHF14AMfNested(const char *Cmd)\r
-{\r
+int CmdHF14AMfNested(const char *Cmd) {\r
int i, j, res, iterations;\r
sector_t *e_sector = NULL;\r
uint8_t blockNo = 0;\r
uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
uint8_t keyBlock[MifareDefaultKeysSize * 6];\r
uint64_t key64 = 0;\r
- // timeout in units. (ms * 106)/10 or us*0.0106\r
- uint8_t btimeout14a = MF_CHKKEYS_DEFTIMEOUT; // fast by default\r
+ // timeout in units. (ms * 106) or us*0.106\r
+ uint16_t timeout14a = MF_CHKKEYS_DEFTIMEOUT; // fast by default\r
\r
bool autosearchKey = false;\r
\r
if (param_getchar(Cmd, 1) == '*') {\r
autosearchKey = true;\r
\r
- parseParamTDS(Cmd, 2, &transferToEml, &createDumpFile, &btimeout14a);\r
+ parseParamTDS(Cmd, 2, &transferToEml, &createDumpFile, &timeout14a);\r
\r
PrintAndLog("--nested. sectors:%2d, block no:*, eml:%c, dmp=%c checktimeout=%d us",\r
- SectorsCnt, transferToEml?'y':'n', createDumpFile?'y':'n', ((int)btimeout14a * 10000) / 106);\r
+ SectorsCnt, transferToEml?'y':'n', createDumpFile?'y':'n', ((uint32_t)timeout14a * 1000) / 106);\r
} else {\r
blockNo = param_get8(Cmd, 1);\r
\r
}\r
\r
// check if we can authenticate to sector\r
- res = mfCheckKeys(blockNo, keyType, true, 1, key, &key64);\r
+ res = mfCheckKeys(blockNo, keyType, timeout14a, true, 1, key, &key64);\r
if (res) {\r
PrintAndLog("Can't authenticate to block:%3d key type:%c key:%s", blockNo, keyType?'B':'A', sprint_hex(key, 6));\r
return 3;\r
if (ctmp != 'A' && ctmp != 'a')\r
trgKeyType = 1;\r
\r
- parseParamTDS(Cmd, 6, &transferToEml, &createDumpFile, &btimeout14a);\r
+ parseParamTDS(Cmd, 6, &transferToEml, &createDumpFile, &timeout14a);\r
} else {\r
- parseParamTDS(Cmd, 4, &transferToEml, &createDumpFile, &btimeout14a);\r
+ parseParamTDS(Cmd, 4, &transferToEml, &createDumpFile, &timeout14a);\r
}\r
\r
PrintAndLog("--nested. sectors:%2d, block no:%3d, key type:%c, eml:%c, dmp=%c checktimeout=%d us",\r
- SectorsCnt, blockNo, keyType?'B':'A', transferToEml?'y':'n', createDumpFile?'y':'n', ((int)btimeout14a * 10000) / 106);\r
+ SectorsCnt, blockNo, keyType?'B':'A', transferToEml?'y':'n', createDumpFile?'y':'n', ((uint32_t)timeout14a * 1000) / 106);\r
}\r
\r
// one-sector nested\r
if (cmdp == 'o') { // ------------------------------------ one sector working\r
PrintAndLog("--target block no:%3d, target key type:%c ", trgBlockNo, trgKeyType?'B':'A');\r
- int16_t isOK = mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock, true);\r
- if (isOK) {\r
+ int16_t isOK = mfnested(blockNo, keyType, timeout14a, key, trgBlockNo, trgKeyType, keyBlock, true);\r
+ if (isOK < 0) {\r
switch (isOK) {\r
case -1 : PrintAndLog("Error: No response from Proxmark.\n"); break;\r
case -2 : PrintAndLog("Button pressed. Aborted.\n"); break;\r
case -3 : PrintAndLog("Tag isn't vulnerable to Nested Attack (random numbers are not predictable).\n"); break;\r
- default : PrintAndLog("Unknown Error.\n");\r
+ default : PrintAndLog("Unknown Error (%d)\n", isOK);\r
}\r
return 2;\r
}\r
key64 = bytes_to_num(keyBlock, 6);\r
- if (key64) {\r
+ if (!isOK) {\r
PrintAndLog("Found valid key:%012" PRIx64, key64);\r
\r
// transfer key to the emulator\r
}\r
\r
PrintAndLog("Testing known keys. Sector count=%d", SectorsCnt);\r
- mfCheckKeysSec(SectorsCnt, 2, btimeout14a, true, MifareDefaultKeysSize, keyBlock, e_sector);\r
+ mfCheckKeysSec(SectorsCnt, 2, timeout14a, true, true, true, MifareDefaultKeysSize, keyBlock, e_sector);\r
\r
// get known key from array\r
bool keyFound = false;\r
for (trgKeyType = 0; trgKeyType < 2; trgKeyType++) {\r
if (e_sector[sectorNo].foundKey[trgKeyType]) continue;\r
PrintAndLog("-----------------------------------------------");\r
- int16_t isOK = mfnested(blockNo, keyType, key, FirstBlockOfSector(sectorNo), trgKeyType, keyBlock, calibrate);\r
- if(isOK) {\r
+ int16_t isOK = mfnested(blockNo, keyType, timeout14a, key, FirstBlockOfSector(sectorNo), trgKeyType, keyBlock, calibrate);\r
+ if(isOK < 0) {\r
switch (isOK) {\r
case -1 : PrintAndLog("Error: No response from Proxmark.\n"); break;\r
case -2 : PrintAndLog("Button pressed. Aborted.\n"); break;\r
case -3 : PrintAndLog("Tag isn't vulnerable to Nested Attack (random numbers are not predictable).\n"); break;\r
- default : PrintAndLog("Unknown Error.\n");\r
+ default : PrintAndLog("Unknown Error (%d)\n", isOK);\r
}\r
free(e_sector);\r
return 2;\r
iterations++;\r
\r
key64 = bytes_to_num(keyBlock, 6);\r
- if (key64) {\r
+ if (!isOK) {\r
PrintAndLog("Found valid key:%012" PRIx64, key64);\r
e_sector[sectorNo].foundKey[trgKeyType] = 1;\r
e_sector[sectorNo].Key[trgKeyType] = key64;\r
\r
// try to check this key as a key to the other sectors\r
- mfCheckKeysSec(SectorsCnt, 2, btimeout14a, true, 1, keyBlock, e_sector);\r
+ mfCheckKeysSec(SectorsCnt, 2, timeout14a, true, true, true, 1, keyBlock, e_sector);\r
}\r
}\r
}\r
}\r
\r
\r
-int CmdHF14AMfChk(const char *Cmd)\r
-{\r
+int CmdHF14AMfChk(const char *Cmd) {\r
+\r
if (strlen(Cmd)<3) {\r
PrintAndLog("Usage: hf mf chk <block number>|<*card memory> <key type (A/B/?)> [t|d|s|ss] [<key (12 hex symbols)>] [<dic (*.dic)>]");\r
PrintAndLog(" * - all sectors");\r
uint8_t keyType = 0;\r
uint64_t key64 = 0;\r
// timeout in units. (ms * 106)/10 or us*0.0106\r
- uint8_t btimeout14a = MF_CHKKEYS_DEFTIMEOUT; // fast by default\r
+ uint16_t timeout14a = MF_CHKKEYS_DEFTIMEOUT; // fast by default\r
bool param3InUse = false;\r
bool transferToEml = 0;\r
bool createDumpFile = 0;\r
};\r
}\r
\r
- parseParamTDS(Cmd, 2, &transferToEml, &createDumpFile, &btimeout14a);\r
+ parseParamTDS(Cmd, 2, &transferToEml, &createDumpFile, &timeout14a);\r
\r
if (singleBlock & createDumpFile) {\r
PrintAndLog (" block key check (<block no>) and write to dump file (d) combination is not supported ");\r
return 1;\r
}\r
\r
- param3InUse = transferToEml | createDumpFile | (btimeout14a != MF_CHKKEYS_DEFTIMEOUT);\r
+ param3InUse = transferToEml | createDumpFile | (timeout14a != MF_CHKKEYS_DEFTIMEOUT);\r
\r
PrintAndLog("--chk keys. sectors:%2d, block no:%3d, key type:%c, eml:%c, dmp=%c checktimeout=%d us",\r
- SectorsCnt, blockNo, keyType==0?'A':keyType==1?'B':'?', transferToEml?'y':'n', createDumpFile?'y':'n', ((int)btimeout14a * 10000) / 106);\r
+ SectorsCnt, blockNo, keyType==0?'A':keyType==1?'B':'?', transferToEml?'y':'n', createDumpFile?'y':'n', ((uint32_t)timeout14a * 1000) / 106);\r
\r
for (i = param3InUse; param_getchar(Cmd, 2 + i); i++) {\r
if (!param_gethex(Cmd, 2 + i, keyBlock + 6 * keycnt, 12)) {\r
for (uint32_t c = 0; c < keycnt; c += max_keys) {\r
\r
uint32_t size = keycnt-c > max_keys ? max_keys : keycnt-c;\r
- res = mfCheckKeysSec(SectorsCnt, keyType, btimeout14a, clearTraceLog, size, &keyBlock[6 * c], e_sector); // timeout is (ms * 106)/10 or us*0.0106\r
+ bool init = (c == 0);\r
+ bool drop_field = (c + size == keycnt);\r
+ res = mfCheckKeysSec(SectorsCnt, keyType, timeout14a, clearTraceLog, init, drop_field, size, &keyBlock[6 * c], e_sector); // timeout is (ms * 106)/10 or us*0.0106\r
clearTraceLog = false;\r
\r
if (res != 1) {\r
} else {\r
int keyAB = keyType;\r
do {\r
- for (uint32_t c = 0; c < keycnt; c += max_keys) {\r
-\r
- uint32_t size = keycnt-c > max_keys ? max_keys : keycnt-c;\r
- res = mfCheckKeys(blockNo, keyAB & 0x01, true, size, &keyBlock[6 * c], &key64);\r
- clearTraceLog = false;\r
+ res = mfCheckKeys(blockNo, keyAB & 0x01, timeout14a, true, keycnt, keyBlock, &key64);\r
+ clearTraceLog = false;\r
\r
- if (res != 1) {\r
- if (!res) {\r
- // Use the common format below\r
- // PrintAndLog("Found valid key:[%d:%c]%012" PRIx64, blockNo, (keyAB & 0x01)?'B':'A', key64);\r
- foundAKey = true;\r
+ if (res != 1) {\r
+ if (!res) {\r
+ // Use the common format below\r
+ // PrintAndLog("Found valid key:[%d:%c]%012" PRIx64, blockNo, (keyAB & 0x01)?'B':'A', key64);\r
+ foundAKey = true;\r
\r
- // Store the Single Key for display list\r
- // For a single block check, SectorsCnt = Sector that contains the block\r
- e_sector[SectorsCnt-1].foundKey[(keyAB & 0x01)] = true; // flag key found\r
- e_sector[SectorsCnt-1].Key[(keyAB & 0x01)] = key64; // Save key data\r
+ // Store the Single Key for display list\r
+ // For a single block check, SectorsCnt = Sector that contains the block\r
+ e_sector[SectorsCnt-1].foundKey[(keyAB & 0x01)] = true; // flag key found\r
+ e_sector[SectorsCnt-1].Key[(keyAB & 0x01)] = key64; // Save key data\r
\r
- }\r
- } else {\r
- PrintAndLog("Command execute timeout");\r
}\r
+ } else {\r
+ PrintAndLog("Command execute timeout");\r
}\r
} while(--keyAB > 0);\r
}\r
PrintAndLog("error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1);\r
break;\r
}\r
- fwrite(data+6, 1, 6, fkeys);\r
+ fwrite(data, 1, 6, fkeys);\r
}\r
for(i = 0; i < numSectors; i++) {\r
if (mfEmlGetMem(data, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1)) {\r