-
Notifications
You must be signed in to change notification settings - Fork 7
/
Desfire.h
187 lines (165 loc) · 8.25 KB
/
Desfire.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#ifndef DESFIRE_h
#define DESFIRE_h
#include <Arduino.h>
#include <SPI.h>
#include <MFRC522.h>
/* --------------------------------------
* DESFire Logical Structure
* --------------------------------------
*/
#define MIFARE_MAX_APPLICATION_COUNT 28 /* max applications on one PICC */
#define MIFARE_MAX_FILE_COUNT 16 /* max # of files in each application */
#define MIFARE_UID_BYTES 7 /* number of UID bytes */
#define MIFARE_AID_SIZE 3 /* number of AID bytes */
class DESFire : public MFRC522 {
public:
// DESFire Status and Error Codes.
enum DesfireStatusCode : byte {
MF_OPERATION_OK = 0x00, /* successful operation */
MF_NO_CHANGES = 0x0C, /* no changes done to backup files */
MF_OUT_OF_EEPROM_ERROR = 0x0E, /* insufficient NV-Mem. to complete cmd */
MF_ILLEGAL_COMMAND_CODE = 0x1C, /* command code not supported */
MF_INTEGRITY_ERROR = 0x1E, /* CRC or MAC does not match data */
MF_NO_SUCH_KEY = 0x40, /* invalid key number specified */
MF_LENGTH_ERROR = 0x7E, /* length of command string invalid */
MF_PERMISSION_ERROR = 0x9D, /* curr conf/status doesnt allow cmd */
MF_PARAMETER_ERROR = 0x9E, /* value of the parameter(s) invalid */
MF_APPLICATION_NOT_FOUND = 0xA0, /* requested AID not present on PICC */
MF_APPL_INTEGRITY_ERROR = 0xA1, /* unrecoverable err within app */
MF_AUTHENTICATION_ERROR = 0xAE, /* cur auth status doesnt allow req cmd */
MF_ADDITIONAL_FRAME = 0xAF, /* additional data frame to be sent */
MF_BOUNDARY_ERROR = 0xBE, /* attempt to read/write beyond limits */
MF_PICC_INTEGRITY_ERROR = 0xC1, /* unrecoverable error within PICC */
MF_COMMAND_ABORTED = 0xCA, /* previous command not fully completed */
MF_PICC_DISABLED_ERROR = 0xCD, /* PICC disabled by unrecoverable error */
MF_COUNT_ERROR = 0xCE, /* cant create more apps, already @ 28 */
MF_DUPLICATE_ERROR = 0xDE, /* cant create dup. file/app */
MF_EEPROM_ERROR = 0xEE, /* couldnt complete NV-write operation */
MF_FILE_NOT_FOUND = 0xF0, /* specified file number doesnt exist */
MF_FILE_INTEGRITY_ERROR = 0xF1 /* unrecoverable error within file */
};
// DESFire file types
enum mifare_desfire_file_types : byte {
MDFT_STANDARD_DATA_FILE = 0x00,
MDFT_BACKUP_DATA_FILE = 0x01,
MDFT_VALUE_FILE_WITH_BACKUP = 0x02,
MDFT_LINEAR_RECORD_FILE_WITH_BACKUP = 0x03,
MDFT_CYCLIC_RECORD_FILE_WITH_BACKUP = 0x04
};
// DESFire communication modes
enum mifare_desfire_communication_modes : byte {
MDCM_PLAIN = 0x00, /* Plain Communication */
MDCM_MACED = 0x01, /* Plain Comm secured by DES/3DES MACing */
MDCM_ENCIPHERED = 0x03 /* Fully DES/3DES enciphered comm. */
};
// A struct used for passing a MIFARE DESFire Version
typedef struct {
struct {
uint8_t vendor_id;
uint8_t type;
uint8_t subtype;
uint8_t version_major;
uint8_t version_minor;
uint8_t storage_size;
uint8_t protocol;
} hardware;
struct {
uint8_t vendor_id;
uint8_t type;
uint8_t subtype;
uint8_t version_major;
uint8_t version_minor;
uint8_t storage_size;
uint8_t protocol;
} software;
uint8_t uid[7];
uint8_t batch_number[5];
uint8_t production_week;
uint8_t production_year;
} MIFARE_DESFIRE_Version_t;
typedef struct {
uint8_t data[MIFARE_AID_SIZE];
} mifare_desfire_aid_t;
typedef struct {
MFRC522::StatusCode mfrc522;
DesfireStatusCode desfire;
} StatusCode;
// A struct used for passing a MIFARE DESFire Version
typedef struct {
uint8_t file_type;
uint8_t communication_settings;
uint16_t access_rights;
union {
struct {
uint32_t file_size;
} standard_file;
struct {
int32_t lower_limit;
int32_t upper_limit;
int32_t limited_credit_value;
uint8_t limited_credit_enabled;
} value_file;
struct {
uint32_t record_size;
uint32_t max_number_of_records;
uint32_t current_number_of_records;
} record_file; /* linear and cyclic record files */
} settings;
} mifare_desfire_file_settings_t;
typedef struct {
byte cid; // Card ID
byte pcb; // Protocol Control Byte
byte selected_application[MIFARE_AID_SIZE];
} mifare_desfire_tag;
/////////////////////////////////////////////////////////////////////////////////////
// Functions for setting up the Arduino
/////////////////////////////////////////////////////////////////////////////////////
explicit DESFire() : MFRC522() {};
explicit DESFire(byte resetPowerDownPin) : MFRC522(resetPowerDownPin) {};
explicit DESFire(byte chipSelectPin, byte resetPowerDownPin) : MFRC522(chipSelectPin, resetPowerDownPin) {};
/////////////////////////////////////////////////////////////////////////////////////
// ISO/IEC 14443 functions not currentlly present in MFRC522 library
/////////////////////////////////////////////////////////////////////////////////////
MFRC522::StatusCode PICC_RequestATS(byte *atsBuffer, byte *atsLength);
MFRC522::StatusCode PICC_ProtocolAndParameterSelection(byte cid, byte pps0, byte pps1 = 0x00);
/////////////////////////////////////////////////////////////////////////////////////
// Functions for MIFARE DESFire
/////////////////////////////////////////////////////////////////////////////////////
StatusCode MIFARE_DESFIRE_GetVersion(mifare_desfire_tag *tag, MIFARE_DESFIRE_Version_t *versionInfo);
StatusCode MIFARE_DESFIRE_GetApplicationIds(mifare_desfire_tag *tag, mifare_desfire_aid_t *aids, byte *applicationCount);
StatusCode MIFARE_DESFIRE_SelectApplication(mifare_desfire_tag *tag, mifare_desfire_aid_t *aid);
StatusCode MIFARE_DESFIRE_GetKeySettings(mifare_desfire_tag *tag, byte *settings, byte *maxKeys);
StatusCode MIFARE_DESFIRE_GetKeyVersion(mifare_desfire_tag *tag, byte key, byte *version);
/////////////////////////////////////////////////////////////////////////////////////
// MIFARE DESFire application level commands
/////////////////////////////////////////////////////////////////////////////////////
StatusCode MIFARE_DESFIRE_GetFileIDs(mifare_desfire_tag *tag, byte *files, byte *filesCount);
StatusCode MIFARE_DESFIRE_GetFileSettings(mifare_desfire_tag *tag, byte *file, mifare_desfire_file_settings_t *fileSettings);
/////////////////////////////////////////////////////////////////////////////////////
// MIFARE DESFire data manipulation commands
/////////////////////////////////////////////////////////////////////////////////////
StatusCode MIFARE_DESFIRE_ReadData(mifare_desfire_tag *tag, byte fid, uint32_t offset, uint32_t length, byte *backData, size_t *backLen);
StatusCode MIFARE_DESFIRE_GetValue(mifare_desfire_tag *tag, byte fid, int32_t *value);
/////////////////////////////////////////////////////////////////////////////////////
// Support functions
/////////////////////////////////////////////////////////////////////////////////////
static const __FlashStringHelper *GetDesfireStatusCodeName(DesfireStatusCode code);
virtual const __FlashStringHelper *GetStatusCodeName(MFRC522::StatusCode code) { return MFRC522::GetStatusCodeName(code); };
static const __FlashStringHelper *GetStatusCodeName(StatusCode code);
static const __FlashStringHelper *GetFileTypeName(mifare_desfire_file_types fileType);
static const __FlashStringHelper *GetCommunicationModeName(mifare_desfire_communication_modes communicationMode);
bool IsStatusCodeOK(StatusCode code);
/////////////////////////////////////////////////////////////////////////////////////
// Functions for debugging
/////////////////////////////////////////////////////////////////////////////////////
void PICC_DumpMifareDesfireMasterKey(mifare_desfire_tag *tag);
void PICC_DumpMifareDesfireVersion(mifare_desfire_tag *tag, MIFARE_DESFIRE_Version_t *versionInfo);
void PICC_DumpMifareDesfireApplication(mifare_desfire_tag *tag, mifare_desfire_aid_t *aid);
protected:
/////////////////////////////////////////////////////////////////////////////////////
// Helper methods
/////////////////////////////////////////////////////////////////////////////////////
StatusCode MIFARE_BlockExchange(mifare_desfire_tag *tag, byte cmd, byte *backData = NULL, byte *backLen = NULL);
StatusCode MIFARE_BlockExchangeWithData(mifare_desfire_tag *tag, byte cmd, byte *sendData = NULL, byte *sendLen = NULL, byte *backData = NULL, byte *backLen = NULL);
};
#endif