62 #define MAX_TARGET_COUNT 16
63 #define MAX_UID_LEN 10
76 static mifare_param mp;
78 static uint32_t uiBlocks = 0x10;
79 static uint32_t uiReadPages = 0;
80 static uint8_t iPWD[4] = { 0x0 };
81 static uint8_t iPACK[2] = { 0x0 };
82 static uint8_t iEV1Type = EV1_NONE;
83 static uint8_t iNTAGType = NTAG_NONE;
86 uint8_t abtUnlock1[1] = { 0x40 };
87 uint8_t abtUnlock2[1] = { 0x43 };
90 uint8_t abtEV1[3] = { 0x60, 0x00, 0x00 };
91 uint8_t abtPWAuth[7] = { 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
94 uint8_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 };
96 #define MAX_FRAME_LEN 264
98 static uint8_t abtRx[MAX_FRAME_LEN];
103 .nmt = NMT_ISO14443A,
108 print_success_or_failure(
bool bFailure, uint32_t *uiOkCounter, uint32_t *uiFailedCounter)
110 printf(
"%c", (bFailure) ?
'f' :
'.');
112 *uiOkCounter += (bFailure) ? 0 : 1;
114 *uiFailedCounter += (bFailure) ? 1 : 0;
121 bool bFailure =
false;
122 uint32_t uiFailedPages = 0;
124 printf(
"Reading %d pages |", uiBlocks);
126 for (page = 0; page < uiBlocks; page += 4) {
129 memcpy(mtDump.ul[page / 4].mbd.abtData, mp.mpd.abtData, uiBlocks - page < 4 ? (uiBlocks - page) * 4 : 16);
133 for (uint8_t i = 0; i < (uiBlocks - page < 4 ? uiBlocks - page : 4); i++) {
134 print_success_or_failure(bFailure, &uiReadPages, &uiFailedPages);
138 printf(
"Done, %d of %d pages read (%d pages failed).\n", uiReadPages, uiBlocks, uiFailedPages);
144 memcpy(mtDump.ul[4].mbc11.pwd, iPWD, 4);
145 memcpy(mtDump.ul[4].mbc11.pack, iPACK, 2);
148 memcpy(mtDump.ul[9].mbc21a.pwd, iPWD, 4);
149 memcpy(mtDump.ul[9].mbc21b.pack, iPACK, 2);
158 memcpy(mtDump.nt[43].mbc21356d.pwd, iPWD, 4);
159 memcpy(mtDump.nt[44].mbc21356e.pack, iPACK, 2);
162 memcpy(mtDump.nt[133].mbc21356d.pwd, iPWD, 4);
163 memcpy(mtDump.nt[134].mbc21356e.pack, iPACK, 2);
166 memcpy(mtDump.nt[229].mbc21356d.pwd, iPWD, 4);
167 memcpy(mtDump.nt[230].mbc21356e.pack, iPACK, 2);
178 transmit_bits(
const uint8_t *pbtTx,
const size_t szTxBits)
189 transmit_bytes(
const uint8_t *pbtTx,
const size_t szTx)
219 nfc_perror(pnd,
"nfc_device_set_property_bool");
224 nfc_perror(pnd,
"nfc_device_set_property_bool");
231 get_ev1_version(
void)
233 if (!raw_mode_start())
235 iso14443a_crc_append(abtEV1, 1);
236 if (!transmit_bytes(abtEV1, 3)) {
248 ev1_load_pwd(uint8_t target[4],
const char *pwd)
251 if (sscanf(pwd,
"%2x%2x%2x%2x", &tmp[0], &tmp[1], &tmp[2], &tmp[3]) != 4)
261 ev1_pwd_auth(uint8_t *pwd)
263 if (!raw_mode_start())
265 memcpy(&abtPWAuth[1], pwd, 4);
266 iso14443a_crc_append(abtPWAuth, 5);
267 if (!transmit_bytes(abtPWAuth, 7))
277 if (!raw_mode_start())
279 iso14443a_crc_append(abtHalt, 2);
280 transmit_bytes(abtHalt, 4);
282 if (!transmit_bits(abtUnlock1, 7)) {
285 if (!transmit_bytes(abtUnlock2, 1)) {
294 static bool check_magic(
void)
296 bool directWrite =
true;
298 uint8_t original_b0[12];
299 printf(
"Checking if UL badge is DirectWrite...\n");
301 memcpy(original_b0, mp.mpd.abtData, 12);
302 printf(
" Original Block 0 (Pages 0-2): ");
303 for (
int i = 0; i < 12; i++) {
304 printf(
"%02x", original_b0[i]);
307 printf(
" Original UID: %02x%02x%02x%02x%02x%02x%02x\n",
308 original_b0[0], original_b0[1], original_b0[2], original_b0[4], original_b0[5], original_b0[6], original_b0[7]);
310 printf(
"!\nError: unable to read block 0x%02x\n", 0);
313 printf(
" Attempt to write Block 0 (pages 0-2) ...\n");
314 for (uint32_t page = 0; page <= 2; page++) {
315 printf(
" Writing Page %i:", page);
316 memcpy(mp.mpd.abtData, original_b0 + page * 4, 4);
317 for (
int i = 0; i < 4; i++) {
318 printf(
" %02x", mp.mpd.abtData[i]);
322 printf(
" Failure writing Page %i\n", page);
328 printf(
" Block 0 written successfully\n");
329 printf(
"Card is DirectWrite\n");
332 printf(
"Card is not DirectWrite\n");
333 return unlock_card();
339 write_card(
bool write_otp,
bool write_lock,
bool write_dyn_lock,
bool write_uid)
341 uint32_t uiBlock = 0;
342 bool bFailure =
false;
343 uint32_t uiWrittenPages = 0;
344 uint32_t uiSkippedPages = 0;
345 uint32_t uiFailedPages = 0;
350 printf(
"Write OTP/Capability Bytes ? [yN] ");
351 if (!fgets(buffer, BUFSIZ, stdin)) {
352 ERR(
"Unable to read standard input.");
354 write_otp = ((buffer[0] ==
'y') || (buffer[0] ==
'Y'));
359 printf(
"Write Lock Bytes (Warning: OTP if set) ? [yN] ");
360 if (!fgets(buffer, BUFSIZ, stdin)) {
361 ERR(
"Unable to read standard input.");
363 write_lock = ((buffer[0] ==
'y') || (buffer[0] ==
'Y'));
367 if (!write_dyn_lock && (iNTAGType != NTAG_NONE || iEV1Type == EV1_UL21)) {
368 printf(
"Write Dynamic Lock Bytes ? [yN] ");
369 if (!fgets(buffer, BUFSIZ, stdin)) {
370 ERR(
"Unable to read standard input.");
372 write_dyn_lock = ((buffer[0] ==
'y') || (buffer[0] ==
'Y'));
376 printf(
"Write UID bytes (only for special writeable UID cards) ? [yN] ");
377 if (!fgets(buffer, BUFSIZ, stdin)) {
378 ERR(
"Unable to read standard input.");
380 write_uid = ((buffer[0] ==
'y') || (buffer[0] ==
'Y'));
385 printf(
"Writing %d pages |", uiBlocks);
389 if (!check_magic()) {
390 printf(
"\nUnable to unlock card - are you sure the card is magic?\n");
393 printf(
"Writing %d pages |", uiBlocks);
396 for (uint32_t page = uiSkippedPages; page < uiBlocks; page++) {
397 if ((!write_lock) && page == 0x2) {
403 if ((page == 0x3) && (!write_otp)) {
409 if (((iEV1Type == EV1_UL21 && page == 0x24) || \
410 (iNTAGType == NTAG_213 && page == 0x28) || \
411 (iNTAGType == NTAG_215 && page == 0x82) || \
412 (iNTAGType == NTAG_216 && page == 0xe2)) && (!write_dyn_lock)) {
421 ERR(
"tag was removed");
431 memcpy(mp.mpd.abtData, mtDump.ul[uiBlock].mbd.abtData + ((page % 4) * 4), 4);
432 memset(mp.mpd.abtData + 4, 0, 12);
435 print_success_or_failure(bFailure, &uiWrittenPages, &uiFailedPages);
438 printf(
"Done, %d of %d pages written (%d pages skipped, %d pages failed).\n", uiWrittenPages, uiBlocks, uiSkippedPages, uiFailedPages);
443 static int list_passive_targets(
nfc_device *_pnd)
450 return -EXIT_FAILURE;
457 printf(
"%d ISO14443A passive target(s) found:\n", res);
459 for (i = 0; i < res; i++) {
463 for (szPos = 0; szPos < ant[i].nti.nai.szUidLen; szPos++) {
464 printf(
"%02x", ant[i].nti.nai.abtUid[szPos]);
474 static size_t str_to_uid(
const char *str, uint8_t *uid)
478 memset(uid, 0x0, MAX_UID_LEN);
480 while ((*str !=
'\0') && ((i >> 1) < MAX_UID_LEN)) {
481 char nibble[2] = { 0x00,
'\n' };
484 if (isxdigit(nibble[0])) {
485 if (isupper(nibble[0]))
486 nibble[0] = tolower(nibble[0]);
487 uid[i >> 1] |= strtol(nibble, NULL, 16) << ((i % 2) ? 0 : 4) & ((i % 2) ? 0x0f : 0xf0);
495 print_usage(
const char *argv[])
497 printf(
"Usage: %s r|w <dump.mfd> [OPTIONS]\n", argv[0]);
498 printf(
"Arguments:\n");
499 printf(
"\tr|w - Perform read or write\n");
500 printf(
"\t<dump.mfd> - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n");
501 printf(
"Options:\n");
502 printf(
"\t--otp - Don't prompt for OTP Bytes writing (Assume yes)\n");
503 printf(
"\t--lock - Don't prompt for Lock Bytes (OTP) writing (Assume yes)\n");
504 printf(
"\t--dynlock - Don't prompt for Dynamic Lock Bytes writing (Assume yes)\n");
505 printf(
"\t--uid - Don't prompt for UID writing (Assume yes)\n");
506 printf(
"\t--full - Assume full card write (UID + OTP + Lockbytes + Dynamic Lockbytes)\n");
507 printf(
"\t--with-uid <UID> - Specify UID to read/write from\n");
508 printf(
"\t--pw <PWD> - Specify 8 HEX digit PASSWORD for EV1\n");
509 printf(
"\t--partial - Allow source data size to be other than tag capacity\n");
513 main(
int argc,
const char *argv[])
516 size_t iDumpSize =
sizeof(mifareul_tag);
517 uint8_t iUID[MAX_UID_LEN] = { 0x0 };
521 bool bDynLock =
false;
525 bool bFilename =
false;
533 DBG(
"\nChecking arguments and settings\n");
536 for (
int arg = 1; arg < argc; arg++) {
537 if (0 == strcmp(argv[arg],
"r")) {
539 }
else if (0 == strcmp(argv[arg],
"w")) {
541 }
else if (0 == strcmp(argv[arg],
"--with-uid")) {
542 if (arg + 1 == argc) {
543 ERR(
"Please supply a UID of 4, 7 or 10 bytes long. Ex: a1:b2:c3:d4");
546 szUID = str_to_uid(argv[++arg], iUID);
547 }
else if (0 == strcmp(argv[arg],
"--full")) {
552 }
else if (0 == strcmp(argv[arg],
"--otp")) {
554 }
else if (0 == strcmp(argv[arg],
"--lock")) {
556 }
else if (0 == strcmp(argv[arg],
"--dynlock")) {
558 }
else if (0 == strcmp(argv[arg],
"--uid")) {
560 }
else if (0 == strcmp(argv[arg],
"--check-magic")) {
562 }
else if (0 == strcmp(argv[arg],
"--partial")) {
564 }
else if (0 == strcmp(argv[arg],
"--pw")) {
566 if (arg + 1 == argc || strlen(argv[++arg]) != 8 || ! ev1_load_pwd(iPWD, argv[arg])) {
567 ERR(
"Please supply a PASSWORD of 8 HEX digits");
573 ERR(
"%s is not a supported option.", argv[arg]);
581 if (iAction != 3 && !bFilename) {
582 ERR(
"Please supply a Mifare Dump filename");
588 if (context == NULL) {
589 ERR(
"Unable to init libnfc (malloc)");
596 ERR(
"Error opening NFC device");
602 if (list_passive_targets(pnd)) {
603 nfc_perror(pnd,
"nfc_device_set_property_bool");
618 nfc_perror(pnd,
"nfc_device_set_property_bool");
626 ERR(
"no tag was found\n");
633 if (nt.nti.nai.abtAtqa[1] != 0x44) {
634 ERR(
"tag is not a MIFARE Ultralight card\n");
640 printf(
"Using MIFARE Ultralight card with UID: ");
642 for (szPos = 0; szPos < nt.nti.nai.szUidLen; szPos++) {
643 printf(
"%02x", nt.nti.nai.abtUid[szPos]);
648 if (get_ev1_version()) {
650 printf(
"WARNING: Tag is EV1 or NTAG - PASSWORD may be required\n");
651 if (abtRx[6] == 0x0b || abtRx[6] == 0x00) {
652 printf(
"EV1 type: MF0UL11 (48 bytes)\n");
654 iDumpSize = uiBlocks * 4;
656 }
else if (abtRx[6] == 0x0e) {
657 printf(
"EV1 type: MF0UL21 (128 user bytes)\n");
659 iDumpSize = uiBlocks * 4;
661 }
else if (abtRx[6] == 0x0f) {
662 printf(
"NTAG Type: NTAG213 (144 user bytes)\n");
664 iDumpSize = uiBlocks * 4;
665 iNTAGType = NTAG_213;
666 }
else if (abtRx[6] == 0x11) {
667 printf(
"NTAG Type: NTAG215 (504 user bytes)\n");
669 iDumpSize = uiBlocks * 4;
670 iNTAGType = NTAG_215;
671 }
else if (abtRx[6] == 0x13) {
672 printf(
"NTAG Type: NTAG216 (888 user bytes)\n");
674 iDumpSize = uiBlocks * 4;
675 iNTAGType = NTAG_216;
677 printf(
"unknown! (0x%02x)\n", abtRx[6]);
683 ERR(
"no tag was found\n");
692 printf(
"Authing with PWD: %02x%02x%02x%02x ", iPWD[0], iPWD[1], iPWD[2], iPWD[3]);
693 if (!ev1_pwd_auth(iPWD)) {
695 ERR(
"AUTH failed!\n");
698 printf(
"Success - PACK: %02x%02x\n", abtRx[0], abtRx[1]);
699 memcpy(iPACK, abtRx, 2);
704 memset(&mtDump, 0x00,
sizeof(mtDump));
705 }
else if (iAction == 2) {
706 pfDump = fopen(argv[2],
"rb");
708 if (pfDump == NULL) {
709 ERR(
"Could not open dump file: %s\n", argv[2]);
714 if (((szDump = fread(&mtDump, 1,
sizeof(mtDump), pfDump)) != iDumpSize && !bPart) || szDump <= 0) {
715 ERR(
"Could not read from dump file or size mismatch: %s (read %lu, expected %lu)\n", argv[2], (
unsigned long)szDump, (
unsigned long)iDumpSize);
719 if (szDump != iDumpSize)
720 printf(
"Performing partial write\n");
722 DBG(
"Successfully opened the dump file\n");
723 }
else if (iAction == 3) {
724 DBG(
"Switching to Check Magic Mode\n");
726 ERR(
"Unable to determine operating mode");
731 bool bRF = read_card();
732 printf(
"Writing data to file: %s ... ", argv[2]);
734 pfDump = fopen(argv[2],
"wb");
735 if (pfDump == NULL) {
736 printf(
"Could not open file: %s\n", argv[2]);
741 if (fwrite(&mtDump, 1, uiReadPages * 4, pfDump) != uiReadPages * 4) {
742 printf(
"Could not write to file: %s\n", argv[2]);
751 printf(
"Warning! Read failed - partial data written to file!\n");
752 }
else if (iAction == 2) {
753 write_card(bOTP, bLock, bDynLock, bUID);
754 }
else if (iAction == 3) {
755 if (!check_magic()) {
756 printf(
"Card is not magic\n");
761 printf(
"Card is magic\n");
const char * nfc_device_get_name(nfc_device *pnd)
Returns the device name.
void nfc_close(nfc_device *pnd)
Close from a NFC device.
nfc_device * nfc_open(nfc_context *context, const nfc_connstring connstring)
Open a NFC device.
void nfc_perror(const nfc_device *pnd, const char *pcString)
Display the last error occured on a nfc_device.
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.
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.
int nfc_initiator_init(nfc_device *pnd)
Initialize NFC device as initiator (reader)
int nfc_initiator_list_passive_targets(nfc_device *pnd, const nfc_modulation nm, nfc_target ant[], const size_t szTargets)
List passive or emulated tags.
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.
void nfc_exit(nfc_context *context)
Deinitialize libnfc. Should be called after closing all open devices and before your application term...
void nfc_init(nfc_context **context)
Initialize libnfc. This function must be called before calling any other libnfc function.
int nfc_device_set_property_bool(nfc_device *pnd, const nfc_property property, const bool bEnable)
Set a device's boolean-property value.
bool nfc_initiator_mifare_cmd(nfc_device *pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param *pmp)
Execute a MIFARE Classic Command.
provide samples structs and functions to manipulate MIFARE Classic and Ultralight tags using libnfc
Provide some examples shared functions like print, parity calculation, options parsing.
#define ERR(...)
Print a error message.
#define DBG(...)
Print a message of standard output only in DEBUG mode.
NFC library context Struct which contains internal options, references, pointers, etc....
NFC modulation structure.