]>
git.zerfleddert.de Git - proxmark3-svn/blob - client/mifare/mfkey.c
0c72a37c84b1cd9d341ff75891ad5b57e69728c9
1 //-----------------------------------------------------------------------------
6 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
7 // at your option, any later version. See the LICENSE.txt file for the text of
9 //-----------------------------------------------------------------------------
10 // MIFARE Darkside hack
11 //-----------------------------------------------------------------------------
16 #include "crapto1/crapto1.h"
19 // recover key from 2 different reader responses on same tag challenge
20 bool mfkey32(nonces_t data
, uint64_t *outputkey
) {
21 struct Crypto1State
*s
,*t
;
23 uint64_t key
= 0; // recovered key
24 bool isSuccess
= false;
27 s
= lfsr_recovery32(data
.ar
^ prng_successor(data
.nonce
, 64), 0);
29 for(t
= s
; t
->odd
| t
->even
; ++t
) {
30 lfsr_rollback_word(t
, 0, 0);
31 lfsr_rollback_word(t
, data
.nr
, 1);
32 lfsr_rollback_word(t
, data
.cuid
^ data
.nonce
, 0);
33 crypto1_get_lfsr(t
, &key
);
34 crypto1_word(t
, data
.cuid
^ data
.nonce
, 0);
35 crypto1_word(t
, data
.nr2
, 1);
36 if (data
.ar2
== (crypto1_word(t
, 0, 0) ^ prng_successor(data
.nonce
, 64))) {
37 //PrintAndLog("Found Key: [%012" PRIx64 "]",key);
40 if (counter
== 20) break;
43 isSuccess
= (counter
== 1);
44 *outputkey
= ( isSuccess
) ? outkey
: 0;
46 /* //un-comment to save all keys to a stats.txt file
48 if ((fout = fopen("stats.txt","ab")) == NULL) {
49 PrintAndLog("Could not create file name stats.txt");
52 fprintf(fout, "mfkey32,%d,%08x,%d,%s,%04x%08x,%.0Lf\r\n", counter, data.cuid, data.sector, (data.keytype) ? "B" : "A", (uint32_t)(outkey>>32) & 0xFFFF,(uint32_t)(outkey&0xFFFFFFFF),(long double)t1);
58 // recover key from 2 reader responses on 2 different tag challenges
59 bool mfkey32_moebius(nonces_t data
, uint64_t *outputkey
) {
60 struct Crypto1State
*s
, *t
;
62 uint64_t key
= 0; // recovered key
63 bool isSuccess
= false;
66 s
= lfsr_recovery32(data
.ar
^ prng_successor(data
.nonce
, 64), 0);
68 for(t
= s
; t
->odd
| t
->even
; ++t
) {
69 lfsr_rollback_word(t
, 0, 0);
70 lfsr_rollback_word(t
, data
.nr
, 1);
71 lfsr_rollback_word(t
, data
.cuid
^ data
.nonce
, 0);
72 crypto1_get_lfsr(t
, &key
);
74 crypto1_word(t
, data
.cuid
^ data
.nonce2
, 0);
75 crypto1_word(t
, data
.nr2
, 1);
76 if (data
.ar2
== (crypto1_word(t
, 0, 0) ^ prng_successor(data
.nonce2
, 64))) {
77 //PrintAndLog("Found Key: [%012" PRIx64 "]",key);
84 isSuccess
= (counter
== 1);
85 *outputkey
= ( isSuccess
) ? outkey
: 0;
87 /* // un-comment to output all keys to stats.txt
89 if ((fout = fopen("stats.txt","ab")) == NULL) {
90 PrintAndLog("Could not create file name stats.txt");
93 fprintf(fout, "moebius,%d,%08x,%d,%s,%04x%08x,%0.Lf\r\n", counter, data.cuid, data.sector, (data.keytype) ? "B" : "A", (uint32_t) (outkey>>32),(uint32_t)(outkey&0xFFFFFFFF),(long double)t1);
99 // recover key from reader response and tag response of one authentication sequence
100 int mfkey64(nonces_t data
, uint64_t *outputkey
){
101 uint64_t key
= 0; // recovered key
102 uint32_t ks2
; // keystream used to encrypt reader response
103 uint32_t ks3
; // keystream used to encrypt tag response
104 struct Crypto1State
*revstate
;
106 // Extract the keystream from the messages
107 ks2
= data
.ar
^ prng_successor(data
.nonce
, 64);
108 ks3
= data
.at
^ prng_successor(data
.nonce
, 96);
109 revstate
= lfsr_recovery64(ks2
, ks3
);
110 lfsr_rollback_word(revstate
, 0, 0);
111 lfsr_rollback_word(revstate
, 0, 0);
112 lfsr_rollback_word(revstate
, data
.nr
, 1);
113 lfsr_rollback_word(revstate
, data
.cuid
^ data
.nonce
, 0);
114 crypto1_get_lfsr(revstate
, &key
);
115 // PrintAndLog("Found Key: [%012" PRIx64 "]", key);
116 crypto1_destroy(revstate
);