agherzan / meta-raspberrypi

Yocto/OE BSP layer for the Raspberry Pi boards
https://www.yoctoproject.org/
MIT License
539 stars 415 forks source link

Generate boot.img and boot.sign using yocto project for secure boot #1071

Open Vishwasrao1 opened 2 years ago

Vishwasrao1 commented 2 years ago

As of now , I was manually making boot.img, signing it using usbboot(https://github.com/raspberrypi/usbboot) tool for my custom yocto based image.

I would like to incorporate above step in yocto toolchain. So that I will get final signed image from yocto itself. The hardware is rpi CM4. Once I have achieved this I would like to enhance this and generate complete chain of trust including rootfs with help of yocto project.

I was not sure how to start with this, I was wondering if someone from the community has already given it a try or know how to proceed with this. If anyone can guide me or would like to contribute that will be really helpful.

Additional information:

My current steps are.

  1. Generate custom linux image using yocto.
  2. Flash the image to compute module 4 using usbboot/rpiboot.
  3. Check content of the boot partition. copy the content to a folder secure boot files.
  4. Generate a boot image using make-boot-image in usbboot.
  5. Sign the boot image using rpi-eeprom-digest of usbboot.
  6. copy paste the boot.img and boot.sign in boot partition of cm4
  7. Now the cm4 boots in secure boot mode using the boot.img and boot.sign

What I want to achieve:

  1. Generate boot.img and boot.sign in yocto itself so that I don't have to do steps 2,3,4,5,6.
  2. The yocto project will generate boot.img , sign the image and place it in boot partition of my linux OS.

Let me know if you have any idea or if you have already achieved this.

agherzan commented 2 years ago

This looks like something useful to have in. We would need to have a way to generate the images that create a signed fat fs image. It shouldn't be that complicated, to be honest. We would need to move things from the boot partition to a filesystem image file with the ability to expose the key for signing. Obviously, the integration of the RPI sign tools will also be needed. This sounds like a variable which would enable the above. How does that sound to you?

kraj commented 2 years ago

I think wic template might be able to get this done from putting together image point.

agherzan commented 2 years ago

@kraj It sounds a bit too custom for the wic to be able to do. It would need to convert part of the boot partition into a boot fat image, sign and inject it into the boot partition (if I understand the RPI interface right).

Vishwasrao1 commented 2 years ago

Thank You @kraj for your comment. @agherzan Yes, you understood it correctly and that's what I am currently working on.

Right now I am trying to achieve it using post-build script in yocto. People have already used postbuild.sh in buildroot to achieve the same. (https://github.com/raspberrypi/usbboot/issues/147) So my goal is:

  1. copy content of boot partition to specific path.
  2. Use this content to generate the boot.img utilising usbboot make-boot-image.
  3. Sign this image using usbboot rpi-eeprom-digest.
  4. In the end copy this newly generated boot.img and boot.sign into original boot partition
  5. Make the image using this updated boot partition.

I will use the same key (used in point 3) to sign the EEPROM OTP Fuses. Doing this we can achieve a secure root of trust with signed boot and kernel image. I am yet to figure out about signing the rootFS and adding it to the chain of trust. This is something I will do next.

So any inputs regarding post build script or if you know any alternative in yocto that will be also helpful.

kraj commented 2 years ago

my suggestion is to bundle the final artifacts using wic process. Having custom SD card generation scripts or process should be avoided for best results.

Vishwasrao1 commented 2 years ago

@kraj This means add a recipe > to generate the signed artifacts and bundle them into an image. This can be an approach I will give it a try.

agherzan commented 2 years ago

@kraj of course. I didn't propose external tooling to wic.

The way I see it right now is the following. When SIGN = 1 (variable name to be defined):

  1. Filter out assets that are meant to be deployed as a signed fat image from IMAGE_BOOT_FILES.
  2. Have wic depend on a recipe:do_deploy (which depends on the recipes providing/deploying all the assets needed in the signed image). This new recipe will generate the signed image by taking the input from the deploy directory and generating the signed image based on a key defined in another variable.
  3. Add the signed file in IMAGE_BOOT_FILES.
agherzan commented 2 years ago

As a side note, 1 above can be optional but I don't see why not do this clean and avoid duplication (that has an impact on handling updates for example).