We are working on implementing secure-boot in our Torizon OS image. Following secure-boot-on-torizoncore we have implemented this in our image and have tested by manually burning the fuses in an uboot CLI, however we are atm not sure how to implement this in our production flow. What is the recommended way to burn the fuses in a production setting? Can we do this automatically after flashing with the Easy Installer?
Hi, I’m the Toradex AI Assistant. I’m in early beta, and I would appreciate your feedback.
The Toradex Support team will follow up with you shortly!
Did you like my answer?
Hello,
Implementing secure boot in a production environment for Toradex devices involves several critical steps to ensure the security and integrity of the devices. For Toradex modules running TorizonCore, the process of burning fuses for secure boot should be carefully integrated into your production programming flow.
The recommended way to burn the fuses in a production setting is to use a script or automated process that runs after the initial flashing of the device with the Toradex Easy Installer. This script should leverage the U-Boot environment or a custom application running under Linux to program the fuses. It’s important to note that once the fuses are burned, they cannot be reverted, making the process irreversible and the device will only boot signed images from that point forward.
Here are the general steps you might follow in a production setting:
Initial Flashing with Easy Installer: Use the Toradex Easy Installer to flash the initial TorizonCore image onto the device. This step can be automated using the Easy Installer’s auto-install feature.
Custom Script for Fuse Burning: After the initial flashing, employ a custom script that runs automatically. This script should invoke the necessary commands to burn the fuses. Depending on your specific hardware (e.g., Colibri, Apalis, or Verdin modules), the commands might slightly differ. Typically, this involves using the fuse command in U-Boot or a similar mechanism in Linux.
Verification: After burning the fuses, it’s crucial to verify that the process was successful and that the device boots securely with the signed image. This verification step should be part of your script.
Final Configuration and Testing: Once the fuses are verified to be correctly burned, proceed with any final device configuration and conduct thorough testing to ensure that the device operates as expected in its secure boot state.
It’s essential to thoroughly test this process on a few devices before rolling it out in a full production environment to ensure that there are no unforeseen issues that could affect device functionality.
Remember, the specifics of the commands and procedures might vary based on the exact Toradex module and the version of TorizonCore you are using. It’s also crucial to have a robust error handling mechanism in your script to manage any exceptions or failures during the fuse burning process.
Best regards,
Toradex AI Assistant
Please, also check if these links can help you solve your problem:
The wrapup.sh script runs in the Toradex Easy Installer environment. Since the Easy Installer doesn’t support burning eFuses, you can’t burn fuses from the wrapup.sh script.
Instead, you can use the macro or script support of a terminal program (like TeraTerm or another of your choice) connected to the board’s debug UART. Here is a possible procedure using a TeraTerm macro:
Modify wrapup.sh:
Add a reboot command preceded by an echo command to the debug UART with a distinct string like “Secure image flashed”.
Create a TeraTerm Macro:
Use the waitln command to wait for the specific string from wrapup.sh.
Use the waitln command again to wait for the U-Boot prompt.
Use the sendln command to send a “space” character to stop booting at U-Boot.
Use sendln commands to send the required U-Boot commands to burn the fuses.
Use the beep command to indicate the end of the fuse burning process.
You can add various waitln commands after each fuse prog command in your TeraTerm macro to check if the fusing was done successfully
At least for iMX7/6ULL one can fuse from wrapup.sh. The problem is OCOTP drivers in Tezi1.8 and newer Tezi’s is different. In Tezi 1.8 one would access fuses like /sys/fsl_otp/HW_OCOTP_SRK0, and with newer ones prepare binary fuse data file and dd it to /sys/bus/nvmem/devices/imx-ocotp0/nvmem .
We would prefer a solution that doesn’t need external hardware as we have multiple flashing setups, so this sounds very interesting. Will look into it, thanks.
Edit: we are working with iMX7’s
While testing the script I found out that the version of dd running in the easy installer image doesn’t support conv=notrunc as argument to disable truncation. Do you know a way to get around this? Read in the whole file, modify it, and write it maybe?
notrunc is not required. Even if you tell OCOTP driver do delete all fuses and make fuses file 0 bytes long, it won’t make any effect.
The most important is to think about possibility of power loss / sudden reset in the middle of process. Since lock bit comes prior to SRK bits, you need to fuse SRK first, then disable write access to SRK (there’s dedicated fuse bit), and finally fuse lock bit. Doing it in this order won’t render your SOM dead if power/reset appears in any stage. Disabling write access is necessary to prevent brick of SOM by later writing more 1 bits to SRK locations.
I’m sharing my own wrapup.sh, which supports Tezi1.8 and newer Tezi versions, only iMX7. As is, lack of comments, please dry run, verify what you get in the log file, try running with commented out lock step, and only then try fusing all bits with dryrun=0. You need to edit your srk values, please don’t forget required 0x prefixes. dryrun=0 to fuse, dryrun=1 to skip fuse write. dolog=1 to log some values to logdev device.