]> cvs.zerfleddert.de Git - proxmark3-svn/blob - armsrc/mifaredesfire.c
b7c1bc5b17cda086e0a05090897c239d8337d42b
[proxmark3-svn] / armsrc / mifaredesfire.c
1 #include "mifaredesfire.h"
2 #include "des.h"
3
4 #define MAX_APPLICATION_COUNT 28
5 #define MAX_FILE_COUNT 16
6 #define MAX_FRAME_SIZE 60
7 #define NOT_YET_AUTHENTICATED 255
8 #define FRAME_PAYLOAD_SIZE (MAX_FRAME_SIZE - 5)
9
10 // the block number for the ISO14443-4 PCB
11 uint8_t pcb_blocknum = 0;
12 // Deselect card by sending a s-block. the crc is precalced for speed
13 static uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4};
14
15 //static uint8_t __msg[MAX_FRAME_SIZE] = { 0x0A, 0x00, 0x00, /* ..., */ 0x00 };
16 /* PCB CID CMD PAYLOAD */
17 //static uint8_t __res[MAX_FRAME_SIZE];
18
19 bool InitDesfireCard(){
20
21 // Make sure it is off.
22 // FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
23 // SpinDelay(300);
24
25 byte_t cardbuf[USB_CMD_DATA_SIZE];
26 memset(cardbuf,0,sizeof(cardbuf));
27
28 iso14a_set_tracing(TRUE);
29 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
30
31 iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf;
32 int len = iso14443a_select_card(NULL,card,NULL);
33
34 if (!len) {
35 if (MF_DBGLEVEL >= 1) {
36 Dbprintf("Can't select card");
37 }
38 OnError();
39 return false;
40 }
41 return true;
42 }
43
44 // ARG0 flag enums
45 enum {
46 NONE = 0x00,
47 INIT = 0x01,
48 DISCONNECT = 0x02,
49 CLEARTRACE = 0x04,
50 BAR = 0x08,
51 } CmdOptions ;
52
53 void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){
54
55 /* ARG0 contains flags.
56 0x01 = init card.
57 0x02 = Disconnect
58 0x03
59 */
60 uint8_t flags = arg0;
61 size_t datalen = arg1;
62 uint8_t resp[RECV_RES_SIZE];
63 memset(resp,0,sizeof(resp));
64
65 if (MF_DBGLEVEL >= 4) {
66 Dbprintf(" flags : %02X", flags);
67 Dbprintf(" len : %02X", datalen);
68 print_result(" RX : ", datain, datalen);
69 }
70
71 if ( flags & CLEARTRACE ){
72 iso14a_clear_trace();
73 }
74
75 if ( flags & INIT ){
76 if ( !InitDesfireCard() )
77 return;
78 }
79
80 int len = DesfireAPDU(datain, datalen, resp);
81 if (MF_DBGLEVEL >= 4) {
82 print_result("ERR <--: ", resp, len);
83 }
84
85 if ( !len ) {
86 OnError();
87 return;
88 }
89
90 // reset the pcb_blocknum,
91 pcb_blocknum = 0;
92
93 if ( flags & DISCONNECT ){
94 OnSuccess();
95 }
96
97 cmd_send(CMD_ACK,1,len,0,resp,len);
98 }
99
100 void MifareDesfireGetInformation(){
101
102 int len = 0;
103 uint8_t resp[USB_CMD_DATA_SIZE];
104 uint8_t dataout[USB_CMD_DATA_SIZE];
105 byte_t cardbuf[USB_CMD_DATA_SIZE];
106
107 memset(resp,0,sizeof(resp));
108 memset(dataout,0, sizeof(dataout));
109 memset(cardbuf,0,sizeof(cardbuf));
110
111 /*
112 1 = PCB 1
113 2 = cid 2
114 3 = desfire command 3
115 4-5 = crc 4 key
116 5-6 crc
117 PCB == 0x0A because sending CID byte.
118 CID == 0x00 first card?
119 */
120 iso14a_clear_trace();
121 iso14a_set_tracing(TRUE);
122 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
123
124 // card select - information
125 iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf;
126 byte_t isOK = iso14443a_select_card(NULL, card, NULL);
127 if (isOK != 1) {
128 if (MF_DBGLEVEL >= 1) {
129 Dbprintf("Can't select card");
130 }
131 OnError();
132 return;
133 }
134
135 memcpy(dataout,card->uid,7);
136
137 LED_A_ON();
138 LED_B_OFF();
139 LED_C_OFF();
140
141 uint8_t cmd[] = {GET_VERSION};
142 size_t cmd_len = sizeof(cmd);
143
144 len = DesfireAPDU(cmd, cmd_len, resp);
145 if ( !len ) {
146 print_result("ERROR <--: ", resp, len);
147 OnError();
148 return;
149 }
150
151 LED_A_OFF();
152 LED_B_ON();
153 memcpy(dataout+7,resp+3,7);
154
155 // ADDITION_FRAME 1
156 cmd[0] = ADDITIONAL_FRAME;
157 len = DesfireAPDU(cmd, cmd_len, resp);
158 if ( !len ) {
159 print_result("ERROR <--: ", resp, len);
160 OnError();
161 return;
162 }
163
164 LED_B_OFF();
165 LED_C_ON();
166 memcpy(dataout+7+7,resp+3,7);
167
168 // ADDITION_FRAME 2
169 len = DesfireAPDU(cmd, cmd_len, resp);
170 if ( !len ) {
171 print_result("ERROR <--: ", resp, len);
172 OnError();
173 return;
174 }
175
176 memcpy(dataout+7+7+7,resp+3,14);
177
178 cmd_send(CMD_ACK,1,0,0,dataout,sizeof(dataout));
179
180 // reset the pcb_blocknum,
181 pcb_blocknum = 0;
182 OnSuccess();
183 }
184
185 void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain){
186
187 int len = 0;
188 //uint8_t PICC_MASTER_KEY8[8] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47};
189 uint8_t PICC_MASTER_KEY16[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f };
190 uint8_t null_key_data8[8] = {0x00};
191 //uint8_t null_key_data16[16] = {0x00};
192 //uint8_t new_key_data8[8] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
193 //uint8_t new_key_data16[16] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};
194
195 //uint8_t* bigbuffer = mifare_get_bigbufptr();
196 uint8_t resp[256] = {0x00};
197 uint8_t IV[16] = {0x00};
198
199 size_t datalen = datain[0];
200
201 uint8_t cmd[40] = {0x00};
202 uint8_t encRndB[16] = {0x00};
203 uint8_t decRndB[16] = {0x00};
204 uint8_t nonce[16] = {0x00};
205 uint8_t both[32] = {0x00};
206 uint8_t encBoth[32] = {0x00};
207
208 InitDesfireCard();
209
210 LED_A_ON();
211 LED_B_OFF();
212 LED_C_OFF();
213
214 // 3 olika sätt att authenticera. AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32)
215 // 4 olika crypto algo DES, 3DES, 3K3DES, AES
216 // 3 olika kommunikations sätt, PLAIN,MAC,CRYPTO
217
218 // des, nyckel 0,
219 switch (mode){
220 case 1:{
221 if (algo == 1) {
222
223 uint8_t keybytes[8];
224 uint8_t RndA[8] = {0x00};
225 uint8_t RndB[8] = {0x00};
226
227 if (datain[1] == 0xff){
228 memcpy(keybytes,null_key_data8,8);
229 } else{
230 memcpy(keybytes, datain+1, datalen);
231 }
232
233 struct desfire_key defaultkey = {0};
234 desfirekey_t key = &defaultkey;
235 Desfire_des_key_new(keybytes, key);
236
237 cmd[0] = AUTHENTICATE;
238 cmd[1] = keyno; //keynumber
239 len = DesfireAPDU(cmd, 2, resp);
240 if ( !len ) {
241 if (MF_DBGLEVEL >= 1) {
242 DbpString("Authentication failed. Card timeout.");
243 }
244 OnError();
245 return;
246 }
247
248 if ( resp[2] == 0xaf ){
249 } else {
250 DbpString("Authetication failed. Invalid key number.");
251 OnError();
252 return;
253 }
254
255 memcpy( encRndB, resp+3, 8);
256
257 des_dec(&decRndB, &encRndB, key->data);
258 memcpy(RndB, decRndB, 8);
259 rol(decRndB,8);
260
261 // This should be random
262 uint8_t decRndA[8] = {0x00};
263 memcpy(RndA, decRndA, 8);
264 uint8_t encRndA[8] = {0x00};
265
266 des_dec(&encRndA, &decRndA, key->data);
267
268 memcpy(both, encRndA, 8);
269
270 for (int x = 0; x < 8; x++) {
271 decRndB[x] = decRndB[x] ^ encRndA[x];
272
273 }
274
275 des_dec(&encRndB, &decRndB, key->data);
276
277 memcpy(both + 8, encRndB, 8);
278
279 cmd[0] = ADDITIONAL_FRAME;
280 memcpy(cmd+1, both, 16 );
281
282 len = DesfireAPDU(cmd, 17, resp);
283 if ( !len ) {
284 if (MF_DBGLEVEL >= 1) {
285 DbpString("Authentication failed. Card timeout.");
286 }
287 OnError();
288 return;
289 }
290
291 if ( resp[2] == 0x00 ){
292
293 struct desfire_key sessionKey = {0};
294 desfirekey_t skey = &sessionKey;
295 Desfire_session_key_new( RndA, RndB , key, skey );
296 //print_result("SESSION : ", skey->data, 8);
297
298 memcpy(encRndA, resp+3, 8);
299 des_dec(&encRndA, &encRndA, key->data);
300 rol(decRndA,8);
301 for (int x = 0; x < 8; x++) {
302 if (decRndA[x] != encRndA[x]) {
303 DbpString("Authetication failed. Cannot varify PICC.");
304 OnError();
305 return;
306 }
307 }
308
309 //Change the selected key to a new value.
310 /*
311
312 cmd[0] = 0xc4;
313 cmd[1] = keyno;
314
315 uint8_t newKey[16] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
316
317 uint8_t first, second;
318 uint8_t buff1[8] = {0x00};
319 uint8_t buff2[8] = {0x00};
320 uint8_t buff3[8] = {0x00};
321
322 memcpy(buff1,newKey, 8);
323 memcpy(buff2,newKey + 8, 8);
324
325 ComputeCrc14443(CRC_14443_A, newKey, 16, &first, &second);
326 memcpy(buff3, &first, 1);
327 memcpy(buff3 + 1, &second, 1);
328
329 des_dec(&buff1, &buff1, skey->data);
330 memcpy(cmd+2,buff1,8);
331
332 for (int x = 0; x < 8; x++) {
333 buff2[x] = buff2[x] ^ buff1[x];
334 }
335 des_dec(&buff2, &buff2, skey->data);
336 memcpy(cmd+10,buff2,8);
337
338 for (int x = 0; x < 8; x++) {
339 buff3[x] = buff3[x] ^ buff2[x];
340 }
341 des_dec(&buff3, &buff3, skey->data);
342 memcpy(cmd+18,buff3,8);
343
344 // The command always times out on the first attempt, this will retry until a response
345 // is recieved.
346 len = 0;
347 while(!len) {
348 len = DesfireAPDU(cmd,26,resp);
349 }
350 */
351
352 OnSuccess();
353 cmd_send(CMD_ACK,1,0,0,skey->data,8);
354
355 } else {
356 DbpString("Authetication failed.");
357 OnError();
358 return;
359 }
360
361 }
362 }
363 break;
364 case 2:
365 //SendDesfireCommand(AUTHENTICATE_ISO, &keyno, resp);
366 break;
367 case 3:{
368
369 //defaultkey
370 uint8_t keybytes[16];
371 if (datain[1] == 0xff){
372 memcpy(keybytes,PICC_MASTER_KEY16,16);
373 } else{
374 memcpy(keybytes, datain+1, datalen);
375 }
376
377 struct desfire_key defaultkey = {0};
378 desfirekey_t key = &defaultkey;
379 Desfire_aes_key_new( keybytes, key);
380
381 AesCtx ctx;
382 if ( AesCtxIni(&ctx, IV, key->data, KEY128, CBC) < 0 ){
383 if( MF_DBGLEVEL >= 4) {
384 Dbprintf("AES context failed to init");
385 }
386 OnError();
387 return;
388 }
389
390 cmd[0] = AUTHENTICATE_AES;
391 cmd[1] = 0x00; //keynumber
392 len = DesfireAPDU(cmd, 2, resp);
393 if ( !len ) {
394 if (MF_DBGLEVEL >= 1) {
395 DbpString("Authentication failed. Card timeout.");
396 }
397 OnError();
398 return;
399 }
400
401 memcpy( encRndB, resp+3, 16);
402
403 // dekryptera tagnonce.
404 AesDecrypt(&ctx, encRndB, decRndB, 16);
405 rol(decRndB,16);
406 memcpy(both, nonce,16);
407 memcpy(both+16, decRndB ,16 );
408 AesEncrypt(&ctx, both, encBoth, 32 );
409
410 cmd[0] = ADDITIONAL_FRAME;
411 memcpy(cmd+1, encBoth, 32 );
412
413 len = DesfireAPDU(cmd, 33, resp); // 1 + 32 == 33
414 if ( !len ) {
415 if (MF_DBGLEVEL >= 1) {
416 DbpString("Authentication failed. Card timeout.");
417 }
418 OnError();
419 return;
420 }
421
422 if ( resp[2] == 0x00 ){
423 // Create AES Session key
424 struct desfire_key sessionKey = {0};
425 desfirekey_t skey = &sessionKey;
426 Desfire_session_key_new( nonce, decRndB , key, skey );
427 print_result("SESSION : ", skey->data, 16);
428 } else {
429 DbpString("Authetication failed.");
430 OnError();
431 return;
432 }
433
434 break;
435 }
436 }
437
438 OnSuccess();
439 cmd_send(CMD_ACK,1,len,0,resp,len);
440 }
441
442 // 3 olika ISO sätt att skicka data till DESFIRE (direkt, inkapslat, inkapslat ISO)
443 // cmd = cmd bytes to send
444 // cmd_len = length of cmd
445 // dataout = pointer to response data array
446 int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){
447
448 uint32_t status = 0;
449 size_t wrappedLen = 0;
450 uint8_t wCmd[USB_CMD_DATA_SIZE] = {0};
451
452 wrappedLen = CreateAPDU( cmd, cmd_len, wCmd);
453
454 if (MF_DBGLEVEL >= 4) {
455 print_result("WCMD <--: ", wCmd, wrappedLen);
456 }
457 ReaderTransmit( wCmd, wrappedLen, NULL);
458
459 status = ReaderReceive(dataout);
460
461 if( status == 0x00){
462 if (MF_DBGLEVEL >= 4) {
463 Dbprintf("fukked");
464 }
465 return FALSE; //DATA LINK ERROR
466 }
467 // if we received an I- or R(ACK)-Block with a block number equal to the
468 // current block number, toggle the current block number
469 else if (status >= 4 // PCB+CID+CRC = 4 bytes
470 && ((dataout[0] & 0xC0) == 0 // I-Block
471 || (dataout[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0
472 && (dataout[0] & 0x01) == pcb_blocknum) // equal block numbers
473 {
474 pcb_blocknum ^= 1; //toggle next block
475 }
476 return status;
477 }
478
479 // CreateAPDU
480 size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout){
481
482 size_t cmdlen = MIN(len+4, USB_CMD_DATA_SIZE-1);
483
484 uint8_t cmd[cmdlen];
485 memset(cmd, 0, cmdlen);
486
487 cmd[0] = 0x0A; // 0x0A = skicka cid, 0x02 = ingen cid. Särskilda bitar //
488 cmd[0] |= pcb_blocknum; // OR the block number into the PCB
489 cmd[1] = 0x00; // CID: 0x00 //FIXME: allow multiple selected cards
490
491 memcpy(cmd+2, datain, len);
492 AppendCrc14443a(cmd, len+2);
493
494 memcpy(dataout, cmd, cmdlen);
495
496 return cmdlen;
497 }
498
499 // crc_update(&desfire_crc32, 0, 1); /* CMD_WRITE */
500 // crc_update(&desfire_crc32, addr, addr_sz);
501 // crc_update(&desfire_crc32, byte, 8);
502 // uint32_t crc = crc_finish(&desfire_crc32);
503
504 void OnSuccess(){
505 pcb_blocknum = 0;
506 ReaderTransmit(deselect_cmd, 3 , NULL);
507 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
508 LEDsoff();
509 }
510
511 void OnError(){
512 pcb_blocknum = 0;
513 ReaderTransmit(deselect_cmd, 3 , NULL);
514 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
515 cmd_send(CMD_ACK,0,0,0,0,0);
516 LEDsoff();
517 }
Impressum, Datenschutz