]> git.zerfleddert.de Git - proxmark3-svn/blob - armsrc/mifaredesfire.c
Merge branch 'master' of https://github.com/Proxmark/proxmark3
[proxmark3-svn] / armsrc / mifaredesfire.c
1 #include "mifaredesfire.h"
2
3 #define MAX_APPLICATION_COUNT 28
4 #define MAX_FILE_COUNT 16
5 #define MAX_FRAME_SIZE 60
6 #define NOT_YET_AUTHENTICATED 255
7 #define FRAME_PAYLOAD_SIZE (MAX_FRAME_SIZE - 5)
8
9 // the block number for the ISO14443-4 PCB
10 uint8_t pcb_blocknum = 0;
11 // Deselect card by sending a s-block. the crc is precalced for speed
12 static uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4};
13
14 //static uint8_t __msg[MAX_FRAME_SIZE] = { 0x0A, 0x00, 0x00, /* ..., */ 0x00 };
15 /* PCB CID CMD PAYLOAD */
16 //static uint8_t __res[MAX_FRAME_SIZE];
17
18 bool InitDesfireCard(){
19
20 // Make sure it is off.
21 // FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
22 // SpinDelay(300);
23
24 byte_t cardbuf[USB_CMD_DATA_SIZE];
25 memset(cardbuf,0,sizeof(cardbuf));
26
27 iso14a_set_tracing(TRUE);
28 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
29
30 iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf;
31 int len = iso14443a_select_card(NULL,card,NULL);
32
33 if (!len) {
34 if (MF_DBGLEVEL >= 1) {
35 Dbprintf("Can't select card");
36 }
37 OnError();
38 return false;
39 }
40 return true;
41 }
42
43 // ARG0 flag enums
44 enum {
45 NONE = 0x00,
46 INIT = 0x01,
47 DISCONNECT = 0x02,
48 FOO = 0x04,
49 BAR = 0x08,
50 } CmdOptions ;
51
52 void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){
53
54 /* ARG0 contains flags.
55 0x01 = init card.
56 0x02 = No Disconnect
57 0x03
58 */
59 uint8_t flags = arg0;
60 size_t datalen = arg1;
61 uint8_t resp[RECV_RES_SIZE];
62 memset(resp,0,sizeof(resp));
63
64 if (MF_DBGLEVEL >= 4) {
65 Dbprintf(" flags : %02X", flags);
66 Dbprintf(" len : %02X", datalen);
67 print_result(" RX : ", datain, datalen);
68 }
69
70 if ( flags & INIT ){
71 if ( !InitDesfireCard() )
72 return;
73 }
74
75 int len = DesfireAPDU(datain, datalen, resp);
76 print_result(" <--: ", resp, len);
77 if ( !len ) {
78 if (MF_DBGLEVEL >= 4) {
79 print_result("ERR <--: ", resp, len);
80 }
81 OnError();
82 return;
83 }
84
85 // reset the pcb_blocknum,
86 pcb_blocknum = 0;
87
88 if ( flags & DISCONNECT )
89 OnSuccess();
90
91 cmd_send(CMD_ACK,1,len,0,resp,len);
92 }
93
94 void MifareDesfireGetInformation(){
95
96 int len = 0;
97 uint8_t resp[USB_CMD_DATA_SIZE];
98 uint8_t dataout[USB_CMD_DATA_SIZE];
99 byte_t cardbuf[USB_CMD_DATA_SIZE];
100
101 memset(resp,0,sizeof(resp));
102 memset(dataout,0, sizeof(dataout));
103 memset(cardbuf,0,sizeof(cardbuf));
104
105 /*
106 1 = PCB 1
107 2 = cid 2
108 3 = desfire command 3
109 4-5 = crc 4 key
110 5-6 crc
111 PCB == 0x0A because sending CID byte.
112 CID == 0x00 first card?
113 */
114 iso14a_clear_trace();
115 iso14a_set_tracing(TRUE);
116 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
117
118 // card select - information
119 iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf;
120 byte_t isOK = iso14443a_select_card(NULL, card, NULL);
121 if (isOK != 1) {
122 if (MF_DBGLEVEL >= 1) {
123 Dbprintf("Can't select card");
124 }
125 OnError();
126 return;
127 }
128
129 memcpy(dataout,card->uid,7);
130
131 LED_A_ON();
132 LED_B_OFF();
133 LED_C_OFF();
134
135 uint8_t cmd[] = {GET_VERSION};
136 size_t cmd_len = sizeof(cmd);
137
138 len = DesfireAPDU(cmd, cmd_len, resp);
139 if ( !len ) {
140 print_result("ERROR <--: ", resp, len);
141 OnError();
142 return;
143 }
144
145 LED_A_OFF();
146 LED_B_ON();
147 memcpy(dataout+7,resp+3,7);
148
149 // ADDITION_FRAME 1
150 cmd[0] = ADDITIONAL_FRAME;
151 len = DesfireAPDU(cmd, cmd_len, resp);
152 if ( !len ) {
153 print_result("ERROR <--: ", resp, len);
154 OnError();
155 return;
156 }
157
158 LED_B_OFF();
159 LED_C_ON();
160 memcpy(dataout+7+7,resp+3,7);
161
162 // ADDITION_FRAME 2
163 len = DesfireAPDU(cmd, cmd_len, resp);
164 if ( !len ) {
165 print_result("ERROR <--: ", resp, len);
166 OnError();
167 return;
168 }
169
170 memcpy(dataout+7+7+7,resp+3,14);
171
172 cmd_send(CMD_ACK,1,0,0,dataout,sizeof(dataout));
173
174 // reset the pcb_blocknum,
175 pcb_blocknum = 0;
176 OnSuccess();
177 }
178
179 void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain){
180
181 uint8_t null_key_data[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
182 //uint8_t new_key_data[8] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
183 int res = 0;
184
185 desfirekey_t default_key = Desfire_des_key_new_with_version (null_key_data);
186
187 // res = Desfire_select_application (tags[i], aid);
188 if (res < 0) {
189 print_result("default key: ", default_key->data, 24 );
190 return;
191 }
192
193 return;
194 // pcb cid cmd key crc1 cr2
195 //uint8_t cmd2[] = {0x02,0x00,GET_KEY_VERSION, 0x00, 0x00, 0x00 };
196
197 //uint8_t* bigbuffer = mifare_get_bigbufptr();
198 byte_t isOK = 1;
199 uint8_t resp[256];
200 uint8_t key[24];
201 uint8_t IV[16];
202
203 // första byten håller keylength.
204 uint8_t keylen = datain[0];
205 memcpy(key, datain+1, keylen);
206
207 if (MF_DBGLEVEL >= 1) {
208
209 Dbprintf("MODE: %d", mode);
210 Dbprintf("ALGO: %d", algo);
211 Dbprintf("KEYNO: %d", keyno);
212 Dbprintf("KEYLEN: %d", keylen);
213
214 print_result("KEY", key, keylen);
215 }
216
217 // card select - information
218 byte_t buf[USB_CMD_DATA_SIZE];
219 iso14a_card_select_t *card = (iso14a_card_select_t*)buf;
220
221 // test of DES on ARM side.
222 /*
223 if ( mode == 1){
224 uint8_t IV[8];
225 uint8_t plain[16];
226 uint8_t encData[16];
227
228 uint8_t tmpData[8];
229 uint8_t tmpPlain[8];
230
231 memset(IV, 0, 8);
232 memset(tmpData, 0 ,8);
233 memset(tmpPlain,0 ,8);
234 memcpy(key, datain, 8);
235 memcpy(plain, datain+30, 16);
236
237 for(uint8_t i=0; i< sizeof(plain); i=i+8 ){
238
239 memcpy(tmpPlain, plain+i, 8);
240 des_enc( &tmpData, &tmpPlain, &key);
241 memcpy(encData+i, tmpData, 8);
242 }
243 }
244 */
245
246 iso14a_clear_trace();
247
248 iso14a_set_tracing(TRUE);
249
250 // power up the field
251 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
252
253 // select the card
254 isOK = iso14443a_select_card(resp, card, NULL);
255 if (isOK != 1) {
256 if (MF_DBGLEVEL >= 1) {
257 Dbprintf("CAN'T SELECT CARD, SOMETHING WENT WRONG BEFORE AUTH");
258 }
259 OnError();
260 return;
261 }
262
263 LED_A_ON();
264 LED_B_OFF();
265 LED_C_OFF();
266
267 // 3 olika sätt att authenticera. AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32)
268 // 4 olika crypto algo DES, 3DES, 3K3DES, AES
269 // 3 olika kommunikations sätt, PLAIN,MAC,CRYPTO
270
271 // des, nyckel 0,
272 switch (mode){
273 case 1:
274 // if ( SendDesfireCommand(AUTHENTICATE, &keyno, resp) > 0 ){
275 // // fick nonce från kortet
276 // }
277 break;
278 case 2:
279 //SendDesfireCommand(AUTHENTICATE_ISO, &keyno, resp);
280 break;
281 case 3:{
282 AesCtx ctx;
283 if ( AesCtxIni(&ctx, IV, key, KEY128, CBC) < 0 ){
284 if (MF_DBGLEVEL >= 1) {
285 Dbprintf("AES context failed to init");
286 }
287 OnError();
288 return;
289 }
290 uint8_t real_cmd[6];
291 real_cmd[0] = 0x90;
292 real_cmd[1] = 0x02;
293 real_cmd[2] = AUTHENTICATE_AES;
294 real_cmd[3] = keyno;
295
296 AppendCrc14443a(real_cmd, 4);
297 ReaderTransmit(real_cmd, sizeof(real_cmd), NULL);
298
299 int len = ReaderReceive(resp);
300 if(!len) {
301 OnError();
302 return;
303 }
304
305 print_result("RX:", resp, len);
306
307 enum DESFIRE_STATUS status = resp[1];
308 if ( status != ADDITIONAL_FRAME) {
309 OnError();
310 return;
311 }
312
313 // tags enc nonce
314 uint8_t encRndB[16];
315 uint8_t decRndB[16];
316 uint8_t nonce[16];
317 uint8_t both[32];
318 uint8_t encBoth[32];
319
320 memset(nonce, 0, 16);
321 memcpy( encRndB, resp+2, 16);
322
323 // dekryptera tagnonce.
324 AesDecrypt(&ctx, encRndB, decRndB, 16);
325
326 rol(decRndB,16);
327
328 memcpy(both, nonce,16);
329 memcpy(both+16, decRndB ,16 );
330
331 AesEncrypt(&ctx, both, encBoth, 32 );
332
333 uint8_t real_cmd_A[36];
334 real_cmd_A[0] = 0x03;
335 real_cmd_A[1] = ADDITIONAL_FRAME;
336
337 memcpy(real_cmd_A+2, encBoth, sizeof(encBoth) );
338 AppendCrc14443a(real_cmd_A, 34);
339 ReaderTransmit(real_cmd_A, sizeof(real_cmd_A), NULL);
340
341 len = ReaderReceive(resp);
342
343 print_result("Auth1a ", resp, 36);
344
345 status = resp[1];
346 if ( status != OPERATION_OK) {
347 Dbprintf("Cmd Error: %02x Len: %d", status,len);
348 OnError();
349 return;
350 }
351
352 break;
353 }
354
355 }
356
357 OnSuccess(resp);
358 }
359
360 // 3 olika ISO sätt att skicka data till DESFIRE (direkt, inkapslat, inkapslat ISO)
361 // cmd = cmd bytes to send
362 // cmd_len = length of cmd
363 // dataout = pointer to response data array
364 int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){
365
366 uint32_t status = 0;
367 size_t wrappedLen = 0;
368 uint8_t wCmd[USB_CMD_DATA_SIZE];
369
370 wrappedLen = CreateAPDU( cmd, cmd_len, wCmd);
371
372 if (MF_DBGLEVEL >= 4) {
373 print_result("WCMD <--: ", wCmd, wrappedLen);
374 }
375 ReaderTransmit( wCmd, wrappedLen, NULL);
376
377 status = ReaderReceive(dataout);
378
379 if(!status){
380 return FALSE; //DATA LINK ERROR
381 }
382 // if we received an I- or R(ACK)-Block with a block number equal to the
383 // current block number, toggle the current block number
384 else if (status >= 4 // PCB+CID+CRC = 4 bytes
385 && ((dataout[0] & 0xC0) == 0 // I-Block
386 || (dataout[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0
387 && (dataout[0] & 0x01) == pcb_blocknum) // equal block numbers
388 {
389 pcb_blocknum ^= 1; //toggle next block
390 }
391 return status;
392 }
393
394 // CreateAPDU
395 size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout){
396
397 size_t cmdlen = MIN(len+4, USB_CMD_DATA_SIZE-1);
398
399 uint8_t cmd[cmdlen];
400 memset(cmd, 0, cmdlen);
401
402 cmd[0] = 0x0A; // 0x0A = skicka cid, 0x02 = ingen cid. Särskilda bitar //
403 cmd[0] |= pcb_blocknum; // OR the block number into the PCB
404 cmd[1] = 0x00; // CID: 0x00 //FIXME: allow multiple selected cards
405
406 memcpy(cmd+2, datain, len);
407 AppendCrc14443a(cmd, len+2);
408
409 memcpy(dataout, cmd, cmdlen);
410
411 return cmdlen;
412 }
413
414 // crc_update(&desfire_crc32, 0, 1); /* CMD_WRITE */
415 // crc_update(&desfire_crc32, addr, addr_sz);
416 // crc_update(&desfire_crc32, byte, 8);
417 // uint32_t crc = crc_finish(&desfire_crc32);
418
419
420 /* Version
421
422 //uint8_t versionCmd1[] = {0x02, 0x60};
423 //uint8_t versionCmd2[] = {0x03, 0xaf};
424 //uint8_t versionCmd3[] = {0x02, 0xaf};
425
426 // AUTH 1 - CMD: 0x02, 0x0A, 0x00 = Auth
427 // 0x02 = status byte för simpla svar?!?
428 // 0x0a = krypto typ
429 // 0x00 = key nr
430 //uint8_t initAuthCmdDES[] = {0x02, 0x0a, 0x00}; // DES
431 //uint8_t initAuthCmd3DES[] = {0x02, 0x1a, 0x00}; // 3DES
432 //uint8_t initAuthCmdAES[] = {0x02, 0xaa, 0x00}; // AES
433 // auth 1 - answer command
434 // 0x03 = status byte för komplexa typer?
435 // 0xaf = additional frame
436 // LEN = 1+1+32+2 = 36
437 //uint8_t answerAuthCmd[34] = {0x03, 0xaf};
438
439 // Lägg till CRC
440 //AppendCrc14443a(versionCmd1,sizeof(versionCmd1));
441 */
442
443 // Sending commands
444 /*ReaderTransmit(versionCmd1,sizeof(versionCmd1)+2, NULL);
445 len = ReaderReceive(buffer);
446 print_result("Get Version 3", buffer, 9);
447 */
448
449 // for( int i = 0; i < 8; i++){
450 // // Auth 1 - Request authentication
451 // ReaderTransmit(initAuthCmdAES,sizeof(initAuthCmdAES)+2, NULL);
452 // //len = ReaderReceive(buffer);
453
454 // // 0xAE = authentication error
455 // if (buffer[1] == 0xae) {
456 // Dbprintf("Cmd Error: %02x", buffer[1]);
457 // OnError();
458 // return;
459 // }
460
461 // // tags enc nonce
462 // memcpy(encRndB, buffer+2, 16);
463
464 // // dekryptera svaret från tag.
465 // AesDecrypt(&ctx, encRndB, decRndB, 16);
466
467 // rol8(decRndB,16);
468 // memcpy(RndARndB, RndA,16);
469 // memcpy(RndARndB+16, decRndB ,16 );
470
471 // AesEncrypt(&ctx, RndARndB, encRndARndB, 32 );
472
473 // memcpy(answerAuthCmd+2, encRndARndB, 32);
474 // AppendCrc14443a(answerAuthCmd,sizeof(answerAuthCmd));
475
476 // ReaderTransmit(answerAuthCmd,sizeof(answerAuthCmd)+2, NULL);
477
478 // len = ReaderReceive(buffer);
479
480 // print_result("Auth1a ", buffer, 8);
481 // Dbprintf("Rx len: %02x", len);
482
483 // if (buffer[1] == 0xCA) {
484 // Dbprintf("Cmd Error: %02x Len: %d", buffer[1],len);
485 // cmd_send(CMD_ACK,0,0,0,0,0);
486 // key[1] = i;
487 // AesCtxIni(&ctx, iv, key, KEY128, CBC);
488 // }
489 // }
490
491 //des_dec(decRndB, encRndB, key);
492
493 //Do crypto magic
494 /*
495 DES_ede2_cbc_encrypt(e_RndB,RndB,sizeof(e_RndB),&ks1,&ks2,&iv,0);
496 memcpy(RndARndB,RndA,8);
497 memcpy(RndARndB+8,RndB,8);
498 PrintAndLog(" RA+B:%s",sprint_hex(RndARndB, 16));
499 DES_ede2_cbc_encrypt(RndARndB,RndARndB,sizeof(RndARndB),&ks1,&ks2,&e_RndB,1);
500 PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB, 16));
501 */
502
503
504 int mifare_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
505
506 uint8_t* buffer = mifare_get_bigbufptr();
507 uint8_t dcmd[19];
508
509 dcmd[0] = 0xAF;
510 memcpy(dcmd+1,key,16);
511 AppendCrc14443a(dcmd, 17);
512
513
514 ReaderTransmit(dcmd, sizeof(dcmd), NULL);
515 int len = ReaderReceive(buffer);
516 if(!len) {
517 if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout.");
518 len = ReaderReceive(buffer);
519 }
520
521 if(len==1) {
522 if (MF_DBGLEVEL >= 1) {
523 Dbprintf("NAK - Authentication failed.");
524 Dbprintf("Cmd Error: %02x", buffer[0]);
525 }
526 return 1;
527 }
528
529 if (len == 11){
530 if (MF_DBGLEVEL >= 1) {
531 Dbprintf("Auth2 Resp: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
532 buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],
533 buffer[5],buffer[6],buffer[7],buffer[8],buffer[9],
534 buffer[10]);
535 }
536 return 0;
537 }
538 return 1;
539 }
540
541 void MifareDES_Auth2(uint32_t arg0, uint8_t *datain){
542
543 return;
544 uint32_t cuid = arg0;
545 uint8_t key[16];
546
547 byte_t isOK = 0;
548 byte_t dataoutbuf[16];
549
550 memset(key, 0, 16);
551 memcpy(key, datain, 16);
552
553 LED_A_ON();
554 LED_B_OFF();
555 LED_C_OFF();
556
557 if(mifare_des_auth2(cuid, key, dataoutbuf)){
558 if (MF_DBGLEVEL >= 1) Dbprintf("Authentication part2: Fail...");
559 }
560 isOK=1;
561 if (MF_DBGLEVEL >= 2) DbpString("AUTH 2 FINISHED");
562
563 LED_B_ON();
564 cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,11);
565 LED_B_OFF();
566
567 // Thats it...
568 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
569 LEDsoff();
570 }
571
572 void OnSuccess(){
573 pcb_blocknum = 0;
574 ReaderTransmit(deselect_cmd, 3 , NULL);
575 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
576 LEDsoff();
577 }
578
579 void OnError(){
580 pcb_blocknum = 0;
581 ReaderTransmit(deselect_cmd, 3 , NULL);
582 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
583 cmd_send(CMD_ACK,0,0,0,0,0);
584 LEDsoff();
585 }
Impressum, Datenschutz