Chameleon-Mini
DESFireCrypto.h
1 /*
2 The DESFire stack portion of this firmware source
3 is free software written by Maxie Dion Schmidt (@maxieds):
4 You can redistribute it and/or modify
5 it under the terms of this license.
6 
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 
11 The complete source distribution of
12 this firmware is available at the following link:
13 https://github.com/maxieds/ChameleonMiniFirmwareDESFireStack.
14 
15 Based in part on the original DESFire code created by
16 @dev-zzo (GitHub handle) [Dmitry Janushkevich] available at
17 https://github.com/dev-zzo/ChameleonMini/tree/desfire.
18 
19 This notice must be retained at the top of all source files where indicated.
20 */
21 
22 /*
23  * DESFireCrypto.h
24  * Maxie D. Schmidt (github.com/maxieds)
25  */
26 
27 #ifndef __DESFIRE_CRYPTO_H__
28 #define __DESFIRE_CRYPTO_H__
29 
30 #include "../../Common.h"
31 
32 #include "DESFireFirmwareSettings.h"
33 
34 /* Communication modes:
35  * Define the modes of communication over the RFID channel
36  *
37  * Note there is also an AES wrapped COMMS variant called
38  * LRP Secure Messaging detailed starting on page 37
39  * (Section 7.2) of
40  * https://www.nxp.com/docs/en/application-note/AN12343.pdf
41  */
42 #define DESFIRE_COMMS_PLAINTEXT (0x00)
43 #define DESFIRE_COMMS_PLAINTEXT_MAC (0x01)
44 #define DESFIRE_COMMS_CIPHERTEXT_DES (0x03)
45 #define DESFIRE_COMMS_CIPHERTEXT_AES128 (0x04)
46 #define DESFIRE_DEFAULT_COMMS_STANDARD (DESFIRE_COMMS_PLAINTEXT)
47 
48 #define CRYPTO_TYPE_ANY (0x00)
49 #define CRYPTO_TYPE_DES (0x01)
50 #define CRYPTO_TYPE_2KTDEA (0x0A)
51 #define CRYPTO_TYPE_3K3DES (0x1A)
52 #define CRYPTO_TYPE_AES128 (0x4A)
53 
54 #define CryptoTypeDES(ct) \
55  ((ct == CRYPTO_TYPE_DES) || (ct == CRYPTO_TYPE_ANY))
56 #define CryptoType2KTDEA(ct) \
57  ((ct == CRYPTO_TYPE_2KTDEA) || (ct == CRYPTO_TYPE_ANY))
58 #define CryptoType3KTDEA(ct) \
59  ((ct == CRYPTO_TYPE_3K3DES) || (ct == CRYPTO_TYPE_ANY))
60 #define CryptoTypeAES(ct) \
61  ((ct == CRYPTO_TYPE_AES128) || (ct == CRYPTO_TYPE_ANY))
62 
63 /* Key sizes, block sizes (in bytes): */
64 #define CRYPTO_AES_KEY_SIZE (16)
65 #define CRYPTO_MAX_KEY_SIZE (24)
66 #define CRYPTO_MAX_BLOCK_SIZE (16)
67 #define DESFIRE_AES_IV_SIZE (CRYPTO_AES_BLOCK_SIZE)
68 #define DESFIRE_SESSION_KEY_SIZE (CRYPTO_3KTDEA_KEY_SIZE)
69 #define CRYPTO_CHALLENGE_RESPONSE_BYTES (8)
70 
71 typedef BYTE CryptoKeyBufferType[CRYPTO_MAX_KEY_SIZE];
72 typedef BYTE CryptoIVBufferType[CRYPTO_MAX_BLOCK_SIZE];
73 
74 extern CryptoKeyBufferType SessionKey;
75 extern CryptoIVBufferType SessionIV;
76 extern BYTE SessionIVByteSize;
77 
78 extern uint8_t Authenticated;
79 extern uint8_t AuthenticatedWithKey;
80 extern uint8_t AuthenticatedWithPICCMasterKey;
81 extern uint8_t CryptoAuthMethod;
82 extern uint8_t ActiveCommMode;
83 
84 /* Need to invalidate the authentication state after:
85  * 1) Selecting a new application;
86  * 2) Changing the active key used in the authentication;
87  * 3) A failed authentication;
88  */
89 void InvalidateAuthState(BYTE keepPICCAuthData);
90 bool IsAuthenticated(void);
91 
92 BYTE GetDefaultCryptoMethodKeySize(uint8_t cryptoType);
93 BYTE GetCryptoMethodCommSettings(uint8_t cryptoType);
94 const char *GetCryptoMethodDesc(uint8_t cryptoType);
95 const char *GetCommSettingsDesc(uint8_t cryptoType);
96 
97 #define DESFIRE_MAC_LENGTH 4
98 #define DESFIRE_CMAC_LENGTH 8 // in bytes
99 
100 /* Authentication status */
101 #define DESFIRE_NOT_AUTHENTICATED 0xFF
102 
103 typedef enum DESFIRE_FIRMWARE_ENUM_PACKING {
104  DESFIRE_AUTH_LEGACY,
105  DESFIRE_AUTH_ISO_2KTDEA,
106  DESFIRE_AUTH_ISO_3KTDEA,
107  DESFIRE_AUTH_AES,
108 } DesfireAuthType;
109 
110 BYTE GetCryptoKeyTypeFromAuthenticateMethod(BYTE authCmdMethod);
111 
112 #define CryptoBitsToBytes(cryptoBits) \
113  (cryptoBits / BITS_PER_BYTE)
114 
115 /*********************************************************
116  * AES (128) crypto routines:
117  *********************************************************/
118 
119 #include "../CryptoAES128.h"
120 
121 typedef uint8_t DesfireAESCryptoKey[CRYPTO_AES_KEY_SIZE];
122 
123 extern CryptoAESConfig_t AESCryptoContext;
124 extern DesfireAESCryptoKey AESCryptoSessionKey;
125 extern DesfireAESCryptoKey AESCryptoIVBuffer;
126 
127 void InitAESCryptoKeyData(DesfireAESCryptoKey *cryptoKeyData);
128 
129 typedef void (*CryptoAESCBCFuncType)(uint16_t, void *, void *, uint8_t *, uint8_t *);
130 
131 typedef uint8_t (*CryptoTransferSendFunc)(uint8_t *, uint8_t);
132 typedef uint8_t (*CryptoTransferReceiveFunc)(uint8_t *, uint8_t);
133 uint8_t CryptoAESTransferEncryptSend(uint8_t *Buffer, uint8_t Count, const uint8_t *Key);
134 uint8_t CryptoAESTransferEncryptReceive(uint8_t *Buffer, uint8_t Count, const uint8_t *Key);
135 
136 #define DESFIRE_MAX_PAYLOAD_AES_BLOCKS (DESFIRE_MAX_PAYLOAD_SIZE / CRYPTO_AES_BLOCK_SIZE)
137 
138 /*********************************************************
139  * TripleDES crypto routines:
140  *********************************************************/
141 
142 #include "../CryptoTDEA.h"
143 
144 #define DESFIRE_2KTDEA_NONCE_SIZE (CRYPTO_DES_BLOCK_SIZE)
145 #define DESFIRE_DES_IV_SIZE (CRYPTO_DES_BLOCK_SIZE)
146 #define DESFIRE_MAX_PAYLOAD_TDEA_BLOCKS (DESFIRE_MAX_PAYLOAD_SIZE / CRYPTO_DES_BLOCK_SIZE)
147 
148 /* Checksum routines: */
149 void TransferChecksumUpdateCRCA(const uint8_t *Buffer, uint8_t Count);
150 uint8_t TransferChecksumFinalCRCA(uint8_t *Buffer);
151 void TransferChecksumUpdateMACTDEA(const uint8_t *Buffer, uint8_t Count);
152 uint8_t TransferChecksumFinalMACTDEA(uint8_t *Buffer);
153 
154 #endif