diff --git a/client/src/cmdlfhitag.c b/client/src/cmdlfhitag.c index 02d84321a..f648f42f4 100644 --- a/client/src/cmdlfhitag.c +++ b/client/src/cmdlfhitag.c @@ -17,6 +17,7 @@ #include "fileutils.h" // savefile #include "protocols.h" // defines #include "cliparser.h" +#include "crc.h" static int CmdHelp(const char *Cmd); @@ -970,3 +971,8 @@ int CmdLFHitag(const char *Cmd) { int readHitagUid(void) { return (CmdLFHitagReader("--26") == PM3_SUCCESS); } + +uint8_t hitag1_CRC_check(uint8_t *d, uint32_t nbit){ + if (nbit < 9) return 2; + return (CRC8Hitag1Bits(d, nbit) == 0); +} diff --git a/client/src/cmdlfhitag.h b/client/src/cmdlfhitag.h index 817cb16f3..7f92285e8 100644 --- a/client/src/cmdlfhitag.h +++ b/client/src/cmdlfhitag.h @@ -19,4 +19,5 @@ int readHitagUid(void); void annotateHitag1(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool is_response); void annotateHitag2(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool is_response); void annotateHitagS(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool is_response); +uint8_t hitag1_CRC_check(uint8_t *d, uint32_t nbit); #endif diff --git a/client/src/cmdtrace.c b/client/src/cmdtrace.c index 3de8f3312..15dff55bf 100644 --- a/client/src/cmdtrace.c +++ b/client/src/cmdtrace.c @@ -216,10 +216,11 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr case ISO_15693: crcStatus = iso15693_CRC_check(frame, data_len); break; - case PROTO_CRYPTORF: case PROTO_HITAG1: - case PROTO_HITAG2: case PROTO_HITAGS: + crcStatus = hitag1_CRC_check(frame, (data_len * 8) - ((8 - parityBytes[0]) % 8)); + case PROTO_CRYPTORF: + case PROTO_HITAG2: default: break; } @@ -292,10 +293,8 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr if (markCRCBytes) { //CRC-command if (((protocol == PROTO_HITAG1) || (protocol == PROTO_HITAGS)) && (data_len > 1)) { - // notes hitag S: - // pm3 is using UID REQUEST Adv -> SOF is 111(AC) then 111111(MC) - // for unknown reason, recorded SOF in trace is 1111 instead of 111111 (or should be even skipped) - // CRC on tag response is SOF excluded + // Note that UID REQUEST response has no CRC, but we don't know + // if the response we see is a UID char *pos1 = line[(data_len - 1) / 18] + (((data_len - 1) % 18) * 4) + offset - 1; (*pos1) = '['; char *pos2 = line[(data_len) / 18] + (((data_len) % 18) * 4) + offset - 2; diff --git a/common/crc.c b/common/crc.c index e7f169691..033c244d2 100644 --- a/common/crc.c +++ b/common/crc.c @@ -147,3 +147,25 @@ uint32_t CRC8Hitag1(uint8_t *buff, size_t size) { } return crc_finish(&crc); } + +uint32_t CRC8Hitag1Bits(uint8_t *buff, size_t bitsize) { + crc_t crc; + uint8_t data = 0; + uint8_t n = 0; + crc_init_ref(&crc, 8, 0x1d, 0xff, 0, false, false); + uint8_t i; + for (i = 0; i < bitsize; i++) { + data <<= 1; + data += (buff[i/8] >> (7 - (i % 8))) & 1; + n += 1; + if (n == 8) { + crc_update2(&crc, data, n); + n = 0; + data = 0; + } + } + if (n > 0) { + crc_update2(&crc, data, n); + } + return crc_finish(&crc); +} \ No newline at end of file diff --git a/common/crc.h b/common/crc.h index 1b1faca57..33e289ee8 100644 --- a/common/crc.h +++ b/common/crc.h @@ -78,5 +78,6 @@ uint32_t CRC8Cardx(uint8_t *buff, size_t size); // Calculate CRC-8/Hitag1, ZX8211 checksum uint32_t CRC8Hitag1(uint8_t *buff, size_t size); +uint32_t CRC8Hitag1Bits(uint8_t *buff, size_t bitsize); #endif /* __CRC_H */