6ff6ade2 |
1 | //----------------------------------------------------------------------------- |
2 | // Copyright (C) 2014 Andy Davies |
3 | // |
4 | // This code is licensed to you under the terms of the GNU GPL, version 2 or, |
5 | // at your option, any later version. See the LICENSE.txt file for the text of |
6 | // the license. |
7 | //----------------------------------------------------------------------------- |
8 | // High frequency MIFARE commands |
9 | //----------------------------------------------------------------------------- |
10 | |
11 | #include "cmdhfmf.h" |
12 | #include "util.h" |
13 | #include <openssl/des.h> |
14 | #include <openssl/aes.h> |
15 | |
16 | static int CmdHelp(const char *Cmd); |
17 | |
18 | //DESFIRE |
19 | // Reader 2 Card : 020A, key (1 byte), CRC1 CRC2 ; auth (020a00) |
20 | // Card 2 Reader : 02AF, 8 Bytes(b0), CRC1 CRC2 |
21 | // Reader 2 Card : 03AF, 8 Bytes(b1),8 bytes(b2), CRC1 CRC2 |
22 | // Card 2 Reader : 0300, 8 bytes(b3), CRC1 CRC2 ; success |
23 | |
24 | //send 020A00, receive enc(nc) |
25 | |
26 | //02AE = error |
27 | //receive b3=enc(r4) |
28 | //r5=dec(b3) |
29 | //n'r=rol(r5) |
30 | //verify n'r=nr |
31 | |
32 | int CmdHF14AMfDESAuth(const char *Cmd){ |
33 | |
34 | uint8_t blockNo = 0; |
35 | //keyNo=0; |
36 | uint32_t cuid=0; |
37 | uint8_t reply[16]; |
38 | //DES_cblock r1_b1; |
39 | uint8_t b1[8]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; |
40 | uint8_t b2[8]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; |
41 | DES_cblock nr, b0, r1, r0; |
42 | |
43 | |
44 | uint8_t key[8]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; |
45 | //DES_cblock iv={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; |
46 | DES_key_schedule ks1; |
47 | DES_cblock key1; |
48 | |
49 | if (strlen(Cmd)<1) { |
50 | PrintAndLog("Usage: hf desfire des-auth k <key number>"); |
51 | PrintAndLog(" sample: hf desfire des-auth k 0"); |
52 | return 0; |
53 | } |
54 | |
55 | //Change key to user defined one |
56 | |
57 | memcpy(key1,key,8); |
58 | //memcpy(key2,key+8,8); |
59 | DES_set_key((DES_cblock *)key1,&ks1); |
60 | //DES_set_key((DES_cblock *)key2,&ks2); |
61 | |
62 | //Auth1 |
63 | UsbCommand c = {CMD_MIFARE_DES_AUTH1, {blockNo}}; |
64 | SendCommand(&c); |
65 | UsbCommand resp; |
66 | if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { |
67 | uint8_t isOK = resp.arg[0] & 0xff; |
68 | cuid = resp.arg[1]; |
69 | uint8_t * data= resp.d.asBytes; |
70 | |
71 | if (isOK){ |
72 | PrintAndLog("enc(nc)/b0:%s", sprint_hex(data+2,8)); |
73 | memcpy(b0,data+2,8); |
74 | } |
75 | } else { |
76 | PrintAndLog("Command execute timeout"); |
77 | } |
78 | |
79 | //Do crypto magic |
80 | DES_random_key(&nr); |
81 | //b1=dec(nr) |
82 | //r0=dec(b0) |
83 | DES_ecb_encrypt(&nr,&b1,&ks1,0); |
84 | DES_ecb_encrypt(&b0,&r0,&ks1,0); |
85 | //PrintAndLog("b1:%s",sprint_hex(b1, 8)); |
86 | PrintAndLog("r0:%s",sprint_hex(r0, 8)); |
87 | //r1=rol(r0) |
88 | memcpy(r1,r0,8); |
89 | rol(r1,8); |
90 | PrintAndLog("r1:%s",sprint_hex(r1, 8)); |
91 | for(int i=0;i<8;i++){ |
92 | b2[i]=(r1[i] ^ b1[i]); |
93 | } |
94 | DES_ecb_encrypt(&b2,&b2,&ks1,0); |
95 | //PrintAndLog("b1:%s",sprint_hex(b1, 8)); |
96 | PrintAndLog("b2:%s",sprint_hex(b2, 8)); |
97 | |
98 | //Auth2 |
99 | UsbCommand d = {CMD_MIFARE_DES_AUTH2, {cuid}}; |
100 | memcpy(reply,b1,8); |
101 | memcpy(reply+8,b2,8); |
102 | memcpy(d.d.asBytes,reply, 16); |
103 | SendCommand(&d); |
104 | |
105 | UsbCommand respb; |
106 | if (WaitForResponseTimeout(CMD_ACK,&respb,1500)) { |
107 | uint8_t isOK = respb.arg[0] & 0xff; |
108 | uint8_t * data2= respb.d.asBytes; |
109 | |
110 | if (isOK){ |
111 | PrintAndLog("b3:%s", sprint_hex(data2+2, 8)); |
112 | } |
113 | |
114 | } else { |
115 | PrintAndLog("Command execute timeout"); |
116 | } |
117 | return 1; |
118 | } |
119 | |
120 | //EV1 |
121 | // Reader 2 Card : 02AA, key (1 byte), CRC1 CRC2 ; auth |
122 | // Card 2 Reader : 02AF, 16 Bytes(b0), CRC1 CRC2 |
123 | // Reader 2 Card : 03AF, 16 Bytes(b1),16Bytes(b2) CRC1 CRC2 |
124 | // Card 2 Reader : 0300, 16 bytes(b3), CRC1 CRC2 ; success |
125 | int CmdHF14AMfAESAuth(const char *Cmd){ |
126 | |
127 | uint8_t blockNo = 0; |
128 | //keyNo=0; |
129 | uint32_t cuid=0; |
130 | uint8_t reply[32]; |
131 | //DES_cblock r1_b1; |
132 | //unsigned char * b1, b2, nr, b0, r0, r1; |
133 | |
134 | uint8_t b1[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; |
135 | uint8_t b2[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; |
136 | uint8_t nr[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; |
137 | uint8_t b0[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; |
138 | uint8_t r0[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; |
139 | uint8_t r1[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; |
140 | // |
141 | uint8_t key[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; |
142 | uint8_t iv[16]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; |
143 | AES_KEY key_e; |
144 | AES_KEY key_d; |
145 | |
146 | if (strlen(Cmd)<1) { |
147 | PrintAndLog("Usage: hf desfire aes-auth k <key number>"); |
148 | PrintAndLog(" sample: hf desfire aes-auth k 0"); |
149 | return 0; |
150 | } |
151 | |
152 | //Change key to user defined one |
153 | // |
154 | // int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,AES_KEY *key); |
155 | //int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,AES_KEY *key); |
156 | // |
157 | //memcpy(key1,key,16); |
158 | //memcpy(key2,key+8,8); |
159 | AES_set_encrypt_key(key,128,&key_e); |
160 | AES_set_decrypt_key(key,128,&key_d); |
161 | |
162 | //Auth1 |
163 | UsbCommand c = {CMD_MIFARE_DES_AUTH1, {blockNo}}; |
164 | SendCommand(&c); |
165 | UsbCommand resp; |
166 | if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { |
167 | uint8_t isOK = resp.arg[0] & 0xff; |
168 | cuid = resp.arg[1]; |
169 | uint8_t * data= resp.d.asBytes; |
170 | |
171 | if (isOK){ |
172 | PrintAndLog("enc(nc)/b0:%s", sprint_hex(data+2,16)); |
173 | memcpy(b0,data+2,16); |
174 | } |
175 | } else { |
176 | PrintAndLog("Command execute timeout"); |
177 | } |
178 | // |
179 | // void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, |
180 | //size_t length, const AES_KEY *key, |
181 | //unsigned char *ivec, const int enc); |
182 | |
183 | //Do crypto magic |
184 | //DES_random_key(&nr); |
185 | //b1=dec(nr) |
186 | //r0=dec(b0) |
187 | //AES_cbc_encrypt(&nr,&b1,16,&key,0); |
188 | AES_cbc_encrypt(&b0,&r0,16,&key_d,iv,0); |
189 | //PrintAndLog("b1:%s",sprint_hex(b1, 8)); |
190 | PrintAndLog("r0:%s",sprint_hex(r0, 16)); |
191 | //r1=rol(r0) |
192 | memcpy(r1,r0,16); |
193 | rol(r1,8); |
194 | PrintAndLog("r1:%s",sprint_hex(r1, 16)); |
195 | for(int i=0;i<16;i++){ |
196 | b1[i]=(nr[i] ^ b0[i]); |
197 | b2[i]=(r1[i] ^ b1[i]); |
198 | } |
199 | PrintAndLog("nr:%s",sprint_hex(nr, 16)); |
200 | AES_cbc_encrypt(&b1,&b1,16,&key_e,iv,1); |
201 | AES_cbc_encrypt(&b2,&b2,16,&key_e,iv,1); |
202 | PrintAndLog("b1:%s",sprint_hex(b1, 16)); |
203 | PrintAndLog("b2:%s",sprint_hex(b2, 16)); |
204 | |
205 | //Auth2 |
206 | UsbCommand d = {CMD_MIFARE_DES_AUTH2, {cuid}}; |
207 | memcpy(reply,b1,16); |
208 | memcpy(reply+16,b2,16); |
209 | memcpy(d.d.asBytes,reply, 32); |
210 | SendCommand(&d); |
211 | |
212 | UsbCommand respb; |
213 | if (WaitForResponseTimeout(CMD_ACK,&respb,1500)) { |
214 | uint8_t isOK = respb.arg[0] & 0xff; |
215 | uint8_t * data2= respb.d.asBytes; |
216 | |
217 | if (isOK){ |
218 | PrintAndLog("b3:%s", sprint_hex(data2+2, 16)); |
219 | } |
220 | |
221 | } else { |
222 | PrintAndLog("Command execute timeout"); |
223 | } |
224 | return 1; |
225 | } |
226 | |
227 | |
228 | //------------------------------------ |
229 | // Menu Stuff |
230 | //------------------------------------ |
231 | static command_t CommandTable[] = |
232 | { |
233 | {"help", CmdHelp, 1,"This help"}, |
234 | {"dbg", CmdHF14AMfDbg, 0,"Set default debug mode"}, |
235 | {"des-auth",CmdHF14AMfDESAuth, 0,"Desfire Authentication"}, |
236 | {"ev1-auth",CmdHF14AMfAESAuth, 0,"EV1 Authentication"}, |
237 | {NULL, NULL, 0, NULL} |
238 | }; |
239 | |
240 | int CmdHFMFDesfire(const char *Cmd){ |
241 | // flush |
242 | WaitForResponseTimeout(CMD_ACK,NULL,100); |
243 | CmdsParse(CommandTable, Cmd); |
244 | return 0; |
245 | } |
246 | |
247 | int CmdHelp(const char *Cmd){ |
248 | CmdsHelp(CommandTable); |
249 | return 0; |
250 | } |