+ if (param_gethex(Cmd, 0, KEY, 16))
+ {
+ PrintAndLog("KEY must include 16 HEX symbols");
+ return 1;
+ }
+
+ blockNo = param_get8(Cmd, 1);
+ if (blockNo>32)
+ {
+ PrintAndLog("Error: Maximum number of blocks is 32 for iClass 2K Cards!");
+ return 1;
+ }
+ if (param_gethex(Cmd, 2, bldata, 8))
+ {
+ PrintAndLog("Block data must include 8 HEX symbols");
+ return 1;
+ }
+
+ UsbCommand c = {CMD_ICLASS_ISO14443A_WRITE, {0}};
+ SendCommand(&c);
+ UsbCommand resp;
+
+ if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
+ uint8_t isOK = resp.arg[0] & 0xff;
+ uint8_t * data = resp.d.asBytes;
+
+ memcpy(CSN,data,8);
+ memcpy(CCNR,data+8,8);
+ PrintAndLog("DEBUG: %s",sprint_hex(CSN,8));
+ PrintAndLog("DEBUG: %s",sprint_hex(CCNR,8));
+ PrintAndLog("isOk:%02x", isOK);
+ } else {
+ PrintAndLog("Command execute timeout");
+ }
+
+ diversifyKey(CSN,KEY, div_key);
+
+ PrintAndLog("Div Key: %s",sprint_hex(div_key,8));
+ doMAC(CCNR, div_key, MAC);
+
+ UsbCommand c2 = {CMD_ICLASS_ISO14443A_WRITE, {readerType,blockNo}};
+ memcpy(c2.d.asBytes, bldata, 8);
+ memcpy(c2.d.asBytes+8, MAC, 4);
+ SendCommand(&c2);
+
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+ uint8_t isOK = resp.arg[0] & 0xff;
+ uint8_t * data = resp.d.asBytes;
+
+ if (isOK)
+ PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4));
+ else
+ PrintAndLog("isOk:%02x", isOK);
+ } else {
+ PrintAndLog("Command execute timeout");
+ }
+ return 0;
+}
+int CmdHFiClass_loclass(const char *Cmd)
+{
+ char opt = param_getchar(Cmd, 0);
+
+ if (strlen(Cmd)<1 || opt == 'h') {
+ PrintAndLog("Usage: hf iclass loclass [options]");
+ PrintAndLog("Options:");
+ PrintAndLog("h Show this help");
+ PrintAndLog("t Perform self-test");
+ PrintAndLog("f <filename> Bruteforce iclass dumpfile");
+ PrintAndLog(" An iclass dumpfile is assumed to consist of an arbitrary number of");
+ PrintAndLog(" malicious CSNs, and their protocol responses");
+ PrintAndLog(" The the binary format of the file is expected to be as follows: ");
+ PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
+ PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
+ PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
+ PrintAndLog(" ... totalling N*24 bytes");
+ return 0;
+ }
+ char fileName[255] = {0};
+ if(opt == 'f')
+ {
+ if(param_getstr(Cmd, 1, fileName) > 0)
+ {
+ return bruteforceFileNoKeys(fileName);
+ }else
+ {
+ PrintAndLog("You must specify a filename");
+ }
+ }
+ else if(opt == 't')
+ {
+ int errors = testCipherUtils();
+ errors += testMAC();
+ errors += doKeyTests(0);
+ errors += testElite();
+ if(errors)
+ {
+ prnlog("OBS! There were errors!!!");
+ }
+ return errors;
+ }
+
+ return 0;
+}
+
+static command_t CommandTable[] =
+{
+ {"help", CmdHelp, 1, "This help"},
+ {"list", CmdHFiClassList, 0, "[Deprecated] List iClass history"},
+ {"snoop", CmdHFiClassSnoop, 0, "Eavesdrop iClass communication"},
+ {"sim", CmdHFiClassSim, 0, "Simulate iClass tag"},
+ {"reader",CmdHFiClassReader, 0, "Read an iClass tag"},
+ {"replay",CmdHFiClassReader_Replay, 0, "Read an iClass tag via Reply Attack"},
+ {"dump", CmdHFiClassReader_Dump, 0, "Authenticate and Dump iClass tag"},
+// {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"},
+ {"loclass", CmdHFiClass_loclass, 1, "Use loclass to perform bruteforce of reader attack dump"},
+ {"eload", CmdHFiClassELoad, 0, "[experimental] Load data into iclass emulator memory"},
+ {"decrypt", CmdHFiClassDecrypt, 1, "Decrypt tagdump" },
+ {NULL, NULL, 0, NULL}
+};
+
+int CmdHFiClass(const char *Cmd)
+{
+ CmdsParse(CommandTable, Cmd);
+ return 0;
+}
+
+int CmdHelp(const char *Cmd)
+{
+ CmdsHelp(CommandTable);