From 8de7ce3899b442b8b083bbebc209e32ac116ac04 Mon Sep 17 00:00:00 2001 From: Simon Yorkston Date: Sat, 9 Apr 2016 01:32:14 +1000 Subject: [PATCH 1/2] Adding support for UL Gen 2 Badges --- utils/nfc-mfultralight.c | 86 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/utils/nfc-mfultralight.c b/utils/nfc-mfultralight.c index 4d25114..01752ef 100644 --- a/utils/nfc-mfultralight.c +++ b/utils/nfc-mfultralight.c @@ -64,6 +64,18 @@ static mifare_param mp; static mifareul_tag mtDump; static uint32_t uiBlocks = 0xF; +// special unlock command +uint8_t abtUnlock1[1] = { 0x40 }; +uint8_t abtUnlock2[1] = { 0x43 }; + +//Halt command +uint8_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 }; + +#define MAX_FRAME_LEN 264 + +static uint8_t abtRx[MAX_FRAME_LEN]; +static int szRxBits; + static const nfc_modulation nmMifare = { .nmt = NMT_ISO14443A, .nbr = NBR_106, @@ -107,10 +119,77 @@ read_card(void) return (!bFailure); } +static bool +transmit_bits(const uint8_t *pbtTx, const size_t szTxBits) +{ + // Transmit the bit frame command, we don't use the arbitrary parity feature + if ((szRxBits = nfc_initiator_transceive_bits(pnd, pbtTx, szTxBits, NULL, abtRx, sizeof(abtRx), NULL)) < 0) + return false; + + return true; +} + + +static bool +transmit_bytes(const uint8_t *pbtTx, const size_t szTx) +{ + int res; + if ((res = nfc_initiator_transceive_bytes(pnd, pbtTx, szTx, abtRx, sizeof(abtRx), 0)) < 0) + return false; + + return true; +} + +static bool +unlock_card(void) +{ + // Configure the CRC + if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false) < 0) { + nfc_perror(pnd, "nfc_configure"); + return false; + } + // Use raw send/receive methods + if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, false) < 0) { + nfc_perror(pnd, "nfc_configure"); + return false; + } + + iso14443a_crc_append(abtHalt, 2); + transmit_bytes(abtHalt, 4); + // now send unlock + if (!transmit_bits(abtUnlock1, 7)) { + printf("unlock failure!\n"); + return false; + } + if (!transmit_bytes(abtUnlock2, 1)) { + printf("unlock failure!\n"); + return false; + } + + // reset reader + // Configure the CRC + if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, true) < 0) { + nfc_perror(pnd, "nfc_device_set_property_bool"); + return false; + } + // Switch off raw send/receive methods + if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, true) < 0) { + nfc_perror(pnd, "nfc_device_set_property_bool"); + return false; + } + return true; +} + static bool check_magic() { bool bFailure = false; int uid_data; - + + //Initially check if we can unlock via the MF method + if (unlock_card()) { + printf("Ultralight Magic Gen 2 Detected\n"); + return true; + } + for (uint32_t page = 0; page <= 1; page++) { // Show if the readout went well if (bFailure) { @@ -140,7 +219,8 @@ static bool check_magic() { } else { return false; } - + + printf("Ultralight Magic Gen 1 Detected\n"); return true; } @@ -183,6 +263,8 @@ write_card(bool write_otp, bool write_lock, bool write_uid) if (!write_uid) { printf("ss"); uiSkippedPages = 2; + } else { + unlock_card(); } for (int page = uiSkippedPages; page <= 0xF; page++) { From e37de54e18e03b65b123a5ba81bccc7cde355939 Mon Sep 17 00:00:00 2001 From: Simon Yorkston Date: Sat, 9 Apr 2016 03:42:01 +1000 Subject: [PATCH 2/2] Updated to remove bugs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - For cards that aren’t magic, system will refuse to attempt writing to block 0 / 1 - Tested on Gen 1 & Gen 2 cards: Gen 1 $ ./nfc-mfultralight w ul-test.dmp --full NFC device: SCM Micro / SCL3711-NFC&RW opened Found MIFARE Ultralight card with UID: 044e075ad42184 Writing 16 pages |................| Done, 16 of 16 pages written (0 pages skipped). Gen 2 $ ./nfc-mfultralight w ul-test.dmp --full NFC device: SCM Micro / SCL3711-NFC&RW opened Found MIFARE Ultralight card with UID: 044e075ad42184 Writing 16 pages |................| Done, 16 of 16 pages written (0 pages skipped). Non-magic $ ./nfc-mfultralight w ul-test.dmp --full NFC device: SCM Micro / SCL3711-NFC&RW opened Found MIFARE Ultralight card with UID: 044e075ad42184 Writing 16 pages | Unable to unlock card - are you sure the card is magic? $ --- utils/nfc-mfultralight.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/utils/nfc-mfultralight.c b/utils/nfc-mfultralight.c index 01752ef..615833f 100644 --- a/utils/nfc-mfultralight.c +++ b/utils/nfc-mfultralight.c @@ -158,11 +158,9 @@ unlock_card(void) transmit_bytes(abtHalt, 4); // now send unlock if (!transmit_bits(abtUnlock1, 7)) { - printf("unlock failure!\n"); return false; } if (!transmit_bytes(abtUnlock2, 1)) { - printf("unlock failure!\n"); return false; } @@ -184,12 +182,6 @@ static bool check_magic() { bool bFailure = false; int uid_data; - //Initially check if we can unlock via the MF method - if (unlock_card()) { - printf("Ultralight Magic Gen 2 Detected\n"); - return true; - } - for (uint32_t page = 0; page <= 1; page++) { // Show if the readout went well if (bFailure) { @@ -213,15 +205,24 @@ static bool check_magic() { //Check that the ID is now set to 0x000000000000 if (nfc_initiator_mifare_cmd(pnd, MC_READ, 0, &mp)) { //printf("%u", mp.mpd.abtData); + bool result = true; for(int i = 0; i <= 7; i++) { - if (mp.mpd.abtData[i] != 0x00) return false; + if (mp.mpd.abtData[i] != 0x00) result = false; } + + if (result) { + return true; + } + + } + + //Initially check if we can unlock via the MF method + if (unlock_card()) { + return true; } else { - return false; + return false; } - printf("Ultralight Magic Gen 1 Detected\n"); - return true; } static bool @@ -264,7 +265,11 @@ write_card(bool write_otp, bool write_lock, bool write_uid) printf("ss"); uiSkippedPages = 2; } else { - unlock_card(); + if (!check_magic()) { + printf("\nUnable to unlock card - are you sure the card is magic?\n"); + return false; + bFailure = false; + } } for (int page = uiSkippedPages; page <= 0xF; page++) {