1 #include "mifaredesfire.h"
3 #define MAX_APPLICATION_COUNT 28
4 #define MAX_FILE_COUNT 16
5 #define MAX_DESFIRE_FRAME_SIZE 60
6 #define NOT_YET_AUTHENTICATED 255
7 #define FRAME_PAYLOAD_SIZE (MAX_DESFIRE_FRAME_SIZE - 5)
8 #define RECEIVE_SIZE 64
10 // the block number for the ISO14443-4 PCB
11 uint8_t pcb_blocknum
= 0;
12 // Deselect card by sending a s-block. the crc is precalced for speed
13 static uint8_t deselect_cmd
[] = {0xc2,0xe0,0xb4};
15 //static uint8_t __msg[MAX_FRAME_SIZE] = { 0x0A, 0x00, 0x00, /* ..., */ 0x00 };
16 /* PCB CID CMD PAYLOAD */
17 //static uint8_t __res[MAX_FRAME_SIZE];
19 bool InitDesfireCard(){
21 iso14a_card_select_t card
;
23 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN
);
26 if (!iso14443a_select_card(NULL
, &card
, NULL
, true, 0)) {
27 if (MF_DBGLEVEL
>= MF_DBG_ERROR
) DbpString("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
[RECEIVE_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(" RX : ", datain
, datalen
);
61 if ( flags
& CLEARTRACE
)
65 if ( !InitDesfireCard() )
69 int len
= DesfireAPDU(datain
, datalen
, resp
);
71 print_result("ERR <--: ", resp
, len
);
78 // reset the pcb_blocknum,
81 if ( flags
& DISCONNECT
)
84 cmd_send(CMD_ACK
,1,len
,0,resp
,len
);
87 void MifareDesfireGetInformation(){
90 iso14a_card_select_t card
;
91 uint8_t resp
[USB_CMD_DATA_SIZE
] = {0x00};
92 uint8_t dataout
[USB_CMD_DATA_SIZE
] = {0x00};
100 PCB == 0x0A because sending CID byte.
101 CID == 0x00 first card?
105 iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN
);
107 // card select - information
108 if ( !iso14443a_select_card(NULL
, &card
, NULL
, true, 0) ) {
109 if (MF_DBGLEVEL
>= MF_DBG_ERROR
) DbpString("Can't select card");
114 memcpy(dataout
, card
.uid
, 7);
120 uint8_t cmd
[] = {GET_VERSION
};
121 size_t cmd_len
= sizeof(cmd
);
123 len
= DesfireAPDU(cmd
, cmd_len
, resp
);
125 print_result("ERROR <--: ", resp
, len
);
132 memcpy(dataout
+7,resp
+3,7);
135 cmd
[0] = ADDITIONAL_FRAME
;
136 len
= DesfireAPDU(cmd
, cmd_len
, resp
);
138 print_result("ERROR <--: ", resp
, len
);
145 memcpy(dataout
+7+7,resp
+3,7);
148 len
= DesfireAPDU(cmd
, cmd_len
, resp
);
150 print_result("ERROR <--: ", resp
, len
);
155 memcpy(dataout
+7+7+7,resp
+3,14);
157 cmd_send(CMD_ACK
,1,0,0,dataout
,sizeof(dataout
));
159 // reset the pcb_blocknum,
164 void MifareDES_Auth1(uint8_t mode
, uint8_t algo
, uint8_t keyno
, uint8_t *datain
){
167 //uint8_t PICC_MASTER_KEY8[8] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47};
168 uint8_t PICC_MASTER_KEY16
[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f };
169 uint8_t null_key_data8
[8] = {0x00};
170 //uint8_t null_key_data16[16] = {0x00};
171 //uint8_t new_key_data8[8] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
172 //uint8_t new_key_data16[16] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};
174 uint8_t resp
[256] = {0x00};
175 uint8_t IV
[16] = {0x00};
177 size_t datalen
= datain
[0];
179 uint8_t cmd
[40] = {0x00};
180 uint8_t encRndB
[16] = {0x00};
181 uint8_t decRndB
[16] = {0x00};
182 uint8_t nonce
[16] = {0x00};
183 uint8_t both
[32] = {0x00};
184 uint8_t encBoth
[32] = {0x00};
192 // 3 olika sätt att authenticera. AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32)
193 // 4 olika crypto algo DES, 3DES, 3K3DES, AES
194 // 3 olika kommunikations sätt, PLAIN,MAC,CRYPTO
199 uint8_t keybytes
[16];
200 uint8_t RndA
[8] = {0x00};
201 uint8_t RndB
[8] = {0x00};
204 if (datain
[1] == 0xff){
205 memcpy(keybytes
,PICC_MASTER_KEY16
,16);
207 memcpy(keybytes
, datain
+1, datalen
);
211 if (datain
[1] == 0xff){
212 memcpy(keybytes
,null_key_data8
,8);
214 memcpy(keybytes
, datain
+1, datalen
);
219 struct desfire_key defaultkey
= {0};
220 desfirekey_t key
= &defaultkey
;
223 Desfire_3des_key_new_with_version(keybytes
, key
);
225 Desfire_des_key_new(keybytes
, key
);
227 cmd
[0] = AUTHENTICATE
;
228 cmd
[1] = keyno
; //keynumber
229 len
= DesfireAPDU(cmd
, 2, resp
);
231 if (MF_DBGLEVEL
>= MF_DBG_ERROR
) {
232 DbpString("Authentication failed. Card timeout.");
238 if ( resp
[2] == 0xaf ){
240 DbpString("Authetication failed. Invalid key number.");
245 memcpy( encRndB
, resp
+3, 8);
247 tdes_dec(&decRndB
, &encRndB
, key
->data
);
249 des_dec(&decRndB
, &encRndB
, key
->data
);
251 memcpy(RndB
, decRndB
, 8);
254 // This should be random
255 uint8_t decRndA
[8] = {0x00};
256 memcpy(RndA
, decRndA
, 8);
257 uint8_t encRndA
[8] = {0x00};
260 tdes_dec(&encRndA
, &decRndA
, key
->data
);
262 des_dec(&encRndA
, &decRndA
, key
->data
);
264 memcpy(both
, encRndA
, 8);
266 for (int x
= 0; x
< 8; x
++) {
267 decRndB
[x
] = decRndB
[x
] ^ encRndA
[x
];
272 tdes_dec(&encRndB
, &decRndB
, key
->data
);
274 des_dec(&encRndB
, &decRndB
, key
->data
);
276 memcpy(both
+ 8, encRndB
, 8);
278 cmd
[0] = ADDITIONAL_FRAME
;
279 memcpy(cmd
+1, both
, 16 );
281 len
= DesfireAPDU(cmd
, 17, resp
);
283 if (MF_DBGLEVEL
>= MF_DBG_ERROR
) {
284 DbpString("Authentication failed. Card timeout.");
290 if ( resp
[2] == 0x00 ){
292 struct desfire_key sessionKey
= {0};
293 desfirekey_t skey
= &sessionKey
;
294 Desfire_session_key_new( RndA
, RndB
, key
, skey
);
295 //print_result("SESSION : ", skey->data, 8);
297 memcpy(encRndA
, resp
+3, 8);
300 tdes_dec(&encRndA
, &encRndA
, key
->data
);
302 des_dec(&encRndA
, &encRndA
, key
->data
);
305 for (int x
= 0; x
< 8; x
++) {
306 if (decRndA
[x
] != encRndA
[x
]) {
307 DbpString("Authetication failed. Cannot varify PICC.");
313 //Change the selected key to a new value.
316 // Current key is a 3DES key, change it to a DES key
321 uint8_t newKey[16] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
323 uint8_t first, second;
324 uint8_t buff1[8] = {0x00};
325 uint8_t buff2[8] = {0x00};
326 uint8_t buff3[8] = {0x00};
328 memcpy(buff1,newKey, 8);
329 memcpy(buff2,newKey + 8, 8);
331 ComputeCrc14443(CRC_14443_A, newKey, 16, &first, &second);
332 memcpy(buff3, &first, 1);
333 memcpy(buff3 + 1, &second, 1);
335 tdes_dec(&buff1, &buff1, skey->data);
336 memcpy(cmd+2,buff1,8);
338 for (int x = 0; x < 8; x++) {
339 buff2[x] = buff2[x] ^ buff1[x];
341 tdes_dec(&buff2, &buff2, skey->data);
342 memcpy(cmd+10,buff2,8);
344 for (int x = 0; x < 8; x++) {
345 buff3[x] = buff3[x] ^ buff2[x];
347 tdes_dec(&buff3, &buff3, skey->data);
348 memcpy(cmd+18,buff3,8);
350 // The command always times out on the first attempt, this will retry until a response
354 len = DesfireAPDU(cmd,26,resp);
358 // Current key is a DES key, change it to a 3DES key
363 uint8_t newKey[16] = {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f};
365 uint8_t first, second;
366 uint8_t buff1[8] = {0x00};
367 uint8_t buff2[8] = {0x00};
368 uint8_t buff3[8] = {0x00};
370 memcpy(buff1,newKey, 8);
371 memcpy(buff2,newKey + 8, 8);
373 ComputeCrc14443(CRC_14443_A, newKey, 16, &first, &second);
374 memcpy(buff3, &first, 1);
375 memcpy(buff3 + 1, &second, 1);
377 des_dec(&buff1, &buff1, skey->data);
378 memcpy(cmd+2,buff1,8);
380 for (int x = 0; x < 8; x++) {
381 buff2[x] = buff2[x] ^ buff1[x];
383 des_dec(&buff2, &buff2, skey->data);
384 memcpy(cmd+10,buff2,8);
386 for (int x = 0; x < 8; x++) {
387 buff3[x] = buff3[x] ^ buff2[x];
389 des_dec(&buff3, &buff3, skey->data);
390 memcpy(cmd+18,buff3,8);
392 // The command always times out on the first attempt, this will retry until a response
396 len = DesfireAPDU(cmd,26,resp);
404 cmd_send(CMD_ACK
,1,0,0,skey
->data
,16);
406 cmd_send(CMD_ACK
,1,0,0,skey
->data
,8);
408 DbpString("Authetication failed.");
415 //SendDesfireCommand(AUTHENTICATE_ISO, &keyno, resp);
420 uint8_t keybytes
[16] = {0x00};
421 if (datain
[1] == 0xff){
422 memcpy(keybytes
,PICC_MASTER_KEY16
,16);
424 memcpy(keybytes
, datain
+1, datalen
);
427 struct desfire_key defaultkey
= {0x00};
428 desfirekey_t key
= &defaultkey
;
429 Desfire_aes_key_new( keybytes
, key
);
432 if ( AesCtxIni(&ctx
, IV
, key
->data
, KEY128
, CBC
) < 0 ){
433 if( MF_DBGLEVEL
>= 4) {
434 Dbprintf("AES context failed to init");
440 cmd
[0] = AUTHENTICATE_AES
;
441 cmd
[1] = 0x00; //keynumber
442 len
= DesfireAPDU(cmd
, 2, resp
);
444 if (MF_DBGLEVEL
>= MF_DBG_ERROR
) {
445 DbpString("Authentication failed. Card timeout.");
451 memcpy( encRndB
, resp
+3, 16);
453 // dekryptera tagnonce.
454 AesDecrypt(&ctx
, encRndB
, decRndB
, 16);
456 memcpy(both
, nonce
,16);
457 memcpy(both
+16, decRndB
,16 );
458 AesEncrypt(&ctx
, both
, encBoth
, 32 );
460 cmd
[0] = ADDITIONAL_FRAME
;
461 memcpy(cmd
+1, encBoth
, 32 );
463 len
= DesfireAPDU(cmd
, 33, resp
); // 1 + 32 == 33
465 if (MF_DBGLEVEL
>= MF_DBG_ERROR
) {
466 DbpString("Authentication failed. Card timeout.");
472 if ( resp
[2] == 0x00 ){
473 // Create AES Session key
474 struct desfire_key sessionKey
= {0};
475 desfirekey_t skey
= &sessionKey
;
476 Desfire_session_key_new( nonce
, decRndB
, key
, skey
);
477 print_result("SESSION : ", skey
->data
, 16);
479 DbpString("Authetication failed.");
489 cmd_send(CMD_ACK
,1,len
,0,resp
,len
);
492 // 3 olika ISO sätt att skicka data till DESFIRE (direkt, inkapslat, inkapslat ISO)
493 // cmd = cmd bytes to send
494 // cmd_len = length of cmd
495 // dataout = pointer to response data array
496 int DesfireAPDU(uint8_t *cmd
, size_t cmd_len
, uint8_t *dataout
){
499 size_t wrappedLen
= 0;
500 uint8_t wCmd
[USB_CMD_DATA_SIZE
] = {0x00};
501 uint8_t resp
[MAX_FRAME_SIZE
];
502 uint8_t par
[MAX_PARITY_SIZE
];
504 wrappedLen
= CreateAPDU( cmd
, cmd_len
, wCmd
);
506 if (MF_DBGLEVEL
>= 4)
507 print_result("WCMD <--: ", wCmd
, wrappedLen
);
509 ReaderTransmit( wCmd
, wrappedLen
, NULL
);
511 len
= ReaderReceive(resp
, par
);
513 if (MF_DBGLEVEL
>= 4) Dbprintf("fukked");
514 return FALSE
; //DATA LINK ERROR
516 // if we received an I- or R(ACK)-Block with a block number equal to the
517 // current block number, toggle the current block number
518 else if (len
>= 4 // PCB+CID+CRC = 4 bytes
519 && ((resp
[0] & 0xC0) == 0 // I-Block
520 || (resp
[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0
521 && (resp
[0] & 0x01) == pcb_blocknum
) // equal block numbers
523 pcb_blocknum
^= 1; //toggle next block
526 memcpy(dataout
, resp
, len
);
531 size_t CreateAPDU( uint8_t *datain
, size_t len
, uint8_t *dataout
){
533 size_t cmdlen
= MIN(len
+4, USB_CMD_DATA_SIZE
-1);
536 memset(cmd
, 0, cmdlen
);
538 cmd
[0] = 0x0A; // 0x0A = skicka cid, 0x02 = ingen cid. Särskilda bitar //
539 cmd
[0] |= pcb_blocknum
; // OR the block number into the PCB
540 cmd
[1] = 0x00; // CID: 0x00 //TODO: allow multiple selected cards
542 memcpy(cmd
+2, datain
, len
);
543 AppendCrc14443a(cmd
, len
+2);
545 memcpy(dataout
, cmd
, cmdlen
);
550 // crc_update(&desfire_crc32, 0, 1); /* CMD_WRITE */
551 // crc_update(&desfire_crc32, addr, addr_sz);
552 // crc_update(&desfire_crc32, byte, 8);
553 // uint32_t crc = crc_finish(&desfire_crc32);
557 ReaderTransmit(deselect_cmd
, 3 , NULL
);
559 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF
);
564 void OnError(uint8_t reason
){
565 cmd_send(CMD_ACK
,0,reason
,0,0,0);