+ // test keys
+ res = mfCheckKeys(trgBlockNo, trgKeyType, 8, keyBlock, &key64);
+ if (res)
+ res = mfCheckKeys(trgBlockNo, trgKeyType, 8, &keyBlock[6 * 8], &key64);
+ if (!res)
+ PrintAndLog("Found valid key:%012llx", key64);
+ else
+ PrintAndLog("No valid key found");
+ } else // ------------------------------------ multiple sectors working
+ {
+ blDiff = blockNo % 4;
+ PrintAndLog("Block shift=%d", blDiff);
+ e_sector = calloc(SectorsCnt, sizeof(sector));
+ if (e_sector == NULL) return 1;
+
+ //test current key 4 sectors
+ memcpy(keyBlock, key, 6);
+ num_to_bytes(0xa0a1a2a3a4a5, 6, (uint8_t*)(keyBlock + 1 * 6));
+ num_to_bytes(0xb0b1b2b3b4b5, 6, (uint8_t*)(keyBlock + 2 * 6));
+ num_to_bytes(0xffffffffffff, 6, (uint8_t*)(keyBlock + 3 * 6));
+ num_to_bytes(0x000000000000, 6, (uint8_t*)(keyBlock + 4 * 6));
+ num_to_bytes(0xaabbccddeeff, 6, (uint8_t*)(keyBlock + 5 * 6));
+
+ PrintAndLog("Testing known keys. Sector count=%d", SectorsCnt);
+ for (i = 0; i < SectorsCnt; i++) {
+ for (j = 0; j < 2; j++) {
+ if (e_sector[i].foundKey[j]) continue;
+
+ res = mfCheckKeys(i * 4 + blDiff, j, 6, keyBlock, &key64);
+
+ if (!res) {
+ e_sector[i].Key[j] = key64;
+ e_sector[i].foundKey[j] = 1;
+ }
+ }
+ }
+
+
+ // nested sectors
+ iterations = 0;
+ PrintAndLog("nested...");
+ for (i = 0; i < NESTED_SECTOR_RETRY; i++) {
+ for (trgBlockNo = blDiff; trgBlockNo < SectorsCnt * 4; trgBlockNo = trgBlockNo + 4)
+ for (trgKeyType = 0; trgKeyType < 2; trgKeyType++) {
+ if (e_sector[trgBlockNo / 4].foundKey[trgKeyType]) continue;
+ if (mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock)) continue;
+
+ iterations++;
+
+ //try keys from nested
+ res = mfCheckKeys(trgBlockNo, trgKeyType, 8, keyBlock, &key64);
+ if (res)
+ res = mfCheckKeys(trgBlockNo, trgKeyType, 8, &keyBlock[6 * 8], &key64);
+ if (!res) {
+ PrintAndLog("Found valid key:%012llx", key64);
+ e_sector[trgBlockNo / 4].foundKey[trgKeyType] = 1;
+ e_sector[trgBlockNo / 4].Key[trgKeyType] = key64;
+ }
+ }
+ }
+
+ PrintAndLog("Iterations count: %d", iterations);
+ //print them
+ PrintAndLog("|---|----------------|---|----------------|---|");
+ PrintAndLog("|blk|key A |res|key B |res|");
+ PrintAndLog("|---|----------------|---|----------------|---|");
+ for (i = 0; i < SectorsCnt; i++) {
+ PrintAndLog("|%03d| %012llx | %d | %012llx | %d |", i,
+ e_sector[i].Key[0], e_sector[i].foundKey[0], e_sector[i].Key[1], e_sector[i].foundKey[1]);
+ }
+ PrintAndLog("|---|----------------|---|----------------|---|");
+
+ free(e_sector);
+ }
+
+ return 0;
+}
+
+int CmdHF14AMfChk(const char *Cmd)
+{
+ int i, res;
+ int keycnt = 0;
+ char ctmp = 0x00;
+ uint8_t blockNo = 0;
+ uint8_t keyType = 0;
+ uint8_t keyBlock[8 * 6];
+ uint64_t key64 = 0;
+
+ memset(keyBlock, 0x00, sizeof(keyBlock));
+
+ if (strlen(Cmd)<3) {
+ PrintAndLog("Usage: hf 14a chk <block number> <key A/B> [<key (12 hex symbols)>]");
+ PrintAndLog(" sample: hf 14a chk 0 A FFFFFFFFFFFF a0a1a2a3a4a5 b01b2b3b4b5 ");
+ return 0;