After weeks of work, I finally was able to boot my iMX233 ARM processor from a fully encrypted linux partition… and most importantly, I was able to use the hardware-stored encryption key for this purpose. What a pleasure!
iMX233 features a hardware engine (known as DCP) which can perform 128-bit AES encryption using either a software-provided or the hardware-stored key. The latter key is burnt into the CPU’s OTP ROM and can be made totally hidden from software. This adds extra security: cryptography without any chance of revealling the encryption key.
To me, an ultimate disk encryption method for protecting an embedded application is one whose boot procedure does not include any non-encrypted stage. Otherwise, a malicious user can use her own modified version of that non-encrypted stage in order to boot her own code and try to break the encryption key by generating lot of plain/cipher patterns. The first boot stage of iMX233 (booting kernel from first SD partition) can be encrypted using the same OTP key (see elftosb -k parameter). Then the next stage of booting an encrypted Linux from the second partition was what I was looking for.
I had several obstacles to overcome:
- First of all, I had to write my own version of kernel crypto module that can use the OTP hard-key instead of always expecting a soft-key to be provided [see this quesion].
- Second, the original dm-crypt essiv IV method was not possible without modification in my case. Why? because it relies on the explicit value of the key for IV generation, and as I said, the key value is burried into hardware fuses and unknown to software.
- Finally, I needed to add my custom initramfs into my compiled Freescale’s kernel. It is responsible to cryptsetup, mount the encrypted root partition, and switch_root to it.