From f83918ee41cf270b206fb663baf3848363481927 Mon Sep 17 00:00:00 2001 From: Romain Tartiere Date: Thu, 1 Jul 2010 21:44:40 +0000 Subject: [PATCH] Fix MAD manipulation for Mifare Classic 4K. - Allocate large blocks on Mifare Classic 4K in unit tests; - Constraints sector number in mad_set_aid(); - Fix location of AID storage in mad_set_aid() (wrong variable name and offset, ECOPYPASTETOOFAST); - New API function mad_sector_reserved(); - Use mad_sector_reserved() to avoid trying to use reserved sectors. --- NEWS | 1 + libfreefare/freefare.h | 1 + libfreefare/mad.c | 12 +++++++++--- libfreefare/mifare_application.c | 2 ++ test/test_mifare_classic_application.c | 24 +++++++++++++++++++++++- 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index ccb0751..d32774a 100644 --- a/NEWS +++ b/NEWS @@ -4,4 +4,5 @@ Changes between 0.1.0 and x.x.x [xx XXX xxxx] list. *) The mifare_application_alloc() size parameter is now expressed in bytes and not in sectors. + *) New API function mad_sector_reserved(). diff --git a/libfreefare/freefare.h b/libfreefare/freefare.h index 229efe0..207edbc 100644 --- a/libfreefare/freefare.h +++ b/libfreefare/freefare.h @@ -137,6 +137,7 @@ MifareSectorNumber mad_get_card_publisher_sector (Mad mad); int mad_set_card_publisher_sector (Mad mad, MifareSectorNumber cps); int mad_get_aid (Mad mad, MifareSectorNumber sector, MadAid *aid); int mad_set_aid (Mad mad, MifareSectorNumber sector, MadAid aid); +bool mad_sector_reserved (MifareSectorNumber sector); void mad_free (Mad mad); MifareSectorNumber *mifare_application_alloc (Mad mad, MadAid aid, size_t size); diff --git a/libfreefare/mad.c b/libfreefare/mad.c index 411e7e8..7e1aea1 100644 --- a/libfreefare/mad.c +++ b/libfreefare/mad.c @@ -391,7 +391,7 @@ mad_get_aid(Mad mad, MifareSectorNumber sector, MadAid *aid) int mad_set_aid(Mad mad, MifareSectorNumber sector, MadAid aid) { - if (sector > 0x27) { + if ((sector < 1) || (sector == 0x10) || (sector > 0x27)) { errno = EINVAL; return -1; } @@ -401,8 +401,8 @@ mad_set_aid(Mad mad, MifareSectorNumber sector, MadAid aid) errno = EINVAL; return -1; } - mad->sector_0x00.aids[sector - 0x0f - 1].function_cluster_code = aid.function_cluster_code; - mad->sector_0x00.aids[sector - 0x0f - 1].application_code = aid.application_code; + mad->sector_0x10.aids[sector - 0x0f - 2].function_cluster_code = aid.function_cluster_code; + mad->sector_0x10.aids[sector - 0x0f - 2].application_code = aid.application_code; } else { mad->sector_0x00.aids[sector - 1].function_cluster_code = aid.function_cluster_code; mad->sector_0x00.aids[sector - 1].application_code = aid.application_code; @@ -411,6 +411,12 @@ mad_set_aid(Mad mad, MifareSectorNumber sector, MadAid aid) return 0; } +bool +mad_sector_reserved (MifareSectorNumber sector) +{ + return ((0x00 == sector) || (0x10 == sector)); +} + /* * Free memory allocated by mad_new() and mad_read(). */ diff --git a/libfreefare/mifare_application.c b/libfreefare/mifare_application.c index edb7d86..1a78735 100644 --- a/libfreefare/mifare_application.c +++ b/libfreefare/mifare_application.c @@ -114,6 +114,8 @@ mifare_application_alloc (Mad mad, MadAid aid, size_t size) sector = FIRST_SECTOR; MifareSectorNumber s_max = (mad_get_version (mad) == 1) ? 15 : 31; while ((s > 0) && (sector <= s_max)) { + if (mad_sector_reserved (sector)) + continue; mad_get_aid (mad, sector, §or_aid); if (0 == aidcmp (sector_aid, free_aid)) { sector_map[sector] = 1; diff --git a/test/test_mifare_classic_application.c b/test/test_mifare_classic_application.c index 52935cd..0c4d722 100644 --- a/test/test_mifare_classic_application.c +++ b/test/test_mifare_classic_application.c @@ -36,12 +36,34 @@ test_mifare_classic_application (void) cut_assert_not_null (s_found, cut_message ("mifare_application_alloc() failed")); for (int i = 0; i < 3; i++) { - cut_assert_equal_int (s_alloc[i], s_found[i], cut_message ("Allocated and found blocks don't match")); + cut_assert_equal_int (s_alloc[i], s_found[i], cut_message ("Allocated and found blocks don't match at position %d", i)); } cut_assert_equal_int (0, s_alloc[3], cut_message ("Invalid size")); cut_assert_equal_int (0, s_found[3], cut_message ("Invalid size")); + mifare_application_free (mad, aid); + + free (s_alloc); + free (s_found); + + s_found = mifare_application_find (mad, aid); + cut_assert_null (s_found, cut_message ("mifare_application_free() failed")); + + s_alloc = mifare_application_alloc (mad, aid, 15*16 + 1*16 + 1); + cut_assert_not_null (s_alloc, cut_message ("mifare_application_alloc() failed")); + + s_found = mifare_application_find (mad, aid); + cut_assert_not_null (s_found, cut_message ("mifare_application_alloc() failed")); + + for (int i = 0; i < 3; i++) { + cut_assert_equal_int (s_alloc[i], s_found[i], cut_message ("Allocated and found blocks don't match at position %d", i)); + } + + cut_assert_equal_int (0, s_alloc[3], cut_message ("Invalid size")); + cut_assert_equal_int (0, s_found[3], cut_message ("Invalid size")); + + mifare_application_free (mad, aid); free (s_alloc);