1 /*-
2 * Copyright (C) 2009, 2010, Romain Tartiere, Romuald Conty.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by the
6 * Free Software Foundation, either version 3 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>
16 *
17 * $Id$
18 */
19
20 /*
21 * This implementation was written based on information provided by the
22 * following document:
23 *
24 * AN10787
25 * MIFARE Application Directory (MAD)
26 * Rev. 04 - 5 March 2009
27 *
28 * NXP Type MF1K/4K Tag Operation
29 * Storing NFC Forum data in Mifare Standard 1k/4k
30 * Rev. 1.1 - 21 August 2007
31 */
32 #include "config.h"
33
34 #include <sys/types.h>
35
36 #include <errno.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <strings.h>
40
41 #include <freefare.h>
42
43 /*
44 * The documentation says the preset is 0xE3 but the bits have to be mirrored:
45 * 0xe3 = 1110 0011 <=> 1100 0111 = 0xc7
46 */
47 #define CRC_PRESET 0xc7
48
49 #define SECTOR_0X00_AIDS 15
50 #define SECTOR_0X10_AIDS 23
51
52 struct mad_sector_0x00 {
53 uint8_t crc;
54 uint8_t info;
55 MadAid aids[SECTOR_0X00_AIDS];
56 };
57
58 struct mad_sector_0x10 {
59 uint8_t crc;
60 uint8_t info;
61 MadAid aids[SECTOR_0X10_AIDS];
62 };
63
64 struct mad {
65 struct mad_sector_0x00 sector_0x00;
66 struct mad_sector_0x10 sector_0x10;
67 uint8_t version;
68 };
69
70 /* Public Key A value of MAD sector(s) */
71 const MifareClassicKey mad_public_key_a = {
72 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5
73 };
74
75 /* AID - Administration codes: */
76 /* if sector is free */
77 const MadAid mad_free_aid = {
78 .function_cluster_code = 0x00,
79 .application_code = 0x00,
80 };
81 /* if sector is defect, e.g. access keys are destroyed or unknown */
82 const MadAid mad_defect_aid = {
83 .function_cluster_code = 0x00,
84 .application_code = 0x01,
85 };
86 /* if sector is reserved */
87 const MadAid mad_reserved_aid = {
88 .function_cluster_code = 0x00,
89 .application_code = 0x02,
90 };
91 /* if sector contains card holder information in ASCII format. */
92 const MadAid mad_card_holder_aid = {
93 .function_cluster_code = 0x00,
94 .application_code = 0x04,
95 };
96 /* if sector not applicable (above memory size) */
97 const MadAid mad_not_applicable_aid = {
98 .function_cluster_code = 0x00,
99 .application_code = 0x05,
100 };
101
102 /* NFC Forum AID */
103 const MadAid mad_nfcforum_aid = {
104 .function_cluster_code = 0xe1,
105 .application_code = 0x03,
106 };
107
108 /*
109 * Allocate an empty new MAD.
110 */
111 Mad
mad_new(uint8_t version)112 mad_new (uint8_t version)
113 {
114 Mad mad = malloc (sizeof (*mad));
115
116 if (!mad)
117 return NULL;
118
119 mad->version = version;
120 memset (&(mad->sector_0x00), 0, sizeof (mad->sector_0x00));
121 memset (&(mad->sector_0x10), 0, sizeof (mad->sector_0x10));
122
123 return mad;
124 }
125
126 /*
127 * Compute CRC.
128 */
129 void
nxp_crc(uint8_t * crc,const uint8_t value)130 nxp_crc (uint8_t *crc, const uint8_t value)
131 {
132 /* x^8 + x^4 + x^3 + x^2 + 1 => 0x11d */
133 const uint8_t poly = 0x1d;
134
135 *crc ^= value;
136 for (int current_bit = 7; current_bit >= 0; current_bit--) {
137 int bit_out = (*crc) & 0x80;
138 *crc <<= 1;
139 if (bit_out)
140 *crc ^= poly;
141
142 }
143 }
144
145 uint8_t
sector_0x00_crc8(Mad mad)146 sector_0x00_crc8 (Mad mad)
147 {
148 uint8_t crc = CRC_PRESET;
149
150 nxp_crc (&crc, mad->sector_0x00.info);
151
152 for (int n = 0; n < SECTOR_0X00_AIDS; n++) {
153 nxp_crc (&crc, mad->sector_0x00.aids[n].application_code);
154 nxp_crc (&crc, mad->sector_0x00.aids[n].function_cluster_code);
155 }
156
157 return crc;
158 }
159
160 uint8_t
sector_0x10_crc8(Mad mad)161 sector_0x10_crc8 (Mad mad)
162 {
163 uint8_t crc = CRC_PRESET;
164
165 nxp_crc (&crc, mad->sector_0x10.info);
166
167 for (int n = 0; n < SECTOR_0X10_AIDS; n++) {
168 nxp_crc (&crc, mad->sector_0x10.aids[n].application_code);
169 nxp_crc (&crc, mad->sector_0x10.aids[n].function_cluster_code);
170 }
171
172 return crc;
173 }
174
175 /*
176 * Read a MAD from the provided MIFARE tag.
177 */
178 Mad
mad_read(MifareTag tag)179 mad_read (MifareTag tag)
180 {
181 Mad mad = malloc (sizeof (*mad));
182
183 if (!mad)
184 goto error;
185
186 /* Authenticate using MAD key A */
187 if (mifare_classic_authenticate (tag, 0x03, mad_public_key_a, MFC_KEY_A) < 0) {
188 goto error;
189 }
190
191 /* Read first sector trailer block */
192 MifareClassicBlock data;
193 if (mifare_classic_read (tag, 0x03, &data) < 0) {
194 goto error;
195 }
196 uint8_t gpb = data[9];
197
198 /* Check MAD availability (DA bit) */
199 if (!(gpb & 0x80)) {
200 goto error;
201 }
202
203 /* Get MAD version (ADV bits) */
204 switch (gpb & 0x03) {
205 case 0x01:
206 mad->version = 1;
207 break;
208 case 0x02:
209 mad->version = 2;
210 break;
211 default:
212 /* MAD enabled but version not supported */
213 errno = ENOTSUP;
214 goto error;
215 }
216
217 /* Read MAD data at 0x00 (MAD1, MAD2) */
218 if (mifare_classic_read (tag, 0x01, &data) < 0)
219 goto error;
220
221 uint8_t *p = (uint8_t *) &(mad->sector_0x00);
222 memcpy (p, data, sizeof (data));
223
224 p+= sizeof (data);
225
226 if (mifare_classic_read (tag, 0x02, &data) < 0)
227 goto error;
228 memcpy (p, data, sizeof (data));
229
230 uint8_t crc = mad->sector_0x00.crc;
231 uint8_t computed_crc = sector_0x00_crc8 (mad);
232 if (crc != computed_crc)
233 goto error;
234
235 /* Read MAD data at 0x10 (MAD2) */
236 if (mad->version == 2) {
237
238 /* Authenticate using MAD key A */
239 if (mifare_classic_authenticate (tag, 0x43, mad_public_key_a, MFC_KEY_A) < 0) {
240 goto error;
241 }
242
243 p = (uint8_t *) &(mad->sector_0x10);
244
245 if (mifare_classic_read (tag, 0x40, &data) < 0)
246 goto error;
247 memcpy (p, data, sizeof (data));
248
249 p += sizeof (data);
250
251 if (mifare_classic_read (tag, 0x41, &data) < 0)
252 goto error;
253 memcpy (p, data, sizeof (data));
254
255 p += sizeof (data);
256
257 if (mifare_classic_read (tag, 0x42, &data) < 0)
258 goto error;
259 memcpy (p, data, sizeof (data));
260
261 crc = mad->sector_0x10.crc;
262 computed_crc = sector_0x10_crc8 (mad);
263 if (crc != computed_crc)
264 goto error;
265 }
266
267 return mad;
268
269 error:
270 free (mad);
271 return NULL;
272 }
273
274 /*
275 * Write the mad to the provided MIFARE tad using the provided Key-B keys.
276 */
277 int
mad_write(MifareTag tag,Mad mad,const MifareClassicKey key_b_sector_00,const MifareClassicKey key_b_sector_10)278 mad_write (MifareTag tag, Mad mad, const MifareClassicKey key_b_sector_00, const MifareClassicKey key_b_sector_10)
279 {
280 MifareClassicBlock data;
281
282 if (mifare_classic_authenticate (tag, 0x00, key_b_sector_00, MFC_KEY_B) < 0)
283 return -1;
284
285 if ((1 != mifare_classic_get_data_block_permission (tag, 0x01, MCAB_W, MFC_KEY_B)) ||
286 (1 != mifare_classic_get_data_block_permission (tag, 0x02, MCAB_W, MFC_KEY_B)) ||
287 (1 != mifare_classic_get_trailer_block_permission (tag, 0x03, MCAB_WRITE_KEYA, MFC_KEY_B)) ||
288 (1 != mifare_classic_get_trailer_block_permission (tag, 0x03, MCAB_WRITE_ACCESS_BITS, MFC_KEY_B))) {
289 errno = EPERM;
290 return -1;
291 }
292
293 uint8_t gpb = 0x80;
294
295 /*
296 * FIXME Handle mono-application cards
297 */
298 gpb |= 0x40;
299
300 /* Write MAD version */
301 switch (mad->version) {
302 case 1:
303 gpb |= 0x01;
304 break;
305 case 2:
306 gpb |= 0x02;
307 break;
308 }
309
310 if (2 == mad->version) {
311 if (mifare_classic_authenticate (tag, 0x40, key_b_sector_10, MFC_KEY_B) < 0)
312 return -1;
313
314 if ((1 != mifare_classic_get_data_block_permission (tag, 0x40, MCAB_W, MFC_KEY_B)) ||
315 (1 != mifare_classic_get_data_block_permission (tag, 0x41, MCAB_W, MFC_KEY_B)) ||
316 (1 != mifare_classic_get_data_block_permission (tag, 0x42, MCAB_W, MFC_KEY_B)) ||
317 (1 != mifare_classic_get_trailer_block_permission (tag, 0x43, MCAB_WRITE_KEYA, MFC_KEY_B)) ||
318 (1 != mifare_classic_get_trailer_block_permission (tag, 0x43, MCAB_WRITE_ACCESS_BITS, MFC_KEY_B))) {
319 errno = EPERM;
320 return -1;
321 }
322
323 mad->sector_0x10.crc = sector_0x10_crc8 (mad);
324
325 memcpy (data, (uint8_t *)&(mad->sector_0x10), sizeof (data));
326 if (mifare_classic_write (tag, 0x40, data) < 0) return -1;
327 memcpy (data, (uint8_t *)&(mad->sector_0x10) + sizeof (data), sizeof (data));
328 if (mifare_classic_write (tag, 0x41, data) < 0) return -1;
329 memcpy (data, (uint8_t *)&(mad->sector_0x10) + sizeof (data) * 2, sizeof (data));
330 if (mifare_classic_write (tag, 0x42, data) < 0) return -1;
331
332 mifare_classic_trailer_block (&data, mad_public_key_a, 0x0, 0x1, 0x1, 0x6, 0x00, key_b_sector_10);
333 if (mifare_classic_write (tag, 0x43, data) < 0) return -1;
334
335 }
336
337 mad->sector_0x00.crc = sector_0x00_crc8 (mad);
338
339 if (mifare_classic_authenticate (tag, 0x00, key_b_sector_00, MFC_KEY_B) < 0) return -1;
340 memcpy (data, (uint8_t *)&(mad->sector_0x00), sizeof (data));
341 if (mifare_classic_write (tag, 0x01, data) < 0) return -1;
342 memcpy (data, (uint8_t *)&(mad->sector_0x00) + sizeof (data), sizeof (data));
343 if (mifare_classic_write (tag, 0x02, data) < 0) return -1;
344
345 mifare_classic_trailer_block (&data, mad_public_key_a, 0x0, 0x1, 0x1, 0x6, gpb, key_b_sector_00);
346 if (mifare_classic_write (tag, 0x03, data) < 0) return -1;
347
348 return 0;
349 }
350
351 /*
352 * Return a MAD version.
353 */
354 int
mad_get_version(Mad mad)355 mad_get_version (Mad mad)
356 {
357 return mad->version;
358 }
359
360 /*
361 * Set a MAD version.
362 */
363 void
mad_set_version(Mad mad,const uint8_t version)364 mad_set_version (Mad mad, const uint8_t version)
365 {
366 if ((version == 2) && (mad->version == 1)) {
367 /* We use a larger MAD so initialise the new blocks */
368 memset (&(mad->sector_0x10), 0, sizeof (mad->sector_0x10));
369 }
370 mad->version = version;
371 }
372
373 /*
374 * Return the MAD card publisher sector.
375 */
376 MifareClassicSectorNumber
mad_get_card_publisher_sector(Mad mad)377 mad_get_card_publisher_sector(Mad mad)
378 {
379 return (mad->sector_0x00.info & 0x3f);
380 }
381
382 /*
383 * Set the MAD card publisher sector.
384 */
385 int
mad_set_card_publisher_sector(Mad mad,const MifareClassicSectorNumber cps)386 mad_set_card_publisher_sector(Mad mad, const MifareClassicSectorNumber cps)
387 {
388 if (((mad->version == 2) && (cps > 0x27)) | (mad->version == 1) && (cps > 0x0f)) {
389 errno = EINVAL;
390 return -1;
391 }
392
393 mad->sector_0x00.info = (cps & 0x3f);
394 return 0;
395 }
396
397 /*
398 * Get the provided sector's application identifier.
399 */
400 int
mad_get_aid(Mad mad,const MifareClassicSectorNumber sector,MadAid * aid)401 mad_get_aid(Mad mad, const MifareClassicSectorNumber sector, MadAid *aid)
402 {
403 if ((sector < 1) || (sector == 0x10) || (sector > 0x27)) {
404 errno = EINVAL;
405 return -1;
406 }
407
408 if (sector > 0x0f) {
409 if (mad->version != 2) {
410 errno = EINVAL;
411 return -1;
412 }
413
414 aid->function_cluster_code = mad->sector_0x10.aids[sector - 0x0f - 2].function_cluster_code;
415 aid->application_code = mad->sector_0x10.aids[sector - 0x0f - 2].application_code;
416 } else {
417 aid->function_cluster_code = mad->sector_0x00.aids[sector - 1].function_cluster_code;
418 aid->application_code = mad->sector_0x00.aids[sector - 1].application_code;
419 }
420
421 return 0;
422 }
423
424 /*
425 * Set the provided sector's application identifier.
426 */
427 int
mad_set_aid(Mad mad,const MifareClassicSectorNumber sector,MadAid aid)428 mad_set_aid(Mad mad, const MifareClassicSectorNumber sector, MadAid aid)
429 {
430 if ((sector < 1) || (sector == 0x10) || (sector > 0x27)) {
431 errno = EINVAL;
432 return -1;
433 }
434
435 if (sector > 0x0f) {
436 if (mad->version != 2) {
437 errno = EINVAL;
438 return -1;
439 }
440 mad->sector_0x10.aids[sector - 0x0f - 2].function_cluster_code = aid.function_cluster_code;
441 mad->sector_0x10.aids[sector - 0x0f - 2].application_code = aid.application_code;
442 } else {
443 mad->sector_0x00.aids[sector - 1].function_cluster_code = aid.function_cluster_code;
444 mad->sector_0x00.aids[sector - 1].application_code = aid.application_code;
445 }
446
447 return 0;
448 }
449
450 bool
mad_sector_reserved(const MifareClassicSectorNumber sector)451 mad_sector_reserved (const MifareClassicSectorNumber sector)
452 {
453 return ((0x00 == sector) || (0x10 == sector));
454 }
455
456 /*
457 * Free memory allocated by mad_new() and mad_read().
458 */
459 void
mad_free(Mad mad)460 mad_free (Mad mad)
461 {
462 free (mad);
463 }
464