Chameleon-Mini
DESFireApplicationDirectory.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  * DESFireApplicationDirectory.h :
24  * Maxie D. Schmidt (github.com/maxieds)
25  */
26 
27 #ifndef __DESFIRE_DFAPPDIR_H__
28 #define __DESFIRE_DFAPPDIR_H__
29 
30 #include "DESFireFirmwareSettings.h"
31 #include "DESFirePICCHeaderLayout.h"
32 #include "DESFireInstructions.h"
33 #include "DESFireFile.h"
34 
35 #define DESFIRE_MAX_FILES_EV0 16
36 #define DESFIRE_MAX_FILES_EV1 32
37 
38 #if defined(DESFIRE_MEMORY_LIMITED_TESTING) && !defined(DESFIRE_CUSTOM_MAX_APPS)
39 #define DESFIRE_MAX_APPS (6)
40 #elif defined(DESFIRE_CUSTOM_MAX_APPS)
41 #define DESFIRE_MAX_APPS (DESFIRE_CUSTOM_MAX_APPS)
42 #else
43 #define DESFIRE_MAX_APPS (28)
44 #endif
45 
46 #define DESFIRE_MAX_SLOTS (DESFIRE_MAX_APPS + 1)
47 
48 #if defined(DESFIRE_MEMORY_LIMITED_TESTING) && !defined(DESFIRE_CUSTOM_MAX_FILES)
49 #define DESFIRE_MAX_FILES (6)
50 #elif defined(DESFIRE_CUSTOM_MAX_FILES)
51 #define DESFIRE_MAX_FILES (DESFIRE_CUSTOM_MAX_FILES)
52 #else
53 #define DESFIRE_MAX_FILES (DESFIRE_MAX_FILES_EV1)
54 #endif
55 
56 #if defined(DESFIRE_MEMORY_LIMITED_TESTING) && !defined(DESFIRE_CUSTOM_MAX_KEYS)
57 #define DESFIRE_MAX_KEYS (4)
58 #elif defined(DESFIRE_CUSTOM_MAX_KEYS)
59 #define DESFIRE_MAX_KEYS (DESFIRE_CUSTOM_MAX_KEYS)
60 #else
61 #define DESFIRE_MAX_KEYS (14)
62 #endif
63 
64 #ifdef DESFIRE_USE_FACTORY_SIZES
65 #undef DESFIRE_CUSTOM_MAX_APPS
66 #define DESFIRE_CUSTOM_MAX_APPS (28)
67 #undef DESFIRE_CUSTOM_MAX_KEYS
68 #define DESFIRE_CUSTOM_MAX_KEYS (14)
69 #undef DESFIRE_CUSTOM_MAX_FILES
70 #define DESFIRE_CUSTOM_MAX_FILES (DESFIRE_MAX_FILES_EV1)
71 #elif defined(DESFIRE_MAXIMIZE_SIZES_FOR_STORAGE)
72 #undef DESFIRE_CUSTOM_MAX_APPS
73 #define DESFIRE_CUSTOM_MAX_APPS (DESFIRE_EEPROM_BLOCK_SIZE - 1)
74 #undef DESFIRE_CUSTOM_MAX_KEYS
75 #define DESFIRE_CUSTOM_MAX_KEYS (DESFIRE_EEPROM_BLOCK_SIZE)
76 #undef DESFIRE_CUSTOM_MAX_FILES
77 #define DESFIRE_CUSTOM_MAX_FILES (DESFIRE_EEPROM_BLOCK_SIZE)
78 #endif
79 
80 /* Mifare DESFire EV1 Application crypto operations */
81 #define APPLICATION_CRYPTO_DES 0x00
82 #define APPLICATION_CRYPTO_3K3DES 0x40
83 #define APPLICATION_CRYPTO_AES 0x80
84 
85 /* Define application directory identifiers: */
86 #define MAX_AID_SIZE (12)
87 #define DESFIRE_AID_SIZE (3)
88 
89 typedef BYTE DESFireAidType[DESFIRE_AID_SIZE];
90 
91 /*
92  * Defines the application directory contents.
93  * The application directory maps AIDs to application slots:
94  * the AID's index in `AppIds` is the slot number.
95  *
96  * This is the "global" structure that gets stored in the header
97  * data for the directory. To see the actual byte-for-byte storage
98  * of the accounting data for each instantiated AID slot, refer to the
99  * `DesfireApplicationDataType` structure from above.
100  */
101 typedef struct DESFIRE_FIRMWARE_PACKING {
102  BYTE FirstFreeSlot;
103  DESFireAidType AppIds[DESFIRE_MAX_SLOTS] DESFIRE_FIRMWARE_ARRAY_ALIGNAT;
104  SIZET AppCacheStructBlockOffset[DESFIRE_MAX_SLOTS];
105 } DESFireAppDirType;
106 
107 #define DESFIRE_APP_DIR_BLOCKS DESFIRE_BYTES_TO_BLOCKS(sizeof(DESFireAppDirType))
108 
109 /* Global card structure support routines */
110 void SynchronizeAppDir(void);
111 void SynchronizePICCInfo(void);
112 
113 /* PICC / Application master key settings */
114 /* Mifare DESFire master key settings
115  bit 7 - 4: Always 0.
116  bit 3: PICC master key settings frozen = 0 (WARNING - this is irreversible);
117  PICC master key settings changeable when authenticated with PICC master key = 1
118  bit 2: PICC master key authentication required for creating or deleting applications = 0;
119  Authentication not required = 1
120  bit 1: PICC master key authentication required for listing of applications or
121  reading key settings = 0;
122  Free listing of applications and reading key settings = 1
123  bit 0: PICC master key frozen (reversible with configuration change or when formatting card) = 0;
124  PICC master key changeable = 1
125 */
126 #define DESFIRE_ALLOW_MASTER_KEY_CHANGE (0x01) //(1 << 0)
127 #define DESFIRE_FREE_DIRECTORY_LIST (0x02) //(1 << 1)
128 #define DESFIRE_FREE_CREATE_DELETE (0x04) //(1 << 2)
129 #define DESFIRE_ALLOW_CONFIG_CHANGE (0x08) //(1 << 3)
130 #define DESFIRE_USE_TARGET_KEY 0xE
131 #define DESFIRE_ALL_KEYS_FROZEN 0xF
132 
133 /* PICC master key (PMK) settings for application creation / deletion
134  * (see page 34 of the datasheet)
135  */
136 BYTE PMKConfigurationChangeable(void);
137 BYTE PMKRequiredForAppCreateDelete(void);
138 BYTE PMKFreeDirectoryListing(void);
139 BYTE PMKAllowChangingKey(void);
140 
141 /* Application master key (AMK)
142  * (see page 35 of the datasheet)
143  */
144 BYTE AMKConfigurationChangeable(void);
145 BYTE AMKRequiredForFileCreateDelete(void);
146 BYTE AMKFreeDirectoryListing(void);
147 BYTE AMKAllowChangingKey(void);
148 BYTE AMKRequiredToChangeKeys(void);
149 BYTE AMKGetRequiredKeyToChangeKeys(void);
150 BYTE AMKRequireCurrentKeyToChangeKey(void);
151 BYTE AMKAllKeysFrozen(void);
152 
153 /* Application data management */
154 SIZET GetAppProperty(DesfireCardLayout propId, BYTE AppSlot);
155 void SetAppProperty(DesfireCardLayout propId, BYTE AppSlot, SIZET Value);
156 
157 /* Application key management */
158 bool KeyIdValid(uint8_t AppSlot, uint8_t KeyId);
159 BYTE ReadMaxKeyCount(uint8_t AppSlot);
160 BYTE ReadKeyCount(uint8_t AppSlot);
161 void WriteKeyCount(uint8_t AppSlot, BYTE KeyCount);
162 BYTE ReadKeySettings(uint8_t AppSlot, uint8_t KeyId);
163 void WriteKeySettings(uint8_t AppSlot, uint8_t KeyId, BYTE Value);
164 BYTE ReadKeyVersion(uint8_t AppSlot, uint8_t KeyId);
165 void WriteKeyVersion(uint8_t AppSlot, uint8_t KeyId, BYTE Value);
166 BYTE ReadKeyCryptoType(uint8_t AppSlot, uint8_t KeyId);
167 void WriteKeyCryptoType(uint8_t AppSlot, uint8_t KeyId, BYTE Value);
168 SIZET ReadKeyStorageAddress(uint8_t AppSlot);
169 void WriteKeyStorageAddress(uint8_t AppSlot, SIZET Value);
170 void ReadAppKey(uint8_t AppSlot, uint8_t KeyId, uint8_t *Key, SIZET KeySize);
171 void WriteAppKey(uint8_t AppSlot, uint8_t KeyId, const uint8_t *Key, SIZET KeySize);
172 
173 /* Application file management */
174 BYTE ReadFileCount(uint8_t AppSlot);
175 void WriteFileCount(uint8_t AppSlot, BYTE FileCount);
176 BYTE LookupFileNumberIndex(uint8_t AppSlot, BYTE FileNumber);
177 BYTE LookupFileNumberByIndex(uint8_t AppSlot, BYTE FileIndex);
178 BYTE LookupNextFreeFileSlot(uint8_t AppSlot);
179 void WriteFileNumberAtIndex(uint8_t AppSlot, uint8_t FileIndex, BYTE FileNumber);
180 SIZET ReadFileDataStructAddress(uint8_t AppSlot, uint8_t FileIndex);
181 uint8_t ReadFileType(uint8_t AppSlot, uint8_t FileIndex);
182 uint16_t ReadDataFileSize(uint8_t AppSlot, uint8_t FileIndex);
183 BYTE ReadFileCommSettings(uint8_t AppSlot, uint8_t FileIndex);
184 void WriteFileCommSettings(uint8_t AppSlot, uint8_t FileIndex, BYTE CommSettings);
185 SIZET ReadFileAccessRights(uint8_t AppSlot, uint8_t FileIndex);
186 void WriteFileAccessRights(uint8_t AppSlot, uint8_t FileIndex, SIZET AccessRights);
187 DESFireFileTypeSettings ReadFileSettings(uint8_t AppSlot, uint8_t FileIndex);
188 void WriteFileSettings(uint8_t AppSlot, uint8_t FileIndex, DESFireFileTypeSettings *FileSettings);
189 
190 /* Application selection */
191 uint8_t LookupAppSlot(const DESFireAidType Aid);
192 void SelectAppBySlot(uint8_t AppSlot);
193 bool GetAppData(uint8_t appSlot, SelectedAppCacheType *destData);
194 uint16_t SelectApp(const DESFireAidType Aid);
195 void SelectPiccApp(void);
196 bool IsPiccAppSelected(void);
197 
198 /* Application management */
199 uint16_t CreateApp(const DESFireAidType Aid, uint8_t KeyCount, uint8_t KeySettings);
200 uint16_t DeleteApp(const DESFireAidType Aid);
201 void GetApplicationIdsSetup(void);
202 TransferStatus GetApplicationIdsTransfer(uint8_t *Buffer);
203 uint16_t GetApplicationIdsIterator(uint8_t *Buffer, uint16_t ByteCount);
204 
205 #endif