Ensure Consistency of Stored Data by Using Cyclic Redundancy Check (CRC)
Having data secure is critical for the reliability of the applications. It is very important to have data consistent when managing user's finance, ensuring reliable control of industrial processes, ensuring stable work of medical equipment, etc. But the storage sometimes fails, the transmission lines fail, lastly, there are bugs in the software application. All those factors produce corruption to critical data.
In this article, we will give a code sample on how to use Cyclic Redundancy Check (CRC) to check if the data was tampered or not. Basically, by comparing stored CRC of data with calculated CRC you can tell whether the data was tampered or not. There are several CRC algorithms depending on the length of CRC code. The longer the data chunk to be checked, the longer the CRC code must be used for it. CRC8 is 8-bit code that can be used for data up to few kilobytes. CRC16 is used up to few megabytes. CRC32 is used for even larger chunks of data. The longer the code, the more memory and CPU cycles are needed to calculate it.
We will show simple CRC16 algorithm realization that can be used on microcontrollers that process up to a few kilobytes of data.
#define CRC16 0xA001
uint16_t gen_crc16(const uint8_t *data, const uint16_t uLen)
{
register uint16_t crc = 0xFFFF;
for (uint16_t z = 0; z < uLen; z++)
{
crc ^= data[z];
for (uint8_t i = 0; i < 8; i++)
{
if ((crc & 0x0001) != 0)
crc = (crc >> 1) ^ CRC16;
else
crc = crc >> 1;
}
}
//printf("CRC:%X\r\n", crc);
return crc;
}