1 #include "mifaredesfire.h"
4 #define MAX_APPLICATION_COUNT 28
5 #define MAX_FILE_COUNT 16
6 #define MAX_DESFIRE_FRAME_SIZE 60
7 #define NOT_YET_AUTHENTICATED 255
8 #define FRAME_PAYLOAD_SIZE (MAX_DESFIRE_FRAME_SIZE - 5)
9 #define RECEIVE_SIZE 64
11 // the block number for the ISO14443-4 PCB
12 uint8_t pcb_blocknum
= 0;
13 // Deselect card by sending a s-block. the crc is precalced for speed
14 static uint8_t deselect_cmd
[] = {0xc2,0xe0,0xb4};
16 //static uint8_t __msg[MAX_FRAME_SIZE] = { 0x0A, 0x00, 0x00, /* ..., */ 0x00 };
17 /* PCB CID CMD PAYLOAD */
18 //static uint8_t __res[MAX_FRAME_SIZE];
20 bool InitDesfireCard(){
22 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN
);
25 byte_t cardbuf
[USB_CMD_DATA_SIZE
] = {0x00};
26 iso14a_card_select_t
*card
= (iso14a_card_select_t
*)cardbuf
;
28 int len
= iso14443a_select_card(NULL
,card
,NULL
);
31 if (MF_DBGLEVEL
>= MF_DBG_ERROR
)
32 Dbprintf("Can't select card");
48 void MifareSendCommand(uint8_t arg0
, uint8_t arg1
, uint8_t *datain
){
50 /* ARG0 contains flags.
56 size_t datalen
= arg1
;
57 uint8_t resp
[RECEIVE_SIZE
];
58 memset(resp
,0,sizeof(resp
));
60 if (MF_DBGLEVEL
>= 4) {
61 Dbprintf(" flags : %02X", flags
);
62 Dbprintf(" len : %02X", datalen
);
63 print_result(" RX : ", datain
, datalen
);
66 if ( flags
& CLEARTRACE
){
71 if ( !InitDesfireCard() )
75 int len
= DesfireAPDU(datain
, datalen
, resp
);
76 if (MF_DBGLEVEL
>= 4) {
77 print_result("ERR <--: ", resp
, len
);
85 // reset the pcb_blocknum,
88 if ( flags
& DISCONNECT
){
92 cmd_send(CMD_ACK
,1,len
,0,resp
,len
);
95 void MifareDesfireGetInformation(){
98 uint8_t resp
[USB_CMD_DATA_SIZE
] = {0x00};
99 uint8_t dataout
[USB_CMD_DATA_SIZE
] = {0x00};
100 byte_t cardbuf
[USB_CMD_DATA_SIZE
] = {0x00};
105 3 = desfire command 3
108 PCB == 0x0A because sending CID byte.
109 CID == 0x00 first card?
113 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN
);
115 // card select - information
116 iso14a_card_select_t
*card
= (iso14a_card_select_t
*)cardbuf
;
117 byte_t isOK
= iso14443a_select_card(NULL
, card
, NULL
);
119 if (MF_DBGLEVEL
>= MF_DBG_ERROR
) {
120 Dbprintf("Can't select card");
126 memcpy(dataout
,card
->uid
,7);
132 uint8_t cmd
[] = {GET_VERSION
};
133 size_t cmd_len
= sizeof(cmd
);
135 len
= DesfireAPDU(cmd
, cmd_len
, resp
);
137 print_result("ERROR <--: ", resp
, len
);
144 memcpy(dataout
+7,resp
+3,7);
147 cmd
[0] = ADDITIONAL_FRAME
;
148 len
= DesfireAPDU(cmd
, cmd_len
, resp
);
150 print_result("ERROR <--: ", resp
, len
);
157 memcpy(dataout
+7+7,resp
+3,7);
160 len
= DesfireAPDU(cmd
, cmd_len
, resp
);
162 print_result("ERROR <--: ", resp
, len
);
167 memcpy(dataout
+7+7+7,resp
+3,14);
169 cmd_send(CMD_ACK
,1,0,0,dataout
,sizeof(dataout
));
171 // reset the pcb_blocknum,
176 void MifareDES_Auth1(uint8_t mode
, uint8_t algo
, uint8_t keyno
, uint8_t *datain
){
179 //uint8_t PICC_MASTER_KEY8[8] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47};
180 uint8_t PICC_MASTER_KEY16
[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f };
181 uint8_t null_key_data8
[8] = {0x00};
182 //uint8_t null_key_data16[16] = {0x00};
183 //uint8_t new_key_data8[8] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
184 //uint8_t new_key_data16[16] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};
186 uint8_t resp
[256] = {0x00};
187 uint8_t IV
[16] = {0x00};
189 size_t datalen
= datain
[0];
191 uint8_t cmd
[40] = {0x00};
192 uint8_t encRndB
[16] = {0x00};
193 uint8_t decRndB
[16] = {0x00};
194 uint8_t nonce
[16] = {0x00};
195 uint8_t both
[32] = {0x00};
196 uint8_t encBoth
[32] = {0x00};
204 // 3 olika sätt att authenticera. AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32)
205 // 4 olika crypto algo DES, 3DES, 3K3DES, AES
206 // 3 olika kommunikations sätt, PLAIN,MAC,CRYPTO
211 uint8_t keybytes
[16];
212 uint8_t RndA
[8] = {0x00};
213 uint8_t RndB
[8] = {0x00};
216 if (datain
[1] == 0xff){
217 memcpy(keybytes
,PICC_MASTER_KEY16
,16);
219 memcpy(keybytes
, datain
+1, datalen
);
223 if (datain
[1] == 0xff){
224 memcpy(keybytes
,null_key_data8
,8);
226 memcpy(keybytes
, datain
+1, datalen
);
231 struct desfire_key defaultkey
= {0};
232 desfirekey_t key
= &defaultkey
;
235 Desfire_3des_key_new_with_version(keybytes
, key
);
237 Desfire_des_key_new(keybytes
, key
);
239 cmd
[0] = AUTHENTICATE
;
240 cmd
[1] = keyno
; //keynumber
241 len
= DesfireAPDU(cmd
, 2, resp
);
243 if (MF_DBGLEVEL
>= MF_DBG_ERROR
) {
244 DbpString("Authentication failed. Card timeout.");
250 if ( resp
[2] == 0xaf ){
252 DbpString("Authetication failed. Invalid key number.");
257 memcpy( encRndB
, resp
+3, 8);
259 tdes_dec(&decRndB
, &encRndB
, key
->data
);
261 des_dec(&decRndB
, &encRndB
, key
->data
);
263 memcpy(RndB
, decRndB
, 8);
266 // This should be random
267 uint8_t decRndA
[8] = {0x00};
268 memcpy(RndA
, decRndA
, 8);
269 uint8_t encRndA
[8] = {0x00};
272 tdes_dec(&encRndA
, &decRndA
, key
->data
);
274 des_dec(&encRndA
, &decRndA
, key
->data
);
276 memcpy(both
, encRndA
, 8);
278 for (int x
= 0; x
< 8; x
++) {
279 decRndB
[x
] = decRndB
[x
] ^ encRndA
[x
];
284 tdes_dec(&encRndB
, &decRndB
, key
->data
);
286 des_dec(&encRndB
, &decRndB
, key
->data
);
288 memcpy(both
+ 8, encRndB
, 8);
290 cmd
[0] = ADDITIONAL_FRAME
;
291 memcpy(cmd
+1, both
, 16 );
293 len
= DesfireAPDU(cmd
, 17, resp
);
295 if (MF_DBGLEVEL
>= MF_DBG_ERROR
) {
296 DbpString("Authentication failed. Card timeout.");
302 if ( resp
[2] == 0x00 ){
304 struct desfire_key sessionKey
= {0};
305 desfirekey_t skey
= &sessionKey
;
306 Desfire_session_key_new( RndA
, RndB
, key
, skey
);
307 //print_result("SESSION : ", skey->data, 8);
309 memcpy(encRndA
, resp
+3, 8);
312 tdes_dec(&encRndA
, &encRndA
, key
->data
);
314 des_dec(&encRndA
, &encRndA
, key
->data
);
317 for (int x
= 0; x
< 8; x
++) {
318 if (decRndA
[x
] != encRndA
[x
]) {
319 DbpString("Authetication failed. Cannot varify PICC.");
325 //Change the selected key to a new value.
328 // Current key is a 3DES key, change it to a DES key
333 uint8_t newKey[16] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
335 uint8_t first, second;
336 uint8_t buff1[8] = {0x00};
337 uint8_t buff2[8] = {0x00};
338 uint8_t buff3[8] = {0x00};
340 memcpy(buff1,newKey, 8);
341 memcpy(buff2,newKey + 8, 8);
343 ComputeCrc14443(CRC_14443_A, newKey, 16, &first, &second);
344 memcpy(buff3, &first, 1);
345 memcpy(buff3 + 1, &second, 1);
347 tdes_dec(&buff1, &buff1, skey->data);
348 memcpy(cmd+2,buff1,8);
350 for (int x = 0; x < 8; x++) {
351 buff2[x] = buff2[x] ^ buff1[x];
353 tdes_dec(&buff2, &buff2, skey->data);
354 memcpy(cmd+10,buff2,8);
356 for (int x = 0; x < 8; x++) {
357 buff3[x] = buff3[x] ^ buff2[x];
359 tdes_dec(&buff3, &buff3, skey->data);
360 memcpy(cmd+18,buff3,8);
362 // The command always times out on the first attempt, this will retry until a response
366 len = DesfireAPDU(cmd,26,resp);
370 // Current key is a DES key, change it to a 3DES key
375 uint8_t newKey[16] = {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f};
377 uint8_t first, second;
378 uint8_t buff1[8] = {0x00};
379 uint8_t buff2[8] = {0x00};
380 uint8_t buff3[8] = {0x00};
382 memcpy(buff1,newKey, 8);
383 memcpy(buff2,newKey + 8, 8);
385 ComputeCrc14443(CRC_14443_A, newKey, 16, &first, &second);
386 memcpy(buff3, &first, 1);
387 memcpy(buff3 + 1, &second, 1);
389 des_dec(&buff1, &buff1, skey->data);
390 memcpy(cmd+2,buff1,8);
392 for (int x = 0; x < 8; x++) {
393 buff2[x] = buff2[x] ^ buff1[x];
395 des_dec(&buff2, &buff2, skey->data);
396 memcpy(cmd+10,buff2,8);
398 for (int x = 0; x < 8; x++) {
399 buff3[x] = buff3[x] ^ buff2[x];
401 des_dec(&buff3, &buff3, skey->data);
402 memcpy(cmd+18,buff3,8);
404 // The command always times out on the first attempt, this will retry until a response
408 len = DesfireAPDU(cmd,26,resp);
416 cmd_send(CMD_ACK
,1,0,0,skey
->data
,16);
418 cmd_send(CMD_ACK
,1,0,0,skey
->data
,8);
420 DbpString("Authetication failed.");
427 //SendDesfireCommand(AUTHENTICATE_ISO, &keyno, resp);
432 uint8_t keybytes
[16] = {0x00};
433 if (datain
[1] == 0xff){
434 memcpy(keybytes
,PICC_MASTER_KEY16
,16);
436 memcpy(keybytes
, datain
+1, datalen
);
439 struct desfire_key defaultkey
= {0x00};
440 desfirekey_t key
= &defaultkey
;
441 Desfire_aes_key_new( keybytes
, key
);
444 if ( AesCtxIni(&ctx
, IV
, key
->data
, KEY128
, CBC
) < 0 ){
445 if( MF_DBGLEVEL
>= 4) {
446 Dbprintf("AES context failed to init");
452 cmd
[0] = AUTHENTICATE_AES
;
453 cmd
[1] = 0x00; //keynumber
454 len
= DesfireAPDU(cmd
, 2, resp
);
456 if (MF_DBGLEVEL
>= MF_DBG_ERROR
) {
457 DbpString("Authentication failed. Card timeout.");
463 memcpy( encRndB
, resp
+3, 16);
465 // dekryptera tagnonce.
466 AesDecrypt(&ctx
, encRndB
, decRndB
, 16);
468 memcpy(both
, nonce
,16);
469 memcpy(both
+16, decRndB
,16 );
470 AesEncrypt(&ctx
, both
, encBoth
, 32 );
472 cmd
[0] = ADDITIONAL_FRAME
;
473 memcpy(cmd
+1, encBoth
, 32 );
475 len
= DesfireAPDU(cmd
, 33, resp
); // 1 + 32 == 33
477 if (MF_DBGLEVEL
>= MF_DBG_ERROR
) {
478 DbpString("Authentication failed. Card timeout.");
484 if ( resp
[2] == 0x00 ){
485 // Create AES Session key
486 struct desfire_key sessionKey
= {0};
487 desfirekey_t skey
= &sessionKey
;
488 Desfire_session_key_new( nonce
, decRndB
, key
, skey
);
489 print_result("SESSION : ", skey
->data
, 16);
491 DbpString("Authetication failed.");
501 cmd_send(CMD_ACK
,1,len
,0,resp
,len
);
504 // 3 olika ISO sätt att skicka data till DESFIRE (direkt, inkapslat, inkapslat ISO)
505 // cmd = cmd bytes to send
506 // cmd_len = length of cmd
507 // dataout = pointer to response data array
508 int DesfireAPDU(uint8_t *cmd
, size_t cmd_len
, uint8_t *dataout
){
511 size_t wrappedLen
= 0;
512 uint8_t wCmd
[USB_CMD_DATA_SIZE
] = {0x00};
514 uint8_t resp
[MAX_FRAME_SIZE
];
515 uint8_t par
[MAX_PARITY_SIZE
];
517 wrappedLen
= CreateAPDU( cmd
, cmd_len
, wCmd
);
519 if (MF_DBGLEVEL
>= 4) {
520 print_result("WCMD <--: ", wCmd
, wrappedLen
);
522 ReaderTransmit( wCmd
, wrappedLen
, NULL
);
524 len
= ReaderReceive(resp
, par
);
527 if (MF_DBGLEVEL
>= 4) Dbprintf("fukked");
528 return FALSE
; //DATA LINK ERROR
530 // if we received an I- or R(ACK)-Block with a block number equal to the
531 // current block number, toggle the current block number
532 else if (len
>= 4 // PCB+CID+CRC = 4 bytes
533 && ((resp
[0] & 0xC0) == 0 // I-Block
534 || (resp
[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0
535 && (resp
[0] & 0x01) == pcb_blocknum
) // equal block numbers
537 pcb_blocknum
^= 1; //toggle next block
540 memcpy(dataout
, resp
, len
);
545 size_t CreateAPDU( uint8_t *datain
, size_t len
, uint8_t *dataout
){
547 size_t cmdlen
= MIN(len
+4, USB_CMD_DATA_SIZE
-1);
550 memset(cmd
, 0, cmdlen
);
552 cmd
[0] = 0x0A; // 0x0A = skicka cid, 0x02 = ingen cid. Särskilda bitar //
553 cmd
[0] |= pcb_blocknum
; // OR the block number into the PCB
554 cmd
[1] = 0x00; // CID: 0x00 //TODO: allow multiple selected cards
556 memcpy(cmd
+2, datain
, len
);
557 AppendCrc14443a(cmd
, len
+2);
559 memcpy(dataout
, cmd
, cmdlen
);
564 // crc_update(&desfire_crc32, 0, 1); /* CMD_WRITE */
565 // crc_update(&desfire_crc32, addr, addr_sz);
566 // crc_update(&desfire_crc32, byte, 8);
567 // uint32_t crc = crc_finish(&desfire_crc32);
571 ReaderTransmit(deselect_cmd
, 3 , NULL
);
572 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
577 void OnError(uint8_t reason
){
578 cmd_send(CMD_ACK
,0,reason
,0,0,0);