f38a1528 |
1 | #ifndef __DESFIRE_H |
2 | #define __DESFIRE_H |
3 | |
f6c18637 |
4 | #include <string.h> |
5 | #include <stdarg.h> |
f38a1528 |
6 | #include "aes.h" |
f38a1528 |
7 | |
8 | #define MAX_CRYPTO_BLOCK_SIZE 16 |
9 | /* Mifare DESFire EV1 Application crypto operations */ |
10 | #define APPLICATION_CRYPTO_DES 0x00 |
11 | #define APPLICATION_CRYPTO_3K3DES 0x40 |
12 | #define APPLICATION_CRYPTO_AES 0x80 |
13 | |
14 | #define MAC_LENGTH 4 |
15 | #define CMAC_LENGTH 8 |
16 | |
17 | typedef enum { |
18 | MCD_SEND, |
19 | MCD_RECEIVE |
20 | } MifareCryptoDirection; |
21 | |
22 | typedef enum { |
23 | MCO_ENCYPHER, |
24 | MCO_DECYPHER |
25 | } MifareCryptoOperation; |
26 | |
27 | #define MDCM_MASK 0x000F |
28 | |
29 | #define CMAC_NONE 0 |
30 | |
31 | // Data send to the PICC is used to update the CMAC |
32 | #define CMAC_COMMAND 0x010 |
33 | // Data received from the PICC is used to update the CMAC |
34 | #define CMAC_VERIFY 0x020 |
35 | |
36 | // MAC the command (when MDCM_MACED) |
37 | #define MAC_COMMAND 0x100 |
38 | // The command returns a MAC to verify (when MDCM_MACED) |
39 | #define MAC_VERIFY 0x200 |
40 | |
41 | #define ENC_COMMAND 0x1000 |
42 | #define NO_CRC 0x2000 |
43 | |
44 | #define MAC_MASK 0x0F0 |
45 | #define CMAC_MACK 0xF00 |
46 | |
47 | /* Communication mode */ |
48 | #define MDCM_PLAIN 0x00 |
49 | #define MDCM_MACED 0x01 |
50 | #define MDCM_ENCIPHERED 0x03 |
51 | |
52 | /* Error code managed by the library */ |
53 | #define CRYPTO_ERROR 0x01 |
54 | |
55 | |
56 | enum DESFIRE_AUTH_SCHEME { |
57 | AS_LEGACY, |
58 | AS_NEW |
59 | }; |
60 | |
61 | enum DESFIRE_CRYPTOALGO { |
62 | T_DES = 0x00, |
63 | T_3DES = 0x01, |
64 | T_3K3DES = 0x02, |
65 | T_AES = 0x03 |
66 | }; |
67 | |
f38a1528 |
68 | |
f6c18637 |
69 | #define DESFIRE_KEY(key) ((struct desfire_key *) key) |
70 | struct desfire_key { |
f38a1528 |
71 | enum DESFIRE_CRYPTOALGO type; |
72 | uint8_t data[24]; |
73 | // DES_key_schedule ks1; |
74 | // DES_key_schedule ks2; |
75 | // DES_key_schedule ks3; |
76 | AesCtx aes_ks; |
77 | uint8_t cmac_sk1[24]; |
78 | uint8_t cmac_sk2[24]; |
79 | uint8_t aes_version; |
80 | }; |
f38a1528 |
81 | typedef struct desfire_key *desfirekey_t; |
82 | |
f6c18637 |
83 | #define DESFIRE(tag) ((struct desfire_tag *) tag) |
f38a1528 |
84 | struct desfire_tag { |
85 | iso14a_card_select_t info; |
86 | int active; |
87 | uint8_t last_picc_error; |
88 | uint8_t last_internal_error; |
89 | uint8_t last_pcd_error; |
90 | desfirekey_t session_key; |
91 | enum DESFIRE_AUTH_SCHEME authentication_scheme; |
92 | uint8_t authenticated_key_no; |
93 | |
94 | uint8_t ivect[MAX_CRYPTO_BLOCK_SIZE]; |
95 | uint8_t cmac[16]; |
96 | uint8_t *crypto_buffer; |
97 | size_t crypto_buffer_size; |
98 | uint32_t selected_application; |
99 | }; |
100 | typedef struct desfire_tag *desfiretag_t; |
101 | |
102 | |
103 | /* File types */ |
104 | enum DESFIRE_FILE_TYPES { |
105 | MDFT_STANDARD_DATA_FILE = 0x00, |
106 | MDFT_BACKUP_DATA_FILE = 0x01, |
107 | MDFT_VALUE_FILE_WITH_BACKUP = 0x02, |
108 | MDFT_LINEAR_RECORD_FILE_WITH_BACKUP = 0x03, |
109 | MDFT_CYCLIC_RECORD_FILE_WITH_BACKUP = 0x04 |
110 | }; |
111 | |
f38a1528 |
112 | enum DESFIRE_STATUS { |
113 | OPERATION_OK = 0x00, |
114 | NO_CHANGES = 0x0c, |
115 | OUT_OF_EEPROM_ERROR = 0x0e, |
116 | ILLEGAL_COMMAND_CODE = 0x1c, |
117 | INTEGRITY_ERROR = 0x1e, |
118 | NO_SUCH_KEY = 0x40, |
119 | LENGTH_ERROR = 0x7e, |
120 | PERMISSION_DENIED = 0x9d, |
121 | PARAMETER_ERROR = 0x9e, |
122 | APPLICATION_NOT_FOUND = 0xa0, |
123 | APPL_INTEGRITY_ERROR = 0xa1, |
124 | AUTHENTICATION_ERROR = 0xae, |
125 | ADDITIONAL_FRAME = 0xaf, |
126 | BOUNDARY_ERROR = 0xbe, |
127 | PICC_INTEGRITY_ERROR = 0xc1, |
128 | COMMAND_ABORTED = 0xca, |
129 | PICC_DISABLED_ERROR = 0xcd, |
130 | COUNT_ERROR = 0xce, |
131 | DUPLICATE_ERROR = 0xde, |
132 | EEPROM_ERROR = 0xee, |
133 | FILE_NOT_FOUND = 0xf0, |
134 | FILE_INTEGRITY_ERROR = 0xf1 |
135 | }; |
136 | |
137 | enum DESFIRE_CMD { |
138 | CREATE_APPLICATION = 0xca, |
139 | DELETE_APPLICATION = 0xda, |
140 | GET_APPLICATION_IDS = 0x6a, |
141 | SELECT_APPLICATION = 0x5a, |
142 | FORMAT_PICC = 0xfc, |
143 | GET_VERSION = 0x60, |
144 | READ_DATA = 0xbd, |
145 | WRITE_DATA = 0x3d, |
146 | GET_VALUE = 0x6c, |
147 | CREDIT = 0x0c, |
148 | DEBIT = 0xdc, |
149 | LIMITED_CREDIT = 0x1c, |
150 | WRITE_RECORD = 0x3b, |
151 | READ_RECORDS = 0xbb, |
152 | CLEAR_RECORD_FILE = 0xeb, |
153 | COMMIT_TRANSACTION = 0xc7, |
154 | ABORT_TRANSACTION = 0xa7, |
155 | GET_FREE_MEMORY = 0x6e, |
156 | GET_FILE_IDS = 0x6f, |
157 | GET_FILE_SETTINGS = 0xf5, |
158 | CHANGE_FILE_SETTINGS = 0x5f, |
159 | CREATE_STD_DATA_FILE = 0xcd, |
160 | CREATE_BACKUP_DATA_FILE = 0xcb, |
161 | CREATE_VALUE_FILE = 0xcc, |
162 | CREATE_LINEAR_RECORD_FILE = 0xc1, |
163 | CREATE_CYCLIC_RECORD_FILE = 0xc0, |
164 | DELETE_FILE = 0xdf, |
165 | AUTHENTICATE = 0x0a, // AUTHENTICATE_NATIVE |
166 | AUTHENTICATE_ISO = 0x1a, // AUTHENTICATE_STANDARD |
167 | AUTHENTICATE_AES = 0xaa, |
168 | CHANGE_KEY_SETTINGS = 0x54, |
169 | GET_KEY_SETTINGS = 0x45, |
170 | CHANGE_KEY = 0xc4, |
171 | GET_KEY_VERSION = 0x64, |
172 | AUTHENTICATION_FRAME = 0xAF |
173 | }; |
174 | |
175 | #endif |
176 | |