read extra mf-ul EV1 blocks
This commit is contained in:
parent
fe04b85678
commit
c04dd91e98
2 changed files with 92 additions and 27 deletions
|
@ -9,6 +9,7 @@
|
|||
* Copyright (C) 2012-2013 Ludovic Rousseau
|
||||
* See AUTHORS file for a more comprehensive list of contributors.
|
||||
* Additional contributors of this file:
|
||||
* Copyright (C) 2017 Adam Laurie
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
@ -133,6 +134,19 @@ typedef struct {
|
|||
uint8_t otp[4];
|
||||
} mifareul_block_manufacturer;
|
||||
|
||||
// MIFARE Ultralight EV1 Config Pages
|
||||
typedef struct {
|
||||
uint8_t mod;
|
||||
uint8_t rfui[2];
|
||||
uint8_t auth0;
|
||||
uint8_t access;
|
||||
uint8_t vctid;
|
||||
uint8_t rfui1[2];
|
||||
uint8_t pwd[4];
|
||||
uint8_t pack[2];
|
||||
uint8_t rfui2[2];
|
||||
} mifareul_block_config;
|
||||
|
||||
typedef struct {
|
||||
uint8_t abtData[16];
|
||||
} mifareul_block_data;
|
||||
|
@ -140,12 +154,24 @@ typedef struct {
|
|||
typedef union {
|
||||
mifareul_block_manufacturer mbm;
|
||||
mifareul_block_data mbd;
|
||||
mifareul_block_config mbc;
|
||||
} mifareul_block;
|
||||
|
||||
// standard UL tag - 1 manuf block + 3 user blocks
|
||||
typedef struct {
|
||||
mifareul_block amb[4];
|
||||
} mifareul_tag;
|
||||
|
||||
// UL EV1 MF0UL11 tag - 1 manuf block + 3 user blocks + 1 config block
|
||||
typedef struct {
|
||||
mifareul_block amb[5];
|
||||
} mifareul_ev1_mf0ul11_tag;
|
||||
|
||||
// UL EV1 MF0UL21 tag - 1 manuf block + 8 user blocks + 1 config block
|
||||
typedef struct {
|
||||
mifareul_block amb[10];
|
||||
} mifareul_ev1_mf0ul21_tag;
|
||||
|
||||
// Reset struct alignment to default
|
||||
# pragma pack()
|
||||
|
||||
|
|
|
@ -62,11 +62,19 @@
|
|||
#define MAX_UID_LEN 10
|
||||
#define BLOCK_COUNT 0xf
|
||||
|
||||
#define EV1_NONE 0
|
||||
#define EV1_UL11 1
|
||||
#define EV1_UL21 2
|
||||
|
||||
static nfc_device *pnd;
|
||||
static nfc_target nt;
|
||||
static mifare_param mp;
|
||||
static mifareul_tag mtDump;
|
||||
static const uint32_t uiBlocks = BLOCK_COUNT;
|
||||
static mifareul_ev1_mf0ul21_tag mtDump; // use the largest tag type for internal storage
|
||||
static uint32_t uiBlocks = BLOCK_COUNT;
|
||||
static uint32_t uiReadPages = 0;
|
||||
static uint8_t iPWD[4] = { 0x0 };
|
||||
static uint8_t iPACK[2] = { 0x0 };
|
||||
static uint8_t iEV1Type= EV1_NONE;
|
||||
|
||||
// special unlock command
|
||||
uint8_t abtUnlock1[1] = { 0x40 };
|
||||
|
@ -105,7 +113,6 @@ read_card(void)
|
|||
{
|
||||
uint32_t page;
|
||||
bool bFailure = false;
|
||||
uint32_t uiReadPages = 0;
|
||||
uint32_t uiFailedPages = 0;
|
||||
|
||||
printf("Reading %d pages |", uiBlocks + 1);
|
||||
|
@ -127,6 +134,21 @@ read_card(void)
|
|||
printf("Done, %d of %d pages read (%d pages failed).\n", uiReadPages, uiBlocks + 1, 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);
|
||||
break;
|
||||
case EV1_UL21:
|
||||
memcpy(mtDump.amb[9].mbc.pwd, iPWD, 4);
|
||||
memcpy(mtDump.amb[9].mbc.pack, iPACK, 2);
|
||||
break;
|
||||
case EV1_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (!bFailure);
|
||||
}
|
||||
|
||||
|
@ -445,7 +467,6 @@ main(int argc, const char *argv[])
|
|||
{
|
||||
int iAction = 0;
|
||||
uint8_t iUID[MAX_UID_LEN] = { 0x0 };
|
||||
uint8_t iPWD[4] = { 0x0 };
|
||||
size_t szUID = 0;
|
||||
bool bOTP = false;
|
||||
bool bLock = false;
|
||||
|
@ -569,8 +590,8 @@ main(int argc, const char *argv[])
|
|||
nfc_exit(context);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
// Test if we are dealing with a MIFARE compatible tag
|
||||
|
||||
// Test if we are dealing with a MIFARE compatible tag
|
||||
if (nt.nti.nai.abtAtqa[1] != 0x44) {
|
||||
ERR("tag is not a MIFARE Ultralight card\n");
|
||||
nfc_close(pnd);
|
||||
|
@ -590,13 +611,28 @@ main(int argc, const char *argv[])
|
|||
if(!bPWD)
|
||||
printf("Tag is EV1 - PASSWORD may be required\n");
|
||||
printf("EV1 storage size: ");
|
||||
if(abtRx[6] == 0x0b)
|
||||
if(abtRx[6] == 0x0b) {
|
||||
printf("48 bytes\n");
|
||||
else if(abtRx[6] == 0x0e)
|
||||
uiBlocks= 0x13;
|
||||
iEV1Type= EV1_UL11;
|
||||
}
|
||||
else if(abtRx[6] == 0x0e) {
|
||||
printf("128 bytes\n");
|
||||
uiBlocks= 0x28;
|
||||
iEV1Type= EV1_UL21;
|
||||
}
|
||||
else
|
||||
printf("unknown!\n");
|
||||
}
|
||||
else {
|
||||
// re-init non EV1 tag
|
||||
if (nfc_initiator_select_passive_target(pnd, nmMifare, (szUID) ? iUID : NULL, szUID, &nt) <= 0) {
|
||||
ERR("no tag was found\n");
|
||||
nfc_close(pnd);
|
||||
nfc_exit(context);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
// EV1 login required
|
||||
if(bPWD){
|
||||
|
@ -606,31 +642,34 @@ main(int argc, const char *argv[])
|
|||
ERR("AUTH failed!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else
|
||||
else {
|
||||
printf("Success - PACK: %02x%02x\n", abtRx[0], abtRx[1]);
|
||||
memcpy(iPACK, abtRx, 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (iAction == 1) {
|
||||
if (read_card()) {
|
||||
printf("Writing data to file: %s ... ", argv[2]);
|
||||
fflush(stdout);
|
||||
pfDump = fopen(argv[2], "wb");
|
||||
if (pfDump == NULL) {
|
||||
printf("Could not open file: %s\n", argv[2]);
|
||||
nfc_close(pnd);
|
||||
nfc_exit(context);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (fwrite(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) {
|
||||
printf("Could not write to file: %s\n", argv[2]);
|
||||
fclose(pfDump);
|
||||
nfc_close(pnd);
|
||||
nfc_exit(context);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fclose(pfDump);
|
||||
printf("Done.\n");
|
||||
bool bRF= read_card();
|
||||
printf("Writing data to file: %s ... ", argv[2]);
|
||||
fflush(stdout);
|
||||
pfDump = fopen(argv[2], "wb");
|
||||
if (pfDump == NULL) {
|
||||
printf("Could not open file: %s\n", argv[2]);
|
||||
nfc_close(pnd);
|
||||
nfc_exit(context);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (fwrite(&mtDump, 1, uiReadPages * 4, pfDump) != uiReadPages * 4) {
|
||||
printf("Could not write to file: %s\n", argv[2]);
|
||||
fclose(pfDump);
|
||||
nfc_close(pnd);
|
||||
nfc_exit(context);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fclose(pfDump);
|
||||
printf("Done.\n");
|
||||
if(!bRF)
|
||||
printf("Warning! Read failed - partial data written to file!\n");
|
||||
} else if (iAction == 2) {
|
||||
write_card(bOTP, bLock, bUID);
|
||||
} else if (iAction == 3) {
|
||||
|
|
Loading…
Add table
Reference in a new issue