#include "mifare/mad.h"\r
#include "mifare/ndef.h"\r
#include "emv/dump.h"\r
+#include "protocols.h"\r
\r
#define NESTED_SECTOR_RETRY 10 // how often we try mfested() until we give up\r
\r
PrintAndLog("--block no:%d, key type:%c, key:%s", blockNo, keyType?'B':'A', sprint_hex(key, 6));\r
PrintAndLog("--data: %s", sprint_hex(bldata, 16));\r
\r
- UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}};\r
+ UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}};\r
memcpy(c.d.asBytes, key, 6);\r
memcpy(c.d.asBytes + 10, bldata, 16);\r
- SendCommand(&c);\r
+ SendCommand(&c);\r
\r
UsbCommand resp;\r
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
}\r
PrintAndLog("--block no:%d, key type:%c, key:%s ", blockNo, keyType?'B':'A', sprint_hex(key, 6));\r
\r
- UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};\r
+ UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};\r
memcpy(c.d.asBytes, key, 6);\r
- SendCommand(&c);\r
+ SendCommand(&c);\r
\r
UsbCommand resp;\r
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
return 2;\r
}\r
\r
- return 0;\r
+ return 0;\r
}\r
\r
int CmdHF14AMfRdSc(const char *Cmd)\r
PrintAndLog("Command execute timeout");\r
}\r
\r
- return 0;\r
+ return 0;\r
}\r
\r
uint8_t FirstBlockOfSector(uint8_t sectorNo)\r
// 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
+ PrintAndLog("Can't authenticate to block %d, key type %c, key %s", blockNo, keyType?'B':'A', sprint_hex(key, 6));\r
return 3;\r
}\r
\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
bool singleBlock = false; // Flag to ID if a single or multi key check\r
uint8_t keyFoundCount = 0; // Counter to display the number of keys found/transfered to emulator\r
- \r
+\r
sector_t *e_sector = NULL;\r
\r
keyBlock = calloc(stKeyBlock, 6);\r
return 1;\r
};\r
}\r
- \r
- parseParamTDS(Cmd, 2, &transferToEml, &createDumpFile, &btimeout14a);\r
+\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
uint32_t max_keys = keycnt > USB_CMD_DATA_SIZE / 6 ? USB_CMD_DATA_SIZE / 6 : keycnt;\r
\r
// !SingleKey, so all key check (if SectorsCnt > 0)\r
- if (!singleBlock) { \r
+ if (!singleBlock) {\r
PrintAndLog("To cancel this operation press the button on the proxmark...");\r
printf("--");\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
PrintAndLog("Command execute timeout");\r
}\r
}\r
- } else { \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
-\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
- \r
- }\r
- } else {\r
- PrintAndLog("Command execute timeout");\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
+\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
} while(--keyAB > 0);\r
}\r
for (uint16_t t = 0; t < 2; t++) {\r
if (e_sector[sectorNo].foundKey[t]) {\r
num_to_bytes(e_sector[sectorNo].Key[t], 6, block + t * 10);\r
- keyFoundCount++; // Key found count for information\r
+ keyFoundCount++; // Key found count for information\r
}\r
}\r
mfEmlSetMem(block, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);\r
fclose(fkeys);\r
PrintAndLog("Found keys have been dumped to file dumpkeys.bin. 0xffffffffffff has been inserted for unknown keys.");\r
}\r
- \r
+\r
free(e_sector);\r
free(keyBlock);\r
PrintAndLog("");\r
return 0;\r
}\r
\r
- UsbCommand c = {CMD_MIFARE_SET_DBGMODE, {dbgMode, 0, 0}};\r
- SendCommand(&c);\r
+ UsbCommand c = {CMD_MIFARE_SET_DBGMODE, {dbgMode, 0, 0}};\r
+ SendCommand(&c);\r
\r
- return 0;\r
+ return 0;\r
}\r
\r
int CmdHF14AMfEGet(const char *Cmd)\r
PrintAndLog("Command execute timeout");\r
}\r
\r
- return 0;\r
+ return 0;\r
}\r
\r
int CmdHF14AMfEClear(const char *Cmd)\r
return 0;\r
}\r
\r
- UsbCommand c = {CMD_MIFARE_EML_MEMCLR, {0, 0, 0}};\r
- SendCommand(&c);\r
- return 0;\r
+ UsbCommand c = {CMD_MIFARE_EML_MEMCLR, {0, 0, 0}};\r
+ SendCommand(&c);\r
+ return 0;\r
}\r
\r
\r
\r
PrintAndLog("Saved %d blocks to file: %s", numBlocks, filename);\r
\r
- return 0;\r
+ return 0;\r
}\r
\r
\r
case '\0': numSectors = 16; break;\r
case '2' : numSectors = 32; break;\r
case '4' : numSectors = 40; break;\r
- case 'd' : \r
+ case 'd' :\r
case 'D' : createDumpFile = true; break;\r
}\r
cmdp++;\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
}\r
\r
UsbCommand resp;\r
- if (WaitForResponseTimeoutW(CMD_ACK, &resp, 2000, false)) {\r
+ if (WaitForResponseTimeoutW(CMD_UNKNOWN, &resp, 2000, false)) {\r
res = resp.arg[0] & 0xff;\r
uint16_t traceLen = resp.arg[1];\r
len = resp.arg[2];\r
return 0;\r
}\r
\r
-static command_t CommandTable[] =\r
-{\r
- {"help", CmdHelp, 1, "This help"},\r
- {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},\r
- {"rdbl", CmdHF14AMfRdBl, 0, "Read MIFARE classic block"},\r
- {"rdsc", CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"},\r
- {"dump", CmdHF14AMfDump, 0, "Dump MIFARE classic tag to binary file"},\r
- {"restore", CmdHF14AMfRestore, 0, "Restore MIFARE classic binary file to BLANK tag"},\r
- {"wrbl", CmdHF14AMfWrBl, 0, "Write MIFARE classic block"},\r
- {"auth4", CmdHF14AMfAuth4, 0, "ISO14443-4 AES authentication"},\r
- {"chk", CmdHF14AMfChk, 0, "Test block keys"},\r
- {"mifare", CmdHF14AMifare, 0, "Read parity error messages."},\r
- {"hardnested", CmdHF14AMfNestedHard, 0, "Nested attack for hardened Mifare cards"},\r
- {"nested", CmdHF14AMfNested, 0, "Test nested authentication"},\r
- {"sniff", CmdHF14AMfSniff, 0, "Sniff card-reader communication"},\r
- {"sim", CmdHF14AMfSim, 0, "Simulate MIFARE card"},\r
- {"eclr", CmdHF14AMfEClear, 0, "Clear simulator memory"},\r
- {"eget", CmdHF14AMfEGet, 0, "Get simulator memory block"},\r
- {"eset", CmdHF14AMfESet, 0, "Set simulator memory block"},\r
- {"eload", CmdHF14AMfELoad, 0, "Load from file emul dump"},\r
- {"esave", CmdHF14AMfESave, 0, "Save to file emul dump"},\r
- {"ecfill", CmdHF14AMfECFill, 0, "Fill simulator memory with help of keys from simulator"},\r
- {"ekeyprn", CmdHF14AMfEKeyPrn, 0, "Print keys from simulator memory"},\r
- {"cwipe", CmdHF14AMfCWipe, 0, "Wipe magic Chinese card"},\r
- {"csetuid", CmdHF14AMfCSetUID, 0, "Set UID for magic Chinese card"},\r
- {"csetblk", CmdHF14AMfCSetBlk, 0, "Write block - Magic Chinese card"},\r
- {"cgetblk", CmdHF14AMfCGetBlk, 0, "Read block - Magic Chinese card"},\r
- {"cgetsc", CmdHF14AMfCGetSc, 0, "Read sector - Magic Chinese card"},\r
- {"cload", CmdHF14AMfCLoad, 0, "Load dump into magic Chinese card"},\r
- {"csave", CmdHF14AMfCSave, 0, "Save dump from magic Chinese card into file or emulator"},\r
- {"decrypt", CmdDecryptTraceCmds, 1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"},\r
- {"mad", CmdHF14AMfMAD, 0, "Checks and prints MAD"},\r
- {"ndef", CmdHFMFNDEF, 0, "Prints NDEF records from card"},\r
- {NULL, NULL, 0, NULL}\r
+int CmdHFMFPersonalize(const char *cmd) {\r
+\r
+ CLIParserInit("hf mf personalize",\r
+ "Personalize the UID of a Mifare Classic EV1 card. This is only possible if it is a 7Byte UID card and if it is not already personalized.",\r
+ "Usage:\n\thf mf personalize UIDF0 -> double size UID according to ISO/IEC14443-3\n"\r
+ "\thf mf personalize UIDF1 -> double size UID according to ISO/IEC14443-3, optional usage of selection process shortcut\n"\r
+ "\thf mf personalize UIDF2 -> single size random ID according to ISO/IEC14443-3\n"\r
+ "\thf mf personalize UIDF3 -> single size NUID according to ISO/IEC14443-3\n"\r
+ "\thf mf personalize -t B -k B0B1B2B3B4B5 UIDF3 -> use key B = 0xB0B1B2B3B4B5 instead of default key A\n");\r
+\r
+ void *argtable[] = {\r
+ arg_param_begin,\r
+ arg_str0("tT", "keytype", "<A|B>", "key type (A or B) to authenticate sector 0 (default: A)"),\r
+ arg_str0("kK", "key", "<key (hex 6 Bytes)>", "key to authenticate sector 0 (default: FFFFFFFFFFFF)"),\r
+ arg_str1(NULL, NULL, "<UIDF0|UIDF1|UIDF2|UIDF3>", "Personalization Option"),\r
+ arg_param_end\r
+ };\r
+ CLIExecWithReturn(cmd, argtable, true);\r
+\r
+ char keytypestr[2] = "A";\r
+ uint8_t keytype = 0x00;\r
+ int keytypestr_len;\r
+ int res = CLIParamStrToBuf(arg_get_str(1), (uint8_t*)keytypestr, 1, &keytypestr_len);\r
+ if (res || (keytypestr[0] != 'a' && keytypestr[0] != 'A' && keytypestr[0] != 'b' && keytypestr[0] != 'B')) {\r
+ PrintAndLog("ERROR: not a valid key type. Key type must be A or B");\r
+ CLIParserFree();\r
+ return 1;\r
+ }\r
+ if (keytypestr[0] == 'B' || keytypestr[0] == 'b') {\r
+ keytype = 0x01;\r
+ }\r
+\r
+ uint8_t key[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
+ int key_len;\r
+ res = CLIParamHexToBuf(arg_get_str(2), key, 6, &key_len);\r
+ if (res || (!res && key_len > 0 && key_len != 6)) {\r
+ PrintAndLog("ERROR: not a valid key. Key must be 12 hex digits");\r
+ CLIParserFree();\r
+ return 1;\r
+ }\r
+\r
+ char pers_optionstr[6];\r
+ int opt_len;\r
+ uint8_t pers_option;\r
+ res = CLIParamStrToBuf(arg_get_str(3), (uint8_t*)pers_optionstr, 5, &opt_len);\r
+ if (res || (!res && opt_len > 0 && opt_len != 5)\r
+ || (strncmp(pers_optionstr, "UIDF0", 5) && strncmp(pers_optionstr, "UIDF1", 5) && strncmp(pers_optionstr, "UIDF2", 5) && strncmp(pers_optionstr, "UIDF3", 5))) {\r
+ PrintAndLog("ERROR: invalid personalization option. Must be one of UIDF0, UIDF1, UIDF2, or UIDF3");\r
+ CLIParserFree();\r
+ return 1;\r
+ }\r
+ if (!strncmp(pers_optionstr, "UIDF0", 5)) {\r
+ pers_option = MIFARE_EV1_UIDF0;\r
+ } else if (!strncmp(pers_optionstr, "UIDF1", 5)) {\r
+ pers_option = MIFARE_EV1_UIDF1;\r
+ } else if (!strncmp(pers_optionstr, "UIDF2", 5)) {\r
+ pers_option = MIFARE_EV1_UIDF2;\r
+ } else {\r
+ pers_option = MIFARE_EV1_UIDF3;\r
+ }\r
+\r
+ CLIParserFree();\r
+\r
+ UsbCommand c = {CMD_MIFARE_PERSONALIZE_UID, {keytype, pers_option, 0}};\r
+ memcpy(c.d.asBytes, key, 6);\r
+ SendCommand(&c);\r
+\r
+ UsbCommand resp;\r
+ if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {\r
+ bool isOK = resp.arg[0];\r
+ PrintAndLog("Personalization %s", isOK ? "SUCCEEDED" : "FAILED");\r
+ } else {\r
+ PrintAndLog("Command execute timeout");\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+static command_t CommandTable[] = {\r
+ {"help", CmdHelp, 1, "This help"},\r
+ {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},\r
+ {"rdbl", CmdHF14AMfRdBl, 0, "Read MIFARE classic block"},\r
+ {"rdsc", CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"},\r
+ {"dump", CmdHF14AMfDump, 0, "Dump MIFARE classic tag to binary file"},\r
+ {"restore", CmdHF14AMfRestore, 0, "Restore MIFARE classic binary file to BLANK tag"},\r
+ {"wrbl", CmdHF14AMfWrBl, 0, "Write MIFARE classic block"},\r
+ {"auth4", CmdHF14AMfAuth4, 0, "ISO14443-4 AES authentication"},\r
+ {"chk", CmdHF14AMfChk, 0, "Test block keys"},\r
+ {"mifare", CmdHF14AMifare, 0, "Read parity error messages."},\r
+ {"hardnested", CmdHF14AMfNestedHard, 0, "Nested attack for hardened Mifare cards"},\r
+ {"nested", CmdHF14AMfNested, 0, "Test nested authentication"},\r
+ {"sniff", CmdHF14AMfSniff, 0, "Sniff card-reader communication"},\r
+ {"sim", CmdHF14AMfSim, 0, "Simulate MIFARE card"},\r
+ {"eclr", CmdHF14AMfEClear, 0, "Clear simulator memory"},\r
+ {"eget", CmdHF14AMfEGet, 0, "Get simulator memory block"},\r
+ {"eset", CmdHF14AMfESet, 0, "Set simulator memory block"},\r
+ {"eload", CmdHF14AMfELoad, 0, "Load from file emul dump"},\r
+ {"esave", CmdHF14AMfESave, 0, "Save to file emul dump"},\r
+ {"ecfill", CmdHF14AMfECFill, 0, "Fill simulator memory with help of keys from simulator"},\r
+ {"ekeyprn", CmdHF14AMfEKeyPrn, 0, "Print keys from simulator memory"},\r
+ {"cwipe", CmdHF14AMfCWipe, 0, "Wipe magic Chinese card"},\r
+ {"csetuid", CmdHF14AMfCSetUID, 0, "Set UID for magic Chinese card"},\r
+ {"csetblk", CmdHF14AMfCSetBlk, 0, "Write block - Magic Chinese card"},\r
+ {"cgetblk", CmdHF14AMfCGetBlk, 0, "Read block - Magic Chinese card"},\r
+ {"cgetsc", CmdHF14AMfCGetSc, 0, "Read sector - Magic Chinese card"},\r
+ {"cload", CmdHF14AMfCLoad, 0, "Load dump into magic Chinese card"},\r
+ {"csave", CmdHF14AMfCSave, 0, "Save dump from magic Chinese card into file or emulator"},\r
+ {"decrypt", CmdDecryptTraceCmds, 1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"},\r
+ {"mad", CmdHF14AMfMAD, 0, "Checks and prints MAD"},\r
+ {"ndef", CmdHFMFNDEF, 0, "Prints NDEF records from card"},\r
+ {"personalize", CmdHFMFPersonalize, 0, "Personalize UID (Mifare Classic EV1 only)"},\r
+ {NULL, NULL, 0, NULL}\r
};\r
\r
-int CmdHFMF(const char *Cmd)\r
-{\r
+\r
+int CmdHFMF(const char *Cmd) {\r
(void)WaitForResponseTimeout(CMD_ACK,NULL,100);\r
CmdsParse(CommandTable, Cmd);\r
return 0;\r
}\r
\r
-int CmdHelp(const char *Cmd)\r
-{\r
- CmdsHelp(CommandTable);\r
- return 0;\r
+\r
+int CmdHelp(const char *Cmd) {\r
+ CmdsHelp(CommandTable);\r
+ return 0;\r
}\r