]>
Commit | Line | Data |
---|---|---|
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; | |
0920f54c | 36 | uint32_t cuid = 0; |
37 | uint8_t reply[16] = {0x00}; | |
6ff6ade2 | 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; | |
0920f54c | 129 | uint32_t cuid = 0; |
130 | uint8_t reply[32] = {0x00}; | |
6ff6ade2 | 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 | |
28415b5d | 242 | clearCommandBuffer(); |
6ff6ade2 | 243 | CmdsParse(CommandTable, Cmd); |
244 | return 0; | |
245 | } | |
246 | ||
247 | int CmdHelp(const char *Cmd){ | |
248 | CmdsHelp(CommandTable); | |
249 | return 0; | |
250 | } |