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
,true,0); 
  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 
) 
  70                 if ( !InitDesfireCard() ) 
  74         int len 
= DesfireAPDU(datain
, datalen
, resp
); 
  76                 print_result("ERR <--: ", resp
, len
); 
  83         // reset the pcb_blocknum, 
  86         if ( flags 
& DISCONNECT 
) 
  89         cmd_send(CMD_ACK
,1,len
,0,resp
,len
); 
  92 void MifareDesfireGetInformation(){ 
  95         uint8_t resp
[USB_CMD_DATA_SIZE
] = {0x00}; 
  96         uint8_t dataout
[USB_CMD_DATA_SIZE
] = {0x00}; 
  97         byte_t cardbuf
[USB_CMD_DATA_SIZE
] = {0x00}; 
 102                 3 = desfire command             3  
 105                 PCB == 0x0A because sending CID byte. 
 106                 CID == 0x00 first card?          
 110         iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN
); 
 112         // card select - information 
 113         iso14a_card_select_t 
*card 
= (iso14a_card_select_t
*)cardbuf
; 
 114         byte_t isOK 
= iso14443a_select_card(NULL
, card
, NULL
, true, 0); 
 116                 if (MF_DBGLEVEL 
>= MF_DBG_ERROR
) { 
 117                         Dbprintf("Can't select card"); 
 123         memcpy(dataout
,card
->uid
,7); 
 129         uint8_t cmd
[] = {GET_VERSION
};   
 130         size_t cmd_len 
= sizeof(cmd
); 
 132         len 
=  DesfireAPDU(cmd
, cmd_len
, resp
); 
 134                 print_result("ERROR <--: ", resp
, len
);  
 141         memcpy(dataout
+7,resp
+3,7); 
 144         cmd
[0] = ADDITIONAL_FRAME
; 
 145         len 
=  DesfireAPDU(cmd
, cmd_len
, resp
); 
 147                 print_result("ERROR <--: ", resp
, len
);  
 154         memcpy(dataout
+7+7,resp
+3,7); 
 157         len 
=  DesfireAPDU(cmd
, cmd_len
, resp
); 
 159                 print_result("ERROR <--: ", resp
, len
);  
 164         memcpy(dataout
+7+7+7,resp
+3,14); 
 166         cmd_send(CMD_ACK
,1,0,0,dataout
,sizeof(dataout
)); 
 168         // reset the pcb_blocknum, 
 173 void MifareDES_Auth1(uint8_t mode
, uint8_t algo
, uint8_t keyno
,  uint8_t *datain
){ 
 176         //uint8_t PICC_MASTER_KEY8[8] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47}; 
 177         uint8_t PICC_MASTER_KEY16
[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f }; 
 178         uint8_t null_key_data8
[8] = {0x00}; 
 179         //uint8_t null_key_data16[16] = {0x00};  
 180         //uint8_t new_key_data8[8]  = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77}; 
 181         //uint8_t new_key_data16[16]  = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}; 
 183         uint8_t resp
[256] = {0x00}; 
 184         uint8_t IV
[16] = {0x00}; 
 186         size_t datalen 
= datain
[0]; 
 188         uint8_t cmd
[40] = {0x00}; 
 189         uint8_t encRndB
[16] = {0x00}; 
 190         uint8_t decRndB
[16] = {0x00}; 
 191         uint8_t nonce
[16] = {0x00}; 
 192         uint8_t both
[32] = {0x00}; 
 193         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 
 208             uint8_t keybytes
[16]; 
 209             uint8_t RndA
[8] = {0x00}; 
 210             uint8_t RndB
[8] = {0x00}; 
 213             if (datain
[1] == 0xff){ 
 214                     memcpy(keybytes
,PICC_MASTER_KEY16
,16); 
 216                     memcpy(keybytes
, datain
+1, datalen
); 
 220                     if (datain
[1] == 0xff){ 
 221                 memcpy(keybytes
,null_key_data8
,8); 
 223                 memcpy(keybytes
, datain
+1, datalen
); 
 228             struct desfire_key defaultkey 
= {0}; 
 229             desfirekey_t key 
= &defaultkey
; 
 232                 Desfire_3des_key_new_with_version(keybytes
, key
); 
 234             Desfire_des_key_new(keybytes
, key
); 
 236             cmd
[0] = AUTHENTICATE
; 
 237             cmd
[1] = keyno
;  //keynumber 
 238             len 
= DesfireAPDU(cmd
, 2, resp
); 
 240                 if (MF_DBGLEVEL 
>= MF_DBG_ERROR
) { 
 241                     DbpString("Authentication failed. Card timeout."); 
 247             if ( resp
[2] == 0xaf ){ 
 249                 DbpString("Authetication failed. Invalid key number."); 
 254             memcpy( encRndB
, resp
+3, 8); 
 256                 tdes_dec(&decRndB
, &encRndB
, key
->data
); 
 258             des_dec(&decRndB
, &encRndB
, key
->data
); 
 260             memcpy(RndB
, decRndB
, 8); 
 263             // This should be random 
 264             uint8_t decRndA
[8] = {0x00}; 
 265             memcpy(RndA
, decRndA
, 8); 
 266             uint8_t encRndA
[8] = {0x00}; 
 269                 tdes_dec(&encRndA
, &decRndA
, key
->data
); 
 271             des_dec(&encRndA
, &decRndA
, key
->data
); 
 273             memcpy(both
, encRndA
, 8); 
 275             for (int x 
= 0; x 
< 8; x
++) { 
 276                 decRndB
[x
] = decRndB
[x
] ^ encRndA
[x
]; 
 281                 tdes_dec(&encRndB
, &decRndB
, key
->data
); 
 283             des_dec(&encRndB
, &decRndB
, key
->data
); 
 285             memcpy(both 
+ 8, encRndB
, 8); 
 287             cmd
[0] = ADDITIONAL_FRAME
; 
 288             memcpy(cmd
+1, both
, 16 ); 
 290             len 
= DesfireAPDU(cmd
, 17, resp
); 
 292                 if (MF_DBGLEVEL 
>= MF_DBG_ERROR
) { 
 293                     DbpString("Authentication failed. Card timeout."); 
 299             if ( resp
[2] == 0x00 ){ 
 301                 struct desfire_key sessionKey 
= {0}; 
 302                 desfirekey_t skey 
= &sessionKey
; 
 303                 Desfire_session_key_new( RndA
, RndB 
, key
, skey 
); 
 304                 //print_result("SESSION : ", skey->data, 8); 
 306                 memcpy(encRndA
, resp
+3, 8); 
 309                     tdes_dec(&encRndA
, &encRndA
, key
->data
); 
 311                 des_dec(&encRndA
, &encRndA
, key
->data
); 
 314                 for (int x 
= 0; x 
< 8; x
++) { 
 315                     if (decRndA
[x
] != encRndA
[x
]) { 
 316                         DbpString("Authetication failed. Cannot varify PICC."); 
 322                 //Change the selected key to a new value. 
 325                  // Current key is a 3DES key, change it to a DES key 
 330                 uint8_t newKey[16] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77}; 
 332                 uint8_t first, second; 
 333                 uint8_t buff1[8] = {0x00}; 
 334                 uint8_t buff2[8] = {0x00}; 
 335                 uint8_t buff3[8] = {0x00}; 
 337                 memcpy(buff1,newKey, 8); 
 338                 memcpy(buff2,newKey + 8, 8); 
 340                 ComputeCrc14443(CRC_14443_A, newKey, 16, &first, &second); 
 341                 memcpy(buff3, &first, 1); 
 342                 memcpy(buff3 + 1, &second, 1); 
 344                  tdes_dec(&buff1, &buff1, skey->data); 
 345                  memcpy(cmd+2,buff1,8); 
 347                  for (int x = 0; x < 8; x++) { 
 348                  buff2[x] = buff2[x] ^ buff1[x]; 
 350                  tdes_dec(&buff2, &buff2, skey->data); 
 351                  memcpy(cmd+10,buff2,8); 
 353                  for (int x = 0; x < 8; x++) { 
 354                  buff3[x] = buff3[x] ^ buff2[x]; 
 356                  tdes_dec(&buff3, &buff3, skey->data); 
 357                  memcpy(cmd+18,buff3,8); 
 359                  // The command always times out on the first attempt, this will retry until a response 
 363                  len = DesfireAPDU(cmd,26,resp); 
 367                     // Current key is a DES key, change it to a 3DES key 
 372                         uint8_t newKey[16] = {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f}; 
 374                         uint8_t first, second; 
 375                         uint8_t buff1[8] = {0x00}; 
 376                         uint8_t buff2[8] = {0x00}; 
 377                         uint8_t buff3[8] = {0x00}; 
 379                         memcpy(buff1,newKey, 8); 
 380                         memcpy(buff2,newKey + 8, 8); 
 382                         ComputeCrc14443(CRC_14443_A, newKey, 16, &first, &second); 
 383                         memcpy(buff3, &first, 1); 
 384                         memcpy(buff3 + 1, &second, 1); 
 386                 des_dec(&buff1, &buff1, skey->data); 
 387                 memcpy(cmd+2,buff1,8); 
 389                 for (int x = 0; x < 8; x++) { 
 390                     buff2[x] = buff2[x] ^ buff1[x]; 
 392                 des_dec(&buff2, &buff2, skey->data); 
 393                 memcpy(cmd+10,buff2,8); 
 395                 for (int x = 0; x < 8; x++) { 
 396                     buff3[x] = buff3[x] ^ buff2[x]; 
 398                 des_dec(&buff3, &buff3, skey->data); 
 399                 memcpy(cmd+18,buff3,8); 
 401                 // The command always times out on the first attempt, this will retry until a response 
 405                     len = DesfireAPDU(cmd,26,resp); 
 413                     cmd_send(CMD_ACK
,1,0,0,skey
->data
,16); 
 415                 cmd_send(CMD_ACK
,1,0,0,skey
->data
,8); 
 417                 DbpString("Authetication failed."); 
 424                         //SendDesfireCommand(AUTHENTICATE_ISO, &keyno, resp); 
 429                         uint8_t keybytes
[16] = {0x00}; 
 430                         if (datain
[1] == 0xff){ 
 431                                 memcpy(keybytes
,PICC_MASTER_KEY16
,16);  
 433                                 memcpy(keybytes
, datain
+1, datalen
); 
 436                         struct desfire_key defaultkey 
= {0x00}; 
 437                         desfirekey_t key 
= &defaultkey
; 
 438                         Desfire_aes_key_new( keybytes
, key
); 
 441                         if ( AesCtxIni(&ctx
, IV
, key
->data
, KEY128
, CBC
) < 0 ){ 
 442                                 if( MF_DBGLEVEL 
>= 4) { 
 443                                         Dbprintf("AES context failed to init"); 
 449                         cmd
[0] = AUTHENTICATE_AES
; 
 450                         cmd
[1] = 0x00;  //keynumber 
 451                         len 
= DesfireAPDU(cmd
, 2, resp
); 
 453                                 if (MF_DBGLEVEL 
>= MF_DBG_ERROR
) { 
 454                                         DbpString("Authentication failed. Card timeout."); 
 460                         memcpy( encRndB
, resp
+3, 16); 
 462                         // dekryptera tagnonce. 
 463                         AesDecrypt(&ctx
, encRndB
, decRndB
, 16); 
 465                         memcpy(both
, nonce
,16); 
 466                         memcpy(both
+16, decRndB 
,16 ); 
 467                         AesEncrypt(&ctx
, both
, encBoth
, 32 ); 
 469                         cmd
[0] = ADDITIONAL_FRAME
; 
 470                         memcpy(cmd
+1, encBoth
, 32 ); 
 472                         len 
= DesfireAPDU(cmd
, 33, resp
);  // 1 + 32 == 33 
 474                                 if (MF_DBGLEVEL 
>= MF_DBG_ERROR
) { 
 475                                         DbpString("Authentication failed. Card timeout."); 
 481                         if ( resp
[2] == 0x00 ){ 
 482                                 // Create AES Session key                
 483                                 struct desfire_key sessionKey 
= {0}; 
 484                                 desfirekey_t skey 
= &sessionKey
; 
 485                                 Desfire_session_key_new( nonce
, decRndB 
, key
, skey 
); 
 486                                 print_result("SESSION : ", skey
->data
, 16); 
 488                                 DbpString("Authetication failed."); 
 498         cmd_send(CMD_ACK
,1,len
,0,resp
,len
); 
 501 // 3 olika ISO sätt att skicka data till DESFIRE (direkt, inkapslat, inkapslat ISO) 
 502 // cmd  =  cmd bytes to send 
 503 // cmd_len = length of cmd 
 504 // dataout = pointer to response data array 
 505 int DesfireAPDU(uint8_t *cmd
, size_t cmd_len
, uint8_t *dataout
){ 
 508         size_t wrappedLen 
= 0; 
 509         uint8_t wCmd
[USB_CMD_DATA_SIZE
] = {0x00}; 
 511         uint8_t resp
[MAX_FRAME_SIZE
]; 
 512     uint8_t par
[MAX_PARITY_SIZE
]; 
 514         wrappedLen 
= CreateAPDU( cmd
, cmd_len
, wCmd
); 
 516         if (MF_DBGLEVEL 
>= 4) { 
 517                 print_result("WCMD <--: ", wCmd
, wrappedLen
);    
 519         ReaderTransmit( wCmd
, wrappedLen
, NULL
); 
 521         len 
= ReaderReceive(resp
, par
); 
 524                 if (MF_DBGLEVEL 
>= 4) Dbprintf("fukked"); 
 525                 return FALSE
; //DATA LINK ERROR 
 527         // if we received an I- or R(ACK)-Block with a block number equal to the 
 528         // current block number, toggle the current block number 
 529         else if (len 
>= 4 // PCB+CID+CRC = 4 bytes 
 530                  && ((resp
[0] & 0xC0) == 0 // I-Block 
 531                      || (resp
[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0 
 532                  && (resp
[0] & 0x01) == pcb_blocknum
) // equal block numbers 
 534                 pcb_blocknum 
^= 1;  //toggle next block  
 537         memcpy(dataout
, resp
, len
); 
 542 size_t CreateAPDU( uint8_t *datain
, size_t len
, uint8_t *dataout
){ 
 544         size_t cmdlen 
= MIN(len
+4, USB_CMD_DATA_SIZE
-1); 
 547         memset(cmd
, 0, cmdlen
); 
 549         cmd
[0] = 0x0A;  //  0x0A = skicka cid,  0x02 = ingen cid. Särskilda bitar // 
 550         cmd
[0] |= pcb_blocknum
; // OR the block number into the PCB      
 551         cmd
[1] = 0x00;  //  CID: 0x00 //TODO: allow multiple selected cards 
 553         memcpy(cmd
+2, datain
, len
); 
 554         AppendCrc14443a(cmd
, len
+2); 
 556         memcpy(dataout
, cmd
, cmdlen
); 
 561         // crc_update(&desfire_crc32, 0, 1); /* CMD_WRITE */ 
 562         // crc_update(&desfire_crc32, addr, addr_sz); 
 563         // crc_update(&desfire_crc32, byte, 8); 
 564         // uint32_t crc = crc_finish(&desfire_crc32); 
 568         ReaderTransmit(deselect_cmd
, 3 , NULL
); 
 569         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
); 
 574 void OnError(uint8_t reason
){ 
 575         cmd_send(CMD_ACK
,0,reason
,0,0,0);