Merge pull request #2654 from Antiklesys/master
[RRG-proxmark3.git] / client / src / mifare / desfirecrypto.c
blob6263c23215df162814997d88ad362e20a4a66650
1 //-----------------------------------------------------------------------------
2 // Borrowed initially from https://github.com/nfc-tools/libfreefare
3 // Copyright (C) 2010, Romain Tartiere.
4 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // See LICENSE.txt for the text of the license.
17 //-----------------------------------------------------------------------------
19 #include "desfirecrypto.h"
21 #include <stdlib.h>
22 #include <string.h>
23 #include <util.h>
24 #include "ui.h"
25 #include "aes.h"
26 #include "des.h"
27 #include <mbedtls/cmac.h>
28 #include "crc.h"
29 #include "crc16.h" // crc16 ccitt
30 #include "crc32.h"
31 #include "commonutil.h"
32 #include "desfirecore.h" // DESFIRE_BUFFER_SIZE
34 void DesfireClearContext(DesfireContext_t *ctx) {
35 ctx->keyNum = 0;
36 ctx->keyType = T_DES;
37 memset(ctx->key, 0, sizeof(ctx->key));
39 ctx->secureChannel = DACNone;
40 ctx->cmdSet = DCCNative;
41 ctx->commMode = DCMNone;
43 ctx->isoChaining = false;
44 ctx->appSelected = false;
45 ctx->selectedAID = 0;
47 memset(ctx->uid, 0, sizeof(ctx->uid));
48 ctx->uidlen = 0;
50 ctx->kdfAlgo = 0;
51 ctx->kdfInputLen = 0;
52 memset(ctx->kdfInput, 0, sizeof(ctx->kdfInput));
54 DesfireClearSession(ctx);
57 void DesfireClearSession(DesfireContext_t *ctx) {
58 ctx->secureChannel = DACNone; // here none - not authenticared
60 memset(ctx->IV, 0, sizeof(ctx->IV));
61 memset(ctx->sessionKeyMAC, 0, sizeof(ctx->sessionKeyMAC));
62 memset(ctx->sessionKeyEnc, 0, sizeof(ctx->sessionKeyEnc));
63 memset(ctx->lastIV, 0, sizeof(ctx->lastIV));
64 ctx->lastCommand = 0;
65 ctx->lastRequestZeroLen = false;
66 ctx->cmdCntr = 0;
67 memset(ctx->TI, 0, sizeof(ctx->TI));
70 void DesfireClearIV(DesfireContext_t *ctx) {
71 memset(ctx->IV, 0, sizeof(ctx->IV));
74 void DesfireSetKey(DesfireContext_t *ctx, uint8_t keyNum, DesfireCryptoAlgorithm keyType, uint8_t *key) {
75 DesfireClearContext(ctx);
76 if (key == NULL)
77 return;
79 DesfireSetKeyNoClear(ctx, keyNum, keyType, key);
82 void DesfireSetKeyNoClear(DesfireContext_t *ctx, uint8_t keyNum, DesfireCryptoAlgorithm keyType, uint8_t *key) {
84 if (key == NULL)
85 return;
87 ctx->keyNum = keyNum;
88 ctx->keyType = keyType;
89 memcpy(ctx->key, key, desfire_get_key_length(keyType));
90 memcpy(ctx->masterKey, key, desfire_get_key_length(keyType));
93 void DesfireSetCommandSet(DesfireContext_t *ctx, DesfireCommandSet cmdSet) {
94 ctx->cmdSet = cmdSet;
97 void DesfireSetCommMode(DesfireContext_t *ctx, DesfireCommunicationMode commMode) {
98 ctx->commMode = commMode;
101 void DesfireSetKdf(DesfireContext_t *ctx, uint8_t kdfAlgo, uint8_t *kdfInput, uint8_t kdfInputLen) {
102 ctx->kdfAlgo = kdfAlgo;
103 ctx->kdfInputLen = kdfInputLen;
104 if (kdfInputLen) {
105 memcpy(ctx->kdfInput, kdfInput, kdfInputLen);
109 bool DesfireIsAuthenticated(DesfireContext_t *dctx) {
110 return dctx->secureChannel != DACNone;
113 size_t DesfireGetMACLength(DesfireContext_t *ctx) {
114 size_t mac_length = DESFIRE_MAC_LENGTH;
115 switch (ctx->secureChannel) {
116 case DACNone:
117 mac_length = 0;
118 break;
119 case DACd40:
120 mac_length = 4;
121 break;
122 case DACEV1:
123 mac_length = 8;
124 break;
125 case DACEV2:
126 mac_length = 8;
127 break;
128 case DACLRP:
129 mac_length = 8;
130 break;
132 return mac_length;
135 size_t DesfireSearchCRCPos(uint8_t *data, size_t datalen, uint8_t respcode, uint8_t crclen) {
136 size_t crcpos = datalen - 1;
138 while (crcpos > 0) {
139 if (data[crcpos] == 0) {
140 crcpos--;
141 } else {
142 break;
146 crcpos++; // crc may be 0x00000000 or 0x0000
147 if (crcpos < crclen) {
148 PrintAndLogEx(WARNING, "No space for crc. pos %zu", crcpos);
149 return 0;
152 uint8_t crcdata[DESFIRE_BUFFER_SIZE] = {0};
153 size_t crcposfound = 0;
154 // crc may be 00..00 and at the end of file may be padding 0x80. so we search from last zero to crclen + 2 (one for crc=0 and one for padding 0x80)
155 for (int i = 0; i < crclen + 2; i++) {
157 if (crcpos - i == 0) {
158 break;
161 if (crcpos - i + crclen > datalen) {
162 continue;
165 memcpy(crcdata, data, crcpos - i);
166 crcdata[crcpos - i] = respcode;
168 bool res;
169 if (crclen == 4) {
170 res = desfire_crc32_check(crcdata, crcpos - i + 1, &data[crcpos - i]);
171 } else {
172 res = iso14443a_crc_check(data, crcpos - i, &data[crcpos - i]);
175 if (res) {
176 crcposfound = crcpos - i;
180 return crcposfound;
183 uint8_t *DesfireGetKey(DesfireContext_t *ctx, DesfireCryptoOpKeyType key_type) {
184 if (key_type == DCOSessionKeyMac) {
185 return ctx->sessionKeyMAC;
186 } else if (key_type == DCOSessionKeyEnc) {
187 return ctx->sessionKeyEnc;
188 } else if (key_type == DCOMasterKey) {
189 return ctx->masterKey;
192 return ctx->key;
196 static void DesfireCryptoEncDecSingleBlock(uint8_t *key, DesfireCryptoAlgorithm keyType, uint8_t *data, uint8_t *dstdata, uint8_t *ivect, bool dir_to_send, bool encode) {
197 size_t block_size = desfire_get_key_block_length(keyType);
198 uint8_t sdata[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
199 memcpy(sdata, data, block_size);
200 if (dir_to_send) {
201 bin_xor(sdata, ivect, block_size);
204 uint8_t edata[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
206 switch (keyType) {
207 case T_DES:
208 if (encode)
209 des_encrypt(edata, sdata, key);
210 else
211 des_decrypt(edata, sdata, key);
212 break;
213 case T_3DES:
214 if (encode) {
215 mbedtls_des3_context ctx3;
216 mbedtls_des3_set2key_enc(&ctx3, key);
217 mbedtls_des3_crypt_ecb(&ctx3, sdata, edata);
218 } else {
219 mbedtls_des3_context ctx3;
220 mbedtls_des3_set2key_dec(&ctx3, key);
221 mbedtls_des3_crypt_ecb(&ctx3, sdata, edata);
223 break;
224 case T_3K3DES:
225 if (encode) {
226 mbedtls_des3_context ctx3;
227 mbedtls_des3_set3key_enc(&ctx3, key);
228 mbedtls_des3_crypt_ecb(&ctx3, sdata, edata);
229 } else {
230 mbedtls_des3_context ctx3;
231 mbedtls_des3_set3key_dec(&ctx3, key);
232 mbedtls_des3_crypt_ecb(&ctx3, sdata, edata);
234 break;
235 case T_AES:
236 if (encode) {
237 mbedtls_aes_context actx;
238 mbedtls_aes_init(&actx);
239 mbedtls_aes_setkey_enc(&actx, key, 128);
240 mbedtls_aes_crypt_ecb(&actx, MBEDTLS_AES_ENCRYPT, sdata, edata);
241 mbedtls_aes_free(&actx);
242 } else {
243 mbedtls_aes_context actx;
244 mbedtls_aes_init(&actx);
245 mbedtls_aes_setkey_dec(&actx, key, 128);
246 mbedtls_aes_crypt_ecb(&actx, MBEDTLS_AES_DECRYPT, sdata, edata);
247 mbedtls_aes_free(&actx);
249 break;
252 if (dir_to_send) {
253 memcpy(ivect, edata, block_size);
254 } else {
255 bin_xor(edata, ivect, block_size);
256 memcpy(ivect, data, block_size);
259 memcpy(dstdata, edata, block_size);
262 void DesfireCryptoEncDecEx(DesfireContext_t *ctx, DesfireCryptoOpKeyType key_type, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool dir_to_send, bool encode, uint8_t *iv) {
264 uint8_t data[DESFIRE_BUFFER_SIZE] = {0};
265 uint8_t xiv[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
267 if (ctx->secureChannel == DACd40) {
268 memset(ctx->IV, 0, DESFIRE_MAX_CRYPTO_BLOCK_SIZE);
271 size_t block_size = desfire_get_key_block_length(ctx->keyType);
273 if (iv == NULL)
274 memcpy(xiv, ctx->IV, block_size);
275 else
276 memcpy(xiv, iv, block_size);
278 uint8_t *key = DesfireGetKey(ctx, key_type);
279 if (key == NULL)
280 return;
282 if (ctx->secureChannel == DACLRP) {
283 size_t dstlen = 0;
284 LRPEncDec(key, xiv, encode, srcdata, srcdatalen, data, &dstlen);
285 } else {
286 size_t offset = 0;
287 while (offset < srcdatalen) {
288 DesfireCryptoEncDecSingleBlock(key, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode);
290 offset += block_size;
294 if (iv == NULL)
295 memcpy(ctx->IV, xiv, block_size);
296 else
297 memcpy(iv, xiv, block_size);
299 if (dstdata) {
300 memcpy(dstdata, data, srcdatalen);
304 void DesfireCryptoEncDec(DesfireContext_t *ctx, DesfireCryptoOpKeyType key_type, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode) {
305 bool dir_to_send = encode;
306 bool xencode = encode;
307 if (ctx->secureChannel == DACd40) {
308 xencode = false;
311 DesfireCryptoEncDecEx(ctx, key_type, srcdata, srcdatalen, dstdata, dir_to_send, xencode, NULL);
314 void DesfireCMACGenerateSubkeys(DesfireContext_t *ctx, DesfireCryptoOpKeyType key_type, uint8_t *sk1, uint8_t *sk2) {
315 int kbs = desfire_get_key_block_length(ctx->keyType);
316 const uint8_t R = (kbs == 8) ? 0x1B : 0x87;
318 uint8_t l[kbs];
319 memset(l, 0, kbs);
321 uint8_t ivect[kbs];
322 memset(ivect, 0, kbs);
324 DesfireCryptoEncDecEx(ctx, key_type, l, kbs, l, true, true, ivect);
326 bool txor = false;
328 // Used to compute CMAC on complete blocks
329 memcpy(sk1, l, kbs);
330 txor = l[0] & 0x80;
331 lsl(sk1, kbs);
332 if (txor) {
333 sk1[kbs - 1] ^= R;
336 // Used to compute CMAC on the last block if non-complete
337 memcpy(sk2, sk1, kbs);
338 txor = sk1[0] & 0x80;
339 lsl(sk2, kbs);
340 if (txor) {
341 sk2[kbs - 1] ^= R;
345 void DesfireCryptoCMACEx(DesfireContext_t *ctx, DesfireCryptoOpKeyType key_type, uint8_t *data, size_t len, size_t minlen, uint8_t *cmac) {
346 int kbs = desfire_get_key_block_length(ctx->keyType);
347 if (kbs == 0) {
348 return;
351 uint8_t buffer[padded_data_length(MAX(minlen, len) + 1, kbs)];
352 memset(buffer, 0, sizeof(buffer));
354 uint8_t sk1[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
355 uint8_t sk2[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
356 DesfireCMACGenerateSubkeys(ctx, key_type, sk1, sk2);
358 memcpy(buffer, data, len);
360 if ((!len) || (len % kbs) || (len < minlen)) {
361 buffer[len++] = 0x80;
362 while (len % kbs || len < minlen) {
363 buffer[len++] = 0x00;
365 bin_xor(buffer + len - kbs, sk2, kbs);
366 } else {
367 bin_xor(buffer + len - kbs, sk1, kbs);
370 DesfireCryptoEncDec(ctx, key_type, buffer, len, NULL, true);
372 if (cmac != NULL) {
373 memcpy(cmac, ctx->IV, kbs);
377 void DesfireCryptoCMAC(DesfireContext_t *ctx, uint8_t *data, size_t len, uint8_t *cmac) {
378 DesfireCryptoCMACEx(ctx, DCOSessionKeyMac, data, len, 0, cmac);
381 // This function is almot like cmac(...). but with some key differences.
382 void MifareKdfAn10922(DesfireContext_t *ctx, DesfireCryptoOpKeyType key_type, const uint8_t *data, size_t len) {
383 if (ctx == NULL || data == NULL || len < 1 || len > 31)
384 return;
386 int kbs = desfire_get_key_block_length(ctx->keyType); // 8 or 16
387 if (kbs == 0) {
388 return;
391 uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE * 3] = {0};
392 uint8_t buffer[DESFIRE_MAX_CRYPTO_BLOCK_SIZE * 3] = {0};
394 if (ctx->keyType == T_AES) {
395 // AES uses 16 byte IV
396 if (kbs < CRYPTO_AES_BLOCK_SIZE) {
397 kbs = CRYPTO_AES_BLOCK_SIZE;
400 buffer[0] = 0x01;
401 memcpy(&buffer[1], data, len);
403 DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, cmac);
404 memcpy(ctx->key, cmac, kbs);
405 } else if (ctx->keyType == T_3DES) {
406 buffer[0] = 0x21;
407 memcpy(&buffer[1], data, len);
409 DesfireClearIV(ctx);
410 DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, cmac);
412 buffer[0] = 0x22;
413 memcpy(&buffer[1], data, len);
415 DesfireClearIV(ctx);
416 DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, &cmac[kbs]);
418 memcpy(ctx->key, cmac, kbs * 2);
419 } else if (ctx->keyType == T_3K3DES) {
420 buffer[0] = 0x31;
421 memcpy(&buffer[1], data, len);
423 DesfireClearIV(ctx);
424 DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, cmac);
426 buffer[0] = 0x32;
427 memcpy(&buffer[1], data, len);
429 DesfireClearIV(ctx);
430 DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, &cmac[kbs]);
432 buffer[0] = 0x33;
433 memcpy(&buffer[1], data, len);
435 DesfireClearIV(ctx);
436 DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, &cmac[kbs * 2]);
438 memcpy(ctx->key, cmac, kbs * 3);
442 void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorithm keytype, uint8_t version) {
443 if (keytype == T_AES)
444 return;
446 // clear version
447 for (int n = 0; n < desfire_get_key_length(keytype); n++) {
448 key[n] &= 0xFE;
451 // set version
452 for (int n = 0; n < 8; n++) {
453 uint8_t version_bit = ((version & (1 << (7 - n))) >> (7 - n));
455 key[n] &= 0xFE;
456 key[n] |= version_bit;
458 if (keytype == T_DES) {
459 key[n + 8] = key[n];
460 } else {
461 // Write ~version to avoid turning a 3DES key into a DES key
462 key[n + 8] &= 0xFE;
463 key[n + 8] |= (~version_bit) & 0x01;
468 uint8_t DesfireDESKeyGetVersion(const uint8_t *key) {
469 uint8_t version = 0;
470 for (int n = 0; n < 8; n++) {
471 version |= ((key[n] & 1) << (7 - n));
474 return version;
477 DesfireCryptoAlgorithm DesfireKeyTypeToAlgo(uint8_t keyType) {
478 switch (keyType) {
479 case 00:
480 return T_3DES;
481 case 01:
482 return T_3K3DES;
483 case 02:
484 return T_AES;
485 default:
486 return T_3DES; // unknown....
490 uint8_t DesfireKeyAlgoToType(DesfireCryptoAlgorithm keyType) {
491 switch (keyType) {
492 case T_DES:
493 return 0x00;
494 case T_3DES:
495 return 0x00;
496 case T_3K3DES:
497 return 0x01;
498 case T_AES:
499 return 0x02;
501 return 0;
504 void DesfirePrintCardKeyType(uint8_t keyType) {
505 switch (keyType) {
506 case 00:
507 PrintAndLogEx(SUCCESS, "Key: 2TDEA");
508 break;
509 case 01:
510 PrintAndLogEx(SUCCESS, "Key: 3TDEA");
511 break;
512 case 02:
513 PrintAndLogEx(SUCCESS, "Key: AES");
514 break;
515 default:
516 PrintAndLogEx(SUCCESS, "Key: unknown: 0x%02x", keyType);
517 break;
521 DesfireCommunicationMode DesfireFileCommModeToCommMode(uint8_t file_comm_mode) {
522 DesfireCommunicationMode mode = DCMNone;
523 switch (file_comm_mode & 0x03) {
524 case 0x00:
525 case 0x02:
526 mode = DCMPlain;
527 break;
528 case 0x01:
529 mode = DCMMACed;
530 break;
531 case 0x03:
532 mode = DCMEncrypted;
533 break;
534 default:
535 break;
537 return mode;
540 uint8_t DesfireCommModeToFileCommMode(DesfireCommunicationMode comm_mode) {
541 uint8_t fmode = DCMNone;
542 switch (comm_mode) {
543 case DCMPlain:
544 fmode = 0x00;
545 break;
546 case DCMMACed:
547 fmode = 0x01;
548 break;
549 case DCMEncrypted:
550 case DCMEncryptedWithPadding:
551 case DCMEncryptedPlain:
552 fmode = 0x11;
553 break;
554 case DCMNone:
555 break;
557 return fmode;
560 void DesfireGenSessionKeyEV1(const uint8_t rnda[], const uint8_t rndb[], DesfireCryptoAlgorithm keytype, uint8_t *key) {
561 switch (keytype) {
562 case T_DES:
563 memcpy(key, rnda, 4);
564 memcpy(key + 4, rndb, 4);
565 break;
566 case T_3DES:
567 memcpy(key, rnda, 4);
568 memcpy(key + 4, rndb, 4);
569 memcpy(key + 8, rnda + 4, 4);
570 memcpy(key + 12, rndb + 4, 4);
571 break;
572 case T_3K3DES:
573 memcpy(key, rnda, 4);
574 memcpy(key + 4, rndb, 4);
575 memcpy(key + 8, rnda + 6, 4);
576 memcpy(key + 12, rndb + 6, 4);
577 memcpy(key + 16, rnda + 12, 4);
578 memcpy(key + 20, rndb + 12, 4);
579 break;
580 case T_AES:
581 memcpy(key, rnda, 4);
582 memcpy(key + 4, rndb, 4);
583 memcpy(key + 8, rnda + 12, 4);
584 memcpy(key + 12, rndb + 12, 4);
585 break;
589 // https://www.nxp.com/docs/en/application-note/AN12343.pdf
590 // page 35
591 void DesfireGenSessionKeyEV2(uint8_t *key, uint8_t *rndA, uint8_t *rndB, bool enckey, uint8_t *sessionkey) {
592 uint8_t data[64] = {0};
593 memset(sessionkey, 0, CRYPTO_AES_BLOCK_SIZE);
595 if (enckey) {
596 data[0] = 0xa5;
597 data[1] = 0x5a;
598 } else {
599 data[0] = 0x5a;
600 data[1] = 0xa5;
602 data[3] = 0x01;
603 data[5] = 0x80;
605 // data+6 - start of rnd part
606 memcpy(data + 6, rndA, 8);
607 bin_xor(data + 8, rndB, 6); // xor rndb 6b
608 memcpy(data + 14, rndB + 6, 10);
609 memcpy(data + 24, rndA + 8, 8);
611 uint8_t cmac[CRYPTO_AES_BLOCK_SIZE] = {0};
612 DesfireContext_t ctx = {0};
613 ctx.keyType = T_AES;
614 memcpy(ctx.key, key, 16); // aes-128
615 DesfireCryptoCMAC(&ctx, data, 32, cmac);
617 memcpy(sessionkey, cmac, CRYPTO_AES_BLOCK_SIZE);
620 // https://www.nxp.com/docs/en/data-sheet/MF2DLHX0.pdf
621 // page 35
622 void DesfireGenSessionKeyLRP(uint8_t *key, uint8_t *rndA, uint8_t *rndB, bool enckey, uint8_t *sessionkey) {
623 uint8_t data[64] = {0};
624 memset(sessionkey, 0, CRYPTO_AES_BLOCK_SIZE);
626 data[1] = 0x01;
627 data[3] = 0x80;
628 memcpy(data + 4, rndA, 8);
629 bin_xor(data + 6, rndB, 6); // xor rndb 6b
630 memcpy(data + 12, rndB + 6, 10);
631 memcpy(data + 22, rndA + 8, 8);
632 data[30] = 0x96;
633 data[31] = 0x69;
635 LRPContext_t ctx = {0};
636 LRPSetKey(&ctx, key, 0, true);
637 LRPCMAC(&ctx, data, 32, sessionkey);
640 void DesfireEV2FillIV(DesfireContext_t *ctx, bool ivforcommand, uint8_t *iv) {
641 uint8_t xiv[CRYPTO_AES_BLOCK_SIZE] = {0};
643 if (ivforcommand) {
644 xiv[0] = 0xa5;
645 xiv[1] = 0x5a;
646 } else {
647 xiv[0] = 0x5a;
648 xiv[1] = 0xa5;
651 memcpy(xiv + 2, ctx->TI, 4);
652 Uint2byteToMemLe(xiv + 2 + 4, ctx->cmdCntr);
654 if (aes_encode(NULL, ctx->sessionKeyEnc, xiv, xiv, CRYPTO_AES_BLOCK_SIZE))
655 return;
657 if (iv == NULL)
658 memcpy(ctx->IV, xiv, CRYPTO_AES_BLOCK_SIZE);
659 else
660 memcpy(iv, xiv, CRYPTO_AES_BLOCK_SIZE);
663 int DesfireEV2CalcCMAC(DesfireContext_t *ctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *mac) {
664 uint8_t mdata[DESFIRE_BUFFER_SIZE] = {0};
665 size_t mdatalen = 0;
667 mdata[0] = cmd;
668 Uint2byteToMemLe(&mdata[1], ctx->cmdCntr);
669 memcpy(&mdata[3], ctx->TI, 4);
670 if (data != NULL && datalen > 0) {
671 memcpy(&mdata[7], data, datalen);
674 mdatalen = 1 + 2 + 4 + datalen;
676 return aes_cmac8(NULL, ctx->sessionKeyMAC, mdata, mac, mdatalen);
679 // https://www.nxp.com/docs/en/data-sheet/MF2DLHX0.pdf
680 // page 42
681 void DesfireGenTransSessionKeyEV2(uint8_t *key, uint32_t trCntr, uint8_t *uid, bool forMAC, uint8_t *sessionkey) {
682 uint8_t xiv[CRYPTO_AES_BLOCK_SIZE] = {0};
684 if (forMAC) {
685 xiv[0] = 0x5a;
686 } else {
687 xiv[0] = 0xa5;
689 xiv[2] = 0x01;
690 xiv[4] = 0x80;
691 Uint4byteToMemLe(&xiv[5], trCntr + 1);
692 memcpy(&xiv[9], uid, 7);
694 DesfireContext_t ctx = {0};
695 DesfireSetKey(&ctx, 0, T_AES, key);
696 DesfireCryptoCMACEx(&ctx, DCOMainKey, xiv, 16, 0, sessionkey);
699 // https://www.nxp.com/docs/en/data-sheet/MF2DLHX0.pdf
700 // page 43
701 void DesfireGenTransSessionKeyLRP(uint8_t *key, uint32_t trCntr, uint8_t *uid, bool forMAC, uint8_t *sessionkey) {
702 uint8_t data[CRYPTO_AES_BLOCK_SIZE] = {0};
704 // SV1 = 00h||01h||00h||80h||(actTMC+1)||(sesTMC+1)||UID||5Ah
705 // SV2 = 00h||01h||00h||80h||(actTMC+1)||(sesTMC+1)||UID||A5h
706 // SesTMMACKey = MACLRP (AppTransactionMACKey; SV1)
707 // SesTMENCKey = MACLRP (AppTransactionMACKey; SV2)
709 data[1] = 0x01;
710 data[3] = 0x80;
711 // we thought that CommitReaderID is the first command in the transaction (actTMC == 0 !!!)
712 Uint4byteToMemLe(&data[4], (trCntr & 0xffff) + 0x00010001);
713 memcpy(&data[8], uid, 7);
714 if (forMAC) {
715 data[15] = 0x5a;
716 } else {
717 data[15] = 0xa5;
720 LRPContext_t lctx = {0};
721 LRPSetKey(&lctx, key, 0, false);
722 LRPCMAC(&lctx, data, sizeof(data), sessionkey);
725 void DesfireDecodePrevReaderID(DesfireContext_t *ctx, uint8_t *key, uint32_t trCntr, uint8_t *encPrevReaderID, uint8_t *prevReaderID) {
726 uint8_t sessionkey[CRYPTO_AES128_KEY_SIZE] = {0};
727 uint8_t uid[12] = {0};
728 memcpy(uid, ctx->uid, MAX(ctx->uidlen, 7));
730 if (ctx->secureChannel == DACEV2) {
731 DesfireGenTransSessionKeyEV2(key, trCntr, uid, false, sessionkey);
732 } else if (ctx->secureChannel == DACLRP) {
733 DesfireGenTransSessionKeyLRP(key, trCntr, uid, false, sessionkey);
735 aes_decode(NULL, sessionkey, encPrevReaderID, prevReaderID, CRYPTO_AES128_KEY_SIZE);
738 int DesfireLRPCalcCMAC(DesfireContext_t *ctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *mac) {
739 uint8_t mdata[DESFIRE_BUFFER_SIZE] = {0};
740 size_t mdatalen = 0;
742 mdata[0] = cmd;
743 Uint2byteToMemLe(&mdata[1], ctx->cmdCntr);
745 memcpy(&mdata[3], ctx->TI, 4);
747 if (data != NULL && datalen > 0) {
748 memcpy(&mdata[7], data, datalen);
751 mdatalen = 1 + 2 + 4 + datalen;
753 LRPContext_t lctx = {0};
754 LRPSetKey(&lctx, ctx->sessionKeyMAC, 0, true);
755 LRPCMAC8(&lctx, mdata, mdatalen, mac);
757 return 0;
760 int desfire_get_key_length(DesfireCryptoAlgorithm key_type) {
761 switch (key_type) {
762 case T_DES:
763 return 8;
764 case T_3DES:
765 return 16;
766 case T_3K3DES:
767 return 24;
768 case T_AES:
769 return 16;
771 return 0;
774 size_t desfire_get_key_block_length(DesfireCryptoAlgorithm key_type) {
775 size_t block_size = 8;
776 switch (key_type) {
777 case T_DES:
778 case T_3DES:
779 case T_3K3DES:
780 block_size = 8;
781 break;
782 case T_AES:
783 block_size = 16;
784 break;
786 return block_size;
790 * Size required to store nbytes of data in a buffer of size n*block_size.
792 size_t padded_data_length(const size_t nbytes, const size_t block_size) {
793 if ((!nbytes) || (nbytes % block_size))
794 return ((nbytes / block_size) + 1) * block_size;
795 else
796 return nbytes;
799 void desfire_crc32(const uint8_t *data, const size_t len, uint8_t *crc) {
800 crc32_ex(data, len, crc);
803 void desfire_crc32_append(uint8_t *data, const size_t len) {
804 crc32_ex(data, len, data + len);
807 bool desfire_crc32_check(uint8_t *data, const size_t len, uint8_t *crc) {
808 uint8_t ccrc[4] = {0};
809 desfire_crc32(data, len, ccrc);
810 return (memcmp(ccrc, crc, 4) == 0);
813 void iso14443a_crc_append(uint8_t *data, size_t len) {
814 compute_crc(CRC_14443_A, data, len, data + len, data + len + 1);
817 void iso14443a_crc(uint8_t *data, size_t len, uint8_t *pbtCrc) {
818 compute_crc(CRC_14443_A, data, len, pbtCrc, pbtCrc + 1);
821 bool iso14443a_crc_check(uint8_t *data, const size_t len, uint8_t *crc) {
822 uint8_t ccrc[2] = {0};
823 iso14443a_crc(data, len, ccrc);
824 return (memcmp(ccrc, crc, 2) == 0);