diff --git a/drivers/tpm/tpm_tis_sandbox.c b/drivers/tpm/tpm_tis_sandbox.c index 9ea98075b3..4aade565e2 100644 --- a/drivers/tpm/tpm_tis_sandbox.c +++ b/drivers/tpm/tpm_tis_sandbox.c @@ -217,7 +217,7 @@ static int sandbox_tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, rsk.struct_version = 2; rsk.uid = ROLLBACK_SPACE_KERNEL_UID; rsk.kernel_versions = 0; - rsk.crc8 = crc8((unsigned char *)&rsk, + rsk.crc8 = crc8(0, (unsigned char *)&rsk, offsetof(struct rollback_space_kernel, crc8)); memcpy(data, &rsk, sizeof(rsk)); diff --git a/include/linux/crc8.h b/include/linux/crc8.h index b5fd2ac9d6..f7c300a9b1 100644 --- a/include/linux/crc8.h +++ b/include/linux/crc8.h @@ -14,10 +14,11 @@ * This uses an x^8 + x^2 + x + 1 polynomial. A table-based algorithm would * be faster, but for only a few bytes it isn't worth the code size * + * @crc_start: CRC8 start value * @vptr: Buffer to checksum * @len: Length of buffer in bytes * @return CRC8 checksum */ -unsigned int crc8(const unsigned char *vptr, int len); +unsigned int crc8(unsigned int crc_start, const unsigned char *vptr, int len); #endif diff --git a/lib/crc8.c b/lib/crc8.c index 8b68a29e40..51d540fbcb 100644 --- a/lib/crc8.c +++ b/lib/crc8.c @@ -6,20 +6,27 @@ #include "linux/crc8.h" -unsigned int crc8(const unsigned char *vptr, int len) -{ - const unsigned char *data = vptr; - unsigned int crc = 0; - int i, j; +#define POLY (0x1070U << 3) - for (j = len; j; j--, data++) { - crc ^= (*data << 8); - for (i = 8; i; i--) { - if (crc & 0x8000) - crc ^= (0x1070 << 3); - crc <<= 1; - } +static unsigned char _crc8(unsigned short data) +{ + int i; + + for (i = 0; i < 8; i++) { + if (data & 0x8000) + data = data ^ POLY; + data = data << 1; } - return (crc >> 8) & 0xff; + return (unsigned char)(data >> 8); +} + +unsigned int crc8(unsigned int crc, const unsigned char *vptr, int len) +{ + int i; + + for (i = 0; i < len; i++) + crc = _crc8((crc ^ vptr[i]) << 8); + + return crc; }