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.
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"
27 #include <mbedtls/cmac.h>
29 #include "crc16.h" // crc16 ccitt
31 #include "commonutil.h"
32 #include "desfirecore.h" // DESFIRE_BUFFER_SIZE
34 void DesfireClearContext(DesfireContext_t
*ctx
) {
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;
47 memset(ctx
->uid
, 0, sizeof(ctx
->uid
));
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
));
65 ctx
->lastRequestZeroLen
= false;
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
);
79 DesfireSetKeyNoClear(ctx
, keyNum
, keyType
, key
);
82 void DesfireSetKeyNoClear(DesfireContext_t
*ctx
, uint8_t keyNum
, DesfireCryptoAlgorithm keyType
, uint8_t *key
) {
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
) {
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
;
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
) {
135 size_t DesfireSearchCRCPos(uint8_t *data
, size_t datalen
, uint8_t respcode
, uint8_t crclen
) {
136 size_t crcpos
= datalen
- 1;
139 if (data
[crcpos
] == 0) {
146 crcpos
++; // crc may be 0x00000000 or 0x0000
147 if (crcpos
< crclen
) {
148 PrintAndLogEx(WARNING
, "No space for crc. pos %zu", crcpos
);
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) {
161 if (crcpos
- i
+ crclen
> datalen
) {
165 memcpy(crcdata
, data
, crcpos
- i
);
166 crcdata
[crcpos
- i
] = respcode
;
170 res
= desfire_crc32_check(crcdata
, crcpos
- i
+ 1, &data
[crcpos
- i
]);
172 res
= iso14443a_crc_check(data
, crcpos
- i
, &data
[crcpos
- i
]);
176 crcposfound
= crcpos
- i
;
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
;
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
);
201 bin_xor(sdata
, ivect
, block_size
);
204 uint8_t edata
[DESFIRE_MAX_CRYPTO_BLOCK_SIZE
] = {0};
209 des_encrypt(edata
, sdata
, key
);
211 des_decrypt(edata
, sdata
, key
);
215 mbedtls_des3_context ctx3
;
216 mbedtls_des3_set2key_enc(&ctx3
, key
);
217 mbedtls_des3_crypt_ecb(&ctx3
, sdata
, edata
);
219 mbedtls_des3_context ctx3
;
220 mbedtls_des3_set2key_dec(&ctx3
, key
);
221 mbedtls_des3_crypt_ecb(&ctx3
, sdata
, edata
);
226 mbedtls_des3_context ctx3
;
227 mbedtls_des3_set3key_enc(&ctx3
, key
);
228 mbedtls_des3_crypt_ecb(&ctx3
, sdata
, edata
);
230 mbedtls_des3_context ctx3
;
231 mbedtls_des3_set3key_dec(&ctx3
, key
);
232 mbedtls_des3_crypt_ecb(&ctx3
, sdata
, edata
);
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
);
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
);
253 memcpy(ivect
, edata
, block_size
);
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
);
274 memcpy(xiv
, ctx
->IV
, block_size
);
276 memcpy(xiv
, iv
, block_size
);
278 uint8_t *key
= DesfireGetKey(ctx
, key_type
);
282 if (ctx
->secureChannel
== DACLRP
) {
284 LRPEncDec(key
, xiv
, encode
, srcdata
, srcdatalen
, data
, &dstlen
);
287 while (offset
< srcdatalen
) {
288 DesfireCryptoEncDecSingleBlock(key
, ctx
->keyType
, srcdata
+ offset
, data
+ offset
, xiv
, dir_to_send
, encode
);
290 offset
+= block_size
;
295 memcpy(ctx
->IV
, xiv
, block_size
);
297 memcpy(iv
, xiv
, block_size
);
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
) {
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;
322 memset(ivect
, 0, kbs
);
324 DesfireCryptoEncDecEx(ctx
, key_type
, l
, kbs
, l
, true, true, ivect
);
328 // Used to compute CMAC on complete blocks
336 // Used to compute CMAC on the last block if non-complete
337 memcpy(sk2
, sk1
, kbs
);
338 txor
= sk1
[0] & 0x80;
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
);
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
);
367 bin_xor(buffer
+ len
- kbs
, sk1
, kbs
);
370 DesfireCryptoEncDec(ctx
, key_type
, buffer
, len
, NULL
, true);
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)
386 int kbs
= desfire_get_key_block_length(ctx
->keyType
); // 8 or 16
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
;
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
) {
407 memcpy(&buffer
[1], data
, len
);
410 DesfireCryptoCMACEx(ctx
, key_type
, buffer
, len
+ 1, kbs
* 2, cmac
);
413 memcpy(&buffer
[1], data
, len
);
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
) {
421 memcpy(&buffer
[1], data
, len
);
424 DesfireCryptoCMACEx(ctx
, key_type
, buffer
, len
+ 1, kbs
* 2, cmac
);
427 memcpy(&buffer
[1], data
, len
);
430 DesfireCryptoCMACEx(ctx
, key_type
, buffer
, len
+ 1, kbs
* 2, &cmac
[kbs
]);
433 memcpy(&buffer
[1], data
, len
);
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
)
447 for (int n
= 0; n
< desfire_get_key_length(keytype
); n
++) {
452 for (int n
= 0; n
< 8; n
++) {
453 uint8_t version_bit
= ((version
& (1 << (7 - n
))) >> (7 - n
));
456 key
[n
] |= version_bit
;
458 if (keytype
== T_DES
) {
461 // Write ~version to avoid turning a 3DES key into a DES key
463 key
[n
+ 8] |= (~version_bit
) & 0x01;
468 uint8_t DesfireDESKeyGetVersion(const uint8_t *key
) {
470 for (int n
= 0; n
< 8; n
++) {
471 version
|= ((key
[n
] & 1) << (7 - n
));
477 DesfireCryptoAlgorithm
DesfireKeyTypeToAlgo(uint8_t keyType
) {
486 return T_3DES
; // unknown....
490 uint8_t DesfireKeyAlgoToType(DesfireCryptoAlgorithm keyType
) {
504 void DesfirePrintCardKeyType(uint8_t keyType
) {
507 PrintAndLogEx(SUCCESS
, "Key: 2TDEA");
510 PrintAndLogEx(SUCCESS
, "Key: 3TDEA");
513 PrintAndLogEx(SUCCESS
, "Key: AES");
516 PrintAndLogEx(SUCCESS
, "Key: unknown: 0x%02x", keyType
);
521 DesfireCommunicationMode
DesfireFileCommModeToCommMode(uint8_t file_comm_mode
) {
522 DesfireCommunicationMode mode
= DCMNone
;
523 switch (file_comm_mode
& 0x03) {
540 uint8_t DesfireCommModeToFileCommMode(DesfireCommunicationMode comm_mode
) {
541 uint8_t fmode
= DCMNone
;
550 case DCMEncryptedWithPadding
:
551 case DCMEncryptedPlain
:
560 void DesfireGenSessionKeyEV1(const uint8_t rnda
[], const uint8_t rndb
[], DesfireCryptoAlgorithm keytype
, uint8_t *key
) {
563 memcpy(key
, rnda
, 4);
564 memcpy(key
+ 4, rndb
, 4);
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);
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);
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);
589 // https://www.nxp.com/docs/en/application-note/AN12343.pdf
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
);
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};
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
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
);
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);
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};
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
))
658 memcpy(ctx
->IV
, xiv
, CRYPTO_AES_BLOCK_SIZE
);
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};
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
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};
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
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)
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);
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};
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
);
760 int desfire_get_key_length(DesfireCryptoAlgorithm key_type
) {
774 size_t desfire_get_key_block_length(DesfireCryptoAlgorithm key_type
) {
775 size_t block_size
= 8;
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
;
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);