diff --git a/NEWS b/NEWS index d32774a..235d979 100644 --- a/NEWS +++ b/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 and not in sectors. *) 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(). diff --git a/examples/mifare-classic-format.c b/examples/mifare-classic-format.c index ccacf0d..3ccba0a 100644 --- a/examples/mifare-classic-format.c +++ b/examples/mifare-classic-format.c @@ -41,7 +41,7 @@ MifareClassicKey default_keys[] = { }; int format_mifare_classic_1k (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 mod_block = 10; @@ -64,7 +64,7 @@ format_mifare_classic_1k (MifareTag tag) { printf (START_FORMAT_N, 16); for (int sector = 0; sector < 16; sector++) { - if (!try_format_sector (tag, sector * 4)) + if (!try_format_sector (tag, sector)) return 0; } printf (DONE_FORMAT); @@ -75,12 +75,8 @@ int format_mifare_classic_4k (MifareTag tag) { printf (START_FORMAT_N, 32 + 8); - for (int sector = 0; sector < 32; sector++) { - if (!try_format_sector (tag, sector * 4)) - return 0; - } - for (int sector = 0; sector < 8; sector++) { - if (!try_format_sector (tag, 128 + sector * 16)) + for (int sector = 0; sector < (32 + 8); sector++) { + if (!try_format_sector (tag, sector)) return 0; } printf (DONE_FORMAT); @@ -88,32 +84,33 @@ format_mifare_classic_4k (MifareTag tag) } int -try_format_sector (MifareTag tag, MifareClassicBlockNumber block) +try_format_sector (MifareTag tag, MifareSectorNumber sector) { display_progress (); 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_format_sector (tag, block)) { + if (0 == mifare_classic_format_sector (tag, sector)) { mifare_classic_disconnect (tag); return 1; } else if (EIO == errno) { - err (EXIT_FAILURE, "block %d", block); + err (EXIT_FAILURE, "sector %d", sector); } 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_format_sector (tag, block)) { + if (0 == mifare_classic_format_sector (tag, sector)) { mifare_classic_disconnect (tag); return 1; } else if (EIO == errno) { - err (EXIT_FAILURE, "block %d", block); + err (EXIT_FAILURE, "sector %d", sector); } mifare_classic_disconnect (tag); } } - warnx ("No known authentication key for block %d", block); + warnx ("No known authentication key for sector %d", sector); return 0; } diff --git a/libfreefare/freefare.h b/libfreefare/freefare.h index 207edbc..8ed2620 100644 --- a/libfreefare/freefare.h +++ b/libfreefare/freefare.h @@ -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); +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_001 1 #define C_010 2 diff --git a/libfreefare/freefare_internal.h b/libfreefare/freefare_internal.h index 549b549..c80d059 100644 --- a/libfreefare/freefare_internal.h +++ b/libfreefare/freefare_internal.h @@ -50,8 +50,6 @@ MifareTag mifare_ultralight_tag_new (void); void mifare_ultralight_tag_free (MifareTag tag); uint8_t sector_0x00_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 diff --git a/libfreefare/mifare_classic.3 b/libfreefare/mifare_classic.3 index bd92d1f..4665982 100644 --- a/libfreefare/mifare_classic.3 +++ b/libfreefare/mifare_classic.3 @@ -84,7 +84,7 @@ Mifare card manipulation library (libfreefare, \-lfreefare) .Ft int .Fn mifare_classic_get_data_block_permission "MifareTag tag" "const MifareClassicBlockNumber block" "const unsigned char permission" "const MifareClassicKeyType key_type" .Ft int -.Fn mifare_classic_format_sector "MifareTag tag" "const MifareClassicBlockNumber block" +.Fn mifare_classic_format_sector "MifareTag tag" "const MifareSectorNumber sector" .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" .\" ____ _ _ _ @@ -181,10 +181,7 @@ are .Ar MCAB_WRITE_KEYB . .Pp A whole sector can be reset to factory defaults using -.Fn mifare_classic_format_sector -and providing any -.Vt block -in the sector. +.Fn mifare_classic_format_sector . .Pp The .Fn mifare_classic_trailer_block diff --git a/libfreefare/mifare_classic.c b/libfreefare/mifare_classic.c index cb696fc..c31b2cf 100644 --- a/libfreefare/mifare_classic.c +++ b/libfreefare/mifare_classic.c @@ -521,7 +521,7 @@ get_block_access_bits (MifareTag tag, const MifareClassicBlockNumber block, Mifa 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 @@ -632,10 +632,10 @@ mifare_classic_get_data_block_permission (MifareTag tag, const MifareClassicBloc * Reset a MIFARE target sector to factory default. */ 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 last_sector_block = mifare_classic_last_sector_block (block); + MifareClassicBlockNumber first_sector_block = mifare_classic_sector_first_block (sector); + MifareClassicBlockNumber last_sector_block = mifare_classic_sector_last_block (sector); /* * 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; } -/* - * Get the sector's first block number in the provided block's sector. - */ -MifareClassicBlockNumber -mifare_classic_first_sector_block (MifareClassicBlockNumber block) +MifareSectorNumber +mifare_classic_block_sector (MifareClassicBlockNumber block) { - int res; - if (block < 128) { - res = (block / 4) * 4; - } else { - res = ((block - 128) / 16) * 16 + 128; - } + MifareSectorNumber res; + + if (block < 32 * 4) + res = block / 4; + else + res = 32 + ( (block - (32 * 4)) / 16 ); return res; } /* - * Get the sector's last block number (aka trailer block) in the provided - * block's sector. + * Get the sector's first block number */ MifareClassicBlockNumber -mifare_classic_last_sector_block (MifareClassicBlockNumber block) +mifare_classic_sector_first_block (MifareSectorNumber sector) { int res; - if (block < 128) { - res = (block / 4) * 4 + 3; + if (sector < 32) { + res = sector * 4; } else { - res = ((block - 128) / 16) * 16 + 15 + 128; + res = 32 * 4 + (sector - 32) * 16; } 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. */ diff --git a/test/test_mifare_classic.c b/test/test_mifare_classic.c index eeaa064..1c9059a 100644 --- a/test/test_mifare_classic.c +++ b/test/test_mifare_classic.c @@ -122,7 +122,7 @@ test_mifare_classic_format (void) res = mifare_classic_write (tag, 0x3e, data); 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")); res = mifare_classic_read (tag, 0x3c, &data); diff --git a/test/test_mifare_classic_mad.c b/test/test_mifare_classic_mad.c index 20204f1..c8bf6f3 100644 --- a/test/test_mifare_classic_mad.c +++ b/test/test_mifare_classic_mad.c @@ -172,7 +172,7 @@ test_mifare_classic_mad (void) 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")); - 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")); } diff --git a/test/test_mifare_classic_sector_boundaries.c b/test/test_mifare_classic_sector_boundaries.c index 7c0ba6b..d54790d 100644 --- a/test/test_mifare_classic_sector_boundaries.c +++ b/test/test_mifare_classic_sector_boundaries.c @@ -27,15 +27,15 @@ test_mifare_classic_sector_boundaries (void) { for (int i=0; i < 32; i++) { 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 + 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, 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_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 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 + 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, 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_sector_last_block (mifare_classic_block_sector (128 + 16 * i + j)), cut_message ("Wrong last block number for block %d", i)); } } }