-int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKey, bool calibrate)
-{
- uint32_t i, j;
- uint32_t uid;
- UsbCommand resp;
-
- int num_unique_nonces;
-
- StateList_t statelists[2];
- struct Crypto1State *p1, *p2, *p3, *p4;
-
- uint8_t *keyBlock = NULL;
- uint64_t key64;
-
- int isOK = 1;
-
- uint64_t next_print_time = 0;
- uint64_t start_time;
- float brute_force_time;
- float brute_force_per_second;
-
- // flush queue
- (void)WaitForResponseTimeout(CMD_ACK,NULL,100);
-
- UsbCommand c = {CMD_MIFARE_NESTED, {blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, calibrate}};
- memcpy(c.d.asBytes, key, 6);
- SendCommand(&c);
-
- if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
- // some cards can cause it to get stuck in a loop, so break out of it
- UsbCommand c = {CMD_PING};
- SendCommand(&c);
- (void)WaitForResponseTimeout(CMD_ACK,NULL,500);
- return -1;
- }
+static int nested_fixed_nonce(StateList_t statelist, uint32_t fixed_nt, uint32_t authentication_timeout, uint8_t *resultKey) {
+ // We have a tag with a fixed nonce (nt) and therefore only one (usually long) list of possible crypto states.
+ // Instead of testing all those keys on the device with a complete authentication cycle, we do all of the crypto operations here.
+ uint8_t nr_enc[4] = NESTED_FIXED_NR_ENC; // we use a fixed {nr}
+ uint8_t ar[4];
+ num_to_bytes(prng_successor(fixed_nt, 64), 4, ar); // ... and ar is fixed too