+int CmdHFiClassCheckKeys(const char *Cmd) {
+
+ char ctmp = 0x00;
+ ctmp = param_getchar(Cmd, 0);
+ if (ctmp == 'h' || ctmp == 'H') return usage_hf_iclass_chk();
+
+ uint8_t mac[4] = {0x00,0x00,0x00,0x00};
+ uint8_t key[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+ uint8_t div_key[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+
+ // elite key, raw key, standard key
+ bool elite = false;
+ bool rawkey = false;
+ bool found_debit = false;
+ bool found_credit = false;
+
+ FILE * f;
+ char filename[FILE_PATH_SIZE] = {0};
+ char buf[17];
+ uint8_t *keyBlock = NULL, *p;
+ int keyitems = 0, keycnt = 0;
+
+
+ // May be a dictionary file
+ if ( param_getstr(Cmd, 1, filename, sizeof(filename)) >= FILE_PATH_SIZE ) {
+ PrintAndLog("File name too long");
+ free(keyBlock);
+ return 2;
+ }
+
+ if ( !(f = fopen( filename , "r")) ) {
+ PrintAndLog("File: %s: not found or locked.", filename);
+ free(keyBlock);
+ return 1;
+ }
+
+ while( fgets(buf, sizeof(buf), f) ){
+ if (strlen(buf) < 16 || buf[15] == '\n')
+ continue;
+
+ while (fgetc(f) != '\n' && !feof(f)) ; //goto next line
+
+ if( buf[0]=='#' ) continue; //The line start with # is comment, skip
+
+ if (!isxdigit(buf[0])){
+ PrintAndLog("File content error. '%s' must include 16 HEX symbols",buf);
+ continue;
+ }
+
+ buf[16] = 0;
+
+ p = realloc(keyBlock, 8 * (keyitems += 64));
+ if (!p) {
+ PrintAndLog("Cannot allocate memory for default keys");
+ free(keyBlock);
+ fclose(f);
+ return 2;
+ }
+ keyBlock = p;
+
+ memset(keyBlock + 8 * keycnt, 0, 8);
+ num_to_bytes(strtoull(buf, NULL, 16), 8, keyBlock + 8 * keycnt);
+
+ //PrintAndLog("check key[%2d] %016" PRIx64, keycnt, bytes_to_num(keyBlock + 8*keycnt, 8));
+ keycnt++;
+ memset(buf, 0, sizeof(buf));
+ }
+ fclose(f);
+ PrintAndLog("Loaded %2d keys from %s", keycnt, filename);
+
+ // time
+ uint64_t t1 = msclock();
+
+ for (uint32_t c = 0; c < keycnt; c += 1) {
+ printf("."); fflush(stdout);
+ if (ukbhit()) {
+ int gc = getchar(); (void)gc;
+ printf("\naborted via keyboard!\n");
+ break;
+ }
+
+ memcpy(key, keyBlock + 8 * c , 8);
+
+ // debit key. try twice
+ for (int foo = 0; foo < 2 && !found_debit; foo++) {
+ if (!select_and_auth(key, mac, div_key, false, elite, rawkey, false))
+ continue;
+
+ // key found.
+ PrintAndLog("\n--------------------------------------------------------");
+ PrintAndLog(" Found AA1 debit key\t\t[%s]", sprint_hex(key, 8));
+ found_debit = true;
+ }
+
+ // credit key. try twice
+ for (int foo = 0; foo < 2 && !found_credit; foo++) {
+ if (!select_and_auth(key, mac, div_key, true, elite, rawkey, false))
+ continue;
+
+ // key found
+ PrintAndLog("\n--------------------------------------------------------");
+ PrintAndLog(" Found AA2 credit key\t\t[%s]", sprint_hex(key, 8));
+ found_credit = true;
+ }
+
+ // both keys found.
+ if ( found_debit && found_credit )
+ break;
+ }
+
+ t1 = msclock() - t1;
+
+ PrintAndLog("\nTime in iclass checkkeys: %.0f seconds\n", (float)t1/1000.0);
+
+ DropField();
+ free(keyBlock);
+ PrintAndLog("");
+ return 0;
+}
+