2 * Copyright (C) 2010, Romain Tartiere.
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by the
6 * Free Software Foundation, either version 3 of the License, or (at your
7 * option) any later version.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>
21 * This implementation was written based on information provided by the
22 * following documents:
24 * NIST Special Publication 800-38B
25 * Recommendation for Block Cipher Modes of Operation: The CMAC Mode for Authentication
28 #include "desfire_crypto.h"
30 static void xor (const uint8_t *ivect
, uint8_t *data
, const size_t len
);
31 static size_t key_macing_length (desfirekey_t key
);
33 static void xor (const uint8_t *ivect
, uint8_t *data
, const size_t len
) {
34 for (size_t i
= 0; i
< len
; i
++) {
39 void cmac_generate_subkeys ( desfirekey_t key
) {
40 int kbs
= key_block_size (key
);
41 const uint8_t R
= (kbs
== 8) ? 0x1B : 0x87;
47 memset (ivect
, 0, kbs
);
49 mifare_cypher_blocks_chained (NULL
, key
, ivect
, l
, kbs
, MCD_RECEIVE
, MCO_ENCYPHER
);
53 // Used to compute CMAC on complete blocks
54 memcpy (key
->cmac_sk1
, l
, kbs
);
56 lsl (key
->cmac_sk1
, kbs
);
58 key
->cmac_sk1
[kbs
-1] ^= R
;
60 // Used to compute CMAC on the last block if non-complete
61 memcpy (key
->cmac_sk2
, key
->cmac_sk1
, kbs
);
62 xor = key
->cmac_sk1
[0] & 0x80;
63 lsl (key
->cmac_sk2
, kbs
);
65 key
->cmac_sk2
[kbs
-1] ^= R
;
68 void cmac (const desfirekey_t key
, uint8_t *ivect
, const uint8_t *data
, size_t len
, uint8_t *cmac
) {
69 int kbs
= key_block_size (key
);
70 uint8_t *buffer
= malloc (padded_data_length (len
, kbs
));
72 memcpy (buffer
, data
, len
);
74 if ((!len
) || (len
% kbs
)) {
79 xor (key
->cmac_sk2
, buffer
+ len
- kbs
, kbs
);
81 xor (key
->cmac_sk1
, buffer
+ len
- kbs
, kbs
);
84 mifare_cypher_blocks_chained (NULL
, key
, ivect
, buffer
, len
, MCD_SEND
, MCO_ENCYPHER
);
86 memcpy (cmac
, ivect
, kbs
);
90 size_t key_block_size (const desfirekey_t key
) {
91 size_t block_size
= 8;
106 * Size of MACing produced with the key.
108 static size_t key_macing_length (const desfirekey_t key
) {
109 size_t mac_length
= MAC_LENGTH
;
113 mac_length
= MAC_LENGTH
;
117 mac_length
= CMAC_LENGTH
;
124 * Size required to store nbytes of data in a buffer of size n*block_size.
126 size_t padded_data_length (const size_t nbytes
, const size_t block_size
) {
127 if ((!nbytes
) || (nbytes
% block_size
))
128 return ((nbytes
/ block_size
) + 1) * block_size
;
134 * Buffer size required to MAC nbytes of data
136 size_t maced_data_length (const desfirekey_t key
, const size_t nbytes
) {
137 return nbytes
+ key_macing_length (key
);
140 * Buffer size required to encipher nbytes of data and a two bytes CRC.
142 size_t enciphered_data_length (const desfiretag_t tag
, const size_t nbytes
, int communication_settings
) {
143 size_t crc_length
= 0;
144 if (!(communication_settings
& NO_CRC
)) {
145 switch (DESFIRE(tag
)->authentication_scheme
) {
155 size_t block_size
= DESFIRE(tag
)->session_key
? key_block_size (DESFIRE(tag
)->session_key
) : 1;
157 return padded_data_length (nbytes
+ crc_length
, block_size
);
160 void* mifare_cryto_preprocess_data (desfiretag_t tag
, void *data
, size_t *nbytes
, size_t offset
, int communication_settings
) {
164 bool append_mac
= true;
165 desfirekey_t key
= DESFIRE(tag
)->session_key
;
170 switch (communication_settings
& MDCM_MASK
) {
172 if (AS_LEGACY
== DESFIRE(tag
)->authentication_scheme
)
176 * When using new authentication methods, PLAIN data transmission from
177 * the PICC to the PCD are CMACed, so we have to maintain the
178 * cryptographic initialisation vector up-to-date to check data
181 * The only difference with CMACed data transmission is that the CMAC
182 * is not apended to the data send by the PCD to the PICC.
189 switch (DESFIRE(tag
)->authentication_scheme
) {
191 if (!(communication_settings
& MAC_COMMAND
))
195 edl
= padded_data_length (*nbytes
- offset
, key_block_size (DESFIRE(tag
)->session_key
)) + offset
;
197 // Fill in the crypto buffer with data ...
198 memcpy (res
, data
, *nbytes
);
200 memset (res
+ *nbytes
, 0, edl
- *nbytes
);
202 mifare_cypher_blocks_chained (tag
, NULL
, NULL
, res
+ offset
, edl
- offset
, MCD_SEND
, MCO_ENCYPHER
);
204 memcpy (mac
, res
+ edl
- 8, 4);
206 // Copy again provided data (was overwritten by mifare_cypher_blocks_chained)
207 memcpy (res
, data
, *nbytes
);
209 if (!(communication_settings
& MAC_COMMAND
))
212 size_t bla
= maced_data_length (DESFIRE(tag
)->session_key
, *nbytes
- offset
) + offset
;
215 memcpy (res
+ *nbytes
, mac
, 4);
220 if (!(communication_settings
& CMAC_COMMAND
))
222 cmac (key
, DESFIRE (tag
)->ivect
, res
, *nbytes
, DESFIRE (tag
)->cmac
);
225 size_t len
= maced_data_length (key
, *nbytes
);
227 memcpy (res
, data
, *nbytes
);
228 memcpy (res
+ *nbytes
, DESFIRE (tag
)->cmac
, CMAC_LENGTH
);
229 *nbytes
+= CMAC_LENGTH
;
235 case MDCM_ENCIPHERED
:
236 /* |<-------------- data -------------->|
237 * |<--- offset -->| |
238 * +---------------+--------------------+-----+---------+
239 * | CMD + HEADERS | DATA TO BE SECURED | CRC | PADDING |
240 * +---------------+--------------------+-----+---------+ ----------------
241 * | |<~~~~v~~~~~~~~~~~~~>| ^ | | (DES / 3DES)
242 * | | `---- crc16() ----' | |
243 * | | | ^ | | ----- *or* -----
244 * |<~~~~~~~~~~~~~~~~~~~~v~~~~~~~~~~~~~>| ^ | | (3K3DES / AES)
245 * | `---- crc32() ----' | |
246 * | | ---- *then* ----
247 * |<---------------------------------->|
248 * encypher()/decypher()
251 if (!(communication_settings
& ENC_COMMAND
))
253 edl
= enciphered_data_length (tag
, *nbytes
- offset
, communication_settings
) + offset
;
255 // Fill in the crypto buffer with data ...
256 memcpy (res
, data
, *nbytes
);
257 if (!(communication_settings
& NO_CRC
)) {
259 switch (DESFIRE (tag
)->authentication_scheme
) {
261 AppendCrc14443a(res
+ offset
, *nbytes
- offset
);
265 crc32_append (res
, *nbytes
);
271 memset (res
+ *nbytes
, 0, edl
- *nbytes
);
275 mifare_cypher_blocks_chained (tag
, NULL
, NULL
, res
+ offset
, *nbytes
- offset
, MCD_SEND
, (AS_NEW
== DESFIRE(tag
)->authentication_scheme
) ? MCO_ENCYPHER
: MCO_DECYPHER
);
288 void* mifare_cryto_postprocess_data (desfiretag_t tag
, void *data
, size_t *nbytes
, int communication_settings
)
293 uint8_t first_cmac_byte
= 0x00;
295 desfirekey_t key
= DESFIRE(tag
)->session_key
;
300 // Return directly if we just have a status code.
304 switch (communication_settings
& MDCM_MASK
) {
307 if (AS_LEGACY
== DESFIRE(tag
)->authentication_scheme
)
312 switch (DESFIRE (tag
)->authentication_scheme
) {
314 if (communication_settings
& MAC_VERIFY
) {
315 *nbytes
-= key_macing_length (key
);
320 Dbprintf ("No room for MAC!");
325 edl
= enciphered_data_length (tag
, *nbytes
- 1, communication_settings
);
326 edata
= malloc (edl
);
328 memcpy (edata
, data
, *nbytes
- 1);
329 memset ((uint8_t *)edata
+ *nbytes
- 1, 0, edl
- *nbytes
+ 1);
331 mifare_cypher_blocks_chained (tag
, NULL
, NULL
, edata
, edl
, MCD_SEND
, MCO_ENCYPHER
);
333 if (0 != memcmp ((uint8_t *)data
+ *nbytes
- 1, (uint8_t *)edata
+ edl
- 8, 4)) {
335 Dbprintf ("MACing not verified");
336 hexdump ((uint8_t *)data
+ *nbytes
- 1, key_macing_length (key
), "Expect ", 0);
337 hexdump ((uint8_t *)edata
+ edl
- 8, key_macing_length (key
), "Actual ", 0);
339 DESFIRE (tag
)->last_pcd_error
= CRYPTO_ERROR
;
346 if (!(communication_settings
& CMAC_COMMAND
))
348 if (communication_settings
& CMAC_VERIFY
) {
354 first_cmac_byte
= ((uint8_t *)data
)[*nbytes
- 9];
355 ((uint8_t *)data
)[*nbytes
- 9] = ((uint8_t *)data
)[*nbytes
-1];
358 int n
= (communication_settings
& CMAC_VERIFY
) ? 8 : 0;
359 cmac (key
, DESFIRE (tag
)->ivect
, ((uint8_t *)data
), *nbytes
- n
, DESFIRE (tag
)->cmac
);
361 if (communication_settings
& CMAC_VERIFY
) {
362 ((uint8_t *)data
)[*nbytes
- 9] = first_cmac_byte
;
363 if (0 != memcmp (DESFIRE (tag
)->cmac
, (uint8_t *)data
+ *nbytes
- 9, 8)) {
365 Dbprintf ("CMAC NOT verified :-(");
366 hexdump ((uint8_t *)data
+ *nbytes
- 9, 8, "Expect ", 0);
367 hexdump (DESFIRE (tag
)->cmac
, 8, "Actual ", 0);
369 DESFIRE (tag
)->last_pcd_error
= CRYPTO_ERROR
;
382 case MDCM_ENCIPHERED
:
384 bool verified
= false;
386 int end_crc_pos
= 0x00;
391 * ,-----------------+-------------------------------+--------+
392 * \ BLOCK n-1 | BLOCK n | STATUS |
393 * / PAYLOAD | CRC0 | CRC1 | 0x80? | 0x000000000000 | 0x9100 |
394 * `-----------------+-------------------------------+--------+
396 * <------------ DATA ------------>
397 * FRAME = PAYLOAD + CRC(PAYLOAD) + PADDING
400 * ,-------------------------------+-----------------------------------------------+--------+
401 * \ BLOCK n-1 | BLOCK n | STATUS |
402 * / PAYLOAD | CRC0 | CRC1 | CRC2 | CRC3 | 0x80? | 0x0000000000000000000000000000 | 0x9100 |
403 * `-------------------------------+-----------------------------------------------+--------+
404 * <----------------------------------- DATA ------------------------------------->|
406 * <----------------- DATA ---------------->
407 * FRAME = PAYLOAD + CRC(PAYLOAD + STATUS) + PADDING + STATUS
408 * `------------------'
411 mifare_cypher_blocks_chained (tag
, NULL
, NULL
, res
, *nbytes
, MCD_RECEIVE
, MCO_DECYPHER
);
414 * Look for the CRC and ensure it is followed by NULL padding. We
415 * can't start by the end because the CRC is supposed to be 0 when
416 * verified, and accumulating 0's in it should not change it.
418 switch (DESFIRE (tag
)->authentication_scheme
) {
420 crc_pos
= *nbytes
- 8 - 1; // The CRC can be over two blocks
427 /* Move status between payload and CRC */
428 res
= DESFIRE (tag
)->crypto_buffer
;
429 memcpy (res
, data
, *nbytes
);
431 crc_pos
= (*nbytes
) - 16 - 3;
436 memcpy ((uint8_t *)res
+ crc_pos
+ 1, (uint8_t *)res
+ crc_pos
, *nbytes
- crc_pos
);
437 ((uint8_t *)res
)[crc_pos
] = 0x00;
444 uint16_t crc16
=0x00;
446 switch (DESFIRE (tag
)->authentication_scheme
) {
448 end_crc_pos
= crc_pos
+ 2;
449 AppendCrc14443a (res
, end_crc_pos
);
457 end_crc_pos
= crc_pos
+ 4;
458 crc32_ex (res
, end_crc_pos
, (uint8_t *)&crc
);
463 for (int n
= end_crc_pos
; n
< *nbytes
- 1; n
++) {
464 uint8_t byte
= ((uint8_t *)res
)[n
];
465 if (!( (0x00 == byte
) || ((0x80 == byte
) && (n
== end_crc_pos
)) ))
471 switch (DESFIRE (tag
)->authentication_scheme
) {
473 ((uint8_t *)data
)[(*nbytes
)++] = 0x00;
476 /* The status byte was already before the CRC */
480 switch (DESFIRE (tag
)->authentication_scheme
) {
484 x
= ((uint8_t *)res
)[crc_pos
- 1];
485 ((uint8_t *)res
)[crc_pos
- 1] = ((uint8_t *)res
)[crc_pos
];
486 ((uint8_t *)res
)[crc_pos
] = x
;
491 } while (!verified
&& (end_crc_pos
< *nbytes
));
495 /* FIXME In some configurations, the file is transmitted PLAIN */
496 Dbprintf("CRC not verified in decyphered stream");
498 DESFIRE (tag
)->last_pcd_error
= CRYPTO_ERROR
;
505 Dbprintf("Unknown communication settings");
515 void mifare_cypher_single_block (desfirekey_t key
, uint8_t *data
, uint8_t *ivect
, MifareCryptoDirection direction
, MifareCryptoOperation operation
, size_t block_size
)
517 uint8_t ovect
[MAX_CRYPTO_BLOCK_SIZE
];
519 if (direction
== MCD_SEND
) {
520 xor (ivect
, data
, block_size
);
522 memcpy (ovect
, data
, block_size
);
525 uint8_t edata
[MAX_CRYPTO_BLOCK_SIZE
];
531 //DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
532 des_enc(edata
, data
, key
->data
);
535 //DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
536 des_dec(edata
, data
, key
->data
);
543 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
544 // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT);
545 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
546 tdes_enc(edata
,data
, key
->data
);
549 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
550 // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT);
551 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
552 tdes_dec(data
, edata
, key
->data
);
559 tdes_enc(edata
,data
, key
->data
);
560 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
561 // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT);
562 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_ENCRYPT);
565 tdes_dec(data
, edata
, key
->data
);
566 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_DECRYPT);
567 // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT);
568 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
578 AesCtxIni(&ctx
, ivect
, key
->data
, KEY128
,CBC
);
579 AesEncrypt(&ctx
, data
, edata
, sizeof(edata
) );
585 AesCtxIni(&ctx
, ivect
, key
->data
, KEY128
,CBC
);
586 AesDecrypt(&ctx
, edata
, data
, sizeof(edata
));
593 memcpy (data
, edata
, block_size
);
595 if (direction
== MCD_SEND
) {
596 memcpy (ivect
, data
, block_size
);
598 xor (ivect
, data
, block_size
);
599 memcpy (ivect
, ovect
, block_size
);
604 * This function performs all CBC cyphering / deciphering.
606 * The tag argument may be NULL, in which case both key and ivect shall be set.
607 * When using the tag session_key and ivect for processing data, these
608 * arguments should be set to NULL.
610 * Because the tag may contain additional data, one may need to call this
611 * function with tag, key and ivect defined.
613 void mifare_cypher_blocks_chained (desfiretag_t tag
, desfirekey_t key
, uint8_t *ivect
, uint8_t *data
, size_t data_size
, MifareCryptoDirection direction
, MifareCryptoOperation operation
) {
618 key
= DESFIRE (tag
)->session_key
;
620 ivect
= DESFIRE (tag
)->ivect
;
622 switch (DESFIRE (tag
)->authentication_scheme
) {
624 memset (ivect
, 0, MAX_CRYPTO_BLOCK_SIZE
);
631 block_size
= key_block_size (key
);
634 while (offset
< data_size
) {
635 mifare_cypher_single_block (key
, data
+ offset
, ivect
, direction
, operation
, block_size
);
636 offset
+= block_size
;