]>
git.zerfleddert.de Git - proxmark3-svn/blob - client/nonce2key/nonce2key.c
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 //-----------------------------------------------------------------------------
12 #include "nonce2key.h"
13 #include "mifarehost.h"
15 #include "proxmark3.h"
17 int nonce2key(uint32_t uid
, uint32_t nt
, uint32_t nr
, uint64_t par_info
, uint64_t ks_info
, uint64_t * key
) {
19 struct Crypto1State
*state
;
20 uint32_t i
, pos
, rr
= 0, nr_diff
;
21 byte_t bt
, ks3x
[8], par
[8][8];
23 // Reset the last three significant bits of the reader nonce
26 PrintAndLog("\nuid(%08x) nt(%08x) par(%016"llx
") ks(%016"llx
") nr(%08"llx
")\n\n", uid
, nt
, par_info
, ks_info
, nr
);
28 for ( pos
= 0; pos
< 8; pos
++ ) {
29 ks3x
[7-pos
] = (ks_info
>> (pos
*8)) & 0x0f;
30 bt
= (par_info
>> (pos
*8)) & 0xff;
32 for ( i
= 0; i
< 8; i
++) {
33 par
[7-pos
][i
] = (bt
>> i
) & 0x01;
37 printf("|diff|{nr} |ks3|ks3^5|parity |\n");
38 printf("+----+--------+---+-----+---------------+\n");
40 for ( i
= 0; i
< 8; i
++) {
41 nr_diff
= nr
| i
<< 5;
42 printf("| %02x |%08x|", i
<< 5, nr_diff
);
43 printf(" %01x | %01x |", ks3x
[i
], ks3x
[i
]^5);
44 for (pos
= 0; pos
< 7; pos
++) printf("%01x,", par
[i
][pos
]);
45 printf("%01x|\n", par
[i
][7]);
47 printf("+----+--------+---+-----+---------------+\n");
49 state
= lfsr_common_prefix(nr
, rr
, ks3x
, par
);
50 lfsr_rollback_word(state
, uid
^nt
, 0);
51 crypto1_get_lfsr(state
, key
);
52 crypto1_destroy(state
);
56 // *outputkey is not used...
57 int tryMfk32(uint64_t myuid
, uint8_t *data
, uint8_t *outputkey
){
59 struct Crypto1State
*s
,*t
;
60 uint64_t key
; // recovered key
61 uint32_t uid
; // serial number
62 uint32_t nt
; // tag challenge
63 uint32_t nr0_enc
; // first encrypted reader challenge
64 uint32_t ar0_enc
; // first encrypted reader response
65 uint32_t nr1_enc
; // second encrypted reader challenge
66 uint32_t ar1_enc
; // second encrypted reader response
67 bool isSuccess
= FALSE
;
70 uid
= myuid
;//(uint32_t)bytes_to_num(data + 0, 4);
71 nt
= *(uint32_t*)(data
+8);
72 nr0_enc
= *(uint32_t*)(data
+12);
73 ar0_enc
= *(uint32_t*)(data
+16);
74 nr1_enc
= *(uint32_t*)(data
+32);
75 ar1_enc
= *(uint32_t*)(data
+36);
77 // PrintAndLog("recovering key for:");
78 // PrintAndLog(" uid: %08x %08x",uid, myuid);
79 // PrintAndLog(" nt: %08x",nt);
80 // PrintAndLog(" {nr_0}: %08x",nr0_enc);
81 // PrintAndLog(" {ar_0}: %08x",ar0_enc);
82 // PrintAndLog(" {nr_1}: %08x",nr1_enc);
83 // PrintAndLog(" {ar_1}: %08x",ar1_enc);
85 s
= lfsr_recovery32(ar0_enc
^ prng_successor(nt
, 64), 0);
87 for(t
= s
; t
->odd
| t
->even
; ++t
) {
88 lfsr_rollback_word(t
, 0, 0);
89 lfsr_rollback_word(t
, nr0_enc
, 1);
90 lfsr_rollback_word(t
, uid
^ nt
, 0);
91 crypto1_get_lfsr(t
, &key
);
92 crypto1_word(t
, uid
^ nt
, 0);
93 crypto1_word(t
, nr1_enc
, 1);
94 if (ar1_enc
== (crypto1_word(t
, 0, 0) ^ prng_successor(nt
, 64))) {
95 PrintAndLog("Found Key: [%012"llx
"]", key
);
103 num_to_bytes(key
, 6, outputkey
);
108 int tryMfk32_moebius(uint64_t myuid
, uint8_t *data
, uint8_t *outputkey
){
110 struct Crypto1State
*s
, *t
;
111 uint64_t key
; // recovered key
112 uint32_t uid
; // serial number
113 uint32_t nt0
; // tag challenge first
114 uint32_t nt1
; // tag challenge second
115 uint32_t nr0_enc
; // first encrypted reader challenge
116 uint32_t ar0_enc
; // first encrypted reader response
117 uint32_t nr1_enc
; // second encrypted reader challenge
118 uint32_t ar1_enc
; // second encrypted reader response
119 bool isSuccess
= FALSE
;
122 uid
= myuid
;//(uint32_t)bytes_to_num(data + 0, 4);
123 nt0
= *(uint32_t*)(data
+8);
124 nr0_enc
= *(uint32_t*)(data
+12);
125 ar0_enc
= *(uint32_t*)(data
+16);
126 nt1
= *(uint32_t*)(data
+8);
127 nr1_enc
= *(uint32_t*)(data
+32);
128 ar1_enc
= *(uint32_t*)(data
+36);
130 s
= lfsr_recovery32(ar0_enc
^ prng_successor(nt0
, 64), 0);
132 for(t
= s
; t
->odd
| t
->even
; ++t
) {
133 lfsr_rollback_word(t
, 0, 0);
134 lfsr_rollback_word(t
, nr0_enc
, 1);
135 lfsr_rollback_word(t
, uid
^ nt0
, 0);
136 crypto1_get_lfsr(t
, &key
);
138 crypto1_word(t
, uid
^ nt1
, 0);
139 crypto1_word(t
, nr1_enc
, 1);
140 if (ar1_enc
== (crypto1_word(t
, 0, 0) ^ prng_successor(nt1
, 64))) {
141 PrintAndLog("Found Key: [%012"llx
"]",key
);
148 num_to_bytes(key
, 6, outputkey
);
153 int tryMfk64(uint64_t myuid
, uint8_t *data
, uint8_t *outputkey
){
155 struct Crypto1State
*revstate
;
156 uint64_t key
; // recovered key
157 uint32_t uid
; // serial number
158 uint32_t nt
; // tag challenge
159 uint32_t nr_enc
; // encrypted reader challenge
160 uint32_t ar_enc
; // encrypted reader response
161 uint32_t at_enc
; // encrypted tag response
162 uint32_t ks2
; // keystream used to encrypt reader response
163 uint32_t ks3
; // keystream used to encrypt tag response
165 struct Crypto1State mpcs
= {0, 0};
166 struct Crypto1State
*pcs
;
169 uid
= myuid
;//(uint32_t)bytes_to_num(data + 0, 4);
170 nt
= *(uint32_t*)(data
+8);
171 nr_enc
= *(uint32_t*)(data
+12);
172 ar_enc
= *(uint32_t*)(data
+16);
174 crypto1_word(pcs
, nr_enc
, 1);
175 at_enc
= prng_successor(nt
, 96) ^ crypto1_word(pcs
, 0, 0);
177 // printf("Recovering key for:\n");
178 // printf(" uid: %08x\n",uid);
179 // printf(" nt: %08x\n",nt);
180 // printf(" {nr}: %08x\n",nr_enc);
181 // printf(" {ar}: %08x\n",ar_enc);
182 // printf(" {at}: %08x\n",at_enc);
184 // Extract the keystream from the messages
185 ks2
= ar_enc
^ prng_successor(nt
, 64);
186 ks3
= at_enc
^ prng_successor(nt
, 96);
188 revstate
= lfsr_recovery64(ks2
, ks3
);
189 lfsr_rollback_word(revstate
, 0, 0);
190 lfsr_rollback_word(revstate
, 0, 0);
191 lfsr_rollback_word(revstate
, nr_enc
, 1);
192 lfsr_rollback_word(revstate
, uid
^ nt
, 0);
193 crypto1_get_lfsr(revstate
, &key
);
194 PrintAndLog("Found Key: [%012"llx
"]",key
);
195 num_to_bytes(key
, 6, outputkey
);
196 crypto1_destroy(revstate
);