libnfc  1.7.1
nfc-mfsetuid.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 Adam Laurie
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are met:
16  * 1) Redistributions of source code must retain the above copyright notice,
17  * this list of conditions and the following disclaimer.
18  * 2 )Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Note that this license only applies on the examples, NFC library itself is under LGPL
35  *
36  */
37 
47 #ifdef HAVE_CONFIG_H
48 # include "config.h"
49 #endif // HAVE_CONFIG_H
50 
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <stddef.h>
54 #include <stdint.h>
55 #include <stdbool.h>
56 #include <string.h>
57 
58 #include <nfc/nfc.h>
59 
60 #include "utils/nfc-utils.h"
61 
62 #define SAK_FLAG_ATS_SUPPORTED 0x20
63 
64 #define MAX_FRAME_LEN 264
65 
66 static uint8_t abtRx[MAX_FRAME_LEN];
67 static int szRxBits;
68 static uint8_t abtRawUid[12];
69 static uint8_t abtAtqa[2];
70 static uint8_t abtSak;
71 static uint8_t abtAts[MAX_FRAME_LEN];
72 static uint8_t szAts = 0;
73 static size_t szCL = 1;//Always start with Cascade Level 1 (CL1)
74 static nfc_device *pnd;
75 
76 bool quiet_output = false;
77 bool iso_ats_supported = false;
78 
79 // ISO14443A Anti-Collision Commands
80 uint8_t abtReqa[1] = { 0x26 };
81 uint8_t abtSelectAll[2] = { 0x93, 0x20 };
82 uint8_t abtSelectTag[9] = { 0x93, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
83 uint8_t abtRats[4] = { 0xe0, 0x50, 0x00, 0x00 };
84 uint8_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 };
85 #define CASCADE_BIT 0x04
86 
87 // special unlock command
88 uint8_t abtUnlock1[1] = { 0x40 };
89 uint8_t abtUnlock2[1] = { 0x43 };
90 uint8_t abtWipe[1] = { 0x41 };
91 uint8_t abtWrite[4] = { 0xa0, 0x00, 0x5f, 0xb1 };
92 uint8_t abtData[18] = { 0x01, 0x23, 0x45, 0x67, 0x00, 0x08, 0x04, 0x00, 0x46, 0x59, 0x25, 0x58, 0x49, 0x10, 0x23, 0x02, 0x23, 0xeb };
93 uint8_t abtBlank[18] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x80, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x36, 0xCC };
94 
95 
96 static bool
97 transmit_bits(const uint8_t *pbtTx, const size_t szTxBits)
98 {
99  // Show transmitted command
100  if (!quiet_output) {
101  printf("Sent bits: ");
102  print_hex_bits(pbtTx, szTxBits);
103  }
104  // Transmit the bit frame command, we don't use the arbitrary parity feature
105  if ((szRxBits = nfc_initiator_transceive_bits(pnd, pbtTx, szTxBits, NULL, abtRx, sizeof(abtRx), NULL)) < 0)
106  return false;
107 
108  // Show received answer
109  if (!quiet_output) {
110  printf("Received bits: ");
111  print_hex_bits(abtRx, szRxBits);
112  }
113  // Succesful transfer
114  return true;
115 }
116 
117 
118 static bool
119 transmit_bytes(const uint8_t *pbtTx, const size_t szTx)
120 {
121  // Show transmitted command
122  if (!quiet_output) {
123  printf("Sent bits: ");
124  print_hex(pbtTx, szTx);
125  }
126  int res;
127  // Transmit the command bytes
128  if ((res = nfc_initiator_transceive_bytes(pnd, pbtTx, szTx, abtRx, sizeof(abtRx), 0)) < 0)
129  return false;
130 
131  // Show received answer
132  if (!quiet_output) {
133  printf("Received bits: ");
134  print_hex(abtRx, res);
135  }
136  // Succesful transfer
137  return true;
138 }
139 
140 static void
141 print_usage(char *argv[])
142 {
143  printf("Usage: %s [OPTIONS] [UID]\n", argv[0]);
144  printf("Options:\n");
145  printf("\t-h\tHelp. Print this message.\n");
146  printf("\t-f\tFormat. Delete all data (set to 0xFF) and reset ACLs to default.\n");
147  printf("\t-q\tQuiet mode. Suppress output of READER and CARD data (improves timing).\n");
148  printf("\n\tSpecify UID (4 HEX bytes) to set UID, or leave blank for default '01234567'.\n");
149  printf("\tThis utility can be used to recover cards that have been damaged by writing bad\n");
150  printf("\tdata (e.g. wrong BCC), thus making them non-selectable by most tools/readers.\n");
151  printf("\n\t*** Note: this utility only works with special Mifare 1K cards (Chinese clones).\n\n");
152 }
153 
154 int
155 main(int argc, char *argv[])
156 {
157  int arg, i;
158  bool format = false;
159  unsigned int c;
160  char tmp[3] = { 0x00, 0x00, 0x00 };
161 
162 
163  // Get commandline options
164  for (arg = 1; arg < argc; arg++) {
165  if (0 == strcmp(argv[arg], "-h")) {
166  print_usage(argv);
167  exit(EXIT_SUCCESS);
168  } else if (0 == strcmp(argv[arg], "-f")) {
169  format = true;
170  } else if (0 == strcmp(argv[arg], "-q")) {
171  quiet_output = true;
172  } else if (strlen(argv[arg]) == 8) {
173  for (i = 0 ; i < 4 ; ++i) {
174  memcpy(tmp, argv[arg] + i * 2, 2);
175  sscanf(tmp, "%02x", &c);
176  abtData[i] = (char) c;
177  }
178  abtData[4] = abtData[0] ^ abtData[1] ^ abtData[2] ^ abtData[3];
179  iso14443a_crc_append(abtData, 16);
180  } else {
181  ERR("%s is not supported option.", argv[arg]);
182  print_usage(argv);
183  exit(EXIT_FAILURE);
184  }
185  }
186 
187  nfc_context *context;
188  nfc_init(&context);
189  if (context == NULL) {
190  ERR("Unable to init libnfc (malloc)");
191  exit(EXIT_FAILURE);
192  }
193 
194  // Try to open the NFC reader
195  pnd = nfc_open(context, NULL);
196 
197  if (pnd == NULL) {
198  ERR("Error opening NFC reader");
199  nfc_exit(context);
200  exit(EXIT_FAILURE);
201  }
202 
203  // Initialise NFC device as "initiator"
204  if (nfc_initiator_init(pnd) < 0) {
205  nfc_perror(pnd, "nfc_initiator_init");
206  nfc_close(pnd);
207  nfc_exit(context);
208  exit(EXIT_FAILURE);
209  }
210 
211  // Configure the CRC
212  if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false) < 0) {
213  nfc_perror(pnd, "nfc_device_set_property_bool");
214  nfc_close(pnd);
215  nfc_exit(context);
216  exit(EXIT_FAILURE);
217  }
218  // Use raw send/receive methods
219  if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, false) < 0) {
220  nfc_perror(pnd, "nfc_device_set_property_bool");
221  nfc_close(pnd);
222  nfc_exit(context);
223  exit(EXIT_FAILURE);
224  }
225  // Disable 14443-4 autoswitching
226  if (nfc_device_set_property_bool(pnd, NP_AUTO_ISO14443_4, false) < 0) {
227  nfc_perror(pnd, "nfc_device_set_property_bool");
228  nfc_close(pnd);
229  nfc_exit(context);
230  exit(EXIT_FAILURE);
231  }
232 
233  printf("NFC reader: %s opened\n", nfc_device_get_name(pnd));
234 
235  // Send the 7 bits request command specified in ISO 14443A (0x26)
236  if (!transmit_bits(abtReqa, 7)) {
237  printf("Error: No tag available\n");
238  nfc_close(pnd);
239  nfc_exit(context);
240  exit(EXIT_FAILURE);
241  }
242  memcpy(abtAtqa, abtRx, 2);
243 
244  // Anti-collision
245  transmit_bytes(abtSelectAll, 2);
246 
247  // Check answer
248  if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0) {
249  printf("WARNING: BCC check failed!\n");
250  }
251 
252  // Save the UID CL1
253  memcpy(abtRawUid, abtRx, 4);
254 
255  //Prepare and send CL1 Select-Command
256  memcpy(abtSelectTag + 2, abtRx, 5);
257  iso14443a_crc_append(abtSelectTag, 7);
258  transmit_bytes(abtSelectTag, 9);
259  abtSak = abtRx[0];
260 
261  // Test if we are dealing with a CL2
262  if (abtSak & CASCADE_BIT) {
263  szCL = 2;//or more
264  // Check answer
265  if (abtRawUid[0] != 0x88) {
266  printf("WARNING: Cascade bit set but CT != 0x88!\n");
267  }
268  }
269 
270  if (szCL == 2) {
271  // We have to do the anti-collision for cascade level 2
272 
273  // Prepare CL2 commands
274  abtSelectAll[0] = 0x95;
275 
276  // Anti-collision
277  transmit_bytes(abtSelectAll, 2);
278 
279  // Check answer
280  if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0) {
281  printf("WARNING: BCC check failed!\n");
282  }
283 
284  // Save UID CL2
285  memcpy(abtRawUid + 4, abtRx, 4);
286 
287  // Selection
288  abtSelectTag[0] = 0x95;
289  memcpy(abtSelectTag + 2, abtRx, 5);
290  iso14443a_crc_append(abtSelectTag, 7);
291  transmit_bytes(abtSelectTag, 9);
292  abtSak = abtRx[0];
293 
294  // Test if we are dealing with a CL3
295  if (abtSak & CASCADE_BIT) {
296  szCL = 3;
297  // Check answer
298  if (abtRawUid[0] != 0x88) {
299  printf("WARNING: Cascade bit set but CT != 0x88!\n");
300  }
301  }
302 
303  if (szCL == 3) {
304  // We have to do the anti-collision for cascade level 3
305 
306  // Prepare and send CL3 AC-Command
307  abtSelectAll[0] = 0x97;
308  transmit_bytes(abtSelectAll, 2);
309 
310  // Check answer
311  if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0) {
312  printf("WARNING: BCC check failed!\n");
313  }
314 
315  // Save UID CL3
316  memcpy(abtRawUid + 8, abtRx, 4);
317 
318  // Prepare and send final Select-Command
319  abtSelectTag[0] = 0x97;
320  memcpy(abtSelectTag + 2, abtRx, 5);
321  iso14443a_crc_append(abtSelectTag, 7);
322  transmit_bytes(abtSelectTag, 9);
323  abtSak = abtRx[0];
324  }
325  }
326 
327  // Request ATS, this only applies to tags that support ISO 14443A-4
328  if (abtRx[0] & SAK_FLAG_ATS_SUPPORTED) {
329  iso_ats_supported = true;
330  }
331 
332  printf("\nFound tag with\n UID: ");
333  switch (szCL) {
334  case 1:
335  printf("%02x%02x%02x%02x", abtRawUid[0], abtRawUid[1], abtRawUid[2], abtRawUid[3]);
336  break;
337  case 2:
338  printf("%02x%02x%02x", abtRawUid[1], abtRawUid[2], abtRawUid[3]);
339  printf("%02x%02x%02x%02x", abtRawUid[4], abtRawUid[5], abtRawUid[6], abtRawUid[7]);
340  break;
341  case 3:
342  printf("%02x%02x%02x", abtRawUid[1], abtRawUid[2], abtRawUid[3]);
343  printf("%02x%02x%02x", abtRawUid[5], abtRawUid[6], abtRawUid[7]);
344  printf("%02x%02x%02x%02x", abtRawUid[8], abtRawUid[9], abtRawUid[10], abtRawUid[11]);
345  break;
346  }
347  printf("\n");
348  printf("ATQA: %02x%02x\n SAK: %02x\n", abtAtqa[1], abtAtqa[0], abtSak);
349  if (szAts > 1) { // if = 1, it's not actual ATS but error code
350  printf(" ATS: ");
351  print_hex(abtAts, szAts);
352  }
353  printf("\n");
354 
355  // now reset UID
356  iso14443a_crc_append(abtHalt, 2);
357  transmit_bytes(abtHalt, 4);
358  transmit_bits(abtUnlock1, 7);
359  if (format) {
360  transmit_bytes(abtWipe, 1);
361  transmit_bytes(abtHalt, 4);
362  transmit_bits(abtUnlock1, 7);
363  }
364  transmit_bytes(abtUnlock2, 1);
365  transmit_bytes(abtWrite, 4);
366  transmit_bytes(abtData, 18);
367  if (format) {
368  for (i = 3 ; i < 64 ; i += 4) {
369  abtWrite[1] = (char) i;
370  iso14443a_crc_append(abtWrite, 2);
371  transmit_bytes(abtWrite, 4);
372  transmit_bytes(abtBlank, 18);
373  }
374  }
375 
376  nfc_close(pnd);
377  nfc_exit(context);
378  exit(EXIT_SUCCESS);
379 }
nfc_initiator_init
int nfc_initiator_init(nfc_device *pnd)
Initialize NFC device as initiator (reader)
Definition: nfc.c:452
nfc_init
void nfc_init(nfc_context **context)
Initialize libnfc. This function must be called before calling any other libnfc function.
Definition: nfc.c:192
nfc_context
NFC library context Struct which contains internal options, references, pointers, etc....
Definition: nfc-internal.h:175
nfc_device
NFC device information.
Definition: nfc-internal.h:190
NP_HANDLE_CRC
@ NP_HANDLE_CRC
Definition: nfc-types.h:93
nfc_exit
void nfc_exit(nfc_context *context)
Deinitialize libnfc. Should be called after closing all open devices and before your application term...
Definition: nfc.c:209
nfc_initiator_transceive_bytes
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:764
SAK_FLAG_ATS_SUPPORTED
#define SAK_FLAG_ATS_SUPPORTED
Definition: nfc-mfsetuid.c:62
nfc_initiator_transceive_bits
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:807
nfc_device_get_name
const char * nfc_device_get_name(nfc_device *pnd)
Returns the device name.
Definition: nfc.c:1164
nfc_open
nfc_device * nfc_open(nfc_context *context, const nfc_connstring connstring)
Open a NFC device.
Definition: nfc.c:238
nfc_perror
void nfc_perror(const nfc_device *pnd, const char *pcString)
Display the last error occured on a nfc_device.
Definition: nfc.c:1138
NP_AUTO_ISO14443_4
@ NP_AUTO_ISO14443_4
Definition: nfc-types.h:133
ERR
#define ERR(...)
Print a error message.
Definition: nfc-utils.h:85
nfc_close
void nfc_close(nfc_device *pnd)
Close from a NFC device.
Definition: nfc.c:300
NP_EASY_FRAMING
@ NP_EASY_FRAMING
Definition: nfc-types.h:135
nfc-utils.h
Provide some examples shared functions like print, parity calculation, options parsing.
nfc_device_set_property_bool
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:426
nfc.h
libnfc interface