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;
108 * Size of MACing produced with the key.
110 static size_t key_macing_length (const desfirekey_t key
) {
111 size_t mac_length
= MAC_LENGTH
;
116 mac_length
= MAC_LENGTH
;
120 mac_length
= CMAC_LENGTH
;
128 * Size required to store nbytes of data in a buffer of size n*block_size.
130 size_t padded_data_length (const size_t nbytes
, const size_t block_size
) {
131 if ((!nbytes
) || (nbytes
% block_size
))
132 return ((nbytes
/ block_size
) + 1) * block_size
;
138 * Buffer size required to MAC nbytes of data
140 size_t maced_data_length (const desfirekey_t key
, const size_t nbytes
) {
141 return nbytes
+ key_macing_length (key
);
144 * Buffer size required to encipher nbytes of data and a two bytes CRC.
146 size_t enciphered_data_length (const desfiretag_t tag
, const size_t nbytes
, int communication_settings
) {
147 size_t crc_length
= 0;
148 if (!(communication_settings
& NO_CRC
)) {
149 switch (DESFIRE(tag
)->authentication_scheme
) {
159 size_t block_size
= DESFIRE(tag
)->session_key
? key_block_size (DESFIRE(tag
)->session_key
) : 1;
161 return padded_data_length (nbytes
+ crc_length
, block_size
);
164 void* mifare_cryto_preprocess_data (desfiretag_t tag
, void *data
, size_t *nbytes
, size_t offset
, int communication_settings
) {
168 bool append_mac
= true;
169 desfirekey_t key
= DESFIRE(tag
)->session_key
;
174 switch (communication_settings
& MDCM_MASK
) {
176 if (AS_LEGACY
== DESFIRE(tag
)->authentication_scheme
)
180 * When using new authentication methods, PLAIN data transmission from
181 * the PICC to the PCD are CMACed, so we have to maintain the
182 * cryptographic initialisation vector up-to-date to check data
185 * The only difference with CMACed data transmission is that the CMAC
186 * is not apended to the data send by the PCD to the PICC.
193 switch (DESFIRE(tag
)->authentication_scheme
) {
195 if (!(communication_settings
& MAC_COMMAND
))
199 edl
= padded_data_length (*nbytes
- offset
, key_block_size (DESFIRE(tag
)->session_key
)) + offset
;
201 // Fill in the crypto buffer with data ...
202 memcpy (res
, data
, *nbytes
);
204 memset (res
+ *nbytes
, 0, edl
- *nbytes
);
206 mifare_cypher_blocks_chained (tag
, NULL
, NULL
, res
+ offset
, edl
- offset
, MCD_SEND
, MCO_ENCYPHER
);
208 memcpy (mac
, res
+ edl
- 8, 4);
210 // Copy again provided data (was overwritten by mifare_cypher_blocks_chained)
211 memcpy (res
, data
, *nbytes
);
213 if (!(communication_settings
& MAC_COMMAND
))
216 size_t bla
= maced_data_length (DESFIRE(tag
)->session_key
, *nbytes
- offset
) + offset
;
219 memcpy (res
+ *nbytes
, mac
, 4);
224 if (!(communication_settings
& CMAC_COMMAND
))
226 cmac (key
, DESFIRE (tag
)->ivect
, res
, *nbytes
, DESFIRE (tag
)->cmac
);
229 size_t len
= maced_data_length (key
, *nbytes
);
231 memcpy (res
, data
, *nbytes
);
232 memcpy (res
+ *nbytes
, DESFIRE (tag
)->cmac
, CMAC_LENGTH
);
233 *nbytes
+= CMAC_LENGTH
;
239 case MDCM_ENCIPHERED
:
240 /* |<-------------- data -------------->|
241 * |<--- offset -->| |
242 * +---------------+--------------------+-----+---------+
243 * | CMD + HEADERS | DATA TO BE SECURED | CRC | PADDING |
244 * +---------------+--------------------+-----+---------+ ----------------
245 * | |<~~~~v~~~~~~~~~~~~~>| ^ | | (DES / 3DES)
246 * | | `---- crc16() ----' | |
247 * | | | ^ | | ----- *or* -----
248 * |<~~~~~~~~~~~~~~~~~~~~v~~~~~~~~~~~~~>| ^ | | (3K3DES / AES)
249 * | `---- crc32() ----' | |
250 * | | ---- *then* ----
251 * |<---------------------------------->|
252 * encypher()/decypher()
255 if (!(communication_settings
& ENC_COMMAND
))
257 edl
= enciphered_data_length (tag
, *nbytes
- offset
, communication_settings
) + offset
;
259 // Fill in the crypto buffer with data ...
260 memcpy (res
, data
, *nbytes
);
261 if (!(communication_settings
& NO_CRC
)) {
263 switch (DESFIRE (tag
)->authentication_scheme
) {
265 AppendCrc14443a(res
+ offset
, *nbytes
- offset
);
269 crc32_append (res
, *nbytes
);
275 memset (res
+ *nbytes
, 0, edl
- *nbytes
);
279 mifare_cypher_blocks_chained (tag
, NULL
, NULL
, res
+ offset
, *nbytes
- offset
, MCD_SEND
, (AS_NEW
== DESFIRE(tag
)->authentication_scheme
) ? MCO_ENCYPHER
: MCO_DECYPHER
);
292 void* mifare_cryto_postprocess_data (desfiretag_t tag
, void *data
, size_t *nbytes
, int communication_settings
)
297 uint8_t first_cmac_byte
= 0x00;
299 desfirekey_t key
= DESFIRE(tag
)->session_key
;
304 // Return directly if we just have a status code.
308 switch (communication_settings
& MDCM_MASK
) {
311 if (AS_LEGACY
== DESFIRE(tag
)->authentication_scheme
)
316 switch (DESFIRE (tag
)->authentication_scheme
) {
318 if (communication_settings
& MAC_VERIFY
) {
319 *nbytes
-= key_macing_length (key
);
324 Dbprintf ("No room for MAC!");
329 edl
= enciphered_data_length (tag
, *nbytes
- 1, communication_settings
);
330 edata
= malloc (edl
);
332 memcpy (edata
, data
, *nbytes
- 1);
333 memset ((uint8_t *)edata
+ *nbytes
- 1, 0, edl
- *nbytes
+ 1);
335 mifare_cypher_blocks_chained (tag
, NULL
, NULL
, edata
, edl
, MCD_SEND
, MCO_ENCYPHER
);
337 if (0 != memcmp ((uint8_t *)data
+ *nbytes
- 1, (uint8_t *)edata
+ edl
- 8, 4)) {
339 Dbprintf ("MACing not verified");
340 hexdump ((uint8_t *)data
+ *nbytes
- 1, key_macing_length (key
), "Expect ", 0);
341 hexdump ((uint8_t *)edata
+ edl
- 8, key_macing_length (key
), "Actual ", 0);
343 DESFIRE (tag
)->last_pcd_error
= CRYPTO_ERROR
;
350 if (!(communication_settings
& CMAC_COMMAND
))
352 if (communication_settings
& CMAC_VERIFY
) {
358 first_cmac_byte
= ((uint8_t *)data
)[*nbytes
- 9];
359 ((uint8_t *)data
)[*nbytes
- 9] = ((uint8_t *)data
)[*nbytes
-1];
362 int n
= (communication_settings
& CMAC_VERIFY
) ? 8 : 0;
363 cmac (key
, DESFIRE (tag
)->ivect
, ((uint8_t *)data
), *nbytes
- n
, DESFIRE (tag
)->cmac
);
365 if (communication_settings
& CMAC_VERIFY
) {
366 ((uint8_t *)data
)[*nbytes
- 9] = first_cmac_byte
;
367 if (0 != memcmp (DESFIRE (tag
)->cmac
, (uint8_t *)data
+ *nbytes
- 9, 8)) {
369 Dbprintf ("CMAC NOT verified :-(");
370 hexdump ((uint8_t *)data
+ *nbytes
- 9, 8, "Expect ", 0);
371 hexdump (DESFIRE (tag
)->cmac
, 8, "Actual ", 0);
373 DESFIRE (tag
)->last_pcd_error
= CRYPTO_ERROR
;
386 case MDCM_ENCIPHERED
:
388 bool verified
= false;
390 int end_crc_pos
= 0x00;
395 * ,-----------------+-------------------------------+--------+
396 * \ BLOCK n-1 | BLOCK n | STATUS |
397 * / PAYLOAD | CRC0 | CRC1 | 0x80? | 0x000000000000 | 0x9100 |
398 * `-----------------+-------------------------------+--------+
400 * <------------ DATA ------------>
401 * FRAME = PAYLOAD + CRC(PAYLOAD) + PADDING
404 * ,-------------------------------+-----------------------------------------------+--------+
405 * \ BLOCK n-1 | BLOCK n | STATUS |
406 * / PAYLOAD | CRC0 | CRC1 | CRC2 | CRC3 | 0x80? | 0x0000000000000000000000000000 | 0x9100 |
407 * `-------------------------------+-----------------------------------------------+--------+
408 * <----------------------------------- DATA ------------------------------------->|
410 * <----------------- DATA ---------------->
411 * FRAME = PAYLOAD + CRC(PAYLOAD + STATUS) + PADDING + STATUS
412 * `------------------'
415 mifare_cypher_blocks_chained (tag
, NULL
, NULL
, res
, *nbytes
, MCD_RECEIVE
, MCO_DECYPHER
);
418 * Look for the CRC and ensure it is followed by NULL padding. We
419 * can't start by the end because the CRC is supposed to be 0 when
420 * verified, and accumulating 0's in it should not change it.
422 switch (DESFIRE (tag
)->authentication_scheme
) {
424 crc_pos
= *nbytes
- 8 - 1; // The CRC can be over two blocks
431 /* Move status between payload and CRC */
432 res
= DESFIRE (tag
)->crypto_buffer
;
433 memcpy (res
, data
, *nbytes
);
435 crc_pos
= (*nbytes
) - 16 - 3;
440 memcpy ((uint8_t *)res
+ crc_pos
+ 1, (uint8_t *)res
+ crc_pos
, *nbytes
- crc_pos
);
441 ((uint8_t *)res
)[crc_pos
] = 0x00;
448 uint16_t crc16
=0x00;
450 switch (DESFIRE (tag
)->authentication_scheme
) {
452 end_crc_pos
= crc_pos
+ 2;
453 AppendCrc14443a (res
, end_crc_pos
);
461 end_crc_pos
= crc_pos
+ 4;
462 crc32 (res
, end_crc_pos
, (uint8_t *)&crc
);
467 for (int n
= end_crc_pos
; n
< *nbytes
- 1; n
++) {
468 uint8_t byte
= ((uint8_t *)res
)[n
];
469 if (!( (0x00 == byte
) || ((0x80 == byte
) && (n
== end_crc_pos
)) ))
475 switch (DESFIRE (tag
)->authentication_scheme
) {
477 ((uint8_t *)data
)[(*nbytes
)++] = 0x00;
480 /* The status byte was already before the CRC */
484 switch (DESFIRE (tag
)->authentication_scheme
) {
488 x
= ((uint8_t *)res
)[crc_pos
- 1];
489 ((uint8_t *)res
)[crc_pos
- 1] = ((uint8_t *)res
)[crc_pos
];
490 ((uint8_t *)res
)[crc_pos
] = x
;
495 } while (!verified
&& (end_crc_pos
< *nbytes
));
499 /* FIXME In some configurations, the file is transmitted PLAIN */
500 Dbprintf("CRC not verified in decyphered stream");
502 DESFIRE (tag
)->last_pcd_error
= CRYPTO_ERROR
;
509 Dbprintf("Unknown communication settings");
519 void mifare_cypher_single_block (desfirekey_t key
, uint8_t *data
, uint8_t *ivect
, MifareCryptoDirection direction
, MifareCryptoOperation operation
, size_t block_size
)
521 uint8_t ovect
[MAX_CRYPTO_BLOCK_SIZE
];
523 if (direction
== MCD_SEND
) {
524 xor (ivect
, data
, block_size
);
526 memcpy (ovect
, data
, block_size
);
529 uint8_t edata
[MAX_CRYPTO_BLOCK_SIZE
];
535 //DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
536 des_enc(edata
, data
, key
->data
);
539 //DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
540 des_dec(edata
, data
, key
->data
);
547 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
548 // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT);
549 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
550 tdes_enc(edata
,data
, key
->data
);
553 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
554 // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT);
555 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
556 tdes_dec(data
, edata
, key
->data
);
563 tdes_enc(edata
,data
, key
->data
);
564 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
565 // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT);
566 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_ENCRYPT);
569 tdes_dec(data
, edata
, key
->data
);
570 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_DECRYPT);
571 // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT);
572 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
582 AesCtxIni(&ctx
, ivect
, key
->data
, KEY128
,CBC
);
583 AesEncrypt(&ctx
, data
, edata
, sizeof(edata
) );
589 AesCtxIni(&ctx
, ivect
, key
->data
, KEY128
,CBC
);
590 AesDecrypt(&ctx
, edata
, data
, sizeof(edata
));
597 memcpy (data
, edata
, block_size
);
599 if (direction
== MCD_SEND
) {
600 memcpy (ivect
, data
, block_size
);
602 xor (ivect
, data
, block_size
);
603 memcpy (ivect
, ovect
, block_size
);
608 * This function performs all CBC cyphering / deciphering.
610 * The tag argument may be NULL, in which case both key and ivect shall be set.
611 * When using the tag session_key and ivect for processing data, these
612 * arguments should be set to NULL.
614 * Because the tag may contain additional data, one may need to call this
615 * function with tag, key and ivect defined.
617 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
) {
622 key
= DESFIRE (tag
)->session_key
;
624 ivect
= DESFIRE (tag
)->ivect
;
626 switch (DESFIRE (tag
)->authentication_scheme
) {
628 memset (ivect
, 0, MAX_CRYPTO_BLOCK_SIZE
);
635 block_size
= key_block_size (key
);
638 while (offset
< data_size
) {
639 mifare_cypher_single_block (key
, data
+ offset
, ivect
, direction
, operation
, block_size
);
640 offset
+= block_size
;