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