From 01b149efa5809a4f480f27a9abda325585cc9986 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 30 Oct 2019 15:44:57 +0100 Subject: [PATCH] fix: fdx crc calc --- client/cmdlffdx.c | 22 ++++++++++++---------- common/crc16.c | 17 ++++++++++++++++- common/crc16.h | 11 ++++++++--- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 244c0caf3..6cf3b0efa 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -13,6 +13,7 @@ #include #include #include +#include // tolower #include "cmdparser.h" // command_t #include "comms.h" @@ -226,15 +227,12 @@ static int CmdFdxDemod(const char *Cmd) { uint8_t dataBlockBit = DemodBuffer[48]; uint32_t reservedCode = bytebits_to_byteLSBF(DemodBuffer + 49, 14); uint8_t animalBit = DemodBuffer[63]; - uint32_t crc_16 = bytebits_to_byteLSBF(DemodBuffer + 64, 16); + uint16_t crc = bytebits_to_byteLSBF(DemodBuffer + 64, 16); uint32_t extended = bytebits_to_byteLSBF(DemodBuffer + 80, 24); uint64_t rawid = (uint64_t)(bytebits_to_byte(DemodBuffer, 32)) << 32 | bytebits_to_byte(DemodBuffer + 32, 32); uint8_t raw[8]; num_to_bytes(rawid, 8, raw); - - uint16_t calcCrc = crc16_kermit(raw, 8); - PrintAndLogEx(SUCCESS, "\nFDX-B / ISO 11784/5 Animal Tag ID Found: Raw : %s", sprint_hex(raw, 8)); PrintAndLogEx(SUCCESS, "Animal ID %04u-%012" PRIu64, countryCode, NationalCode); PrintAndLogEx(SUCCESS, "National Code %012" PRIu64 " (0x%" PRIx64 ")", NationalCode, NationalCode); @@ -242,7 +240,10 @@ static int CmdFdxDemod(const char *Cmd) { PrintAndLogEx(SUCCESS, "Reserved/RFU %u (0x04%X)", reservedCode, reservedCode); PrintAndLogEx(SUCCESS, "Animal Tag %s", animalBit ? _YELLOW_("True") : "False"); PrintAndLogEx(SUCCESS, "Has extended data %s [0x%X]", dataBlockBit ? _YELLOW_("True") : "False", extended); - PrintAndLogEx(SUCCESS, "CRC-16 0x%04X - 0x%04X [%s]", crc_16, calcCrc, (calcCrc == crc_16) ? _GREEN_("Ok") : _RED_("Fail")); + + uint8_t c[] = {0, 0}; + compute_crc(CRC_11784, raw, sizeof(raw), &c[0], &c[1]); + PrintAndLogEx(SUCCESS, "CRC-16 0x%04X [ %s] ", crc, (crc == (c[1] << 8 | c[0]) ) ? _GREEN_("OK") : _RED_("Fail")); if (g_debugMode) { PrintAndLogEx(DEBUG, "Start marker %d; Size %zu", preambleIndex, size); @@ -265,8 +266,8 @@ static int CmdFdxClone(const char *Cmd) { uint32_t countryid = 0; uint64_t animalid = 0; - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_fdx_clone(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_fdx_clone(); countryid = param_get32ex(Cmd, 0, 0, 10); animalid = param_get64ex(Cmd, 1, 0, 10); @@ -305,8 +306,8 @@ static int CmdFdxSim(const char *Cmd) { uint32_t countryid = 0; uint64_t animalid = 0; - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_fdx_sim(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_fdx_sim(); countryid = param_get32ex(Cmd, 0, 0, 10); animalid = param_get64ex(Cmd, 1, 0, 10); @@ -417,7 +418,8 @@ int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t for (uint8_t i = 0; i < 8; ++i) raw[i] = bytebits_to_byte(bits + 11 + i * 9, 8); - uint16_t crc = crc16_kermit(raw, 8); + init_table(CRC_11784); + uint16_t crc = crc16_fdx(raw, 8); num_to_bytebitsLSBF(crc >> 0, 8, bits + 83); num_to_bytebitsLSBF(crc >> 8, 8, bits + 92); diff --git a/common/crc16.c b/common/crc16.c index 22445beda..b1c2ac248 100644 --- a/common/crc16.c +++ b/common/crc16.c @@ -46,6 +46,9 @@ void init_table(CrcType_t crctype) { case CRC_KERMIT: generate_table(CRC16_POLY_CCITT, true); break; + case CRC_11784: + generate_table(CRC16_POLY_CCITT, false); + break; case CRC_NONE: crc_table_init = false; current_crc_type = CRC_NONE; @@ -185,6 +188,9 @@ void compute_crc(CrcType_t ct, const uint8_t *d, size_t n, uint8_t *first, uint8 case CRC_KERMIT: crc = crc16_kermit(d, n); break; + case CRC_11784: + crc = crc16_fdx(d, n); + break; case CRC_LEGIC: // TODO return; @@ -215,6 +221,8 @@ uint16_t Crc16ex(CrcType_t ct, const uint8_t *d, size_t n) { return crc16_ccitt(d, n); case CRC_KERMIT: return crc16_kermit(d, n); + case CRC_11784: + return crc16_fdx(d, n); case CRC_LEGIC: // TODO return 0; @@ -257,6 +265,8 @@ bool check_crc(CrcType_t ct, const uint8_t *d, size_t n) { return (crc16_ccitt(d, n) == 0); case CRC_KERMIT: return (crc16_kermit(d, n) == 0); + case CRC_11784: + return (crc16_fdx(d, n) == 0); case CRC_LEGIC: // TODO return false; @@ -272,7 +282,12 @@ uint16_t crc16_ccitt(uint8_t const *d, size_t n) { return crc16_fast(d, n, 0xffff, false, false); } -// FDX-B ISO11784/85) uses KERMIT +// FDX-B ISO11784/85) uses KERMIT/CCITT +// poly 0x xx init=0x000 refin=false refout=true xorout=0x0000 ... +uint16_t crc16_fdx(uint8_t const *d, size_t n) { + return crc16_fast(d, n, 0x0000, false, true); +} + // poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 name="KERMIT" uint16_t crc16_kermit(uint8_t const *d, size_t n) { return crc16_fast(d, n, 0x0000, true, true); diff --git a/common/crc16.h b/common/crc16.h index 6989af22e..7a273683c 100644 --- a/common/crc16.h +++ b/common/crc16.h @@ -10,14 +10,16 @@ #include "common.h" -#define CRC16_POLY_CCITT 0x1021 -#define CRC16_POLY_LEGIC 0xc6c6 //0x6363 -#define CRC16_POLY_DNP 0x3d65 +#define CRC16_POLY_CCITT 0x1021 +#define CRC16_POLY_KERMIT 0x8408 +#define CRC16_POLY_LEGIC 0xc6c6 //0x6363 +#define CRC16_POLY_DNP 0x3d65 #define X25_CRC_CHECK ((uint16_t)(~0xF0B8 & 0xFFFF)) // use this for checking of a correct crc typedef enum { CRC_NONE, + CRC_11784, CRC_14443_A, CRC_14443_B, CRC_15693, @@ -41,6 +43,9 @@ bool check_crc(CrcType_t ct, const uint8_t *d, size_t n); uint16_t crc16_ccitt(uint8_t const *d, size_t n); // Calculate CRC-16/KERMIT (FDX-B ISO11784/85) LF +uint16_t crc16_fdx(uint8_t const *d, size_t n); + +// Calculate CRC-16/KERMIT uint16_t crc16_kermit(uint8_t const *d, size_t n); // Calculate CRC-16/XMODEM (FeliCa)