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