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