Implementing code signing in low-cost controllers
For a reliable and trusted product ecosystem, trustworthy software stacks and upgrade packages are essential. Counterfeiting as well as unauthorized software manipulation and compromising, can be prevented by adding code signing into the software supply chain. This is particularly important in the Internet of Things (IoT) with its multitude of small, connected devices.
The concept of code signing itself is quite simple to explain. Typically, a unique “fingerprint” is created for the software package and then signed by a trusted authority. The public key of the code-signing instance is then integrated into the device’s firmware. Thus, each time the software is started or updated, its signature can be verified.
However, it can be easier said than done to get secure, trusted, and audit-friendly code signing integrated into the software supply chain and product lifecycle.
Lack of best practices and implementation scenarios
When observing the IoT component market, we see that more and more processor and controller manufacturers integrate security into their products from inception. For example, in the low-cost sector, controllers like the Espressif ESP32 come with built-in cryptographic extensions plus a multi-stage boot process that enables the integration of code signing procedures. However, what is missing is the actual how-to for integrating a scalable and reliable signing solution into the software build process.
The out-of-the-box code signing solution provided with Espressif’s tools only allows the developer to store the private part of the signature key locally. In other words, it can be accessible, unprotected, and with limited evidence of being authentic. The Espressif manual states that this method is only suitable for single-user development and refers to centralized tools for enterprise-grade deployment, but there is no clear implementation roadmap.
Sadly, we see this trend with many suppliers. Best practices, implementation scenarios, and application examples are lacking.
Nonetheless, it is imperative to implement a trustworthy lifecycle for IoT devices, especially with emerging regulations and legal requirements. Here, code signing is an essential building block.
How to enable a trustworthy code signing process for ESP32
It is possible to integrate code signing into ESP32’s boot process and for updates, as stated earlier.
By integrating Espressif ESP32 with our open-source PKI (EJBCA) and signature (SignServer) solutions, we believe that we have been able to achieve a smooth and trustworthy build process. SignServer is a server-side signature solution that uses an HSM (Hardware Security Module) to secure the code-signing keys and integrates with the EJBCA PKI to issue the required code-signing certificates.
Enabling centralized signature creation with ESP32 and SignServer is simple:
- In the standard build process of ESP32, disable signature generation
- Add a script that fetches the plain code application and enables the connection to SignServer
- Get the signature back from SignServer and add it to the application binary package (and don’t forget to add the format string!)
For the full set of instructions, view our tutorials on how to set up SignServer and create a code signing certificate using EJBCA. We also share the script that performs the signature creation and provides the signed package for loading into the ESP32. Give it a try and let us know what you think!
Note: The procedures described in the tutorial are based on ESP32 with Secure Boot version 1.