STM32 hex file signing with CRC - Page 1
Forum section: electronics / general

author: Jeroen3
author_rank: Super Contributor
timestamp: March 09, 2017, 09:50:54 am
content: Due to it not being googlable to find a piece of code/tool that inserts a checksum to a hex file equal to the STM32F1 hardware CRC. I deciced to make it googlable, right here, after I spend a day getting it working.Basically you'll need to insert a checksum in the hex/binary file generated by the compiler. Then you'd want to tell the debugger to use that hex file. Or make the embedded code pass on both correct crc and 0xFFFFFFFF.Required:- Linker memory layout knowledge of your target.-SRecord. I used 1.64.- Call sign.bat after compilation.Sign.bat:Code::: The linker omits blocks of 0xFF to speed up programming, you'll need these 0xFF for the checksum to be valid.srec_cat @1_fillgaps.srec:: Perform the CRC signingsrec_cat @2_sign.srec:: Remove the block of 0xFF again, because empty flash will be 0xFF.srec_cat @3_unfillgaps.srec1_fillgaps.srecCode:.\build\source.hex # Source hex file-Intel # type Intel Hex-fill 0xFF 0x08000000 0x08040000 # Memory from 0x08000000 to 0x08040000 (stm32f103 256k)-o .\build\1_filled.hex # Output file-Intel # Output type Intel Hex2_sign.srecCode:.\build\1_filled.hex # Source hex file-intel # input Intel Hex-crop 0x08000000 0x0803FFFC # CRC from 0x08000000 to 0x0803FFFC-4 (stm32f103 256k)-STM32 0x0803FFFC # Put CRC here (calculate identical as STM32)-o .\build\2_signed.hex # Output file-intel # output Intel Hex3_unfillgaps.srecCode:.\build\srec\2_signed.hex # Source hex file-Intel # type Intel Hex-unfill 0xFF # Remove >256 bytes blocks 0xFF-Output_Block_Size=16 # Limit hex file line length-address-length=4 # Limit address length-o .\build\source_signed.hex # output file name-Intel # type Intel HexTo tell your compiler to load .\build\source_signed.hex instead you should refer to the manual.There is often a script thing available.For Keil for example:debug.iniCode:LOAD .\source_signed.hex INCREMENTALIn the embedded device link a symbol to 0x0803FFFC.Code: (c)// Absolute linked symbol (keil method)uint32_t flash_crc __attribute__((at(0x08040000-4)));int flashcheck(void){uint32_t crc = 0;uint32_t *d;uint32_t len;// Enable CRC__HAL_RCC_CRC_CLK_ENABLE();CRC->CR |= 1;d= (uint32_t*)0x08000000;len = (0x08040000 - 4) / 4; // feed wordswhile(len--){CRC->DR = *d++;}crc = CRC->DR;// Disable CRC__HAL_RCC_CRC_CLK_DISABLE();if( flash_crc == crc ){return 0;}else{return -1;}}I hope this helps you.

author: technix
author_rank: Super Contributor
timestamp: March 09, 2017, 10:28:12 am
content: I would prefer a better technique using proper crypto.The bootloader embeds an RSA-4096 public key that you have the private key of. After writing the firmware image to the flash, the SHA-256 hash of the image is calculated. An RSA-encrypted signature is then received, decrypted using the embedded public key, and compared against the calculated hash. If the hashes agree the image is accepted.To guard against incomplete uploads and TOCTTOU vulnerabilities, the Reset vector and initial stack pointer is not written to the Flash before the entire image is verified. Instead the entry point and stack pointer of the bootloader is written there.RSA-4096 and SHA-512 are both strong crypto. Unless either someone got big enough a quantum computer, got way too much CPU cycles, or hacked your computer holding the private key, your bootloader won't accept anything that is not cryptographically signed by you. And if you managed to prevent your bootloader from being bypassed, you can use it as a root of trust, and your microcontroller won't be running a single instruction that is not signed by you.

author: Jeroen3
author_rank: Super Contributor
timestamp: March 09, 2017, 11:13:55 am
content: The purpose is not to authenticate firmware uploads, but protect the integrity of the flash.To do this in an as short as possible time, the hardware crc is used.Obvously, you can change above adresses and script to not use -STM32 but -SHA256.

author: technix
author_rank: Super Contributor
timestamp: March 09, 2017, 01:53:32 pm
content: So if the upload time integrity is protected using crypto, what are you protecting then?

author: Jeroen3
author_rank: Super Contributor
timestamp: March 09, 2017, 02:09:43 pm
content: Some certifications require the software to perform integrity check. Flash can get corrupted, even after it has been programmed. Especially if it contains eeprom emulation.I also made a more complex version that splits the original image in two parts.- The firmware image.- The calibrations and settings sector. (later adjusted during production testing)This way srecord puts in a crc for the firmware, and the calibrations.

author: technix
author_rank: Super Contributor
timestamp: March 09, 2017, 02:42:37 pm
content: You really should avoid EEPROM emulating too much, at least throw those sectors far far away from program code, and perform wear balancing. If there are a lot of changing data, consider using external EEPROM. Adding an 24C32 isn't that expensive.

author: Jeroen3
author_rank: Super Contributor
timestamp: March 09, 2017, 04:21:55 pm
content: In my use case they are ideally written twice.Once during calibration.Once during commisioning.I know the weak points of on chip flash. There is fram for runtime non-volatile values.