]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/desfire_crypto.c
FIX: Coverity, Unintended sign extension, data[7] would have become int, then uint64_...
[proxmark3-svn] / armsrc / desfire_crypto.c
CommitLineData
f38a1528 1/*-
2 * Copyright (C) 2010, Romain Tartiere.
3 *
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.
8 *
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
12 * more details.
13 *
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/>
16 *
17 * $Id$
18 */
19
20/*
21 * This implementation was written based on information provided by the
22 * following documents:
23 *
24 * NIST Special Publication 800-38B
25 * Recommendation for Block Cipher Modes of Operation: The CMAC Mode for Authentication
26 * May 2005
27 */
28#include "desfire_crypto.h"
29
7838f4be 30static void xor (const uint8_t *ivect, uint8_t *data, const size_t len);
31static size_t key_macing_length (desfirekey_t key);
f38a1528 32
33static void xor (const uint8_t *ivect, uint8_t *data, const size_t len) {
34 for (size_t i = 0; i < len; i++) {
35 data[i] ^= ivect[i];
36 }
37}
38
39void cmac_generate_subkeys ( desfirekey_t key) {
40 int kbs = key_block_size (key);
41 const uint8_t R = (kbs == 8) ? 0x1B : 0x87;
42
43 uint8_t l[kbs];
44 memset (l, 0, kbs);
45
46 uint8_t ivect[kbs];
47 memset (ivect, 0, kbs);
48
49 mifare_cypher_blocks_chained (NULL, key, ivect, l, kbs, MCD_RECEIVE, MCO_ENCYPHER);
50
51 bool xor = false;
52
53 // Used to compute CMAC on complete blocks
54 memcpy (key->cmac_sk1, l, kbs);
55 xor = l[0] & 0x80;
56 lsl (key->cmac_sk1, kbs);
57 if (xor)
58 key->cmac_sk1[kbs-1] ^= R;
59
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);
64 if (xor)
65 key->cmac_sk2[kbs-1] ^= R;
66}
67
68void 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));
71
72 memcpy (buffer, data, len);
73
74 if ((!len) || (len % kbs)) {
75 buffer[len++] = 0x80;
76 while (len % kbs) {
77 buffer[len++] = 0x00;
78 }
79 xor (key->cmac_sk2, buffer + len - kbs, kbs);
80 } else {
81 xor (key->cmac_sk1, buffer + len - kbs, kbs);
82 }
83
84 mifare_cypher_blocks_chained (NULL, key, ivect, buffer, len, MCD_SEND, MCO_ENCYPHER);
85
86 memcpy (cmac, ivect, kbs);
87}
88
89size_t key_block_size (const desfirekey_t key) {
90 size_t block_size = 8;
91
92 switch (key->type) {
93 case T_DES:
94 case T_3DES:
95 case T_3K3DES:
96 block_size = 8;
97 break;
98 case T_AES:
99 block_size = 16;
100 break;
101 }
102
103 return block_size;
104}
105
106/*
107 * Size of MACing produced with the key.
108 */
109static size_t key_macing_length (const desfirekey_t key) {
110 size_t mac_length = MAC_LENGTH;
111
112 switch (key->type) {
113 case T_DES:
114 case T_3DES:
115 mac_length = MAC_LENGTH;
116 break;
117 case T_3K3DES:
118 case T_AES:
119 mac_length = CMAC_LENGTH;
120 break;
121 }
122
123 return mac_length;
124}
125
126/*
127 * Size required to store nbytes of data in a buffer of size n*block_size.
128 */
129size_t padded_data_length (const size_t nbytes, const size_t block_size) {
130 if ((!nbytes) || (nbytes % block_size))
131 return ((nbytes / block_size) + 1) * block_size;
132 else
133 return nbytes;
134}
135
136/*
137 * Buffer size required to MAC nbytes of data
138 */
139size_t maced_data_length (const desfirekey_t key, const size_t nbytes) {
140 return nbytes + key_macing_length (key);
141}
142/*
143 * Buffer size required to encipher nbytes of data and a two bytes CRC.
144 */
145size_t enciphered_data_length (const desfiretag_t tag, const size_t nbytes, int communication_settings) {
146 size_t crc_length = 0;
147 if (!(communication_settings & NO_CRC)) {
148 switch (DESFIRE(tag)->authentication_scheme) {
149 case AS_LEGACY:
150 crc_length = 2;
151 break;
152 case AS_NEW:
153 crc_length = 4;
154 break;
155 }
156 }
157
158 size_t block_size = DESFIRE(tag)->session_key ? key_block_size (DESFIRE(tag)->session_key) : 1;
159
160 return padded_data_length (nbytes + crc_length, block_size);
161}
162
163void* mifare_cryto_preprocess_data (desfiretag_t tag, void *data, size_t *nbytes, off_t offset, int communication_settings) {
164 uint8_t *res = data;
165 uint8_t mac[4];
166 size_t edl;
167 bool append_mac = true;
168 desfirekey_t key = DESFIRE(tag)->session_key;
169
170 if (!key)
171 return data;
172
173 switch (communication_settings & MDCM_MASK) {
174 case MDCM_PLAIN:
175 if (AS_LEGACY == DESFIRE(tag)->authentication_scheme)
176 break;
177
178 /*
179 * When using new authentication methods, PLAIN data transmission from
180 * the PICC to the PCD are CMACed, so we have to maintain the
181 * cryptographic initialisation vector up-to-date to check data
182 * integrity later.
183 *
184 * The only difference with CMACed data transmission is that the CMAC
185 * is not apended to the data send by the PCD to the PICC.
186 */
187
188 append_mac = false;
189
190 /* pass through */
191 case MDCM_MACED:
192 switch (DESFIRE(tag)->authentication_scheme) {
193 case AS_LEGACY:
194 if (!(communication_settings & MAC_COMMAND))
195 break;
196
197 /* pass through */
198 edl = padded_data_length (*nbytes - offset, key_block_size (DESFIRE(tag)->session_key)) + offset;
199
200 // Fill in the crypto buffer with data ...
201 memcpy (res, data, *nbytes);
202 // ... and 0 padding
203 memset (res + *nbytes, 0, edl - *nbytes);
204
205 mifare_cypher_blocks_chained (tag, NULL, NULL, res + offset, edl - offset, MCD_SEND, MCO_ENCYPHER);
206
207 memcpy (mac, res + edl - 8, 4);
208
209 // Copy again provided data (was overwritten by mifare_cypher_blocks_chained)
210 memcpy (res, data, *nbytes);
211
212 if (!(communication_settings & MAC_COMMAND))
213 break;
214 // Append MAC
215 size_t bla = maced_data_length (DESFIRE(tag)->session_key, *nbytes - offset) + offset;
216 bla++;
217
218 memcpy (res + *nbytes, mac, 4);
219
220 *nbytes += 4;
221 break;
222 case AS_NEW:
223 if (!(communication_settings & CMAC_COMMAND))
224 break;
225 cmac (key, DESFIRE (tag)->ivect, res, *nbytes, DESFIRE (tag)->cmac);
226
227 if (append_mac) {
228 maced_data_length (key, *nbytes);
229
230 memcpy (res, data, *nbytes);
231 memcpy (res + *nbytes, DESFIRE (tag)->cmac, CMAC_LENGTH);
232 *nbytes += CMAC_LENGTH;
233 }
234 break;
235 }
236
237 break;
238 case MDCM_ENCIPHERED:
239 /* |<-------------- data -------------->|
240 * |<--- offset -->| |
241 * +---------------+--------------------+-----+---------+
242 * | CMD + HEADERS | DATA TO BE SECURED | CRC | PADDING |
243 * +---------------+--------------------+-----+---------+ ----------------
244 * | |<~~~~v~~~~~~~~~~~~~>| ^ | | (DES / 3DES)
245 * | | `---- crc16() ----' | |
246 * | | | ^ | | ----- *or* -----
247 * |<~~~~~~~~~~~~~~~~~~~~v~~~~~~~~~~~~~>| ^ | | (3K3DES / AES)
248 * | `---- crc32() ----' | |
249 * | | ---- *then* ----
250 * |<---------------------------------->|
251 * encypher()/decypher()
252 */
253
254 if (!(communication_settings & ENC_COMMAND))
255 break;
256 edl = enciphered_data_length (tag, *nbytes - offset, communication_settings) + offset;
257
258 // Fill in the crypto buffer with data ...
259 memcpy (res, data, *nbytes);
260 if (!(communication_settings & NO_CRC)) {
261 // ... CRC ...
262 switch (DESFIRE (tag)->authentication_scheme) {
263 case AS_LEGACY:
264 AppendCrc14443a(res + offset, *nbytes - offset);
265 *nbytes += 2;
266 break;
267 case AS_NEW:
268 crc32_append (res, *nbytes);
269 *nbytes += 4;
270 break;
271 }
272 }
273 // ... and padding
274 memset (res + *nbytes, 0, edl - *nbytes);
275
276 *nbytes = edl;
277
278 mifare_cypher_blocks_chained (tag, NULL, NULL, res + offset, *nbytes - offset, MCD_SEND, (AS_NEW == DESFIRE(tag)->authentication_scheme) ? MCO_ENCYPHER : MCO_DECYPHER);
279 break;
280 default:
281
282 *nbytes = -1;
283 res = NULL;
284 break;
285 }
286
287 return res;
288
289}
290
291void* mifare_cryto_postprocess_data (desfiretag_t tag, void *data, ssize_t *nbytes, int communication_settings)
292{
293 void *res = data;
294 size_t edl;
295 void *edata = NULL;
296 uint8_t first_cmac_byte = 0x00;
297
298 desfirekey_t key = DESFIRE(tag)->session_key;
299
300 if (!key)
301 return data;
302
303 // Return directly if we just have a status code.
304 if (1 == *nbytes)
305 return res;
306
307 switch (communication_settings & MDCM_MASK) {
308 case MDCM_PLAIN:
309
310 if (AS_LEGACY == DESFIRE(tag)->authentication_scheme)
311 break;
312
313 /* pass through */
314 case MDCM_MACED:
315 switch (DESFIRE (tag)->authentication_scheme) {
316 case AS_LEGACY:
317 if (communication_settings & MAC_VERIFY) {
318 *nbytes -= key_macing_length (key);
319 if (*nbytes <= 0) {
320 *nbytes = -1;
321 res = NULL;
322#ifdef WITH_DEBUG
8d0a3e87 323 Dbprintf ("No room for MAC!");
f38a1528 324#endif
325 break;
326 }
327
328 edl = enciphered_data_length (tag, *nbytes - 1, communication_settings);
329 edata = malloc (edl);
330
331 memcpy (edata, data, *nbytes - 1);
332 memset ((uint8_t *)edata + *nbytes - 1, 0, edl - *nbytes + 1);
333
334 mifare_cypher_blocks_chained (tag, NULL, NULL, edata, edl, MCD_SEND, MCO_ENCYPHER);
335
336 if (0 != memcmp ((uint8_t *)data + *nbytes - 1, (uint8_t *)edata + edl - 8, 4)) {
337#ifdef WITH_DEBUG
8d0a3e87 338 Dbprintf ("MACing not verified");
f38a1528 339 hexdump ((uint8_t *)data + *nbytes - 1, key_macing_length (key), "Expect ", 0);
340 hexdump ((uint8_t *)edata + edl - 8, key_macing_length (key), "Actual ", 0);
341#endif
342 DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR;
343 *nbytes = -1;
344 res = NULL;
345 }
346 }
347 break;
348 case AS_NEW:
349 if (!(communication_settings & CMAC_COMMAND))
350 break;
351 if (communication_settings & CMAC_VERIFY) {
352 if (*nbytes < 9) {
353 *nbytes = -1;
354 res = NULL;
355 break;
356 }
357 first_cmac_byte = ((uint8_t *)data)[*nbytes - 9];
358 ((uint8_t *)data)[*nbytes - 9] = ((uint8_t *)data)[*nbytes-1];
359 }
360
361 int n = (communication_settings & CMAC_VERIFY) ? 8 : 0;
362 cmac (key, DESFIRE (tag)->ivect, ((uint8_t *)data), *nbytes - n, DESFIRE (tag)->cmac);
363
364 if (communication_settings & CMAC_VERIFY) {
365 ((uint8_t *)data)[*nbytes - 9] = first_cmac_byte;
366 if (0 != memcmp (DESFIRE (tag)->cmac, (uint8_t *)data + *nbytes - 9, 8)) {
367#ifdef WITH_DEBUG
8d0a3e87 368 Dbprintf ("CMAC NOT verified :-(");
f38a1528 369 hexdump ((uint8_t *)data + *nbytes - 9, 8, "Expect ", 0);
370 hexdump (DESFIRE (tag)->cmac, 8, "Actual ", 0);
371#endif
372 DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR;
373 *nbytes = -1;
374 res = NULL;
375 } else {
376 *nbytes -= 8;
377 }
378 }
379 break;
380 }
381
382 free (edata);
383
384 break;
385 case MDCM_ENCIPHERED:
386 (*nbytes)--;
387 bool verified = false;
388 int crc_pos = 0x00;
389 int end_crc_pos = 0x00;
390 uint8_t x;
391
392 /*
393 * AS_LEGACY:
394 * ,-----------------+-------------------------------+--------+
395 * \ BLOCK n-1 | BLOCK n | STATUS |
396 * / PAYLOAD | CRC0 | CRC1 | 0x80? | 0x000000000000 | 0x9100 |
397 * `-----------------+-------------------------------+--------+
398 *
399 * <------------ DATA ------------>
400 * FRAME = PAYLOAD + CRC(PAYLOAD) + PADDING
401 *
402 * AS_NEW:
403 * ,-------------------------------+-----------------------------------------------+--------+
404 * \ BLOCK n-1 | BLOCK n | STATUS |
405 * / PAYLOAD | CRC0 | CRC1 | CRC2 | CRC3 | 0x80? | 0x0000000000000000000000000000 | 0x9100 |
406 * `-------------------------------+-----------------------------------------------+--------+
407 * <----------------------------------- DATA ------------------------------------->|
408 *
409 * <----------------- DATA ---------------->
410 * FRAME = PAYLOAD + CRC(PAYLOAD + STATUS) + PADDING + STATUS
411 * `------------------'
412 */
413
414 mifare_cypher_blocks_chained (tag, NULL, NULL, res, *nbytes, MCD_RECEIVE, MCO_DECYPHER);
415
416 /*
417 * Look for the CRC and ensure it is followed by NULL padding. We
418 * can't start by the end because the CRC is supposed to be 0 when
419 * verified, and accumulating 0's in it should not change it.
420 */
421 switch (DESFIRE (tag)->authentication_scheme) {
422 case AS_LEGACY:
423 crc_pos = *nbytes - 8 - 1; // The CRC can be over two blocks
424 if (crc_pos < 0) {
425 /* Single block */
426 crc_pos = 0;
427 }
428 break;
429 case AS_NEW:
430 /* Move status between payload and CRC */
431 res = DESFIRE (tag)->crypto_buffer;
432 memcpy (res, data, *nbytes);
433
434 crc_pos = (*nbytes) - 16 - 3;
435 if (crc_pos < 0) {
436 /* Single block */
437 crc_pos = 0;
438 }
439 memcpy ((uint8_t *)res + crc_pos + 1, (uint8_t *)res + crc_pos, *nbytes - crc_pos);
440 ((uint8_t *)res)[crc_pos] = 0x00;
441 crc_pos++;
442 *nbytes += 1;
443 break;
444 }
445
446 do {
447 uint16_t crc16 =0x00;
448 uint32_t crc;
449 switch (DESFIRE (tag)->authentication_scheme) {
450 case AS_LEGACY:
451 end_crc_pos = crc_pos + 2;
452 AppendCrc14443a (res, end_crc_pos);
453
454 //
455
456
457 crc = crc16;
458 break;
459 case AS_NEW:
460 end_crc_pos = crc_pos + 4;
461 crc32 (res, end_crc_pos, (uint8_t *)&crc);
462 break;
463 }
464 if (!crc) {
465 verified = true;
466 for (int n = end_crc_pos; n < *nbytes - 1; n++) {
467 uint8_t byte = ((uint8_t *)res)[n];
468 if (!( (0x00 == byte) || ((0x80 == byte) && (n == end_crc_pos)) ))
469 verified = false;
470 }
471 }
472 if (verified) {
473 *nbytes = crc_pos;
474 switch (DESFIRE (tag)->authentication_scheme) {
475 case AS_LEGACY:
476 ((uint8_t *)data)[(*nbytes)++] = 0x00;
477 break;
478 case AS_NEW:
479 /* The status byte was already before the CRC */
480 break;
481 }
482 } else {
483 switch (DESFIRE (tag)->authentication_scheme) {
484 case AS_LEGACY:
485 break;
486 case AS_NEW:
487 x = ((uint8_t *)res)[crc_pos - 1];
488 ((uint8_t *)res)[crc_pos - 1] = ((uint8_t *)res)[crc_pos];
489 ((uint8_t *)res)[crc_pos] = x;
490 break;
491 }
492 crc_pos++;
493 }
494 } while (!verified && (end_crc_pos < *nbytes));
495
496 if (!verified) {
497#ifdef WITH_DEBUG
498 /* FIXME In some configurations, the file is transmitted PLAIN */
499 Dbprintf("CRC not verified in decyphered stream");
500#endif
501 DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR;
502 *nbytes = -1;
503 res = NULL;
504 }
505
506 break;
507 default:
508 Dbprintf("Unknown communication settings");
509 *nbytes = -1;
510 res = NULL;
511 break;
512
513 }
514 return res;
515}
516
517
518void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size)
519{
520 uint8_t ovect[MAX_CRYPTO_BLOCK_SIZE];
521
522 if (direction == MCD_SEND) {
523 xor (ivect, data, block_size);
524 } else {
525 memcpy (ovect, data, block_size);
526 }
527
528 uint8_t edata[MAX_CRYPTO_BLOCK_SIZE];
529
530 switch (key->type) {
531 case T_DES:
532 switch (operation) {
533 case MCO_ENCYPHER:
534 //DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
535 des_enc(edata, data, key->data);
536 break;
537 case MCO_DECYPHER:
538 //DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
539 des_dec(edata, data, key->data);
540 break;
541 }
542 break;
543 case T_3DES:
544 switch (operation) {
545 case MCO_ENCYPHER:
546 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
547 // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT);
548 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
549 tdes_enc(edata,data, key->data);
550 break;
551 case MCO_DECYPHER:
552 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
553 // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT);
554 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
555 tdes_dec(data, edata, key->data);
556 break;
557 }
558 break;
559 case T_3K3DES:
560 switch (operation) {
561 case MCO_ENCYPHER:
562 tdes_enc(edata,data, key->data);
563 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
564 // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT);
565 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_ENCRYPT);
566 break;
567 case MCO_DECYPHER:
568 tdes_dec(data, edata, key->data);
569 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_DECRYPT);
570 // DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT);
571 // DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
572 break;
573 }
574 break;
575 case T_AES:
576 switch (operation)
577 {
578 case MCO_ENCYPHER:
579 {
580 AesCtx ctx;
581 AesCtxIni(&ctx, ivect, key->data, KEY128,CBC);
582 AesEncrypt(&ctx, data, edata, sizeof(data) );
583 break;
584 }
585 case MCO_DECYPHER:
586 {
587 AesCtx ctx;
588 AesCtxIni(&ctx, ivect, key->data, KEY128,CBC);
589 AesDecrypt(&ctx, edata, data, sizeof(edata));
590 break;
591 }
592 }
593 break;
594 }
595
596 memcpy (data, edata, block_size);
597
598 if (direction == MCD_SEND) {
599 memcpy (ivect, data, block_size);
600 } else {
601 xor (ivect, data, block_size);
602 memcpy (ivect, ovect, block_size);
603 }
604}
605
606/*
607 * This function performs all CBC cyphering / deciphering.
608 *
609 * The tag argument may be NULL, in which case both key and ivect shall be set.
610 * When using the tag session_key and ivect for processing data, these
611 * arguments should be set to NULL.
612 *
613 * Because the tag may contain additional data, one may need to call this
614 * function with tag, key and ivect defined.
615 */
616void mifare_cypher_blocks_chained (desfiretag_t tag, desfirekey_t key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation) {
617 size_t block_size;
618
619 if (tag) {
620 if (!key)
621 key = DESFIRE (tag)->session_key;
622 if (!ivect)
623 ivect = DESFIRE (tag)->ivect;
624
625 switch (DESFIRE (tag)->authentication_scheme) {
626 case AS_LEGACY:
627 memset (ivect, 0, MAX_CRYPTO_BLOCK_SIZE);
628 break;
629 case AS_NEW:
630 break;
631 }
632 }
633
634 block_size = key_block_size (key);
635
636 size_t offset = 0;
637 while (offset < data_size) {
638 mifare_cypher_single_block (key, data + offset, ivect, direction, operation, block_size);
639 offset += block_size;
640 }
641}
Impressum, Datenschutz