Refactoring Blocks vs. Sectors.
- mifare_classic_format_sector() now wants a sector instead of a block (the name was really disturbing); - New public API functions for Block <=> Sector conversions.
This commit is contained in:
parent
cc5de33a56
commit
163ce56cc0
9 changed files with 62 additions and 48 deletions
5
NEWS
5
NEWS
|
@ -5,4 +5,9 @@ Changes between 0.1.0 and x.x.x [xx XXX xxxx]
|
||||||
*) The mifare_application_alloc() size parameter is now expressed in bytes
|
*) The mifare_application_alloc() size parameter is now expressed in bytes
|
||||||
and not in sectors.
|
and not in sectors.
|
||||||
*) New API function mad_sector_reserved().
|
*) New API function mad_sector_reserved().
|
||||||
|
*) The mifare_classic_format_sector() functions now require a sector number
|
||||||
|
instead of a block number.
|
||||||
|
*) New API functions mifare_classic_block_sector(),
|
||||||
|
mifare_classic_sector_first_block(), mifare_classic_sector_block_count()
|
||||||
|
and mifare_classic_sector_last_block().
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ MifareClassicKey default_keys[] = {
|
||||||
};
|
};
|
||||||
int format_mifare_classic_1k (MifareTag tag);
|
int format_mifare_classic_1k (MifareTag tag);
|
||||||
int format_mifare_classic_4k (MifareTag tag);
|
int format_mifare_classic_4k (MifareTag tag);
|
||||||
int try_format_sector (MifareTag tag, MifareClassicBlockNumber block);
|
int try_format_sector (MifareTag tag, MifareSectorNumber sector);
|
||||||
|
|
||||||
static int at_block = 0;
|
static int at_block = 0;
|
||||||
static int mod_block = 10;
|
static int mod_block = 10;
|
||||||
|
@ -64,7 +64,7 @@ format_mifare_classic_1k (MifareTag tag)
|
||||||
{
|
{
|
||||||
printf (START_FORMAT_N, 16);
|
printf (START_FORMAT_N, 16);
|
||||||
for (int sector = 0; sector < 16; sector++) {
|
for (int sector = 0; sector < 16; sector++) {
|
||||||
if (!try_format_sector (tag, sector * 4))
|
if (!try_format_sector (tag, sector))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
printf (DONE_FORMAT);
|
printf (DONE_FORMAT);
|
||||||
|
@ -75,12 +75,8 @@ int
|
||||||
format_mifare_classic_4k (MifareTag tag)
|
format_mifare_classic_4k (MifareTag tag)
|
||||||
{
|
{
|
||||||
printf (START_FORMAT_N, 32 + 8);
|
printf (START_FORMAT_N, 32 + 8);
|
||||||
for (int sector = 0; sector < 32; sector++) {
|
for (int sector = 0; sector < (32 + 8); sector++) {
|
||||||
if (!try_format_sector (tag, sector * 4))
|
if (!try_format_sector (tag, sector))
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
for (int sector = 0; sector < 8; sector++) {
|
|
||||||
if (!try_format_sector (tag, 128 + sector * 16))
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
printf (DONE_FORMAT);
|
printf (DONE_FORMAT);
|
||||||
|
@ -88,32 +84,33 @@ format_mifare_classic_4k (MifareTag tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
try_format_sector (MifareTag tag, MifareClassicBlockNumber block)
|
try_format_sector (MifareTag tag, MifareSectorNumber sector)
|
||||||
{
|
{
|
||||||
display_progress ();
|
display_progress ();
|
||||||
for (size_t i = 0; i < (sizeof (default_keys) / sizeof (MifareClassicKey)); i++) {
|
for (size_t i = 0; i < (sizeof (default_keys) / sizeof (MifareClassicKey)); i++) {
|
||||||
|
MifareClassicBlockNumber block = mifare_classic_sector_last_block (sector);
|
||||||
if ((0 == mifare_classic_connect (tag)) && (0 == mifare_classic_authenticate (tag, block, default_keys[i], MFC_KEY_A))) {
|
if ((0 == mifare_classic_connect (tag)) && (0 == mifare_classic_authenticate (tag, block, default_keys[i], MFC_KEY_A))) {
|
||||||
if (0 == mifare_classic_format_sector (tag, block)) {
|
if (0 == mifare_classic_format_sector (tag, sector)) {
|
||||||
mifare_classic_disconnect (tag);
|
mifare_classic_disconnect (tag);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (EIO == errno) {
|
} else if (EIO == errno) {
|
||||||
err (EXIT_FAILURE, "block %d", block);
|
err (EXIT_FAILURE, "sector %d", sector);
|
||||||
}
|
}
|
||||||
mifare_classic_disconnect (tag);
|
mifare_classic_disconnect (tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((0 == mifare_classic_connect (tag)) && (0 == mifare_classic_authenticate (tag, block, default_keys[i], MFC_KEY_B))) {
|
if ((0 == mifare_classic_connect (tag)) && (0 == mifare_classic_authenticate (tag, block, default_keys[i], MFC_KEY_B))) {
|
||||||
if (0 == mifare_classic_format_sector (tag, block)) {
|
if (0 == mifare_classic_format_sector (tag, sector)) {
|
||||||
mifare_classic_disconnect (tag);
|
mifare_classic_disconnect (tag);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (EIO == errno) {
|
} else if (EIO == errno) {
|
||||||
err (EXIT_FAILURE, "block %d", block);
|
err (EXIT_FAILURE, "sector %d", sector);
|
||||||
}
|
}
|
||||||
mifare_classic_disconnect (tag);
|
mifare_classic_disconnect (tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
warnx ("No known authentication key for block %d", block);
|
warnx ("No known authentication key for sector %d", sector);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,11 @@ int mifare_classic_format_sector (MifareTag tag, const MifareClassicBlockNumbe
|
||||||
|
|
||||||
void mifare_classic_trailer_block (MifareClassicBlock *block, const MifareClassicKey key_a, uint8_t ab_0, uint8_t ab_1, uint8_t ab_2, uint8_t ab_tb, const uint8_t gpb, const MifareClassicKey key_b);
|
void mifare_classic_trailer_block (MifareClassicBlock *block, const MifareClassicKey key_a, uint8_t ab_0, uint8_t ab_1, uint8_t ab_2, uint8_t ab_tb, const uint8_t gpb, const MifareClassicKey key_b);
|
||||||
|
|
||||||
|
MifareSectorNumber mifare_classic_block_sector (MifareClassicBlockNumber block);
|
||||||
|
MifareClassicBlockNumber mifare_classic_sector_first_block (MifareSectorNumber sector);
|
||||||
|
size_t mifare_classic_sector_block_count (MifareSectorNumber sector);
|
||||||
|
MifareClassicBlockNumber mifare_classic_sector_last_block (MifareSectorNumber sector);
|
||||||
|
|
||||||
#define C_000 0
|
#define C_000 0
|
||||||
#define C_001 1
|
#define C_001 1
|
||||||
#define C_010 2
|
#define C_010 2
|
||||||
|
|
|
@ -50,8 +50,6 @@ MifareTag mifare_ultralight_tag_new (void);
|
||||||
void mifare_ultralight_tag_free (MifareTag tag);
|
void mifare_ultralight_tag_free (MifareTag tag);
|
||||||
uint8_t sector_0x00_crc8 (Mad mad);
|
uint8_t sector_0x00_crc8 (Mad mad);
|
||||||
uint8_t sector_0x10_crc8 (Mad mad);
|
uint8_t sector_0x10_crc8 (Mad mad);
|
||||||
MifareClassicBlockNumber mifare_classic_first_sector_block (MifareClassicBlockNumber block);
|
|
||||||
MifareClassicBlockNumber mifare_classic_last_sector_block (MifareClassicBlockNumber block);
|
|
||||||
|
|
||||||
#define MIFARE_ULTRALIGHT_PAGE_COUNT 16
|
#define MIFARE_ULTRALIGHT_PAGE_COUNT 16
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ Mifare card manipulation library (libfreefare, \-lfreefare)
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn mifare_classic_get_data_block_permission "MifareTag tag" "const MifareClassicBlockNumber block" "const unsigned char permission" "const MifareClassicKeyType key_type"
|
.Fn mifare_classic_get_data_block_permission "MifareTag tag" "const MifareClassicBlockNumber block" "const unsigned char permission" "const MifareClassicKeyType key_type"
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn mifare_classic_format_sector "MifareTag tag" "const MifareClassicBlockNumber block"
|
.Fn mifare_classic_format_sector "MifareTag tag" "const MifareSectorNumber sector"
|
||||||
.Ft void
|
.Ft void
|
||||||
.Fn mifare_classic_trailer_block "MifareClassicBlock *block" "const MifareClassicKey key_a" "const uint8_t ab_0" "const uint8_t ab_1" "const uint8_t ab_2" "const uint8_t ab_tb" "const uint8_t gpb" "const MifareClassicKey key_b"
|
.Fn mifare_classic_trailer_block "MifareClassicBlock *block" "const MifareClassicKey key_a" "const uint8_t ab_0" "const uint8_t ab_1" "const uint8_t ab_2" "const uint8_t ab_tb" "const uint8_t gpb" "const MifareClassicKey key_b"
|
||||||
.\" ____ _ _ _
|
.\" ____ _ _ _
|
||||||
|
@ -181,10 +181,7 @@ are
|
||||||
.Ar MCAB_WRITE_KEYB .
|
.Ar MCAB_WRITE_KEYB .
|
||||||
.Pp
|
.Pp
|
||||||
A whole sector can be reset to factory defaults using
|
A whole sector can be reset to factory defaults using
|
||||||
.Fn mifare_classic_format_sector
|
.Fn mifare_classic_format_sector .
|
||||||
and providing any
|
|
||||||
.Vt block
|
|
||||||
in the sector.
|
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
.Fn mifare_classic_trailer_block
|
.Fn mifare_classic_trailer_block
|
||||||
|
|
|
@ -521,7 +521,7 @@ get_block_access_bits (MifareTag tag, const MifareClassicBlockNumber block, Mifa
|
||||||
|
|
||||||
uint16_t sector_access_bits, sector_access_bits_;
|
uint16_t sector_access_bits, sector_access_bits_;
|
||||||
|
|
||||||
MifareClassicBlockNumber trailer = mifare_classic_last_sector_block (block);
|
MifareClassicBlockNumber trailer = mifare_classic_sector_last_block (mifare_classic_block_sector (block));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The trailer block contains access bits for the whole sector in a 3 bytes
|
* The trailer block contains access bits for the whole sector in a 3 bytes
|
||||||
|
@ -632,10 +632,10 @@ mifare_classic_get_data_block_permission (MifareTag tag, const MifareClassicBloc
|
||||||
* Reset a MIFARE target sector to factory default.
|
* Reset a MIFARE target sector to factory default.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
mifare_classic_format_sector (MifareTag tag, const MifareClassicBlockNumber block)
|
mifare_classic_format_sector (MifareTag tag, const MifareSectorNumber sector)
|
||||||
{
|
{
|
||||||
MifareClassicBlockNumber first_sector_block = mifare_classic_first_sector_block (block);
|
MifareClassicBlockNumber first_sector_block = mifare_classic_sector_first_block (sector);
|
||||||
MifareClassicBlockNumber last_sector_block = mifare_classic_last_sector_block (block);
|
MifareClassicBlockNumber last_sector_block = mifare_classic_sector_last_block (sector);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that the current key allow us to rewrite data and trailer blocks.
|
* Check that the current key allow us to rewrite data and trailer blocks.
|
||||||
|
@ -679,39 +679,51 @@ mifare_classic_format_sector (MifareTag tag, const MifareClassicBlockNumber bloc
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
MifareSectorNumber
|
||||||
* Get the sector's first block number in the provided block's sector.
|
mifare_classic_block_sector (MifareClassicBlockNumber block)
|
||||||
*/
|
|
||||||
MifareClassicBlockNumber
|
|
||||||
mifare_classic_first_sector_block (MifareClassicBlockNumber block)
|
|
||||||
{
|
{
|
||||||
int res;
|
MifareSectorNumber res;
|
||||||
if (block < 128) {
|
|
||||||
res = (block / 4) * 4;
|
if (block < 32 * 4)
|
||||||
} else {
|
res = block / 4;
|
||||||
res = ((block - 128) / 16) * 16 + 128;
|
else
|
||||||
}
|
res = 32 + ( (block - (32 * 4)) / 16 );
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the sector's last block number (aka trailer block) in the provided
|
* Get the sector's first block number
|
||||||
* block's sector.
|
|
||||||
*/
|
*/
|
||||||
MifareClassicBlockNumber
|
MifareClassicBlockNumber
|
||||||
mifare_classic_last_sector_block (MifareClassicBlockNumber block)
|
mifare_classic_sector_first_block (MifareSectorNumber sector)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
if (block < 128) {
|
if (sector < 32) {
|
||||||
res = (block / 4) * 4 + 3;
|
res = sector * 4;
|
||||||
} else {
|
} else {
|
||||||
res = ((block - 128) / 16) * 16 + 15 + 128;
|
res = 32 * 4 + (sector - 32) * 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
mifare_classic_sector_block_count (MifareSectorNumber sector)
|
||||||
|
{
|
||||||
|
return (sector < 32) ? 4 : 16 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the sector's last block number (aka trailer block)
|
||||||
|
*/
|
||||||
|
MifareClassicBlockNumber
|
||||||
|
mifare_classic_sector_last_block (MifareSectorNumber sector)
|
||||||
|
{
|
||||||
|
return mifare_classic_sector_first_block (sector) +
|
||||||
|
mifare_classic_sector_block_count (sector) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generates a MIFARE trailer block.
|
* Generates a MIFARE trailer block.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -122,7 +122,7 @@ test_mifare_classic_format (void)
|
||||||
res = mifare_classic_write (tag, 0x3e, data);
|
res = mifare_classic_write (tag, 0x3e, data);
|
||||||
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed"));
|
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed"));
|
||||||
|
|
||||||
res = mifare_classic_format_sector (tag, 0x3c);
|
res = mifare_classic_format_sector (tag, mifare_classic_block_sector (0x3c));
|
||||||
cut_assert_equal_int (0, res, cut_message ("mifare_classic_format_sector() failed"));
|
cut_assert_equal_int (0, res, cut_message ("mifare_classic_format_sector() failed"));
|
||||||
|
|
||||||
res = mifare_classic_read (tag, 0x3c, &data);
|
res = mifare_classic_read (tag, 0x3c, &data);
|
||||||
|
|
|
@ -172,7 +172,7 @@ test_mifare_classic_mad (void)
|
||||||
|
|
||||||
res = mifare_classic_authenticate (tag, 0x40, key_b_sector_10, MFC_KEY_B);
|
res = mifare_classic_authenticate (tag, 0x40, key_b_sector_10, MFC_KEY_B);
|
||||||
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));
|
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));
|
||||||
res = mifare_classic_format_sector (tag, 0x40);
|
res = mifare_classic_format_sector (tag, 0x10);
|
||||||
cut_assert_equal_int (0, res, cut_message ("mifare_classic_format_sector() failed"));
|
cut_assert_equal_int (0, res, cut_message ("mifare_classic_format_sector() failed"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,15 +27,15 @@ test_mifare_classic_sector_boundaries (void)
|
||||||
{
|
{
|
||||||
for (int i=0; i < 32; i++) {
|
for (int i=0; i < 32; i++) {
|
||||||
for (int j=0; j < 4; j++) {
|
for (int j=0; j < 4; j++) {
|
||||||
cut_assert_equal_int (4 * i, mifare_classic_first_sector_block (4 * i), cut_message ("Wrong first block number for block %d", i));
|
cut_assert_equal_int (4 * i, mifare_classic_sector_first_block (mifare_classic_block_sector (4 * i)), cut_message ("Wrong first block number for block %d", i));
|
||||||
cut_assert_equal_int (4 * i + 3, mifare_classic_last_sector_block (4 * i + j), cut_message ("Wrong last block number for block %d", i));
|
cut_assert_equal_int (4 * i + 3, mifare_classic_sector_last_block (mifare_classic_block_sector (4 * i + j)), cut_message ("Wrong last block number for block %d", i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i < 8; i++) {
|
for (int i=0; i < 8; i++) {
|
||||||
for (int j=0; j < 16; j++) {
|
for (int j=0; j < 16; j++) {
|
||||||
cut_assert_equal_int (128 + 16 * i, mifare_classic_first_sector_block (128 + 16 * i), cut_message ("Wrong last block number for block %d", i));
|
cut_assert_equal_int (128 + 16 * i, mifare_classic_sector_first_block (mifare_classic_block_sector (128 + 16 * i)), cut_message ("Wrong last block number for block %d", i));
|
||||||
cut_assert_equal_int (128 + 16 * i + 15, mifare_classic_last_sector_block (128 + 16 * i + j), cut_message ("Wrong last block number for block %d", i));
|
cut_assert_equal_int (128 + 16 * i + 15, mifare_classic_sector_last_block (mifare_classic_block_sector (128 + 16 * i + j)), cut_message ("Wrong last block number for block %d", i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue