libnfc  1.8.0
nfc-mfclassic.c
Go to the documentation of this file.
1 /*-
2  * Free/Libre Near Field Communication (NFC) library
3  *
4  * Libnfc historical contributors:
5  * Copyright (C) 2009 Roel Verdult
6  * Copyright (C) 2009-2013 Romuald Conty
7  * Copyright (C) 2010-2012 Romain Tartière
8  * Copyright (C) 2010-2013 Philippe Teuwen
9  * Copyright (C) 2012-2013 Ludovic Rousseau
10  * See AUTHORS file for a more comprehensive list of contributors.
11  * Additional contributors of this file:
12  * Copyright (C) 2011-2013 Adam Laurie
13  * Copyright (C) 2018-2019 Danielle Bruneo
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions are met:
17  * 1) Redistributions of source code must retain the above copyright notice,
18  * this list of conditions and the following disclaimer.
19  * 2 )Redistributions in binary form must reproduce the above copyright
20  * notice, this list of conditions and the following disclaimer in the
21  * documentation and/or other materials provided with the distribution.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  * Note that this license only applies on the examples, NFC library itself is under LGPL
36  *
37  */
38 
44 #ifdef HAVE_CONFIG_H
45 # include "config.h"
46 #endif // HAVE_CONFIG_H
47 
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <stdint.h>
51 #include <stddef.h>
52 #include <stdbool.h>
53 
54 #include <string.h>
55 #include <ctype.h>
56 
57 #include <nfc/nfc.h>
58 
59 #include "mifare.h"
60 #include "nfc-utils.h"
61 
62 static nfc_context *context;
63 static nfc_device *pnd;
64 static nfc_target nt;
65 static mifare_param mp;
66 static mifare_classic_tag mtKeys;
67 static mifare_classic_tag mtDump;
68 static bool bUseKeyA;
69 static bool bUseKeyFile;
70 static bool bForceKeyFile;
71 static bool bTolerateFailures;
72 static bool bFormatCard;
73 static bool magic2 = false;
74 static bool magic3 = false;
75 static bool unlocked = false;
76 static uint8_t uiBlocks;
77 static uint8_t keys[] = {
78  0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
79  0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7,
80  0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5,
81  0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5,
82  0x4d, 0x3a, 0x99, 0xc3, 0x51, 0xdd,
83  0x1a, 0x98, 0x2c, 0x7e, 0x45, 0x9a,
84  0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
85  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86  0xab, 0xcd, 0xef, 0x12, 0x34, 0x56
87 };
88 static uint8_t default_key[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
89 static uint8_t default_acl[] = {0xff, 0x07, 0x80, 0x69};
90 
91 static const nfc_modulation nmMifare = {
92  .nmt = NMT_ISO14443A,
93  .nbr = NBR_106,
94 };
95 
96 static size_t num_keys = sizeof(keys) / 6;
97 
98 #define MAX_FRAME_LEN 264
99 
100 static uint8_t abtRx[MAX_FRAME_LEN];
101 static int szRxBits;
102 
103 uint8_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 };
104 
105 // special unlock command
106 uint8_t abtUnlock1[1] = { 0x40 };
107 uint8_t abtUnlock2[1] = { 0x43 };
108 
109 static bool
110 transmit_bits(const uint8_t *pbtTx, const size_t szTxBits)
111 {
112  // Show transmitted command
113  printf("Sent bits: ");
114  print_hex_bits(pbtTx, szTxBits);
115  // Transmit the bit frame command, we don't use the arbitrary parity feature
116  if ((szRxBits = nfc_initiator_transceive_bits(pnd, pbtTx, szTxBits, NULL, abtRx, sizeof(abtRx), NULL)) < 0)
117  return false;
118 
119  // Show received answer
120  printf("Received bits: ");
121  print_hex_bits(abtRx, szRxBits);
122  // Succesful transfer
123  return true;
124 }
125 
126 
127 static bool
128 transmit_bytes(const uint8_t *pbtTx, const size_t szTx)
129 {
130  // Show transmitted command
131  printf("Sent bits: ");
132  print_hex(pbtTx, szTx);
133  // Transmit the command bytes
134  int res;
135  if ((res = nfc_initiator_transceive_bytes(pnd, pbtTx, szTx, abtRx, sizeof(abtRx), 0)) < 0)
136  return false;
137 
138  // Show received answer
139  printf("Received bits: ");
140  print_hex(abtRx, res);
141  // Succesful transfer
142  return true;
143 }
144 
145 static void
146 print_success_or_failure(bool bFailure, uint32_t *uiBlockCounter)
147 {
148  printf("%c", (bFailure) ? 'x' : '.');
149  if (uiBlockCounter && !bFailure)
150  *uiBlockCounter += 1;
151 }
152 
153 static bool
154 is_first_block(uint32_t uiBlock)
155 {
156  // Test if we are in the small or big sectors
157  if (uiBlock < 128)
158  return ((uiBlock) % 4 == 0);
159  else
160  return ((uiBlock) % 16 == 0);
161 }
162 
163 static bool
164 is_trailer_block(uint32_t uiBlock)
165 {
166  // Test if we are in the small or big sectors
167  if (uiBlock < 128)
168  return ((uiBlock + 1) % 4 == 0);
169  else
170  return ((uiBlock + 1) % 16 == 0);
171 }
172 
173 static uint32_t
174 get_trailer_block(uint32_t uiFirstBlock)
175 {
176  // Test if we are in the small or big sectors
177  uint32_t trailer_block = 0;
178  if (uiFirstBlock < 128) {
179  trailer_block = uiFirstBlock + (3 - (uiFirstBlock % 4));
180  } else {
181  trailer_block = uiFirstBlock + (15 - (uiFirstBlock % 16));
182  }
183  return trailer_block;
184 }
185 
186 static bool
187 authenticate(uint32_t uiBlock)
188 {
189  mifare_cmd mc;
190 
191  // Set the authentication information (uid)
192  memcpy(mp.mpa.abtAuthUid, nt.nti.nai.abtUid + nt.nti.nai.szUidLen - 4, 4);
193 
194  // Should we use key A or B?
195  mc = (bUseKeyA) ? MC_AUTH_A : MC_AUTH_B;
196 
197  // Key file authentication.
198  if (bUseKeyFile) {
199 
200  // Locate the trailer (with the keys) used for this sector
201  uint32_t uiTrailerBlock;
202  uiTrailerBlock = get_trailer_block(uiBlock);
203 
204  // Extract the right key from dump file
205  if (bUseKeyA)
206  memcpy(mp.mpa.abtKey, mtKeys.amb[uiTrailerBlock].mbt.abtKeyA, sizeof(mp.mpa.abtKey));
207  else
208  memcpy(mp.mpa.abtKey, mtKeys.amb[uiTrailerBlock].mbt.abtKeyB, sizeof(mp.mpa.abtKey));
209 
210  // Try to authenticate for the current sector
211  if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp))
212  return true;
213 
214  } else if (magic3) {
215  //If it's a One Time Write card, we're gonna authenticate with the default keys
216  memcpy(mp.mpa.abtKey, default_key, sizeof(default_key));
217 
218 
219  // Try to authenticate for the current sector
220  if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp)) {
221  return true;
222  }
223  // If formatting or not using key file, try to guess the right key
224  } else if (bFormatCard || !bUseKeyFile) {
225  for (size_t key_index = 0; key_index < num_keys; key_index++) {
226  memcpy(mp.mpa.abtKey, keys + (key_index * 6), 6);
227  if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp)) {
228  if (bUseKeyA)
229  memcpy(mtKeys.amb[uiBlock].mbt.abtKeyA, &mp.mpa.abtKey, sizeof(mtKeys.amb[uiBlock].mbt.abtKeyA));
230  else
231  memcpy(mtKeys.amb[uiBlock].mbt.abtKeyB, &mp.mpa.abtKey, sizeof(mtKeys.amb[uiBlock].mbt.abtKeyB));
232  return true;
233  }
234  if (nfc_initiator_select_passive_target(pnd, nmMifare, nt.nti.nai.abtUid, nt.nti.nai.szUidLen, NULL) <= 0) {
235  ERR("tag was removed");
236  return false;
237  }
238  }
239  }
240 
241  return false;
242 }
243 
244 static bool
245 unlock_card(void)
246 {
247  // Configure the CRC
248  if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false) < 0) {
249  nfc_perror(pnd, "nfc_configure");
250  return false;
251  }
252  // Use raw send/receive methods
253  if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, false) < 0) {
254  nfc_perror(pnd, "nfc_configure");
255  return false;
256  }
257 
258  iso14443a_crc_append(abtHalt, 2);
259  transmit_bytes(abtHalt, 4);
260  // now send unlock
261  if (!transmit_bits(abtUnlock1, 7)) {
262  printf("Warning: Unlock command [1/2]: failed / not acknowledged.\n");
263  } else {
264  if (transmit_bytes(abtUnlock2, 1)) {
265  printf("Card unlocked\n");
266  unlocked = true;
267  } else {
268  printf("Warning: Unlock command [2/2]: failed / not acknowledged.\n");
269  }
270  }
271 
272  // reset reader
273  // Configure the CRC
274  if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, true) < 0) {
275  nfc_perror(pnd, "nfc_device_set_property_bool");
276  return false;
277  }
278  // Switch off raw send/receive methods
279  if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, true) < 0) {
280  nfc_perror(pnd, "nfc_device_set_property_bool");
281  return false;
282  }
283  return true;
284 }
285 
286 static int
287 get_rats(void)
288 {
289  int res;
290  uint8_t abtRats[2] = { 0xe0, 0x50};
291  // Use raw send/receive methods
292  if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, false) < 0) {
293  nfc_perror(pnd, "nfc_configure");
294  return -1;
295  }
296  res = nfc_initiator_transceive_bytes(pnd, abtRats, sizeof(abtRats), abtRx, sizeof(abtRx), 0);
297  if (res > 0) {
298  // ISO14443-4 card, turn RF field off/on to access ISO14443-3 again
299  if (nfc_device_set_property_bool(pnd, NP_ACTIVATE_FIELD, false) < 0) {
300  nfc_perror(pnd, "nfc_configure");
301  return -1;
302  }
303  if (nfc_device_set_property_bool(pnd, NP_ACTIVATE_FIELD, true) < 0) {
304  nfc_perror(pnd, "nfc_configure");
305  return -1;
306  }
307  }
308  // Reselect tag
309  if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) {
310  printf("Error: tag disappeared\n");
311  nfc_close(pnd);
312  nfc_exit(context);
313  exit(EXIT_FAILURE);
314  }
315  return res;
316 }
317 
318 static bool
319 read_card(int read_unlocked)
320 {
321  int32_t iBlock;
322  bool bFailure = false;
323  uint32_t uiReadBlocks = 0;
324 
325  if (read_unlocked) {
326  //If the user is attempting an unlocked read, but has a direct-write type magic card, they don't
327  //need to use the R mode. We'll trigger a warning and let them proceed.
328  if (magic2) {
329  printf("Note: This card does not require an unlocked read (R) \n");
330  read_unlocked = 0;
331  } else {
332  //If User has requested an unlocked read, but we're unable to unlock the card, we'll error out.
333  if (!unlock_card()) {
334  return false;
335  }
336  }
337  }
338 
339  printf("Reading out %d blocks |", uiBlocks + 1);
340  // Read the card from end to begin
341  for (iBlock = uiBlocks; iBlock >= 0; iBlock--) {
342  // Authenticate everytime we reach a trailer block
343  if (is_trailer_block(iBlock)) {
344  if (bFailure) {
345  // When a failure occured we need to redo the anti-collision
346  if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) {
347  printf("!\nError: tag was removed\n");
348  return false;
349  }
350  bFailure = false;
351  }
352 
353  fflush(stdout);
354 
355  // Try to authenticate for the current sector
356  if (!read_unlocked && !authenticate(iBlock)) {
357  printf("!\nError: authentication failed for block 0x%02x\n", iBlock);
358  return false;
359  }
360  // Try to read out the trailer
361  if (nfc_initiator_mifare_cmd(pnd, MC_READ, iBlock, &mp)) {
362  if (read_unlocked) {
363  memcpy(mtDump.amb[iBlock].mbd.abtData, mp.mpd.abtData, sizeof(mtDump.amb[iBlock].mbd.abtData));
364  } else {
365  //If we're using a One Time Write ('Magic 3') Badge - we'll use default keys + ACL
366  if (magic3) {
367  memcpy(mtDump.amb[iBlock].mbt.abtKeyA, default_key, sizeof(default_key));
368  memcpy(mtDump.amb[iBlock].mbt.abtAccessBits, mp.mpt.abtAccessBits, sizeof(mtDump.amb[iBlock].mbt.abtAccessBits));
369  memcpy(mtDump.amb[iBlock].mbt.abtKeyB, default_key, sizeof(default_key));
370  } else {
371  // Copy the keys over from our key dump and store the retrieved access bits
372  memcpy(mtDump.amb[iBlock].mbt.abtKeyA, mtKeys.amb[iBlock].mbt.abtKeyA, sizeof(mtDump.amb[iBlock].mbt.abtKeyA));
373  memcpy(mtDump.amb[iBlock].mbt.abtAccessBits, mp.mpt.abtAccessBits, sizeof(mtDump.amb[iBlock].mbt.abtAccessBits));
374  memcpy(mtDump.amb[iBlock].mbt.abtKeyB, mtKeys.amb[iBlock].mbt.abtKeyB, sizeof(mtDump.amb[iBlock].mbt.abtKeyB));
375  }
376  }
377  } else {
378  printf("!\nfailed to read trailer block 0x%02x\n", iBlock);
379  bFailure = true;
380  }
381  } else {
382  // Make sure a earlier readout did not fail
383  if (!bFailure) {
384  // Try to read out the data block
385  if (nfc_initiator_mifare_cmd(pnd, MC_READ, iBlock, &mp)) {
386  memcpy(mtDump.amb[iBlock].mbd.abtData, mp.mpd.abtData, sizeof(mtDump.amb[iBlock].mbd.abtData));
387  } else {
388  printf("!\nError: unable to read block 0x%02x\n", iBlock);
389  bFailure = true;
390  }
391  }
392  }
393  // Show if the readout went well for each block
394  print_success_or_failure(bFailure, &uiReadBlocks);
395  if ((!bTolerateFailures) && bFailure)
396  return false;
397  }
398  printf("|\n");
399  printf("Done, %d of %d blocks read.\n", uiReadBlocks, uiBlocks + 1);
400  fflush(stdout);
401 
402  return true;
403 }
404 
405 static bool
406 write_card(int write_block_zero)
407 {
408  uint32_t uiBlock;
409  bool bFailure = false;
410  uint32_t uiWriteBlocks = 0;
411 
412  //Determine if we have to unlock the card
413  if (write_block_zero) {
414  //If the user is attempting an unlocked write, but has a direct-write type magic card, they don't
415  //need to use the W mode. We'll trigger a warning and let them proceed.
416  if (magic2) {
417  printf("Note: This card does not require an unlocked write (W) \n");
418  write_block_zero = 0;
419  } else {
420  //If User has requested an unlocked write, but we're unable to unlock the card, we'll error out.
421  if (!unlock_card()) {
422  return false;
423  }
424  }
425  }
426 
427  printf("Writing %d blocks |", uiBlocks + 1);
428  // Completely write the card, end to start, but skipping block 0
429  for (uiBlock = 4; uiBlock <= uiBlocks; uiBlock++) {
430  // Authenticate everytime we reach the first sector of a new block
431  if (is_first_block(uiBlock)) {
432  if (bFailure) {
433  // When a failure occured we need to redo the anti-collision
434  if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) {
435  printf("!\nError: tag was removed\n");
436  return false;
437  }
438  bFailure = false;
439  }
440 
441  fflush(stdout);
442 
443  // Try to authenticate for the current sector
444  // If we are are writing to a chinese magic card, we've already unlocked
445  // If we're writing to a One Time Write card, we need to authenticate
446  // If we're writing something else, we'll need to authenticate
447  if ((write_block_zero && magic3) || !write_block_zero) {
448  if (!authenticate(uiBlock) && !bTolerateFailures) {
449  printf("!\nError: authentication failed for block %02x\n", uiBlock);
450  return false;
451  }
452  }
453 
454  if (is_trailer_block(uiBlock)) {
455  if (bFormatCard) {
456  // Copy the default key and reset the access bits
457  memcpy(mp.mpt.abtKeyA, default_key, sizeof(mp.mpt.abtKeyA));
458  memcpy(mp.mpt.abtAccessBits, default_acl, sizeof(mp.mpt.abtAccessBits));
459  memcpy(mp.mpt.abtKeyB, default_key, sizeof(mp.mpt.abtKeyB));
460  } else {
461  // Copy the keys over from our key dump and store the retrieved access bits
462  memcpy(mp.mpt.abtKeyA, mtDump.amb[uiBlock].mbt.abtKeyA, sizeof(mp.mpt.abtKeyA));
463  memcpy(mp.mpt.abtAccessBits, mtDump.amb[uiBlock].mbt.abtAccessBits, sizeof(mp.mpt.abtAccessBits));
464  memcpy(mp.mpt.abtKeyB, mtDump.amb[uiBlock].mbt.abtKeyB, sizeof(mp.mpt.abtKeyB));
465  }
466 
467  // Try to write the trailer
468  if (nfc_initiator_mifare_cmd(pnd, MC_WRITE, uiBlock, &mp) == false) {
469  printf("failed to write trailer block %d \n", uiBlock);
470  bFailure = true;
471  }
472  } else {
473  // The first block 0x00 is read only, skip this
474  if (uiBlock == 0 && !write_block_zero && !magic2)
475  continue;
476 
477  // Make sure a earlier write did not fail
478  if (!bFailure) {
479  // Try to write the data block
480  if (bFormatCard && uiBlock)
481 
482  memset(mp.mpd.abtData, 0x00, sizeof(mp.mpd.abtData));
483  else
484  memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData, sizeof(mp.mpd.abtData));
485  // do not write a block 0 with incorrect BCC - card will be made invalid!
486  if (uiBlock == 0) {
487  if ((mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3] ^ mp.mpd.abtData[4]) != 0x00 && !magic2) {
488  printf("!\nError: incorrect BCC in MFD file!\n");
489  printf("Expecting BCC=%02X\n", mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3]);
490  return false;
491  }
492  }
493  if (!nfc_initiator_mifare_cmd(pnd, MC_WRITE, uiBlock, &mp)) {
494  bFailure = true;
495  printf("Failure to write to data block %i\n", uiBlock);
496  }
497 
498  } else {
499  printf("Failure during write process.\n");
500  }
501  }
502  }
503  // Show if the write went well for each block
504  print_success_or_failure(bFailure, &uiWriteBlocks);
505  if ((! bTolerateFailures) && bFailure)
506  return false;
507  }
508 
509  //Write Block 0 if necessary
510  if (write_block_zero || magic2 || magic3) {
511  for (uiBlock = 0; uiBlock < 4; uiBlock++) {
512 
513  // The first block 0x00 is read only, skip this
514  if (uiBlock == 0) {
515  //If the card is not magic, we're gonna skip over
516  if (write_block_zero || magic2 || magic3) {
517  //NOP
518  } else {
519  continue;
520  }
521  }
522 
523  if (is_first_block(uiBlock)) {
524  if (bFailure) {
525  // When a failure occured we need to redo the anti-collision
526  if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) {
527  printf("!\nError: tag was removed\n");
528  return false;
529  }
530  bFailure = false;
531  }
532 
533  fflush(stdout);
534  // Try to authenticate for the current sector
535  // If we are are writing to a chinese magic card, we've already unlocked
536  // If we're writing to a One Time Write, we need to authenticate
537  // If we're writing something else, we'll need to authenticate
538  if ((write_block_zero && magic3) || !write_block_zero) {
539  if (!authenticate(uiBlock) && !bTolerateFailures) {
540  printf("!\nError: authentication failed for block %02x\n", uiBlock);
541  return false;
542  }
543  }
544  }
545 
546  // Make sure a earlier write did not fail
547  if (!bFailure) {
548  // Try to write the data block
549  if (bFormatCard && uiBlock)
550  memset(mp.mpd.abtData, 0x00, sizeof(mp.mpd.abtData));
551  else
552  memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData, sizeof(mp.mpd.abtData));
553  // do not write a block 0 with incorrect BCC - card will be made invalid!
554  if (uiBlock == 0) {
555  if ((mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3] ^ mp.mpd.abtData[4]) != 0x00 && !magic2) {
556  printf("!\nError: incorrect BCC in MFD file!\n");
557  printf("Expecting BCC=%02X\n", mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3]);
558  return false;
559  }
560  }
561  if (!nfc_initiator_mifare_cmd(pnd, MC_WRITE, uiBlock, &mp)) {
562  bFailure = true;
563  printf("Failure to write to data block %i\n", uiBlock);
564  }
565 
566  } else {
567  printf("Failure during write process.\n");
568  }
569 
570  // Show if the write went well for each block
571  print_success_or_failure(bFailure, &uiWriteBlocks);
572  if ((! bTolerateFailures) && bFailure)
573  return false;
574 
575  }
576 
577  }
578 
579  printf("|\n");
580  printf("Done, %d of %d blocks written.\n", uiWriteBlocks, uiBlocks + 1);
581  fflush(stdout);
582 
583  return true;
584 }
585 
586 typedef enum {
587  ACTION_READ,
588  ACTION_WRITE,
589  ACTION_USAGE
590 } action_t;
591 
592 static void
593 print_usage(const char *pcProgramName)
594 {
595  printf("Usage: ");
596  printf("%s f|r|R|w|W a|b u|U<01ab23cd> <dump.mfd> [<keys.mfd> [f]]\n", pcProgramName);
597  printf(" f|r|R|w|W - Perform format (f) or read from (r) or unlocked read from (R) or write to (w) or unlocked write to (W) card\n");
598  printf(" *** format will reset all keys to FFFFFFFFFFFF and all data to 00 and all ACLs to default\n");
599  printf(" *** unlocked read does not require authentication and will reveal A and B keys\n");
600  printf(" *** note that unlocked write will attempt to overwrite block 0 including UID\n");
601  printf(" *** unlocking only works with special Mifare 1K cards (Chinese clones)\n");
602  printf(" a|A|b|B - Use A or B keys for action; Halt on errors (a|b) or tolerate errors (A|B)\n");
603  printf(" u|U - Use any (u) uid or supply a uid specifically as U01ab23cd.\n");
604  printf(" <dump.mfd> - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n");
605  printf(" <keys.mfd> - MiFare Dump (MFD) that contain the keys (optional)\n");
606  printf(" f - Force using the keyfile even if UID does not match (optional)\n");
607 
608  printf("Examples: \n\n");
609  printf(" Read card to file, using key A:\n\n");
610  printf(" %s r a u mycard.mfd\n\n", pcProgramName);
611  printf(" Write file to blank card, using key A:\n\n");
612  printf(" %s w a u mycard.mfd\n\n", pcProgramName);
613  printf(" Write new data and/or keys to previously written card, using key A:\n\n");
614  printf(" %s w a u newdata.mfd mycard.mfd\n\n", pcProgramName);
615  printf(" Format/wipe card (note two passes required to ensure writes for all ACL cases):\n\n");
616  printf(" %s f A u dummy.mfd keyfile.mfd f\n", pcProgramName);
617  printf(" %s f B u dummy.mfd keyfile.mfd f\n\n", pcProgramName);
618  printf(" Read card to file, using key A and uid 0x01 0xab 0x23 0xcd:\n\n");
619  printf(" %s r a U01ab23cd mycard.mfd\n\n", pcProgramName);
620 }
621 
622 
623 static bool is_directwrite(void)
624 {
625  printf("Checking if Badge is DirectWrite...\n");
626 
627  // Set default keys
628  memcpy(mtDump.amb[0].mbt.abtKeyA, default_key, sizeof(default_key));
629  memcpy(mtDump.amb[0].mbt.abtAccessBits, default_acl, sizeof(mp.mpt.abtAccessBits));
630  memcpy(mtDump.amb[0].mbt.abtKeyB, default_key, sizeof(default_key));
631 
632  // Temporarly override bUseKeyFile
633  bool orig_bUseKeyFile = bUseKeyFile;
634  bUseKeyFile = false;
635  // Try to authenticate for the current sector
636  if (!authenticate(0)) {
637  printf("!\nError: authentication failed for block 0x%02x\n", 0);
638  bUseKeyFile = orig_bUseKeyFile;
639  return false;
640  }
641  // restore bUseKeyFile
642  bUseKeyFile = orig_bUseKeyFile;
643 
644  // Try to read block 0
645  uint8_t original_b0[16];
646  if (nfc_initiator_mifare_cmd(pnd, MC_READ, 0, &mp)) {
647  memcpy(original_b0, mp.mpd.abtData, sizeof(mp.mpd.abtData));
648  printf(" Original Block 0: ");
649  for (int i = 0; i < 16; i++) {
650  printf("%02x", original_b0[i]);
651  }
652  printf("\n");
653  printf(" Original UID: %02x%02x%02x%02x\n",
654  original_b0[0], original_b0[1], original_b0[2], original_b0[3]);
655  } else {
656  printf("!\nError: unable to read block 0x%02x\n", 0);
657  return false;
658  }
659 
660  printf(" Attempt to write Block 0 ...\n");
661  memcpy(mp.mpd.abtData, original_b0, sizeof(original_b0));
662  if (!nfc_initiator_mifare_cmd(pnd, MC_WRITE, 0, &mp)) {
663  printf("Failure to write to data block %i\n", 0);
664  return false;
665  }
666  printf(" Block 0 written successfully\n");
667 
668  return true;
669 }
670 
671 int
672 main(int argc, const char *argv[])
673 {
674  action_t atAction = ACTION_USAGE;
675  uint8_t *pbtUID;
676  uint8_t _tag_uid[4];
677  uint8_t *tag_uid = _tag_uid;
678 
679  int unlock = 0;
680 
681  if (argc < 2) {
682  print_usage(argv[0]);
683  exit(EXIT_FAILURE);
684  }
685  const char *command = argv[1];
686 
687  if (argc < 5) {
688  print_usage(argv[0]);
689  exit(EXIT_FAILURE);
690  }
691  if (strcmp(command, "r") == 0 || strcmp(command, "R") == 0) {
692  atAction = ACTION_READ;
693  if (strcmp(command, "R") == 0)
694  unlock = 1;
695  bUseKeyA = tolower((int)((unsigned char) * (argv[2]))) == 'a';
696  bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
697  bUseKeyFile = (argc > 5);
698  bForceKeyFile = ((argc > 6) && (strcmp((char *)argv[6], "f") == 0));
699  } else if (strcmp(command, "w") == 0 || strcmp(command, "W") == 0 || strcmp(command, "f") == 0) {
700  atAction = ACTION_WRITE;
701  if (strcmp(command, "W") == 0)
702  unlock = 1;
703  bFormatCard = (strcmp(command, "f") == 0);
704  bUseKeyA = tolower((int)((unsigned char) * (argv[2]))) == 'a';
705  bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
706  bUseKeyFile = (argc > 5);
707  bForceKeyFile = ((argc > 6) && (strcmp((char *)argv[6], "f") == 0));
708  }
709  if (argv[3][0] == 'U') {
710  unsigned long int _uid;
711 
712  if (strlen(argv[3]) != 9) {
713  printf("Error, illegal tag specification, use U01ab23cd for example.\n");
714  print_usage(argv[0]);
715  exit(EXIT_FAILURE);
716  }
717  _uid = strtoul(argv[3] + 1, NULL, 16);
718  tag_uid[0] = (_uid & 0xff000000UL) >> 24;
719  tag_uid[1] = (_uid & 0x00ff0000UL) >> 16;
720  tag_uid[2] = (_uid & 0x0000ff00UL) >> 8;
721  tag_uid[3] = (_uid & 0x000000ffUL);
722  printf("Attempting to use specific UID: 0x%2x 0x%2x 0x%2x 0x%2x\n",
723  tag_uid[0], tag_uid[1], tag_uid[2], tag_uid[3]);
724  } else {
725  tag_uid = NULL;
726  }
727 
728  if (atAction == ACTION_USAGE) {
729  print_usage(argv[0]);
730  exit(EXIT_FAILURE);
731  }
732  // We don't know yet the card size so let's read only the UID from the keyfile for the moment
733  if (bUseKeyFile) {
734  FILE *pfKeys = fopen(argv[5], "rb");
735  if (pfKeys == NULL) {
736  printf("Could not open keys file: %s\n", argv[5]);
737  exit(EXIT_FAILURE);
738  }
739  if (fread(&mtKeys, 1, 4, pfKeys) != 4) {
740  printf("Could not read UID from key file: %s\n", argv[5]);
741  fclose(pfKeys);
742  exit(EXIT_FAILURE);
743  }
744  fclose(pfKeys);
745  }
746  nfc_init(&context);
747  if (context == NULL) {
748  ERR("Unable to init libnfc (malloc)");
749  exit(EXIT_FAILURE);
750  }
751 
752 // Try to open the NFC reader
753  pnd = nfc_open(context, NULL);
754  if (pnd == NULL) {
755  ERR("Error opening NFC reader");
756  nfc_exit(context);
757  exit(EXIT_FAILURE);
758  }
759 
760  if (nfc_initiator_init(pnd) < 0) {
761  nfc_perror(pnd, "nfc_initiator_init");
762  nfc_close(pnd);
763  nfc_exit(context);
764  exit(EXIT_FAILURE);
765  };
766 
767 // Let the reader only try once to find a tag
768  if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) {
769  nfc_perror(pnd, "nfc_device_set_property_bool");
770  nfc_close(pnd);
771  nfc_exit(context);
772  exit(EXIT_FAILURE);
773  }
774 // Disable ISO14443-4 switching in order to read devices that emulate Mifare Classic with ISO14443-4 compliance.
775  if (nfc_device_set_property_bool(pnd, NP_AUTO_ISO14443_4, false) < 0) {
776  nfc_perror(pnd, "nfc_device_set_property_bool");
777  nfc_close(pnd);
778  nfc_exit(context);
779  exit(EXIT_FAILURE);
780  }
781 
782  printf("NFC reader: %s opened\n", nfc_device_get_name(pnd));
783 
784 // Try to find a MIFARE Classic tag
785  int tags;
786 
787  tags = nfc_initiator_select_passive_target(pnd, nmMifare, tag_uid, tag_uid == NULL ? 0 : 4, &nt);
788  if (tags <= 0) {
789  printf("Error: no tag was found\n");
790  nfc_close(pnd);
791  nfc_exit(context);
792  exit(EXIT_FAILURE);
793  }
794 // Test if we are dealing with a MIFARE compatible tag
795  if ((nt.nti.nai.btSak & 0x08) == 0) {
796  printf("Warning: tag is probably not a MFC!\n");
797  }
798 
799 // Get the info from the current tag
800  pbtUID = nt.nti.nai.abtUid;
801 
802  if (bUseKeyFile) {
803  uint8_t fileUid[4];
804  memcpy(fileUid, mtKeys.amb[0].mbm.abtUID, 4);
805 // Compare if key dump UID is the same as the current tag UID, at least for the first 4 bytes
806  if (memcmp(pbtUID, fileUid, 4) != 0) {
807  printf("Expected MIFARE Classic card with UID starting as: %02x%02x%02x%02x\n",
808  fileUid[0], fileUid[1], fileUid[2], fileUid[3]);
809  printf("Got card with UID starting as: %02x%02x%02x%02x\n",
810  pbtUID[0], pbtUID[1], pbtUID[2], pbtUID[3]);
811  if (!bForceKeyFile) {
812  printf("Aborting!\n");
813  nfc_close(pnd);
814  nfc_exit(context);
815  exit(EXIT_FAILURE);
816  }
817  }
818  }
819  printf("Found MIFARE Classic card:\n");
820  print_nfc_target(&nt, false);
821 
822 // Guessing size
823  if ((nt.nti.nai.abtAtqa[1] & 0x02) == 0x02 || nt.nti.nai.btSak == 0x18)
824 // 4K
825  uiBlocks = 0xff;
826  else if (nt.nti.nai.btSak == 0x09)
827 // 320b
828  uiBlocks = 0x13;
829  else
830 // 1K/2K, checked through RATS
831  uiBlocks = 0x3f;
832 // Testing RATS
833  int res;
834  if ((res = get_rats()) > 0) {
835  printf("RATS support: yes\n");
836  if ((res >= 10) && (abtRx[5] == 0xc1) && (abtRx[6] == 0x05)
837  && (abtRx[7] == 0x2f) && (abtRx[8] == 0x2f)
838  && ((nt.nti.nai.abtAtqa[1] & 0x02) == 0x00)) {
839  // MIFARE Plus 2K
840  uiBlocks = 0x7f;
841  }
842  // Chinese magic emulation card, ATS=0978009102:dabc1910
843  if ((res == 9) && (abtRx[5] == 0xda) && (abtRx[6] == 0xbc)
844  && (abtRx[7] == 0x19) && (abtRx[8] == 0x10)) {
845  magic2 = true;
846  }
847  } else
848  printf("RATS support: no\n");
849  printf("Guessing size: seems to be a %lu-byte card\n", (unsigned long)((uiBlocks + 1) * sizeof(mifare_classic_block)));
850 
851  //If size is 4k check for direct-write card
852  if (uiBlocks == 0xff) {
853  if (is_directwrite()) {
854  printf("Card is DirectWrite\n");
855  magic3 = true;
856  unlock = 0;
857  } else {
858  printf("Card is not DirectWrite\n");
859  }
860  }
861 
862  //Check to see if we have a One Time Write badge (magic3)
863  if (pbtUID[0] == 0xaa && pbtUID[1] == 0x55 &&
864  pbtUID[2] == 0xc3 && pbtUID[3] == 0x96) {
865  printf("Card appears to be a One Time Write Card..\n");
866  magic3 = true;
867  unlock = 0;
868  }
869 
870 
871  if (bUseKeyFile) {
872  FILE *pfKeys = fopen(argv[5], "rb");
873  if (pfKeys == NULL) {
874  printf("Could not open keys file: %s\n", argv[5]);
875  exit(EXIT_FAILURE);
876  }
877  if (fread(&mtKeys, 1, (uiBlocks + 1) * sizeof(mifare_classic_block), pfKeys) != (uiBlocks + 1) * sizeof(mifare_classic_block)) {
878  printf("Could not read keys file: %s\n", argv[5]);
879  fclose(pfKeys);
880  exit(EXIT_FAILURE);
881  }
882  fclose(pfKeys);
883  }
884 
885  if (atAction == ACTION_READ) {
886  memset(&mtDump, 0x00, sizeof(mtDump));
887  } else {
888  FILE *pfDump = fopen(argv[4], "rb");
889 
890  if (pfDump == NULL) {
891  printf("Could not open dump file: %s\n", argv[4]);
892  exit(EXIT_FAILURE);
893 
894  }
895 
896  if (fread(&mtDump, 1, (uiBlocks + 1) * sizeof(mifare_classic_block), pfDump) != (uiBlocks + 1) * sizeof(mifare_classic_block)) {
897  printf("Could not read dump file: %s\n", argv[4]);
898  fclose(pfDump);
899  exit(EXIT_FAILURE);
900  }
901  fclose(pfDump);
902  }
903 // printf("Successfully opened required files\n");
904 
905  if (atAction == ACTION_READ) {
906  if (read_card(unlock)) {
907  printf("Writing data to file: %s ...", argv[4]);
908  fflush(stdout);
909  FILE *pfDump = fopen(argv[4], "wb");
910  if (pfDump == NULL) {
911  printf("Could not open dump file: %s\n", argv[4]);
912  nfc_close(pnd);
913  nfc_exit(context);
914  exit(EXIT_FAILURE);
915  }
916  if (fwrite(&mtDump, 1, (uiBlocks + 1) * sizeof(mifare_classic_block), pfDump) != ((uiBlocks + 1) * sizeof(mifare_classic_block))) {
917  printf("\nCould not write to file: %s\n", argv[4]);
918  fclose(pfDump);
919  nfc_close(pnd);
920  nfc_exit(context);
921  exit(EXIT_FAILURE);
922  }
923  printf("Done.\n");
924  fclose(pfDump);
925  }
926  } else if (atAction == ACTION_WRITE) {
927  write_card(unlock);
928  }
929 
930  nfc_close(pnd);
931  nfc_exit(context);
932  exit(EXIT_SUCCESS);
933 }
const char * nfc_device_get_name(nfc_device *pnd)
Returns the device name.
Definition: nfc.c:1209
void nfc_close(nfc_device *pnd)
Close from a NFC device.
Definition: nfc.c:339
nfc_device * nfc_open(nfc_context *context, const nfc_connstring connstring)
Open a NFC device.
Definition: nfc.c:277
void nfc_perror(const nfc_device *pnd, const char *pcString)
Display the last error occured on a nfc_device.
Definition: nfc.c:1183
int nfc_initiator_transceive_bytes(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, const size_t szRx, int timeout)
Send data to target then retrieve data from target.
Definition: nfc.c:809
int nfc_initiator_transceive_bits(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar, uint8_t *pbtRx, const size_t szRx, uint8_t *pbtRxPar)
Transceive raw bit-frames to a target.
Definition: nfc.c:852
int nfc_initiator_init(nfc_device *pnd)
Initialize NFC device as initiator (reader)
Definition: nfc.c:493
int nfc_initiator_select_passive_target(nfc_device *pnd, const nfc_modulation nm, const uint8_t *pbtInitData, const size_t szInitData, nfc_target *pnt)
Select a passive or emulated tag.
Definition: nfc.c:562
void nfc_exit(nfc_context *context)
Deinitialize libnfc. Should be called after closing all open devices and before your application term...
Definition: nfc.c:248
void nfc_init(nfc_context **context)
Initialize libnfc. This function must be called before calling any other libnfc function.
Definition: nfc.c:231
int nfc_device_set_property_bool(nfc_device *pnd, const nfc_property property, const bool bEnable)
Set a device's boolean-property value.
Definition: nfc.c:466
bool nfc_initiator_mifare_cmd(nfc_device *pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param *pmp)
Execute a MIFARE Classic Command.
Definition: mifare.c:60
provide samples structs and functions to manipulate MIFARE Classic and Ultralight tags using libnfc
@ NP_INFINITE_SELECT
Definition: nfc-types.h:115
@ NP_HANDLE_CRC
Definition: nfc-types.h:94
@ NP_ACTIVATE_FIELD
Definition: nfc-types.h:105
@ NP_AUTO_ISO14443_4
Definition: nfc-types.h:134
@ NP_EASY_FRAMING
Definition: nfc-types.h:136
Provide some examples shared functions like print, parity calculation, options parsing.
#define ERR(...)
Print a error message.
Definition: nfc-utils.h:85
libnfc interface
NFC library context Struct which contains internal options, references, pointers, etc....
Definition: nfc-internal.h:175
NFC device information.
Definition: nfc-internal.h:190
NFC modulation structure.
Definition: nfc-types.h:342
NFC target structure.
Definition: nfc-types.h:351