8.2.4 Hash Value Calculations

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 can sometimes be too computationally demanding when used in an embedded environment, particularly for smaller devices.

Hexmate implements several hash algorithms, such as checksums and cyclic redundancy checks, which can be selected to calculate a hash value of a program image that is contained in a HEX file. This value can be embedded into that same HEX file and burned into the target device along with the program image. At runtime, the target device can 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's -ck option requests that a hash be calculated, as described in 8.2.3.12 Ck Hexmate Option. If you are using xc8-cc or the MPLAB X IDE to perform XC8 project builds, the compiler driver’s -mchecksum option and suitable arguments will invoke Hexmate and pass it the appropriate options to calculate a hash.

Some consideration is required when a hash value is being calculated over memory that contains unused memory locations. Consider using Hexmate's -fill option (see 8.2.3.13 Fill Option) to have these locations programmed with a known value. Avoid filling the locations where the hash value will be stored, as memory is filled before the hash is calculated, and this can result in an error. If you are using xc8-cc or the MPLAB X IDE to perform project builds, requesting a hash value automatically requests that Hexmate fill unused memory locations to match unprogrammed device memory.

Hexmate can produce a hash value from any Intel HEX file, regardless of which compiler produced the file and which device that file is intended to program. However, the architecture of the target device may restrict which memory locations can be read at runtime, thus requiring modification to the way in which Hexmate should perform hash calculations, so that the two hashes are calculated similarly and agree. In addition, some compilers might insert padding or phantom bytes into the HEX file that are not present in the device memory. These bytes might need to be ignored by Hexmate when it calculates a hash value and the following discussion indicates possible solutions.

Not all devices can read the entire width of their program memory. For example, Baseline and Mid-range PIC devices can only read the lower byte of each program memory location. The HEX file, however, will contain two bytes for each program memory word and both these bytes will normally be processed by Hexmate when calculating a hash value. Use the s2 suboption to Hexmate's -ck option to have the MSB of each 2-byte word skipped. If you are using xc8-cc or the MPLAB X IDE to perform project builds, use the skip=2 suboption to the -mchecksum option to have Hexmate skip the MSB of each program word. Note, however, that this sort of verification process will not detect corruption in the MSB of each program word.

Some devices have hardware CRC modules which can calculate a CRC hash value. If desired, program memory data can be streamed to this module using the Scanner module to automate the calculation. As the Scanner module reads the MSB of each program memory word first, you need to have Hexmate also process HEX file bytes within an instruction word in the reverse order. Use the r2 suboption to Hexmate's -ck option to have Hexmate process the bytes in a 2-byte word in reverse order. If you are using xc8-cc or the MPLAB X IDE to perform project builds when using these modules, use the revword=2 suboption to the -mchecksum option to have Hexmate process the bytes in a 2-byte word in reverse order.

Some consideration must also be given to how the Hexmate hash value encoded in the HEX file can be read at runtime.

Baseline and Mid-range PIC devices must store data in program memory using retlw instructions. Thus they need one instruction to store each byte of the hash value calculated by Hexmate. Use the t34 suboption to Hexmate's -ck option to have Hexmate store each byte of the hash value in a retlw instruction. (The retlw instruction is encoded as 0x34nn, where nn is the 8-bit data value to be loaded to WREG when executed.) If you are using xc8-cc or the MPLAB X IDE to perform project builds when using these devices, use the code=34 suboption to the -mchecksum option to have Hexmate store each byte of the hash value in a retlw instruction.