1 #include "mifaredesfire.h" 
   5 #define MAX_APPLICATION_COUNT 28 
   6 #define MAX_FILE_COUNT 16 
   7 #define MAX_DESFIRE_FRAME_SIZE 60 
   8 #define NOT_YET_AUTHENTICATED 255 
   9 #define FRAME_PAYLOAD_SIZE (MAX_DESFIRE_FRAME_SIZE - 5) 
  10 #define RECEIVE_SIZE 64 
  12 // the block number for the ISO14443-4 PCB 
  13 uint8_t pcb_blocknum 
= 0; 
  14 // Deselect card by sending a s-block. the crc is precalced for speed 
  15 static  uint8_t deselect_cmd
[] = {0xc2,0xe0,0xb4}; 
  17 //static uint8_t __msg[MAX_FRAME_SIZE] = { 0x0A, 0x00, 0x00, /* ..., */ 0x00 }; 
  18 /*                                       PCB   CID   CMD    PAYLOAD    */ 
  19 //static uint8_t __res[MAX_FRAME_SIZE]; 
  21 bool InitDesfireCard(){ 
  23         iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN
); 
  26         byte_t cardbuf
[USB_CMD_DATA_SIZE
] = {0x00}; 
  27         iso14a_card_select_t 
*card 
= (iso14a_card_select_t
*)cardbuf
; 
  29         int len 
= iso14443a_select_card(NULL
,card
,NULL
); 
  32                 if (MF_DBGLEVEL 
>= MF_DBG_ERROR
) 
  33                         Dbprintf("Can't select card"); 
  49 void MifareSendCommand(uint8_t arg0
, uint8_t arg1
, uint8_t *datain
){ 
  51         /* ARG0 contains flags. 
  57         size_t datalen 
= arg1
; 
  58         uint8_t resp
[RECEIVE_SIZE
]; 
  59         memset(resp
,0,sizeof(resp
)); 
  61         if (MF_DBGLEVEL 
>= 4) { 
  62                 Dbprintf(" flags : %02X", flags
); 
  63                 Dbprintf(" len   : %02X", datalen
); 
  64                 print_result(" RX    : ", datain
, datalen
); 
  67         if ( flags 
& CLEARTRACE 
){ 
  72                 if ( !InitDesfireCard() ) 
  76         int len 
= DesfireAPDU(datain
, datalen
, resp
); 
  77         if (MF_DBGLEVEL 
>= 4) { 
  78                 print_result("ERR <--: ", resp
, len
); 
  86         // reset the pcb_blocknum, 
  89         if ( flags 
& DISCONNECT 
){ 
  93         cmd_send(CMD_ACK
,1,len
,0,resp
,len
); 
  96 void MifareDesfireGetInformation(){ 
  99         uint8_t resp
[USB_CMD_DATA_SIZE
] = {0x00}; 
 100         uint8_t dataout
[USB_CMD_DATA_SIZE
] = {0x00}; 
 101         byte_t cardbuf
[USB_CMD_DATA_SIZE
] = {0x00}; 
 106                 3 = desfire command             3  
 109                 PCB == 0x0A because sending CID byte. 
 110                 CID == 0x00 first card?          
 114         iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN
); 
 116         // card select - information 
 117         iso14a_card_select_t 
*card 
= (iso14a_card_select_t
*)cardbuf
; 
 118         byte_t isOK 
= iso14443a_select_card(NULL
, card
, NULL
); 
 120                 if (MF_DBGLEVEL 
>= MF_DBG_ERROR
) { 
 121                         Dbprintf("Can't select card"); 
 127         memcpy(dataout
,card
->uid
,7); 
 133         uint8_t cmd
[] = {GET_VERSION
};   
 134         size_t cmd_len 
= sizeof(cmd
); 
 136         len 
=  DesfireAPDU(cmd
, cmd_len
, resp
); 
 138                 print_result("ERROR <--: ", resp
, len
);  
 145         memcpy(dataout
+7,resp
+3,7); 
 148         cmd
[0] = ADDITIONAL_FRAME
; 
 149         len 
=  DesfireAPDU(cmd
, cmd_len
, resp
); 
 151                 print_result("ERROR <--: ", resp
, len
);  
 158         memcpy(dataout
+7+7,resp
+3,7); 
 161         len 
=  DesfireAPDU(cmd
, cmd_len
, resp
); 
 163                 print_result("ERROR <--: ", resp
, len
);  
 168         memcpy(dataout
+7+7+7,resp
+3,14); 
 170         cmd_send(CMD_ACK
,1,0,0,dataout
,sizeof(dataout
)); 
 172         // reset the pcb_blocknum, 
 177 void MifareDES_Auth1(uint8_t mode
, uint8_t algo
, uint8_t keyno
,  uint8_t *datain
){ 
 180         //uint8_t PICC_MASTER_KEY8[8] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47}; 
 181         uint8_t PICC_MASTER_KEY16
[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f }; 
 182         uint8_t null_key_data8
[8] = {0x00}; 
 183         //uint8_t null_key_data16[16] = {0x00};  
 184         //uint8_t new_key_data8[8]  = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77}; 
 185         //uint8_t new_key_data16[16]  = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}; 
 187         uint8_t resp
[256] = {0x00}; 
 188         uint8_t IV
[16] = {0x00}; 
 190         size_t datalen 
= datain
[0]; 
 192         uint8_t cmd
[40] = {0x00}; 
 193         uint8_t encRndB
[16] = {0x00}; 
 194         uint8_t decRndB
[16] = {0x00}; 
 195         uint8_t nonce
[16] = {0x00}; 
 196         uint8_t both
[32] = {0x00}; 
 197         uint8_t encBoth
[32] = {0x00}; 
 201         // 3 olika sätt att authenticera.   AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32) 
 202         // 4 olika crypto algo   DES, 3DES, 3K3DES, AES 
 203         // 3 olika kommunikations sätt,   PLAIN,MAC,CRYPTO 
 210             uint8_t keybytes
[8] = {0x00}; 
 211             uint8_t RndA
[8] = {0x00}; 
 212             uint8_t RndB
[8] = {0x00}; 
 214             if (datain
[1] == 0xff){ 
 215                 memcpy(keybytes
,null_key_data8
,8); 
 217                 memcpy(keybytes
, datain
+1, datalen
); 
 220             struct desfire_key defaultkey 
= {0}; 
 221             desfirekey_t key 
= &defaultkey
; 
 222             Desfire_des_key_new(keybytes
, key
); 
 224             cmd
[0] = AUTHENTICATE
; 
 225             cmd
[1] = keyno
;  //keynumber 
 226             len 
= DesfireAPDU(cmd
, 2, resp
); 
 228                 if (MF_DBGLEVEL 
>= MF_DBG_ERROR
) { 
 229                     DbpString("Authentication failed. Card timeout."); 
 235             if ( resp
[2] == 0xaf ){ 
 237                 DbpString("Authetication failed. Invalid key number."); 
 242             memcpy( encRndB
, resp
+3, 8); 
 244             des_dec(&decRndB
, &encRndB
, key
->data
); 
 245             memcpy(RndB
, decRndB
, 8); 
 248             // This should be random 
 249             uint8_t decRndA
[8] = {0x00}; 
 250             memcpy(RndA
, decRndA
, 8); 
 251             uint8_t encRndA
[8] = {0x00}; 
 253             des_dec(&encRndA
, &decRndA
, key
->data
); 
 255             memcpy(both
, encRndA
, 8); 
 257             for (int x 
= 0; x 
< 8; x
++) { 
 258                 decRndB
[x
] = decRndB
[x
] ^ encRndA
[x
]; 
 261             des_dec(&encRndB
, &decRndB
, key
->data
); 
 263             memcpy(both 
+ 8, encRndB
, 8); 
 265             cmd
[0] = ADDITIONAL_FRAME
; 
 266             memcpy(cmd
+1, both
, 16 ); 
 268             len 
= DesfireAPDU(cmd
, 17, resp
); 
 270                 if (MF_DBGLEVEL 
>= MF_DBG_ERROR
) { 
 271                     DbpString("Authentication failed. Card timeout."); 
 277             if ( resp
[2] == 0x00 ){ 
 279                 struct desfire_key sessionKey 
= {0}; 
 280                 desfirekey_t skey 
= &sessionKey
; 
 281                 Desfire_session_key_new( RndA
, RndB 
, key
, skey 
); 
 282                 //print_result("SESSION : ", skey->data, 8); 
 284                 memcpy(encRndA
, resp
+3, 8); 
 285                 des_dec(&encRndA
, &encRndA
, key
->data
); 
 287                 for (int x 
= 0; x 
< 8; x
++) { 
 288                     if (decRndA
[x
] != encRndA
[x
]) { 
 289                         DbpString("Authetication failed. Cannot varify PICC."); 
 295                 //Change the selected key to a new value. 
 301                 uint8_t newKey[16] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77}; 
 303                 uint8_t first, second; 
 304                 uint8_t buff1[8] = {0x00}; 
 305                 uint8_t buff2[8] = {0x00}; 
 306                 uint8_t buff3[8] = {0x00}; 
 308                 memcpy(buff1,newKey, 8); 
 309                 memcpy(buff2,newKey + 8, 8); 
 311                 ComputeCrc14443(CRC_14443_A, newKey, 16, &first, &second); 
 312                 memcpy(buff3, &first, 1); 
 313                 memcpy(buff3 + 1, &second, 1); 
 315                 des_dec(&buff1, &buff1, skey->data); 
 316                 memcpy(cmd+2,buff1,8); 
 318                 for (int x = 0; x < 8; x++) { 
 319                     buff2[x] = buff2[x] ^ buff1[x]; 
 321                 des_dec(&buff2, &buff2, skey->data); 
 322                 memcpy(cmd+10,buff2,8); 
 324                 for (int x = 0; x < 8; x++) { 
 325                     buff3[x] = buff3[x] ^ buff2[x]; 
 327                 des_dec(&buff3, &buff3, skey->data); 
 328                 memcpy(cmd+18,buff3,8); 
 330                 // The command always times out on the first attempt, this will retry until a response 
 334                     len = DesfireAPDU(cmd,26,resp); 
 339                 cmd_send(CMD_ACK
,1,0,0,skey
->data
,8); 
 342                 DbpString("Authetication failed."); 
 351                         //SendDesfireCommand(AUTHENTICATE_ISO, &keyno, resp); 
 356                         uint8_t keybytes
[16] = {0x00}; 
 357                         if (datain
[1] == 0xff){ 
 358                                 memcpy(keybytes
,PICC_MASTER_KEY16
,16);  
 360                                 memcpy(keybytes
, datain
+1, datalen
); 
 363                         struct desfire_key defaultkey 
= {0x00}; 
 364                         desfirekey_t key 
= &defaultkey
; 
 365                         Desfire_aes_key_new( keybytes
, key
); 
 368                         if ( AesCtxIni(&ctx
, IV
, key
->data
, KEY128
, CBC
) < 0 ){ 
 369                                 if( MF_DBGLEVEL 
>= 4) { 
 370                                         Dbprintf("AES context failed to init"); 
 376                         cmd
[0] = AUTHENTICATE_AES
; 
 377                         cmd
[1] = 0x00;  //keynumber 
 378                         len 
= DesfireAPDU(cmd
, 2, resp
); 
 380                                 if (MF_DBGLEVEL 
>= MF_DBG_ERROR
) { 
 381                                         DbpString("Authentication failed. Card timeout."); 
 387                         memcpy( encRndB
, resp
+3, 16); 
 389                         // dekryptera tagnonce. 
 390                         AesDecrypt(&ctx
, encRndB
, decRndB
, 16); 
 392                         memcpy(both
, nonce
,16); 
 393                         memcpy(both
+16, decRndB 
,16 ); 
 394                         AesEncrypt(&ctx
, both
, encBoth
, 32 ); 
 396                         cmd
[0] = ADDITIONAL_FRAME
; 
 397                         memcpy(cmd
+1, encBoth
, 32 ); 
 399                         len 
= DesfireAPDU(cmd
, 33, resp
);  // 1 + 32 == 33 
 401                                 if (MF_DBGLEVEL 
>= MF_DBG_ERROR
) { 
 402                                         DbpString("Authentication failed. Card timeout."); 
 408                         if ( resp
[2] == 0x00 ){ 
 409                                 // Create AES Session key                
 410                                 struct desfire_key sessionKey 
= {0}; 
 411                                 desfirekey_t skey 
= &sessionKey
; 
 412                                 Desfire_session_key_new( nonce
, decRndB 
, key
, skey 
); 
 413                                 print_result("SESSION : ", skey
->data
, 16); 
 415                                 DbpString("Authetication failed."); 
 424         cmd_send(CMD_ACK
,1,len
,0,resp
,len
); 
 427 // 3 olika ISO sätt att skicka data till DESFIRE (direkt, inkapslat, inkapslat ISO) 
 428 // cmd  =  cmd bytes to send 
 429 // cmd_len = length of cmd 
 430 // dataout = pointer to response data array 
 431 int DesfireAPDU(uint8_t *cmd
, size_t cmd_len
, uint8_t *dataout
){ 
 434         size_t wrappedLen 
= 0; 
 435         uint8_t wCmd
[USB_CMD_DATA_SIZE
] = {0x00}; 
 437         uint8_t resp
[MAX_FRAME_SIZE
]; 
 438     uint8_t par
[MAX_PARITY_SIZE
]; 
 440         wrappedLen 
= CreateAPDU( cmd
, cmd_len
, wCmd
); 
 442         if (MF_DBGLEVEL 
>= 4) { 
 443                 print_result("WCMD <--: ", wCmd
, wrappedLen
);    
 445         ReaderTransmit( wCmd
, wrappedLen
, NULL
); 
 447         len 
= ReaderReceive(resp
, par
); 
 450                 if (MF_DBGLEVEL 
>= 4) Dbprintf("fukked"); 
 451                 return FALSE
; //DATA LINK ERROR 
 453         // if we received an I- or R(ACK)-Block with a block number equal to the 
 454         // current block number, toggle the current block number 
 455         else if (len 
>= 4 // PCB+CID+CRC = 4 bytes 
 456                  && ((resp
[0] & 0xC0) == 0 // I-Block 
 457                      || (resp
[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0 
 458                  && (resp
[0] & 0x01) == pcb_blocknum
) // equal block numbers 
 460                 pcb_blocknum 
^= 1;  //toggle next block  
 463         memcpy(dataout
, resp
, len
); 
 468 size_t CreateAPDU( uint8_t *datain
, size_t len
, uint8_t *dataout
){ 
 470         size_t cmdlen 
= MIN(len
+4, USB_CMD_DATA_SIZE
-1); 
 473         memset(cmd
, 0, cmdlen
); 
 475         cmd
[0] = 0x0A;  //  0x0A = skicka cid,  0x02 = ingen cid. Särskilda bitar // 
 476         cmd
[0] |= pcb_blocknum
; // OR the block number into the PCB      
 477         cmd
[1] = 0x00;  //  CID: 0x00 //TODO: allow multiple selected cards 
 479         memcpy(cmd
+2, datain
, len
); 
 480         AppendCrc14443a(cmd
, len
+2); 
 482         memcpy(dataout
, cmd
, cmdlen
); 
 487         // crc_update(&desfire_crc32, 0, 1); /* CMD_WRITE */ 
 488         // crc_update(&desfire_crc32, addr, addr_sz); 
 489         // crc_update(&desfire_crc32, byte, 8); 
 490         // uint32_t crc = crc_finish(&desfire_crc32); 
 494         ReaderTransmit(deselect_cmd
, 3 , NULL
); 
 495         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
); 
 500 void OnError(uint8_t reason
){ 
 502         ReaderTransmit(deselect_cmd
, 3 , NULL
); 
 504         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
); 
 505         cmd_send(CMD_ACK
,0,reason
,0,0,0);