Project context: Why integrate secure boot and dm-verity?
At The Embedded Kit we have been working on Welma, a pre-configured Yocto for OEMs for the last few years. Welma aims to:
- Simplify Yocto for teams without deep Linux expertise.
- Provide pre-integrated security features.
- Enable long-term maintenance and updates.
In this context, we decided to implement secure boot and extend its guarantees beyond the kernel to the entire software stack with dm verity. Our goal was clear: deliver a chain of trust from power-on to application execution.
Secure Boot: Building secure foundation
We started by leveraging the hardware root of trust available on modern MPUs. This immutable ROM code provided the first link in the chain, authenticating the bootloader at startup.
From there, we implemented:
- Bootloader verification using U-Boot’s FIT image verification.
- Authentication of the kernel and initial RAM filesystem via cryptographic signatures.
This ensured that every component loaded during boot was validated.
However, we quickly realized that stopping at the kernel was not enough. Applications run from filesystems, and if those filesystems were compromised, the entire security model would collapse.
Read our article on how to enable secure boot.
Extending trust beyond the kernel
The next challenge was to protect root and application filesystems.
We needed a mechanism that:
- Guaranteed integrity at runtime, not just at boot.
- Introduced minimal overhead.
- Worked with read-only partitions (our design choice for security).
We could have considered a single digest approach, hashing the entire filesystem and verifying it at boot. But this method only detects tampering before startup and requires periodic re-hashing for runtime protection, which is impractical. So we needed something better.
Why we chose dm-verity?
Here’s why we selected this feature:
- Continuous verification: dm verity checks integrity during runtime, not just at boot.
- Efficient design:
- Kernel-native: No external dependencies; activated via kernel configuration.
The Merkle tree approach was key. Instead of one big hash, dm-verity hashed each block (default: 4 KB), then combined hashes recursively. This allowed quick detection of any modification (even a single bit) by recalculating only the affected branch of the tree.
How to integrate dm verity in Yocto?
Our integration involved several steps:
1. Kernel configuration
We enabled CONFIG_DM_VERITY in the Yocto build.
2. Partition management
We extended our partition description system so customers could enable authenticity flags alongside options like read/write mode or A/B updates.
3. Image generation
During build, we:
- Created the filesystem.
- Generated the Merkle tree.
- Added a custom header containing:
- Magic number for integrity checks.
- Offset of the Merkle tree.
- Root hash.
- Signature of the root hash (critical for authenticity).
This design ensured that every partition could be authenticated dynamically during boot and throughout runtime.
Update workflow: Maintaining integrity over time
Beyond initial image creation, we needed a secure way to handle OTA updates without breaking the chain of trust. Our approach was to embed dm-verity metadata directly into update images.
Here’s what we implemented:
- Signed updates: Each update image included the Merkle tree and its signed root hash, ensuring that new partitions were authenticated before being flashed.
- Automated regeneration: When generating an update, our build system automatically recalculated hashes and signatures for modified partitions.
- Seamless integration: This design allowed us to deliver updates that maintained the same security guarantees as the original image, without requiring complex manual steps or kernel keyring management.
By integrating dm-verity into both initial builds and update workflows, we ensured that integrity checks remained consistent throughout the device lifecycle.
Runtime verification: How it works
At boot, the ramdisk init script:
- Loads partitions and extracts dm-verity headers.
- Verifies the root hash against its signature using public keys.
- Creates a device-mapper target for each protected partition.
- Mounts the filesystem through dm-verity, enabling on-the-fly integrity checks.
If tampering was detected , dm-verity triggers configurable responses (such as reboot or error reporting) ensuring the system never ran compromised code.
Challenges and lessons learned
- Performance trade-offs: dm-verity added negligible overhead for standard boot times, but ultra-fast boots requires careful tuning.
- Metadata management: Designing headers and update workflows was critical to maintain flexibility for OTA updates.
- Key handling: We opted for storing verification keys in the filesystem header rather than the RAM to simplify updates.
Key takeaways
- Secure Boot is essential, but incomplete without filesystem integrity.
- dm-verity offers a kernel-native, efficient solution for runtime verification.
- Integration in Yocto requires careful design of partitioning, metadata, and update workflows.
- Welma brings these capabilities to OEMs as a ready-to-use, secure Linux distribution.




