]> cvs.zerfleddert.de Git - proxmark3-svn/blame - armsrc/desfire_crypto.c
FIX: `hf mf sim` - authentication works again.
[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);
4a71da5a 87 free(buffer);
f38a1528 88}
89
90size_t key_block_size (const desfirekey_t key) {
91 size_t block_size = 8;
f38a1528 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 }
f38a1528 102 return block_size;
103}
104
105/*
106 * Size of MACing produced with the key.
107 */
108static size_t key_macing_length (const desfirekey_t key) {
109 size_t mac_length = MAC_LENGTH;
f38a1528 110 switch (key->type) {
111 case T_DES:
112 case T_3DES:
113 mac_length = MAC_LENGTH;
114 break;
115 case T_3K3DES:
116 case T_AES:
117 mac_length = CMAC_LENGTH;
118 break;
119 }
f38a1528 120 return mac_length;
121}
122
123/*
124 * Size required to store nbytes of data in a buffer of size n*block_size.
125 */
126size_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;
129 else
130 return nbytes;
131}
132
133/*
134 * Buffer size required to MAC nbytes of data
135 */
136size_t maced_data_length (const desfirekey_t key, const size_t nbytes) {
137 return nbytes + key_macing_length (key);
138}
139/*
140 * Buffer size required to encipher nbytes of data and a two bytes CRC.
141 */
142size_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) {
146 case AS_LEGACY:
147 crc_length = 2;
148 break;
149 case AS_NEW:
150 crc_length = 4;
151 break;
152 }
153 }
154
155 size_t block_size = DESFIRE(tag)->session_key ? key_block_size (DESFIRE(tag)->session_key) : 1;
156
157 return padded_data_length (nbytes + crc_length, block_size);
158}
159
60e26e50 160void* mifare_cryto_preprocess_data (desfiretag_t tag, void *data, size_t *nbytes, size_t offset, int communication_settings) {
f38a1528 161 uint8_t *res = data;
162 uint8_t mac[4];
163 size_t edl;
164 bool append_mac = true;
165 desfirekey_t key = DESFIRE(tag)->session_key;
166
167 if (!key)
168 return data;
169
170 switch (communication_settings & MDCM_MASK) {
171 case MDCM_PLAIN:
172 if (AS_LEGACY == DESFIRE(tag)->authentication_scheme)
173 break;
174
175 /*
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
179 * integrity later.
180 *
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.
183 */
184
185 append_mac = false;
186
187 /* pass through */
188 case MDCM_MACED:
189 switch (DESFIRE(tag)->authentication_scheme) {
190 case AS_LEGACY:
191 if (!(communication_settings & MAC_COMMAND))
192 break;
193
194 /* pass through */
195 edl = padded_data_length (*nbytes - offset, key_block_size (DESFIRE(tag)->session_key)) + offset;
196
197 // Fill in the crypto buffer with data ...
198 memcpy (res, data, *nbytes);
199 // ... and 0 padding
200 memset (res + *nbytes, 0, edl - *nbytes);
201
202 mifare_cypher_blocks_chained (tag, NULL, NULL, res + offset, edl - offset, MCD_SEND, MCO_ENCYPHER);
203
204 memcpy (mac, res + edl - 8, 4);
205
206 // Copy again provided data (was overwritten by mifare_cypher_blocks_chained)
207 memcpy (res, data, *nbytes);
208
209 if (!(communication_settings & MAC_COMMAND))
210 break;
211 // Append MAC
212 size_t bla = maced_data_length (DESFIRE(tag)->session_key, *nbytes - offset) + offset;
213 bla++;
214
215 memcpy (res + *nbytes, mac, 4);
216
217 *nbytes += 4;
218 break;
219 case AS_NEW:
220 if (!(communication_settings & CMAC_COMMAND))
221 break;
222 cmac (key, DESFIRE (tag)->ivect, res, *nbytes, DESFIRE (tag)->cmac);
223
224 if (append_mac) {
da198be4 225 size_t len = maced_data_length (key, *nbytes);
226 ++len;
f38a1528 227 memcpy (res, data, *nbytes);
228 memcpy (res + *nbytes, DESFIRE (tag)->cmac, CMAC_LENGTH);
229 *nbytes += CMAC_LENGTH;
230 }
231 break;
232 }
233
234 break;
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()
249 */
250
251 if (!(communication_settings & ENC_COMMAND))
252 break;
253 edl = enciphered_data_length (tag, *nbytes - offset, communication_settings) + offset;
254
255 // Fill in the crypto buffer with data ...
256 memcpy (res, data, *nbytes);
257 if (!(communication_settings & NO_CRC)) {
258 // ... CRC ...
259 switch (DESFIRE (tag)->authentication_scheme) {
260 case AS_LEGACY:
261 AppendCrc14443a(res + offset, *nbytes - offset);
262 *nbytes += 2;
263 break;
264 case AS_NEW:
265 crc32_append (res, *nbytes);
266 *nbytes += 4;
267 break;
268 }
269 }
270 // ... and padding
271 memset (res + *nbytes, 0, edl - *nbytes);
272
273 *nbytes = edl;
274
275 mifare_cypher_blocks_chained (tag, NULL, NULL, res + offset, *nbytes - offset, MCD_SEND, (AS_NEW == DESFIRE(tag)->authentication_scheme) ? MCO_ENCYPHER : MCO_DECYPHER);
276 break;
277 default:
278
279 *nbytes = -1;
280 res = NULL;
281 break;
282 }
283
284 return res;
285
286}
287
60e26e50 288void* mifare_cryto_postprocess_data (desfiretag_t tag, void *data, size_t *nbytes, int communication_settings)
f38a1528 289{
290 void *res = data;
291 size_t edl;
292 void *edata = NULL;
293 uint8_t first_cmac_byte = 0x00;
294
295 desfirekey_t key = DESFIRE(tag)->session_key;
296
297 if (!key)
298 return data;
299
300 // Return directly if we just have a status code.
301 if (1 == *nbytes)
302 return res;
303
304 switch (communication_settings & MDCM_MASK) {
305 case MDCM_PLAIN:
306
307 if (AS_LEGACY == DESFIRE(tag)->authentication_scheme)
308 break;
309
310 /* pass through */
311 case MDCM_MACED:
312 switch (DESFIRE (tag)->authentication_scheme) {
313 case AS_LEGACY:
314 if (communication_settings & MAC_VERIFY) {
315 *nbytes -= key_macing_length (key);
316 if (*nbytes <= 0) {
317 *nbytes = -1;
318 res = NULL;
319#ifdef WITH_DEBUG
8d0a3e87 320 Dbprintf ("No room for MAC!");
f38a1528 321#endif
322 break;
323 }
324
325 edl = enciphered_data_length (tag, *nbytes - 1, communication_settings);
326 edata = malloc (edl);
327
328 memcpy (edata, data, *nbytes - 1);
329 memset ((uint8_t *)edata + *nbytes - 1, 0, edl - *nbytes + 1);
330
331 mifare_cypher_blocks_chained (tag, NULL, NULL, edata, edl, MCD_SEND, MCO_ENCYPHER);
332
333 if (0 != memcmp ((uint8_t *)data + *nbytes - 1, (uint8_t *)edata + edl - 8, 4)) {
334#ifdef WITH_DEBUG
8d0a3e87 335 Dbprintf ("MACing not verified");
f38a1528 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);
338#endif
339 DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR;
340 *nbytes = -1;
341 res = NULL;
342 }
343 }
344 break;
345 case AS_NEW:
346 if (!(communication_settings & CMAC_COMMAND))
347 break;
348 if (communication_settings & CMAC_VERIFY) {
349 if (*nbytes < 9) {
350 *nbytes = -1;
351 res = NULL;
352 break;
353 }
354 first_cmac_byte = ((uint8_t *)data)[*nbytes - 9];
355 ((uint8_t *)data)[*nbytes - 9] = ((uint8_t *)data)[*nbytes-1];
356 }
357
358 int n = (communication_settings & CMAC_VERIFY) ? 8 : 0;
359 cmac (key, DESFIRE (tag)->ivect, ((uint8_t *)data), *nbytes - n, DESFIRE (tag)->cmac);
360
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)) {
364#ifdef WITH_DEBUG
8d0a3e87 365 Dbprintf ("CMAC NOT verified :-(");
f38a1528 366 hexdump ((uint8_t *)data + *nbytes - 9, 8, "Expect ", 0);
367 hexdump (DESFIRE (tag)->cmac, 8, "Actual ", 0);
368#endif
369 DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR;
370 *nbytes = -1;
371 res = NULL;
372 } else {
373 *nbytes -= 8;
374 }
375 }
376 break;
377 }
378
379 free (edata);
380
381 break;
382 case MDCM_ENCIPHERED:
383 (*nbytes)--;
384 bool verified = false;
385 int crc_pos = 0x00;
386 int end_crc_pos = 0x00;
387 uint8_t x;
388
389 /*
390 * AS_LEGACY:
391 * ,-----------------+-------------------------------+--------+
392 * \ BLOCK n-1 | BLOCK n | STATUS |
393 * / PAYLOAD | CRC0 | CRC1 | 0x80? | 0x000000000000 | 0x9100 |
394 * `-----------------+-------------------------------+--------+
395 *
396 * <------------ DATA ------------>
397 * FRAME = PAYLOAD + CRC(PAYLOAD) + PADDING
398 *
399 * AS_NEW:
400 * ,-------------------------------+-----------------------------------------------+--------+
401 * \ BLOCK n-1 | BLOCK n | STATUS |
402 * / PAYLOAD | CRC0 | CRC1 | CRC2 | CRC3 | 0x80? | 0x0000000000000000000000000000 | 0x9100 |
403 * `-------------------------------+-----------------------------------------------+--------+
404 * <----------------------------------- DATA ------------------------------------->|
405 *
406 * <----------------- DATA ---------------->
407 * FRAME = PAYLOAD + CRC(PAYLOAD + STATUS) + PADDING + STATUS
408 * `------------------'
409 */
410
411 mifare_cypher_blocks_chained (tag, NULL, NULL, res, *nbytes, MCD_RECEIVE, MCO_DECYPHER);
412
413 /*
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.
417 */
418 switch (DESFIRE (tag)->authentication_scheme) {
419 case AS_LEGACY:
420 crc_pos = *nbytes - 8 - 1; // The CRC can be over two blocks
421 if (crc_pos < 0) {
422 /* Single block */
423 crc_pos = 0;
424 }
425 break;
426 case AS_NEW:
427 /* Move status between payload and CRC */
428 res = DESFIRE (tag)->crypto_buffer;
429 memcpy (res, data, *nbytes);
430
431 crc_pos = (*nbytes) - 16 - 3;
432 if (crc_pos < 0) {
433 /* Single block */
434 crc_pos = 0;
435 }
436 memcpy ((uint8_t *)res + crc_pos + 1, (uint8_t *)res + crc_pos, *nbytes - crc_pos);
437 ((uint8_t *)res)[crc_pos] = 0x00;
438 crc_pos++;
439 *nbytes += 1;
440 break;
441 }
442
443 do {
444 uint16_t crc16 =0x00;
445 uint32_t crc;
446 switch (DESFIRE (tag)->authentication_scheme) {
447 case AS_LEGACY:
448 end_crc_pos = crc_pos + 2;
449 AppendCrc14443a (res, end_crc_pos);
450
451 //
452
453
454 crc = crc16;
455 break;
456 case AS_NEW:
457 end_crc_pos = crc_pos + 4;
53d5dc64 458 crc32_ex (res, end_crc_pos, (uint8_t *)&crc);
f38a1528 459 break;
460 }
461 if (!crc) {
462 verified = true;
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)) ))
466 verified = false;
467 }
468 }
469 if (verified) {
470 *nbytes = crc_pos;
471 switch (DESFIRE (tag)->authentication_scheme) {
472 case AS_LEGACY:
473 ((uint8_t *)data)[(*nbytes)++] = 0x00;
474 break;
475 case AS_NEW:
476 /* The status byte was already before the CRC */
477 break;
478 }
479 } else {
480 switch (DESFIRE (tag)->authentication_scheme) {
481 case AS_LEGACY:
482 break;
483 case AS_NEW:
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;
487 break;
488 }
489 crc_pos++;
490 }
491 } while (!verified && (end_crc_pos < *nbytes));
492
493 if (!verified) {
494#ifdef WITH_DEBUG
495 /* FIXME In some configurations, the file is transmitted PLAIN */
496 Dbprintf("CRC not verified in decyphered stream");
497#endif
498 DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR;
499 *nbytes = -1;
500 res = NULL;
501 }
502
503 break;
504 default:
505 Dbprintf("Unknown communication settings");
506 *nbytes = -1;
507 res = NULL;
508 break;
509
510 }
511 return res;
512}
513
514
515void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size)
516{
517 uint8_t ovect[MAX_CRYPTO_BLOCK_SIZE];
518
519 if (direction == MCD_SEND) {
520 xor (ivect, data, block_size);
521 } else {
522 memcpy (ovect, data, block_size);
523 }
524
525 uint8_t edata[MAX_CRYPTO_BLOCK_SIZE];
526
527 switch (key->type) {
528 case T_DES:
529 switch (operation) {
530 case MCO_ENCYPHER:
531 //DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
532 des_enc(edata, data, key->data);
533 break;
534 case MCO_DECYPHER:
535 //DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
536 des_dec(edata, data, key->data);
537 break;
538 }
539 break;
540 case T_3DES:
541 switch (operation) {
542 case MCO_ENCYPHER:
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);
547 break;
548 case MCO_DECYPHER:
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);
553 break;
554 }
555 break;
556 case T_3K3DES:
557 switch (operation) {
558 case MCO_ENCYPHER:
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);
563 break;
564 case MCO_DECYPHER:
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);
569 break;
570 }
571 break;
572 case T_AES:
573 switch (operation)
574 {
575 case MCO_ENCYPHER:
576 {
577 AesCtx ctx;
578 AesCtxIni(&ctx, ivect, key->data, KEY128,CBC);
aacb96d7 579 AesEncrypt(&ctx, data, edata, sizeof(edata) );
f38a1528 580 break;
581 }
582 case MCO_DECYPHER:
583 {
584 AesCtx ctx;
585 AesCtxIni(&ctx, ivect, key->data, KEY128,CBC);
586 AesDecrypt(&ctx, edata, data, sizeof(edata));
587 break;
588 }
589 }
590 break;
591 }
592
593 memcpy (data, edata, block_size);
594
595 if (direction == MCD_SEND) {
596 memcpy (ivect, data, block_size);
597 } else {
598 xor (ivect, data, block_size);
599 memcpy (ivect, ovect, block_size);
600 }
601}
602
603/*
604 * This function performs all CBC cyphering / deciphering.
605 *
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.
609 *
610 * Because the tag may contain additional data, one may need to call this
611 * function with tag, key and ivect defined.
612 */
613void mifare_cypher_blocks_chained (desfiretag_t tag, desfirekey_t key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation) {
614 size_t block_size;
615
616 if (tag) {
617 if (!key)
618 key = DESFIRE (tag)->session_key;
619 if (!ivect)
620 ivect = DESFIRE (tag)->ivect;
621
622 switch (DESFIRE (tag)->authentication_scheme) {
623 case AS_LEGACY:
624 memset (ivect, 0, MAX_CRYPTO_BLOCK_SIZE);
625 break;
626 case AS_NEW:
627 break;
628 }
629 }
630
631 block_size = key_block_size (key);
632
633 size_t offset = 0;
634 while (offset < data_size) {
635 mifare_cypher_single_block (key, data + offset, ivect, direction, operation, block_size);
636 offset += block_size;
637 }
638}
Impressum, Datenschutz