- UsbCommand resp;
- if (!WaitForResponseTimeout(CMD_ACK,&resp,3000)) return 1;
- if ((resp.arg[0] & 0xff) != 0x01) return 2;
- *key = bytes_to_num(resp.d.asBytes, 6);
- return 0;
+ uint32_t max_keys = (keycnt > (USB_CMD_DATA_SIZE / 6)) ? (USB_CMD_DATA_SIZE / 6) : keycnt;
+ *found_key = -1;
+ bool multisectorCheck = false;
+
+ for (int i = 0, ii = 0; i < keycnt; i += max_keys) {
+
+ if ((i + max_keys) >= keycnt) {
+ max_keys = keycnt - i;
+ }
+
+ bool init = (i == 0);
+ bool drop_field = (max_keys == keycnt);
+ uint8_t flags = clear_trace | multisectorCheck << 1 | init << 2 | drop_field << 3;
+
+ UsbCommand c = {CMD_MIFARE_CHKKEYS, {((blockNo & 0xff) | ((keyType & 0xff) << 8)), flags | timeout14a << 16, max_keys}};
+ memcpy(c.d.asBytes, keys + i * 6, max_keys * 6);
+ SendCommand(&c);
+
+ UsbCommand resp;
+ if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000))
+ return 1;
+
+ if ((resp.arg[0] & 0xff) != 0x01) {
+ if (((int)resp.arg[1]) < 0) { // error
+ return (int)resp.arg[1];
+ } else { // nothing found yet
+ if (display_progress && msclock() >= next_print_time) {
+ float brute_force_per_second = (float)(i - ii) / (float)(msclock() - start_time) * 1000.0;
+ ii = i;
+ start_time = msclock();
+ next_print_time = start_time + 10 * 1000;
+ PrintAndLog(" %8d keys left | %5.1f keys/sec | worst case %6.1f seconds remaining", keycnt - i, brute_force_per_second, (keycnt-i)/brute_force_per_second);
+ }
+ }
+ } else { // success
+ *found_key = bytes_to_num(resp.d.asBytes, 6);
+ return 0;
+ }
+ }
+
+ return 2; // nothing found