1 #include "mifaredesfire.h"
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)
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};
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];
18 bool InitDesfireCard(){
20 // Make sure it is off.
21 // FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
24 byte_t cardbuf
[USB_CMD_DATA_SIZE
];
25 memset(cardbuf
,0,sizeof(cardbuf
));
27 iso14a_set_tracing(TRUE
);
28 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN
);
30 iso14a_card_select_t
*card
= (iso14a_card_select_t
*)cardbuf
;
31 int len
= iso14443a_select_card(NULL
,card
,NULL
);
34 if (MF_DBGLEVEL
>= 1) {
35 Dbprintf("Can't select card");
43 void MifareSendCommand(uint8_t arg0
, uint8_t arg1
, uint8_t *datain
){
45 /* ARG0 contains flags.
51 size_t datalen
= arg1
;
52 uint8_t resp
[RECV_RES_SIZE
];
53 memset(resp
,0,sizeof(resp
));
55 if (MF_DBGLEVEL
>= 4) {
56 Dbprintf(" flags: %02X", flags
);
57 Dbprintf(" len : %02X", datalen
);
58 print_result("to send: ", datain
, datalen
);
62 if ( !InitDesfireCard() )
66 int len
= DesfireAPDU(datain
, datalen
, resp
);
68 if (MF_DBGLEVEL
>= 4) {
69 print_result("ERR <--: ", resp
, len
);
74 cmd_send(CMD_ACK
,1,0,0,resp
,len
);
80 void MifareDesfireGetInformation(){
83 uint8_t resp
[USB_CMD_DATA_SIZE
];
84 uint8_t dataout
[USB_CMD_DATA_SIZE
];
85 byte_t cardbuf
[USB_CMD_DATA_SIZE
];
87 memset(resp
,0,sizeof(resp
));
88 memset(dataout
,0, sizeof(dataout
));
89 memset(cardbuf
,0,sizeof(cardbuf
));
97 PCB == 0x0A because sending CID byte.
98 CID == 0x00 first card?
100 iso14a_clear_trace();
101 iso14a_set_tracing(TRUE
);
102 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN
);
104 // card select - information
105 iso14a_card_select_t
*card
= (iso14a_card_select_t
*)cardbuf
;
106 byte_t isOK
= iso14443a_select_card(NULL
, card
, NULL
);
108 if (MF_DBGLEVEL
>= 1) {
109 Dbprintf("Can't select card");
115 memcpy(dataout
,card
->uid
,7);
121 uint8_t cmd
[] = {GET_VERSION
};
122 size_t cmd_len
= sizeof(cmd
);
124 len
= DesfireAPDU(cmd
, cmd_len
, resp
);
126 print_result("ERROR <--: ", resp
, len
);
133 memcpy(dataout
+7,resp
+3,7);
136 cmd
[0] = ADDITIONAL_FRAME
;
137 len
= DesfireAPDU(cmd
, cmd_len
, resp
);
139 print_result("ERROR <--: ", resp
, len
);
146 memcpy(dataout
+7+7,resp
+3,7);
149 len
= DesfireAPDU(cmd
, cmd_len
, resp
);
151 print_result("ERROR <--: ", resp
, len
);
156 memcpy(dataout
+7+7+7,resp
+3,14);
158 cmd_send(CMD_ACK
,1,0,0,dataout
,sizeof(dataout
));
160 // reset the pcb_blocknum,
165 void MifareDES_Auth1(uint8_t mode
, uint8_t algo
, uint8_t keyno
, uint8_t *datain
){
167 uint8_t null_key_data
[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
168 //uint8_t new_key_data[8] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
171 desfirekey_t default_key
= Desfire_des_key_new_with_version (null_key_data
);
173 // res = Desfire_select_application (tags[i], aid);
175 print_result("default key: ", default_key
->data
, 24 );
180 // pcb cid cmd key crc1 cr2
181 //uint8_t cmd2[] = {0x02,0x00,GET_KEY_VERSION, 0x00, 0x00, 0x00 };
183 //uint8_t* bigbuffer = mifare_get_bigbufptr();
189 // första byten håller keylength.
190 uint8_t keylen
= datain
[0];
191 memcpy(key
, datain
+1, keylen
);
193 if (MF_DBGLEVEL
>= 1) {
195 Dbprintf("MODE: %d", mode
);
196 Dbprintf("ALGO: %d", algo
);
197 Dbprintf("KEYNO: %d", keyno
);
198 Dbprintf("KEYLEN: %d", keylen
);
200 print_result("KEY", key
, keylen
);
203 // card select - information
204 byte_t buf
[USB_CMD_DATA_SIZE
];
205 iso14a_card_select_t
*card
= (iso14a_card_select_t
*)buf
;
207 // test of DES on ARM side.
218 memset(tmpData, 0 ,8);
219 memset(tmpPlain,0 ,8);
220 memcpy(key, datain, 8);
221 memcpy(plain, datain+30, 16);
223 for(uint8_t i=0; i< sizeof(plain); i=i+8 ){
225 memcpy(tmpPlain, plain+i, 8);
226 des_enc( &tmpData, &tmpPlain, &key);
227 memcpy(encData+i, tmpData, 8);
232 iso14a_clear_trace();
234 iso14a_set_tracing(TRUE
);
236 // power up the field
237 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN
);
240 isOK
= iso14443a_select_card(resp
, card
, NULL
);
242 if (MF_DBGLEVEL
>= 1) {
243 Dbprintf("CAN'T SELECT CARD, SOMETHING WENT WRONG BEFORE AUTH");
253 // 3 olika sätt att authenticera. AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32)
254 // 4 olika crypto algo DES, 3DES, 3K3DES, AES
255 // 3 olika kommunikations sätt, PLAIN,MAC,CRYPTO
260 // if ( SendDesfireCommand(AUTHENTICATE, &keyno, resp) > 0 ){
261 // // fick nonce från kortet
265 //SendDesfireCommand(AUTHENTICATE_ISO, &keyno, resp);
269 if ( AesCtxIni(&ctx
, IV
, key
, KEY128
, CBC
) < 0 ){
270 if (MF_DBGLEVEL
>= 1) {
271 Dbprintf("AES context failed to init");
279 real_cmd
[2] = AUTHENTICATE_AES
;
282 AppendCrc14443a(real_cmd
, 2);
283 ReaderTransmit(real_cmd
, sizeof(real_cmd
), NULL
);
285 int len
= ReaderReceive(resp
);
291 print_result("RX:", resp
, len
);
293 enum DESFIRE_STATUS status
= resp
[1];
294 if ( status
!= ADDITIONAL_FRAME
) {
306 memset(nonce
, 0, 16);
307 memcpy( encRndB
, resp
+2, 16);
309 // dekryptera tagnonce.
310 AesDecrypt(&ctx
, encRndB
, decRndB
, 16);
314 memcpy(both
, nonce
,16);
315 memcpy(both
+16, decRndB
,16 );
317 AesEncrypt(&ctx
, both
, encBoth
, 32 );
319 uint8_t real_cmd_A
[36];
320 real_cmd_A
[0] = 0x03;
321 real_cmd_A
[1] = ADDITIONAL_FRAME
;
323 memcpy(real_cmd_A
+2, encBoth
, sizeof(encBoth
) );
324 AppendCrc14443a(real_cmd_A
, sizeof(real_cmd_A
));
325 ReaderTransmit(real_cmd_A
, sizeof(real_cmd_A
), NULL
);
327 len
= ReaderReceive(resp
);
329 print_result("Auth1a ", resp
, 36);
332 if ( status
!= OPERATION_OK
) {
333 Dbprintf("Cmd Error: %02x Len: %d", status
,len
);
346 // 3 olika ISO sätt att skicka data till DESFIRE (direkt, inkapslat, inkapslat ISO)
347 // cmd = cmd bytes to send
348 // cmd_len = length of cmd
349 // dataout = pointer to response data array
350 int DesfireAPDU(uint8_t *cmd
, size_t cmd_len
, uint8_t *dataout
){
353 size_t wrappedLen
= 0;
354 uint8_t wCmd
[USB_CMD_DATA_SIZE
];
356 wrappedLen
= CreateAPDU( cmd
, cmd_len
, wCmd
);
358 if (MF_DBGLEVEL
>= 4) {
359 print_result("WCMD <--: ", wCmd
, wrappedLen
);
361 ReaderTransmit( wCmd
, wrappedLen
, NULL
);
363 status
= ReaderReceive(dataout
);
366 return FALSE
; //DATA LINK ERROR
368 // if we received an I- or R(ACK)-Block with a block number equal to the
369 // current block number, toggle the current block number
370 else if (status
>= 4 // PCB+CID+CRC = 4 bytes
371 && ((dataout
[0] & 0xC0) == 0 // I-Block
372 || (dataout
[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0
373 && (dataout
[0] & 0x01) == pcb_blocknum
) // equal block numbers
375 pcb_blocknum
^= 1; //toggle next block
381 size_t CreateAPDU( uint8_t *datain
, size_t len
, uint8_t *dataout
){
383 size_t cmdlen
= MIN(len
+4, USB_CMD_DATA_SIZE
-1);
386 memset(cmd
, 0, cmdlen
);
388 cmd
[0] = 0x0A; // 0x0A = skicka cid, 0x02 = ingen cid. Särskilda bitar //
389 cmd
[0] |= pcb_blocknum
; // OR the block number into the PCB
390 cmd
[1] = 0x00; // CID: 0x00 //FIXME: allow multiple selected cards
392 memcpy(cmd
+2, datain
, len
);
393 AppendCrc14443a(cmd
, len
+2);
395 memcpy(dataout
, cmd
, cmdlen
);
400 // crc_update(&desfire_crc32, 0, 1); /* CMD_WRITE */
401 // crc_update(&desfire_crc32, addr, addr_sz);
402 // crc_update(&desfire_crc32, byte, 8);
403 // uint32_t crc = crc_finish(&desfire_crc32);
408 //uint8_t versionCmd1[] = {0x02, 0x60};
409 //uint8_t versionCmd2[] = {0x03, 0xaf};
410 //uint8_t versionCmd3[] = {0x02, 0xaf};
412 // AUTH 1 - CMD: 0x02, 0x0A, 0x00 = Auth
413 // 0x02 = status byte för simpla svar?!?
416 //uint8_t initAuthCmdDES[] = {0x02, 0x0a, 0x00}; // DES
417 //uint8_t initAuthCmd3DES[] = {0x02, 0x1a, 0x00}; // 3DES
418 //uint8_t initAuthCmdAES[] = {0x02, 0xaa, 0x00}; // AES
419 // auth 1 - answer command
420 // 0x03 = status byte för komplexa typer?
421 // 0xaf = additional frame
422 // LEN = 1+1+32+2 = 36
423 //uint8_t answerAuthCmd[34] = {0x03, 0xaf};
426 //AppendCrc14443a(versionCmd1,sizeof(versionCmd1));
430 /*ReaderTransmit(versionCmd1,sizeof(versionCmd1)+2, NULL);
431 len = ReaderReceive(buffer);
432 print_result("Get Version 3", buffer, 9);
435 // for( int i = 0; i < 8; i++){
436 // // Auth 1 - Request authentication
437 // ReaderTransmit(initAuthCmdAES,sizeof(initAuthCmdAES)+2, NULL);
438 // //len = ReaderReceive(buffer);
440 // // 0xAE = authentication error
441 // if (buffer[1] == 0xae) {
442 // Dbprintf("Cmd Error: %02x", buffer[1]);
448 // memcpy(encRndB, buffer+2, 16);
450 // // dekryptera svaret från tag.
451 // AesDecrypt(&ctx, encRndB, decRndB, 16);
454 // memcpy(RndARndB, RndA,16);
455 // memcpy(RndARndB+16, decRndB ,16 );
457 // AesEncrypt(&ctx, RndARndB, encRndARndB, 32 );
459 // memcpy(answerAuthCmd+2, encRndARndB, 32);
460 // AppendCrc14443a(answerAuthCmd,sizeof(answerAuthCmd));
462 // ReaderTransmit(answerAuthCmd,sizeof(answerAuthCmd)+2, NULL);
464 // len = ReaderReceive(buffer);
466 // print_result("Auth1a ", buffer, 8);
467 // Dbprintf("Rx len: %02x", len);
469 // if (buffer[1] == 0xCA) {
470 // Dbprintf("Cmd Error: %02x Len: %d", buffer[1],len);
471 // cmd_send(CMD_ACK,0,0,0,0,0);
473 // AesCtxIni(&ctx, iv, key, KEY128, CBC);
477 //des_dec(decRndB, encRndB, key);
481 DES_ede2_cbc_encrypt(e_RndB,RndB,sizeof(e_RndB),&ks1,&ks2,&iv,0);
482 memcpy(RndARndB,RndA,8);
483 memcpy(RndARndB+8,RndB,8);
484 PrintAndLog(" RA+B:%s",sprint_hex(RndARndB, 16));
485 DES_ede2_cbc_encrypt(RndARndB,RndARndB,sizeof(RndARndB),&ks1,&ks2,&e_RndB,1);
486 PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB, 16));
490 int mifare_des_auth2(uint32_t uid
, uint8_t *key
, uint8_t *blockData
){
492 uint8_t* buffer
= mifare_get_bigbufptr();
496 memcpy(dcmd
+1,key
,16);
497 AppendCrc14443a(dcmd
, 17);
500 ReaderTransmit(dcmd
, sizeof(dcmd
), NULL
);
501 int len
= ReaderReceive(buffer
);
503 if (MF_DBGLEVEL
>= 1) Dbprintf("Authentication failed. Card timeout.");
504 len
= ReaderReceive(buffer
);
508 if (MF_DBGLEVEL
>= 1) {
509 Dbprintf("NAK - Authentication failed.");
510 Dbprintf("Cmd Error: %02x", buffer
[0]);
516 if (MF_DBGLEVEL
>= 1) {
517 Dbprintf("Auth2 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
518 buffer
[0],buffer
[1],buffer
[2],buffer
[3],buffer
[4],
519 buffer
[5],buffer
[6],buffer
[7],buffer
[8],buffer
[9],
527 void MifareDES_Auth2(uint32_t arg0
, uint8_t *datain
){
530 uint32_t cuid
= arg0
;
534 byte_t dataoutbuf
[16];
537 memcpy(key
, datain
, 16);
543 if(mifare_des_auth2(cuid
, key
, dataoutbuf
)){
544 if (MF_DBGLEVEL
>= 1) Dbprintf("Authentication part2: Fail...");
547 if (MF_DBGLEVEL
>= 2) DbpString("AUTH 2 FINISHED");
550 cmd_send(CMD_ACK
,isOK
,0,0,dataoutbuf
,11);
554 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
559 // transmit a DESELECT COMMAND for Desfire.
560 ReaderTransmit(deselect_cmd
, 3 , NULL
);
561 // reset the pcb_blocknum,
563 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
568 cmd_send(CMD_ACK
,0,0,0,0,0);
569 ReaderTransmit(deselect_cmd
, 3 , NULL
);
570 // reset the pcb_blocknum,
572 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);