From feb240ee7310344aa38aee5d9cf987b578ed42ce Mon Sep 17 00:00:00 2001 From: Romain Tartiere Date: Thu, 18 Mar 2010 21:03:07 +0000 Subject: [PATCH] Fix MAD CRC algorithm. The CRC algorithm is not a standard CRC algorithm so rename it to nxp_crc() and adjust all related code. --- libfreefare/freefare_internal.h | 2 +- libfreefare/mad.c | 31 ++--- test/test_mad.c | 213 +++++++++++++++----------------- 3 files changed, 110 insertions(+), 136 deletions(-) diff --git a/libfreefare/freefare_internal.h b/libfreefare/freefare_internal.h index 238d769..b205d94 100644 --- a/libfreefare/freefare_internal.h +++ b/libfreefare/freefare_internal.h @@ -39,7 +39,7 @@ struct mad_sector_0x00; struct mad_sector_0x10; -void crc8 (uint8_t *crc, const uint8_t value); +void nxp_crc (uint8_t *crc, const uint8_t value); MifareTag mifare_classic_tag_new (void); void mifare_classic_tag_free (MifareTag tag); MifareTag mifare_ultralight_tag_new (void); diff --git a/libfreefare/mad.c b/libfreefare/mad.c index ddbcd89..7ebc29a 100644 --- a/libfreefare/mad.c +++ b/libfreefare/mad.c @@ -38,15 +38,10 @@ #include "freefare_internal.h" /* - * XXX The documentation says the preset is 0xE3, but the various card dumps - * and the documentation example MAD CRC can be verified only with a CRC - * preset of 0x67. - * - * This is still under investigation: - * http://www.libnfc.org/community/post/667/ - * http://discussion.forum.nokia.com/forum/showthread.php?t=181702#14 + * The documentation says the preset is 0xE3 but the bits have to be mirrored: + * 0xe3 = 1110 0011 <=> 1100 0111 = 0xc7 */ -#define CRC_PRESET 0x67 +#define CRC_PRESET 0xc7 #define SECTOR_0X00_AIDS 15 #define SECTOR_0X10_AIDS 23 @@ -96,15 +91,15 @@ mad_new (uint8_t version) * Compute CRC. */ void -crc8 (uint8_t *crc, const uint8_t value) +nxp_crc (uint8_t *crc, const uint8_t value) { /* x^8 + x^4 + x^3 + x^2 + 1 => 0x11d */ const uint8_t poly = 0x1d; + *crc ^= value; for (int current_bit = 7; current_bit >= 0; current_bit--) { int bit_out = (*crc) & 0x80; - *crc = ((*crc) << 1) | (( value >> (current_bit)) & 0x01); - + *crc <<= 1; if (bit_out) *crc ^= poly; @@ -116,13 +111,12 @@ sector_0x00_crc8 (Mad mad) { uint8_t crc = CRC_PRESET; - crc8 (&crc, mad->sector_0x00.info); + nxp_crc (&crc, mad->sector_0x00.info); for (int n = 0; n < SECTOR_0X00_AIDS; n++) { - crc8 (&crc, mad->sector_0x00.aids[n].application_code); - crc8 (&crc, mad->sector_0x00.aids[n].function_cluster_code); + nxp_crc (&crc, mad->sector_0x00.aids[n].application_code); + nxp_crc (&crc, mad->sector_0x00.aids[n].function_cluster_code); } - crc8 (&crc, 0x00); return crc; } @@ -132,13 +126,12 @@ sector_0x10_crc8 (Mad mad) { uint8_t crc = CRC_PRESET; - crc8 (&crc, mad->sector_0x10.info); + nxp_crc (&crc, mad->sector_0x10.info); for (int n = 0; n < SECTOR_0X10_AIDS; n++) { - crc8 (&crc, mad->sector_0x10.aids[n].application_code); - crc8 (&crc, mad->sector_0x10.aids[n].function_cluster_code); + nxp_crc (&crc, mad->sector_0x10.aids[n].application_code); + nxp_crc (&crc, mad->sector_0x10.aids[n].function_cluster_code); } - crc8 (&crc, 0x00); return crc; } diff --git a/test/test_mad.c b/test/test_mad.c index e5147de..c70b06c 100644 --- a/test/test_mad.c +++ b/test/test_mad.c @@ -67,7 +67,7 @@ test_mad (void) mad_free (mad); } -#define CRC_PRESET 0x67 +#define CRC_PRESET 0xc7 void test_mad_crc8_basic (void) @@ -75,30 +75,14 @@ test_mad_crc8_basic (void) uint8_t crc; const uint8_t crc_value = 0x42; - /* Insert data */ - crc = 0x00; - crc8(&crc, crc_value); - cut_assert_equal_int (crc_value, crc, cut_message ("Initialization should not produce a CRC")); - - /* Insert data with leading zeros */ - crc = 0x00; - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, crc_value); - cut_assert_equal_int (crc_value, crc, cut_message ("Burst error should not be detected with uninitialized polies")); - /* Check integrity */ crc = CRC_PRESET; - crc8(&crc, crc_value); - crc8(&crc, 0x00); + nxp_crc(&crc, crc_value); uint8_t save = crc; crc = CRC_PRESET; - crc8(&crc, crc_value); - crc8(&crc, save); + nxp_crc(&crc, crc_value); + nxp_crc(&crc, save); cut_assert_equal_int (0x00, crc, cut_message ("CRC should verify crc(message + crc(message)) = 0")); } @@ -112,46 +96,45 @@ test_mad_crc8_doc_example (void) uint8_t crc = CRC_PRESET; /* Block 1 -- 0x01 - 0x07 */ - crc8(&crc, 0x01); - crc8(&crc, 0x01); - crc8(&crc, 0x08); - crc8(&crc, 0x01); - crc8(&crc, 0x08); - crc8(&crc, 0x01); - crc8(&crc, 0x08); + nxp_crc(&crc, 0x01); + nxp_crc(&crc, 0x01); + nxp_crc(&crc, 0x08); + nxp_crc(&crc, 0x01); + nxp_crc(&crc, 0x08); + nxp_crc(&crc, 0x01); + nxp_crc(&crc, 0x08); /* Block 2 -- 0x08 - 0x0f */ - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x04); - crc8(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x04); + nxp_crc(&crc, 0x00); /* Block 3 -- 0x00 - 0x07 */ - crc8(&crc, 0x03); - crc8(&crc, 0x10); - crc8(&crc, 0x03); - crc8(&crc, 0x10); - crc8(&crc, 0x02); - crc8(&crc, 0x10); - crc8(&crc, 0x02); - crc8(&crc, 0x10); + nxp_crc(&crc, 0x03); + nxp_crc(&crc, 0x10); + nxp_crc(&crc, 0x03); + nxp_crc(&crc, 0x10); + nxp_crc(&crc, 0x02); + nxp_crc(&crc, 0x10); + nxp_crc(&crc, 0x02); + nxp_crc(&crc, 0x10); /* Block 3 -- 0x08 - 0x0f */ - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x11); - crc8(&crc, 0x30); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x11); + nxp_crc(&crc, 0x30); /* Append zeros of augmented message */ - crc8(&crc, 0x00); cut_assert_equal_int (0x89, crc, cut_message ("Sample CRC should match")); } @@ -166,46 +149,45 @@ test_mad_crc8_real_example_1 (void) uint8_t crc = CRC_PRESET; /* Block 1 -- 0x01 - 0x07 */ - crc8(&crc, 0x01); - crc8(&crc, 0x03); - crc8(&crc, 0xe1); - crc8(&crc, 0x03); - crc8(&crc, 0xe1); - crc8(&crc, 0x03); - crc8(&crc, 0xe1); + nxp_crc(&crc, 0x01); + nxp_crc(&crc, 0x03); + nxp_crc(&crc, 0xe1); + nxp_crc(&crc, 0x03); + nxp_crc(&crc, 0xe1); + nxp_crc(&crc, 0x03); + nxp_crc(&crc, 0xe1); /* Block 2 -- 0x08 - 0x0f */ - crc8(&crc, 0x03); - crc8(&crc, 0xe1); - crc8(&crc, 0x03); - crc8(&crc, 0xe1); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); + nxp_crc(&crc, 0x03); + nxp_crc(&crc, 0xe1); + nxp_crc(&crc, 0x03); + nxp_crc(&crc, 0xe1); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); /* Block 3 -- 0x00 - 0x07 */ - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); /* Block 3 -- 0x08 - 0x0f */ - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); /* Append zeros of augmented message */ - crc8(&crc, 0x00); cut_assert_equal_int (0xc4, crc, cut_message ("Read example 1 CRC should match")); } @@ -220,46 +202,45 @@ test_mad_crc8_real_example_2 (void) uint8_t crc = CRC_PRESET; /* Block 1 -- 0x01 - 0x07 */ - crc8(&crc, 0x01); - crc8(&crc, 0x03); - crc8(&crc, 0xe1); - crc8(&crc, 0x03); - crc8(&crc, 0xe1); - crc8(&crc, 0x03); - crc8(&crc, 0xe1); + nxp_crc(&crc, 0x01); + nxp_crc(&crc, 0x03); + nxp_crc(&crc, 0xe1); + nxp_crc(&crc, 0x03); + nxp_crc(&crc, 0xe1); + nxp_crc(&crc, 0x03); + nxp_crc(&crc, 0xe1); /* Block 2 -- 0x08 - 0x0f */ - crc8(&crc, 0x03); - crc8(&crc, 0xe1); - crc8(&crc, 0x03); - crc8(&crc, 0xe1); - crc8(&crc, 0x03); - crc8(&crc, 0xe1); - crc8(&crc, 0x00); - crc8(&crc, 0x00); + nxp_crc(&crc, 0x03); + nxp_crc(&crc, 0xe1); + nxp_crc(&crc, 0x03); + nxp_crc(&crc, 0xe1); + nxp_crc(&crc, 0x03); + nxp_crc(&crc, 0xe1); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); /* Block 3 -- 0x00 - 0x07 */ - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); /* Block 3 -- 0x08 - 0x0f */ - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); - crc8(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); + nxp_crc(&crc, 0x00); /* Append zeros of augmented message */ - crc8(&crc, 0x00); cut_assert_equal_int (0xab, crc, cut_message ("Read example 1 CRC should match")); }