+ return 0;\r
+}\r
+\r
+\r
+int CmdHF14AMfNestedHard(const char *Cmd)\r
+{\r
+ uint8_t blockNo = 0;\r
+ uint8_t keyType = 0;\r
+ uint8_t trgBlockNo = 0;\r
+ uint8_t trgKeyType = 0;\r
+ uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
+ uint8_t trgkey[6] = {0, 0, 0, 0, 0, 0};\r
+\r
+ char ctmp;\r
+ ctmp = param_getchar(Cmd, 0);\r
+\r
+ if (ctmp != 'R' && ctmp != 'r' && ctmp != 'T' && ctmp != 't' && strlen(Cmd) < 20) {\r
+ PrintAndLog("Usage:");\r
+ PrintAndLog(" hf mf hardnested <block number> <key A|B> <key (12 hex symbols)>");\r
+ PrintAndLog(" <target block number> <target key A|B> [known target key (12 hex symbols)] [w] [s]");\r
+ PrintAndLog(" or hf mf hardnested r [known target key]");\r
+ PrintAndLog(" ");\r
+ PrintAndLog("Options: ");\r
+ PrintAndLog(" w: Acquire nonces and write them to binary file nonces.bin");\r
+ PrintAndLog(" s: Slower acquisition (required by some non standard cards)");\r
+ PrintAndLog(" r: Read nonces.bin and start attack");\r
+ PrintAndLog(" iX: set type of SIMD instructions. Without this flag programs autodetect it.");\r
+ PrintAndLog(" i5: AVX512");\r
+ PrintAndLog(" i2: AVX2");\r
+ PrintAndLog(" ia: AVX");\r
+ PrintAndLog(" is: SSE2");\r
+ PrintAndLog(" im: MMX");\r
+ PrintAndLog(" in: none (use CPU regular instruction set)");\r
+ PrintAndLog(" ");\r
+ PrintAndLog(" sample1: hf mf hardnested 0 A FFFFFFFFFFFF 4 A");\r
+ PrintAndLog(" sample2: hf mf hardnested 0 A FFFFFFFFFFFF 4 A w");\r
+ PrintAndLog(" sample3: hf mf hardnested 0 A FFFFFFFFFFFF 4 A w s");\r
+ PrintAndLog(" sample4: hf mf hardnested r");\r
+ PrintAndLog(" ");\r
+ PrintAndLog("Add the known target key to check if it is present in the remaining key space:");\r
+ PrintAndLog(" sample5: hf mf hardnested 0 A A0A1A2A3A4A5 4 A FFFFFFFFFFFF");\r
+ return 0;\r
+ }\r
+\r
+ bool know_target_key = false;\r
+ bool nonce_file_read = false;\r
+ bool nonce_file_write = false;\r
+ bool slow = false;\r
+ int tests = 0;\r
+\r
+\r
+ uint16_t iindx = 0;\r
+ if (ctmp == 'R' || ctmp == 'r') {\r
+ nonce_file_read = true;\r
+ iindx = 1;\r
+ if (!param_gethex(Cmd, 1, trgkey, 12)) {\r
+ know_target_key = true;\r
+ iindx = 2;\r
+ }\r
+ } else if (ctmp == 'T' || ctmp == 't') {\r
+ tests = param_get32ex(Cmd, 1, 100, 10);\r
+ iindx = 2;\r
+ if (!param_gethex(Cmd, 2, trgkey, 12)) {\r
+ know_target_key = true;\r
+ iindx = 3;\r
+ }\r
+ } else {\r
+ blockNo = param_get8(Cmd, 0);\r
+ ctmp = param_getchar(Cmd, 1);\r
+ if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {\r
+ PrintAndLog("Key type must be A or B");\r
+ return 1;\r
+ }\r
+ if (ctmp != 'A' && ctmp != 'a') {\r
+ keyType = 1;\r
+ }\r
+\r
+ if (param_gethex(Cmd, 2, key, 12)) {\r
+ PrintAndLog("Key must include 12 HEX symbols");\r
+ return 1;\r
+ }\r
+\r
+ trgBlockNo = param_get8(Cmd, 3);\r
+ ctmp = param_getchar(Cmd, 4);\r
+ if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {\r
+ PrintAndLog("Target key type must be A or B");\r
+ return 1;\r
+ }\r
+ if (ctmp != 'A' && ctmp != 'a') {\r
+ trgKeyType = 1;\r
+ }\r
+\r
+ uint16_t i = 5;\r
+\r
+ if (!param_gethex(Cmd, 5, trgkey, 12)) {\r
+ know_target_key = true;\r
+ i++;\r
+ }\r
+ iindx = i;\r
+\r
+ while ((ctmp = param_getchar(Cmd, i))) {\r
+ if (ctmp == 's' || ctmp == 'S') {\r
+ slow = true;\r
+ } else if (ctmp == 'w' || ctmp == 'W') {\r
+ nonce_file_write = true;\r
+ } else if (param_getlength(Cmd, i) == 2 && ctmp == 'i') {\r
+ iindx = i;\r
+ } else {\r
+ PrintAndLog("Possible options are w , s and/or iX");\r
+ return 1;\r
+ }\r
+ i++;\r
+ }\r
+ }\r
+ \r
+ SetSIMDInstr(SIMD_AUTO);\r
+ if (iindx > 0) {\r
+ while ((ctmp = param_getchar(Cmd, iindx))) {\r
+ if (param_getlength(Cmd, iindx) == 2 && ctmp == 'i') {\r
+ switch(param_getchar_indx(Cmd, 1, iindx)) {\r
+ case '5':\r
+ SetSIMDInstr(SIMD_AVX512);\r
+ break;\r
+ case '2':\r
+ SetSIMDInstr(SIMD_AVX2);\r
+ break;\r
+ case 'a':\r
+ SetSIMDInstr(SIMD_AVX);\r
+ break;\r
+ case 's':\r
+ SetSIMDInstr(SIMD_SSE2);\r
+ break;\r
+ case 'm':\r
+ SetSIMDInstr(SIMD_MMX);\r
+ break;\r
+ case 'n':\r
+ SetSIMDInstr(SIMD_NONE);\r
+ break;\r
+ default:\r
+ PrintAndLog("Unknown SIMD type. %c", param_getchar_indx(Cmd, 1, iindx));\r
+ return 1;\r
+ }\r
+ }\r
+ iindx++;\r
+ } \r
+ }\r
+\r
+ PrintAndLog("--target block no:%3d, target key type:%c, known target key: 0x%02x%02x%02x%02x%02x%02x%s, file action: %s, Slow: %s, Tests: %d ",\r
+ trgBlockNo,\r
+ trgKeyType?'B':'A',\r
+ trgkey[0], trgkey[1], trgkey[2], trgkey[3], trgkey[4], trgkey[5],\r
+ know_target_key?"":" (not set)",\r
+ nonce_file_write?"write":nonce_file_read?"read":"none",\r
+ slow?"Yes":"No",\r
+ tests);\r
+\r
+ int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, know_target_key?trgkey:NULL, nonce_file_read, nonce_file_write, slow, tests);\r
+\r
+ if (isOK) {\r
+ switch (isOK) {\r
+ case 1 : PrintAndLog("Error: No response from Proxmark.\n"); break;\r
+ case 2 : PrintAndLog("Button pressed. Aborted.\n"); break;\r
+ default : break;\r
+ }\r
+ return 2;\r
+ }\r