Fix MAD CRC algorithm.
The CRC algorithm is not a standard CRC algorithm so rename it to nxp_crc() and adjust all related code.
This commit is contained in:
parent
42692ccf54
commit
feb240ee73
3 changed files with 110 additions and 136 deletions
|
@ -39,7 +39,7 @@
|
||||||
struct mad_sector_0x00;
|
struct mad_sector_0x00;
|
||||||
struct mad_sector_0x10;
|
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);
|
MifareTag mifare_classic_tag_new (void);
|
||||||
void mifare_classic_tag_free (MifareTag tag);
|
void mifare_classic_tag_free (MifareTag tag);
|
||||||
MifareTag mifare_ultralight_tag_new (void);
|
MifareTag mifare_ultralight_tag_new (void);
|
||||||
|
|
|
@ -38,15 +38,10 @@
|
||||||
#include "freefare_internal.h"
|
#include "freefare_internal.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX The documentation says the preset is 0xE3, but the various card dumps
|
* The documentation says the preset is 0xE3 but the bits have to be mirrored:
|
||||||
* and the documentation example MAD CRC can be verified only with a CRC
|
* 0xe3 = 1110 0011 <=> 1100 0111 = 0xc7
|
||||||
* 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
|
|
||||||
*/
|
*/
|
||||||
#define CRC_PRESET 0x67
|
#define CRC_PRESET 0xc7
|
||||||
|
|
||||||
#define SECTOR_0X00_AIDS 15
|
#define SECTOR_0X00_AIDS 15
|
||||||
#define SECTOR_0X10_AIDS 23
|
#define SECTOR_0X10_AIDS 23
|
||||||
|
@ -96,15 +91,15 @@ mad_new (uint8_t version)
|
||||||
* Compute CRC.
|
* Compute CRC.
|
||||||
*/
|
*/
|
||||||
void
|
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 */
|
/* x^8 + x^4 + x^3 + x^2 + 1 => 0x11d */
|
||||||
const uint8_t poly = 0x1d;
|
const uint8_t poly = 0x1d;
|
||||||
|
|
||||||
|
*crc ^= value;
|
||||||
for (int current_bit = 7; current_bit >= 0; current_bit--) {
|
for (int current_bit = 7; current_bit >= 0; current_bit--) {
|
||||||
int bit_out = (*crc) & 0x80;
|
int bit_out = (*crc) & 0x80;
|
||||||
*crc = ((*crc) << 1) | (( value >> (current_bit)) & 0x01);
|
*crc <<= 1;
|
||||||
|
|
||||||
if (bit_out)
|
if (bit_out)
|
||||||
*crc ^= poly;
|
*crc ^= poly;
|
||||||
|
|
||||||
|
@ -116,13 +111,12 @@ sector_0x00_crc8 (Mad mad)
|
||||||
{
|
{
|
||||||
uint8_t crc = CRC_PRESET;
|
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++) {
|
for (int n = 0; n < SECTOR_0X00_AIDS; n++) {
|
||||||
crc8 (&crc, mad->sector_0x00.aids[n].application_code);
|
nxp_crc (&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].function_cluster_code);
|
||||||
}
|
}
|
||||||
crc8 (&crc, 0x00);
|
|
||||||
|
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
@ -132,13 +126,12 @@ sector_0x10_crc8 (Mad mad)
|
||||||
{
|
{
|
||||||
uint8_t crc = CRC_PRESET;
|
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++) {
|
for (int n = 0; n < SECTOR_0X10_AIDS; n++) {
|
||||||
crc8 (&crc, mad->sector_0x10.aids[n].application_code);
|
nxp_crc (&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].function_cluster_code);
|
||||||
}
|
}
|
||||||
crc8 (&crc, 0x00);
|
|
||||||
|
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
213
test/test_mad.c
213
test/test_mad.c
|
@ -67,7 +67,7 @@ test_mad (void)
|
||||||
mad_free (mad);
|
mad_free (mad);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CRC_PRESET 0x67
|
#define CRC_PRESET 0xc7
|
||||||
|
|
||||||
void
|
void
|
||||||
test_mad_crc8_basic (void)
|
test_mad_crc8_basic (void)
|
||||||
|
@ -75,30 +75,14 @@ test_mad_crc8_basic (void)
|
||||||
uint8_t crc;
|
uint8_t crc;
|
||||||
const uint8_t crc_value = 0x42;
|
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 */
|
/* Check integrity */
|
||||||
crc = CRC_PRESET;
|
crc = CRC_PRESET;
|
||||||
crc8(&crc, crc_value);
|
nxp_crc(&crc, crc_value);
|
||||||
crc8(&crc, 0x00);
|
|
||||||
uint8_t save = crc;
|
uint8_t save = crc;
|
||||||
|
|
||||||
crc = CRC_PRESET;
|
crc = CRC_PRESET;
|
||||||
crc8(&crc, crc_value);
|
nxp_crc(&crc, crc_value);
|
||||||
crc8(&crc, save);
|
nxp_crc(&crc, save);
|
||||||
cut_assert_equal_int (0x00, crc, cut_message ("CRC should verify crc(message + crc(message)) = 0"));
|
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;
|
uint8_t crc = CRC_PRESET;
|
||||||
|
|
||||||
/* Block 1 -- 0x01 - 0x07 */
|
/* Block 1 -- 0x01 - 0x07 */
|
||||||
crc8(&crc, 0x01);
|
nxp_crc(&crc, 0x01);
|
||||||
crc8(&crc, 0x01);
|
nxp_crc(&crc, 0x01);
|
||||||
crc8(&crc, 0x08);
|
nxp_crc(&crc, 0x08);
|
||||||
crc8(&crc, 0x01);
|
nxp_crc(&crc, 0x01);
|
||||||
crc8(&crc, 0x08);
|
nxp_crc(&crc, 0x08);
|
||||||
crc8(&crc, 0x01);
|
nxp_crc(&crc, 0x01);
|
||||||
crc8(&crc, 0x08);
|
nxp_crc(&crc, 0x08);
|
||||||
|
|
||||||
/* Block 2 -- 0x08 - 0x0f */
|
/* Block 2 -- 0x08 - 0x0f */
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x04);
|
nxp_crc(&crc, 0x04);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
|
|
||||||
/* Block 3 -- 0x00 - 0x07 */
|
/* Block 3 -- 0x00 - 0x07 */
|
||||||
crc8(&crc, 0x03);
|
nxp_crc(&crc, 0x03);
|
||||||
crc8(&crc, 0x10);
|
nxp_crc(&crc, 0x10);
|
||||||
crc8(&crc, 0x03);
|
nxp_crc(&crc, 0x03);
|
||||||
crc8(&crc, 0x10);
|
nxp_crc(&crc, 0x10);
|
||||||
crc8(&crc, 0x02);
|
nxp_crc(&crc, 0x02);
|
||||||
crc8(&crc, 0x10);
|
nxp_crc(&crc, 0x10);
|
||||||
crc8(&crc, 0x02);
|
nxp_crc(&crc, 0x02);
|
||||||
crc8(&crc, 0x10);
|
nxp_crc(&crc, 0x10);
|
||||||
|
|
||||||
/* Block 3 -- 0x08 - 0x0f */
|
/* Block 3 -- 0x08 - 0x0f */
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x11);
|
nxp_crc(&crc, 0x11);
|
||||||
crc8(&crc, 0x30);
|
nxp_crc(&crc, 0x30);
|
||||||
|
|
||||||
/* Append zeros of augmented message */
|
/* Append zeros of augmented message */
|
||||||
crc8(&crc, 0x00);
|
|
||||||
|
|
||||||
cut_assert_equal_int (0x89, crc, cut_message ("Sample CRC should match"));
|
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;
|
uint8_t crc = CRC_PRESET;
|
||||||
|
|
||||||
/* Block 1 -- 0x01 - 0x07 */
|
/* Block 1 -- 0x01 - 0x07 */
|
||||||
crc8(&crc, 0x01);
|
nxp_crc(&crc, 0x01);
|
||||||
crc8(&crc, 0x03);
|
nxp_crc(&crc, 0x03);
|
||||||
crc8(&crc, 0xe1);
|
nxp_crc(&crc, 0xe1);
|
||||||
crc8(&crc, 0x03);
|
nxp_crc(&crc, 0x03);
|
||||||
crc8(&crc, 0xe1);
|
nxp_crc(&crc, 0xe1);
|
||||||
crc8(&crc, 0x03);
|
nxp_crc(&crc, 0x03);
|
||||||
crc8(&crc, 0xe1);
|
nxp_crc(&crc, 0xe1);
|
||||||
|
|
||||||
/* Block 2 -- 0x08 - 0x0f */
|
/* Block 2 -- 0x08 - 0x0f */
|
||||||
crc8(&crc, 0x03);
|
nxp_crc(&crc, 0x03);
|
||||||
crc8(&crc, 0xe1);
|
nxp_crc(&crc, 0xe1);
|
||||||
crc8(&crc, 0x03);
|
nxp_crc(&crc, 0x03);
|
||||||
crc8(&crc, 0xe1);
|
nxp_crc(&crc, 0xe1);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
|
|
||||||
/* Block 3 -- 0x00 - 0x07 */
|
/* Block 3 -- 0x00 - 0x07 */
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
|
|
||||||
/* Block 3 -- 0x08 - 0x0f */
|
/* Block 3 -- 0x08 - 0x0f */
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
|
|
||||||
/* Append zeros of augmented message */
|
/* Append zeros of augmented message */
|
||||||
crc8(&crc, 0x00);
|
|
||||||
|
|
||||||
cut_assert_equal_int (0xc4, crc, cut_message ("Read example 1 CRC should match"));
|
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;
|
uint8_t crc = CRC_PRESET;
|
||||||
|
|
||||||
/* Block 1 -- 0x01 - 0x07 */
|
/* Block 1 -- 0x01 - 0x07 */
|
||||||
crc8(&crc, 0x01);
|
nxp_crc(&crc, 0x01);
|
||||||
crc8(&crc, 0x03);
|
nxp_crc(&crc, 0x03);
|
||||||
crc8(&crc, 0xe1);
|
nxp_crc(&crc, 0xe1);
|
||||||
crc8(&crc, 0x03);
|
nxp_crc(&crc, 0x03);
|
||||||
crc8(&crc, 0xe1);
|
nxp_crc(&crc, 0xe1);
|
||||||
crc8(&crc, 0x03);
|
nxp_crc(&crc, 0x03);
|
||||||
crc8(&crc, 0xe1);
|
nxp_crc(&crc, 0xe1);
|
||||||
|
|
||||||
/* Block 2 -- 0x08 - 0x0f */
|
/* Block 2 -- 0x08 - 0x0f */
|
||||||
crc8(&crc, 0x03);
|
nxp_crc(&crc, 0x03);
|
||||||
crc8(&crc, 0xe1);
|
nxp_crc(&crc, 0xe1);
|
||||||
crc8(&crc, 0x03);
|
nxp_crc(&crc, 0x03);
|
||||||
crc8(&crc, 0xe1);
|
nxp_crc(&crc, 0xe1);
|
||||||
crc8(&crc, 0x03);
|
nxp_crc(&crc, 0x03);
|
||||||
crc8(&crc, 0xe1);
|
nxp_crc(&crc, 0xe1);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
|
|
||||||
/* Block 3 -- 0x00 - 0x07 */
|
/* Block 3 -- 0x00 - 0x07 */
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
|
|
||||||
/* Block 3 -- 0x08 - 0x0f */
|
/* Block 3 -- 0x08 - 0x0f */
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
crc8(&crc, 0x00);
|
nxp_crc(&crc, 0x00);
|
||||||
|
|
||||||
/* Append zeros of augmented message */
|
/* Append zeros of augmented message */
|
||||||
crc8(&crc, 0x00);
|
|
||||||
|
|
||||||
cut_assert_equal_int (0xab, crc, cut_message ("Read example 1 CRC should match"));
|
cut_assert_equal_int (0xab, crc, cut_message ("Read example 1 CRC should match"));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue