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 fgets (buffer, BUFSIZ, stdin);
00117 write_otp = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
00118 printf ("Write Lock bytes ? [yN] ");
00119 fgets (buffer, BUFSIZ, stdin);
00120 write_lock = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
00121
00122 printf ("Writing %d pages |", uiBlocks + 1);
00123
00124 printf ("ss");
00125 uiSkippedPages = 2;
00126
00127 for (int page = 0x2; page <= 0xF; page++) {
00128 if ((page==0x2) && (!write_lock)) {
00129 printf ("s");
00130 uiSkippedPages++;
00131 continue;
00132 }
00133 if ((page==0x3) && (!write_otp)) {
00134 printf ("s");
00135 uiSkippedPages++;
00136 continue;
00137 }
00138
00139 if (bFailure) {
00140
00141 if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt)) {
00142 ERR ("tag was removed");
00143 return false;
00144 }
00145 bFailure = false;
00146 }
00147
00148
00149
00150
00151 uiBlock = page / 4;
00152 memcpy (mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData + ((page % 4) * 4), 16);
00153 if (!nfc_initiator_mifare_cmd (pnd, MC_WRITE, page, &mp))
00154 bFailure = true;
00155
00156 print_success_or_failure (bFailure, &uiWritenPages);
00157 }
00158 printf ("|\n");
00159 printf ("Done, %d of %d pages written (%d pages skipped).\n", uiWritenPages, uiBlocks + 1, uiSkippedPages);
00160
00161 return true;
00162 }
00163
00164 int
00165 main (int argc, const char *argv[])
00166 {
00167 bool bReadAction;
00168 FILE *pfDump;
00169
00170 if (argc < 3) {
00171 printf ("\n");
00172 printf ("%s r|w <dump.mfd>\n", argv[0]);
00173 printf ("\n");
00174 printf ("r|w - Perform read from or write to card\n");
00175 printf ("<dump.mfd> - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n");
00176 printf ("\n");
00177 return 1;
00178 }
00179
00180 DBG ("\nChecking arguments and settings\n");
00181
00182 bReadAction = tolower ((int) ((unsigned char) *(argv[1])) == 'r');
00183
00184 if (bReadAction) {
00185 memset (&mtDump, 0x00, sizeof (mtDump));
00186 } else {
00187 pfDump = fopen (argv[2], "rb");
00188
00189 if (pfDump == NULL) {
00190 ERR ("Could not open dump file: %s\n", argv[2]);
00191 return 1;
00192 }
00193
00194 if (fread (&mtDump, 1, sizeof (mtDump), pfDump) != sizeof (mtDump)) {
00195 ERR ("Could not read from dump file: %s\n", argv[2]);
00196 fclose (pfDump);
00197 return 1;
00198 }
00199 fclose (pfDump);
00200 }
00201 DBG ("Successfully opened the dump file\n");
00202
00203
00204 pnd = nfc_connect (NULL);
00205 if (pnd == NULL) {
00206 ERR ("Error connecting NFC device\n");
00207 return 1;
00208 }
00209
00210 nfc_initiator_init (pnd);
00211
00212
00213 if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) {
00214 nfc_perror (pnd, "nfc_configure");
00215 exit (EXIT_FAILURE);
00216 }
00217
00218 if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
00219 nfc_perror (pnd, "nfc_configure");
00220 exit (EXIT_FAILURE);
00221 }
00222 if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
00223 nfc_perror (pnd, "nfc_configure");
00224 exit (EXIT_FAILURE);
00225 }
00226 if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
00227 nfc_perror (pnd, "nfc_configure");
00228 exit (EXIT_FAILURE);
00229 }
00230
00231 if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
00232 nfc_perror (pnd, "nfc_configure");
00233 exit (EXIT_FAILURE);
00234 }
00235
00236 printf ("Connected to NFC device: %s\n", pnd->acName);
00237
00238
00239 if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt)) {
00240 ERR ("no tag was found\n");
00241 nfc_disconnect (pnd);
00242 return 1;
00243 }
00244
00245
00246 if (nt.nti.nai.abtAtqa[1] != 0x44) {
00247 ERR ("tag is not a MIFARE Ultralight card\n");
00248 nfc_disconnect (pnd);
00249 return EXIT_FAILURE;
00250 }
00251
00252 printf ("Found MIFARE Ultralight card with UID: ");
00253 size_t szPos;
00254 for (szPos = 0; szPos < nt.nti.nai.szUidLen; szPos++) {
00255 printf ("%02x", nt.nti.nai.abtUid[szPos]);
00256 }
00257 printf("\n");
00258
00259 if (bReadAction) {
00260 if (read_card ()) {
00261 printf ("Writing data to file: %s ... ", argv[2]);
00262 fflush (stdout);
00263 pfDump = fopen (argv[2], "wb");
00264 if (pfDump == NULL) {
00265 printf ("Could not open file: %s\n", argv[2]);
00266 return EXIT_FAILURE;
00267 }
00268 if (fwrite (&mtDump, 1, sizeof (mtDump), pfDump) != sizeof (mtDump)) {
00269 printf ("Could not write to file: %s\n", argv[2]);
00270 return EXIT_FAILURE;
00271 }
00272 fclose (pfDump);
00273 printf ("Done.\n");
00274 }
00275 } else {
00276 write_card ();
00277 }
00278
00279 nfc_disconnect (pnd);
00280
00281 return EXIT_SUCCESS;
00282 }