Skip to content

Commit

Permalink
nfc-mfultralight: fix support for MF0UL21
Browse files Browse the repository at this point in the history
  • Loading branch information
doegox committed Mar 31, 2017
1 parent 560f6a6 commit 3ec9ecf
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 27 deletions.
36 changes: 29 additions & 7 deletions utils/mifare.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,18 +134,38 @@ typedef struct {
uint8_t otp[4];
} mifareul_block_manufacturer;

// MIFARE Ultralight EV1 Config Pages
// MIFARE Ultralight EV1 MF0UL11 Config Pages
typedef struct {
uint8_t mod;
uint8_t rfui[2];
uint8_t rfui1[2];
uint8_t auth0;
uint8_t access;
uint8_t vctid;
uint8_t rfui1[2];
uint8_t rfui2[2];
uint8_t pwd[4];
uint8_t pack[2];
uint8_t rfui3[2];
} mifareul_block_config11;

// MIFARE Ultralight EV1 MF0UL21 ConfigA Pages
typedef struct {
uint8_t lock[3];
uint8_t rfui0;
uint8_t mod;
uint8_t rfui1[2];
uint8_t auth0;
uint8_t access;
uint8_t vctid;
uint8_t rfui2[2];
} mifareul_block_config;
uint8_t pwd[4];
} mifareul_block_config21A;

// MIFARE Ultralight EV1 MF0UL21 ConfigB Pages
typedef struct {
uint8_t pack[2];
uint8_t rfui3[2];
uint8_t dummy[12];
} mifareul_block_config21B;

typedef struct {
uint8_t abtData[16];
Expand All @@ -154,7 +174,9 @@ typedef struct {
typedef union {
mifareul_block_manufacturer mbm;
mifareul_block_data mbd;
mifareul_block_config mbc;
mifareul_block_config11 mbc11;
mifareul_block_config21A mbc21a;
mifareul_block_config21B mbc21b;
} mifareul_block;

// standard UL tag - 1 manuf block + 3 user blocks
Expand All @@ -167,9 +189,9 @@ typedef struct {
mifareul_block amb[5];
} mifareul_ev1_mf0ul11_tag;

// UL EV1 MF0UL21 tag - 1 manuf block + 8 user blocks + 1 config block
// UL EV1 MF0UL21 tag - 1 manuf block + 8 user blocks + 1/4 lock block + 1 config block
typedef struct {
mifareul_block amb[10];
mifareul_block amb[11];
} mifareul_ev1_mf0ul21_tag;

// Reset struct alignment to default
Expand Down
37 changes: 17 additions & 20 deletions utils/nfc-mfultralight.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@

#define MAX_TARGET_COUNT 16
#define MAX_UID_LEN 10
#define BLOCK_COUNT 0xf

#define EV1_NONE 0
#define EV1_UL11 1
Expand All @@ -70,7 +69,7 @@ static nfc_device *pnd;
static nfc_target nt;
static mifare_param mp;
static mifareul_ev1_mf0ul21_tag mtDump; // use the largest tag type for internal storage
static uint32_t uiBlocks = BLOCK_COUNT;
static uint32_t uiBlocks = 0x10;
static uint32_t uiReadPages = 0;
static uint8_t iPWD[4] = { 0x0 };
static uint8_t iPACK[2] = { 0x0 };
Expand Down Expand Up @@ -115,34 +114,32 @@ read_card(void)
bool bFailure = false;
uint32_t uiFailedPages = 0;

printf("Reading %d pages |", uiBlocks + 1);
printf("Reading %d pages |", uiBlocks);

for (page = 0; page <= uiBlocks; page += 4) {
for (page = 0; page < uiBlocks; page += 4) {
// Try to read out the data block
if (nfc_initiator_mifare_cmd(pnd, MC_READ, page, &mp)) {
memcpy(mtDump.amb[page / 4].mbd.abtData, mp.mpd.abtData, 16);
memcpy(mtDump.amb[page / 4].mbd.abtData, mp.mpd.abtData, uiBlocks - page < 4 ? (uiBlocks - page) * 4 : 16);
} else {
bFailure = true;
}

print_success_or_failure(bFailure, &uiReadPages, &uiFailedPages);
print_success_or_failure(bFailure, &uiReadPages, &uiFailedPages);
print_success_or_failure(bFailure, &uiReadPages, &uiFailedPages);
print_success_or_failure(bFailure, &uiReadPages, &uiFailedPages);
for (uint8_t i=0; i < (uiBlocks - page < 4 ? uiBlocks - page : 4); i++) {
print_success_or_failure(bFailure, &uiReadPages, &uiFailedPages);
}
}
printf("|\n");
printf("Done, %d of %d pages read (%d pages failed).\n", uiReadPages, uiBlocks + 1, uiFailedPages);
printf("Done, %d of %d pages read (%d pages failed).\n", uiReadPages, uiBlocks, uiFailedPages);
fflush(stdout);

// copy EV1 secrets to dump data
switch(iEV1Type) {
case EV1_UL11:
memcpy(mtDump.amb[4].mbc.pwd, iPWD, 4);
memcpy(mtDump.amb[4].mbc.pack, iPACK, 2);
memcpy(mtDump.amb[4].mbc11.pwd, iPWD, 4);
memcpy(mtDump.amb[4].mbc11.pack, iPACK, 2);
break;
case EV1_UL21:
memcpy(mtDump.amb[9].mbc.pwd, iPWD, 4);
memcpy(mtDump.amb[9].mbc.pack, iPACK, 2);
memcpy(mtDump.amb[9].mbc21a.pwd, iPWD, 4);
memcpy(mtDump.amb[9].mbc21b.pack, iPACK, 2);
break;
case EV1_NONE:
default:
Expand Down Expand Up @@ -347,7 +344,7 @@ write_card(bool write_otp, bool write_lock, bool write_uid)
write_uid = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
}

printf("Writing %d pages |", uiBlocks + 1);
printf("Writing %d pages |", uiBlocks);
/* We may need to skip 2 first pages. */
if (!write_uid) {
printf("ss");
Expand All @@ -359,7 +356,7 @@ write_card(bool write_otp, bool write_lock, bool write_uid)
}
}

for (uint32_t page = uiSkippedPages; page <= uiBlocks; page++) {
for (uint32_t page = uiSkippedPages; page < uiBlocks; page++) {
if ((page == 0x2) && (!write_lock)) {
printf("s");
uiSkippedPages++;
Expand Down Expand Up @@ -391,7 +388,7 @@ write_card(bool write_otp, bool write_lock, bool write_uid)
print_success_or_failure(bFailure, &uiWrittenPages, &uiFailedPages);
}
printf("|\n");
printf("Done, %d of %d pages written (%d pages skipped, %d pages failed).\n", uiWrittenPages, uiBlocks + 1, uiSkippedPages, uiFailedPages);
printf("Done, %d of %d pages written (%d pages skipped, %d pages failed).\n", uiWrittenPages, uiBlocks, uiSkippedPages, uiFailedPages);

return true;
}
Expand Down Expand Up @@ -602,13 +599,13 @@ main(int argc, const char *argv[])
printf("EV1 storage size: ");
if(abtRx[6] == 0x0b) {
printf("48 bytes\n");
uiBlocks= 0x13;
uiBlocks= 0x14;
iEV1Type= EV1_UL11;
iDumpSize= sizeof(mifareul_ev1_mf0ul11_tag);
}
else if(abtRx[6] == 0x0e) {
printf("128 bytes\n");
uiBlocks= 0x28;
uiBlocks= 0x29;
iEV1Type= EV1_UL21;
iDumpSize= sizeof(mifareul_ev1_mf0ul21_tag);
}
Expand Down

0 comments on commit 3ec9ecf

Please sign in to comment.