00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00025 #ifdef HAVE_CONFIG_H
00026 # include "config.h"
00027 #endif // HAVE_CONFIG_H
00028
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <stdint.h>
00032 #include <stddef.h>
00033 #include <stdbool.h>
00034
00035 #include <string.h>
00036 #include <ctype.h>
00037
00038 #include <nfc/nfc.h>
00039 #include <nfc/nfc-messages.h>
00040
00041 #include "mifare.h"
00042 #include "nfc-utils.h"
00043
00044 static nfc_device_t *pnd;
00045 static nfc_target_info_t nti;
00046 static mifare_param mp;
00047 static mifareul_tag mtDump;
00048 static uint32_t uiBlocks = 0xF;
00049
00050 static void
00051 print_success_or_failure (bool bFailure, uint32_t * uiCounter)
00052 {
00053 printf ("%c", (bFailure) ? 'x' : '.');
00054 if (uiCounter)
00055 *uiCounter += (bFailure) ? 0 : 1;
00056 }
00057
00058 static bool
00059 read_card (void)
00060 {
00061 uint32_t page;
00062 bool bFailure = false;
00063 uint32_t uiReadedPages = 0;
00064
00065 printf ("Reading %d pages |", uiBlocks + 1);
00066
00067 for (page = 0; page <= uiBlocks; page += 4) {
00068
00069 if (nfc_initiator_mifare_cmd (pnd, MC_READ, page, &mp)) {
00070 memcpy (mtDump.amb[page / 4].mbd.abtData, mp.mpd.abtData, 16);
00071 } else {
00072 bFailure = true;
00073 break;
00074 }
00075
00076 print_success_or_failure (bFailure, &uiReadedPages);
00077 print_success_or_failure (bFailure, &uiReadedPages);
00078 print_success_or_failure (bFailure, &uiReadedPages);
00079 print_success_or_failure (bFailure, &uiReadedPages);
00080 }
00081 printf ("|\n");
00082 printf ("Done, %d of %d pages readed.\n", uiReadedPages, uiBlocks + 1);
00083 fflush (stdout);
00084
00085 return (!bFailure);
00086 }
00087
00088 static bool
00089 write_card (void)
00090 {
00091 uint32_t uiBlock = 0;
00092 int page = 0x4;
00093 bool bFailure = false;
00094 uint32_t uiWritenPages = 0;
00095
00096 char buffer[BUFSIZ];
00097 bool write_otp;
00098
00099 printf ("Write OTP bytes ? [yN] ");
00100 fgets (buffer, BUFSIZ, stdin);
00101 write_otp = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
00102
00103
00104 printf ("Writing %d pages |", uiBlocks + 1);
00105 printf ("sss");
00106
00107 if (write_otp) {
00108 page = 0x3;
00109 } else {
00110
00111 printf ("s");
00112 page = 0x4;
00113 }
00114
00115 for (; page <= 0xF; page++) {
00116
00117 if (bFailure) {
00118
00119 if (!nfc_initiator_select_passive_target (pnd, NM_ISO14443A_106, NULL, 0, &nti)) {
00120 ERR ("tag was removed");
00121 return false;
00122 }
00123 bFailure = false;
00124 }
00125
00126
00127
00128
00129 uiBlock = page / 4;
00130 memcpy (mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData + ((page % 4) * 4), 16);
00131 if (!nfc_initiator_mifare_cmd (pnd, MC_WRITE, page, &mp))
00132 bFailure = true;
00133
00134 print_success_or_failure (bFailure, &uiWritenPages);
00135 }
00136 printf ("|\n");
00137 printf ("Done, %d of %d pages written (%d first pages are skipped).\n", uiWritenPages, uiBlocks + 1,
00138 write_otp ? 3 : 4);
00139
00140 return true;
00141 }
00142
00143 int
00144 main (int argc, const char *argv[])
00145 {
00146 bool bReadAction;
00147 byte_t *pbtUID;
00148 FILE *pfDump;
00149
00150 if (argc < 3) {
00151 printf ("\n");
00152 printf ("%s r|w <dump.mfd>\n", argv[0]);
00153 printf ("\n");
00154 printf ("r|w - Perform read from or write to card\n");
00155 printf ("<dump.mfd> - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n");
00156 printf ("\n");
00157 return 1;
00158 }
00159
00160 DBG ("\nChecking arguments and settings\n");
00161
00162 bReadAction = tolower ((int) ((unsigned char) *(argv[1])) == 'r');
00163
00164 if (bReadAction) {
00165 memset (&mtDump, 0x00, sizeof (mtDump));
00166 } else {
00167 pfDump = fopen (argv[2], "rb");
00168
00169 if (pfDump == NULL) {
00170 ERR ("Could not open dump file: %s\n", argv[2]);
00171 return 1;
00172 }
00173
00174 if (fread (&mtDump, 1, sizeof (mtDump), pfDump) != sizeof (mtDump)) {
00175 ERR ("Could not read from dump file: %s\n", argv[2]);
00176 fclose (pfDump);
00177 return 1;
00178 }
00179 fclose (pfDump);
00180 }
00181 DBG ("Successfully opened the dump file\n");
00182
00183
00184 pnd = nfc_connect (NULL);
00185 if (pnd == NULL) {
00186 ERR ("Error connecting NFC reader\n");
00187 return 1;
00188 }
00189
00190 nfc_initiator_init (pnd);
00191
00192
00193 if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) {
00194 nfc_perror (pnd, "nfc_configure");
00195 exit (EXIT_FAILURE);
00196 }
00197
00198 if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
00199 nfc_perror (pnd, "nfc_configure");
00200 exit (EXIT_FAILURE);
00201 }
00202 if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
00203 nfc_perror (pnd, "nfc_configure");
00204 exit (EXIT_FAILURE);
00205 }
00206 if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
00207 nfc_perror (pnd, "nfc_configure");
00208 exit (EXIT_FAILURE);
00209 }
00210
00211 if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
00212 nfc_perror (pnd, "nfc_configure");
00213 exit (EXIT_FAILURE);
00214 }
00215
00216 printf ("Connected to NFC reader: %s\n", pnd->acName);
00217
00218
00219 if (!nfc_initiator_select_passive_target (pnd, NM_ISO14443A_106, NULL, 0, &nti)) {
00220 ERR ("no tag was found\n");
00221 nfc_disconnect (pnd);
00222 return 1;
00223 }
00224
00225
00226 if (nti.nai.abtAtqa[1] != 0x44) {
00227 ERR ("tag is not a MIFARE Ultralight card\n");
00228 nfc_disconnect (pnd);
00229 return EXIT_FAILURE;
00230 }
00231
00232 pbtUID = nti.nai.abtUid;
00233 printf ("Found MIFARE Ultralight card with UID: %02x%02x%02x%02x\n", pbtUID[3], pbtUID[2], pbtUID[1], pbtUID[0]);
00234
00235 if (bReadAction) {
00236 if (read_card ()) {
00237 printf ("Writing data to file: %s ... ", argv[2]);
00238 fflush (stdout);
00239 pfDump = fopen (argv[2], "wb");
00240 if (pfDump == NULL) {
00241 printf ("Could not open file: %s\n", argv[2]);
00242 return EXIT_FAILURE;
00243 }
00244 if (fwrite (&mtDump, 1, sizeof (mtDump), pfDump) != sizeof (mtDump)) {
00245 printf ("Could not write to file: %s\n", argv[2]);
00246 return EXIT_FAILURE;
00247 }
00248 fclose (pfDump);
00249 printf ("Done.\n");
00250 }
00251 } else {
00252 write_card ();
00253 }
00254
00255 nfc_disconnect (pnd);
00256
00257 return EXIT_SUCCESS;
00258 }