Topic: Mifare Application Directory (MAD) CRC
Hi
I am currently adding CRC verification and generation support to MAD management functions in libfreefare [1] from the nfc-tools [2] project.
According to the MIFARE Application Directory (MAD) Application note,
8 bit CRC uses the polynomial:x8 + x4 + x3 + x2 + 1 and is preset with 0xE3
However, I am not able to have correct results. I have checked the CRC algorithm to ensure the computed value is the same as the one I get if I do the "division" on paper, so the problem seems to be related to the CRC preset.
Using both a real card dump and the MAD provided as example in the documentation, I could brute-force an initialisation value that makes the CRC algorithm return the expected value. Using this preset on another real card was successful too.
I could not find relevant information about this on the Internet (I guess people use the mif_calc_crc() function from MIFARE API... I don't have access to it to compare my CRC and their's). Anybody here ever got working CRC verification using settings from the documentation? Anybody can help me telling me what the mif_calc_crc() function returns in tests cases I could provide?
In case I fail to see an obvious problem, here is the unit test:
#define CRC_PRESET 0x67
DEFINE_TEST(test_mad_crc_doc_example)
{
do {
/* Preset */
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);
/* 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);
/* 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);
/* 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);
/* Append zeros of augmented message */
crc8(&crc, 0x00);
assertEqualInt (crc, 0x89);
} while (0);
}The crc8() function itself is as follow:
void
crc8 (uint8_t *crc, const uint8_t value)
{
/* x^8 + x^4 + x^3 + x^2 + 1 => 0x11d */
const uint8_t poly = 0x1d;
for (int current_bit = 7; current_bit >= 0; current_bit--) {
int bit_out = (*crc) & 0x80;
*crc = ((*crc) << 1) | (( value >> (current_bit)) & 0x01);
if (bit_out)
*crc ^= poly;
}
}Thanks!
Romain
References:
Last edited by romain (2009-12-24 15:55:33)