Hash Functions

A hash value is a small fixed-size value that is calculated from, and used to represent, all the values in an arbitrary-sized block of data. If that data block is copied, a hash recalculated from the new block can be compared to the original hash. Agreement between the two hashes provides a high level of certainty that the copy is valid. There are many hash algorithms. More complex algorithms provide a more robust verification, but could use too many resources when used in an embedded environment.

Hexmate can be used to calculate the hash of a program image that is contained in a HEX file built by the MPLAB XC8 C Compiler. This hash can be embedded into that HEX file and burned into the target device along with the program image. At runtime, the target device might be able to run a similar hash algorithm over the program image, now stored in its memory. If the stored and calculated hashes are the same, the embedded program can assume that it has a valid program image to execute.

Hexmate implements several checksum and cyclic redundancy check algorithms to calculate the hash. If you are using the xc8-cc driver to perform project builds, the driver’s -mchecksum option will instruct the driver to invoke Hexmate and pass it the appropriate Hexmate options. That same option is available in the MPLAB X IDE. If you are driving Hexmate explicitly, the option to select the algorithm is described in Ck. In the discussion of the algorithms below, it is assumed you are using the compiler driver to request a checksum or CRC.

Some consideration is required when program images contain unused memory locations. The driver’s -mchecksum option automatically requests that Hexmate fill unused memory locations to match unprogrammed device memory. You might need to mimic this action if invoking Hexmate explicitly.

Although Hexmate will work with any device, not all devices can read the entire width of their program memory. Mid-range PIC devices also use a 14-bit wide program memory, thus you cannot store a hash larger than a byte directly. For these devices, you would typically use the code=nn argument to the -mcodeoffset option, to have each byte of the hash value encapsulated in an instruction.

The following sections provide examples of the algorithms that can be used to calculate the hash at runtime, but note that these examples are not directly usable with all devices.