Signing boot images for Android Verified Boot (AVB) [v8]

Search This thread

Chainfire

Moderator Emeritus / Senior Recognized Developer
Oct 2, 2007
11,452
87,862
www.chainfire.eu
Various Android devices support Android Verified Boot (AVB). A part of this is more commonly known as dm-verity, which verifies system (and vendor) partition integrity. AVB can however also verify boot images, and stock firmwares generally include signed boot images. Of course this does not mean that all signed boot images are using AVB, many OEMs have their own signature verification scheme.

Note: AOSP is moving towards the use of avbtool (taken from Brillo), the following is the old way for signing boot images.

Bootloaders might or might not accept unsigned boot images, and might or might not accept boot images signed with our own keys (rather than the OEM's keys). This depends on the device, bootloader version, and bootloader unlock state.

For example, with the bootloader unlocked, the Google Pixel (and XL) devices accepted unsigned boot images up to (but not including) the May 2017 release. From the May 2017 release onwards, the boot images must be signed if flashed (booted works without), but may be signed with your own key rather than the OEM's.

Note: The situation changes when you re-lock the bootloader. I have not tested this, but documentation implies that (one of) the keys used in the current boot image must be used for future flashes until it is unlocked again.

Generating custom signing keys

The following openssl commands generate all the keys we need. Execute them line-by-line rather than copying the whole block, as you will be asked for input.

Code:
# private key
openssl genrsa -f4 -out verifiedboot.pem 2048
openssl pkcs8 -in verifiedboot.pem -topk8 -outform DER -out verifiedboot.pk8 -nocrypt

# public key
openssl req -new -x509 -sha256 -key verifiedboot.pem -out verifiedboot.x509.pem
openssl x509 -outform DER -in verifiedboot.x509.pem -out verifiedboot.x509.der

For future signings, you do not need the .pem files, and they can safely be deleted once the .pk8 and .der files are generated. In AOSP's implementation, they were never even written to disk in the first place.

Security-wise, documentation states it is advisable to use a different set of keys for each device you support; though obviously this doesn't matter much if the device is running with the bootloader in unlocked state.

Signing the boot image

Download the attached BootSignature.jar file (built from AOSP sources), and sign the boot image using the keys generated above with the following commands:

Code:
java -jar BootSignature.jar /boot boot.img verifiedboot.pk8 verifiedboot.x509.der boot_signed.img
java -jar BootSignature.jar -verify boot_signed.img

Instead of /boot, /recovery and other values may be used. Their use should be obvious.

From Android

Attached is also BootSignature_Android.jar, which is a version ProGuard-reduced against SDK 21 and then dexed. Provided /system is mounted as is usual on Android (on the Pixel (XL), TWRP mounts this differently by default!), it can be used like this:

Code:
dalvikvm -cp BootSignature_Android.jar com.android.verity.BootSignature /boot boot.img verifiedboot.pk8 verifiedboot.x509.der boot_signed.img
dalvikvm -cp BootSignature_Android.jar com.android.verity.BootSignature -verify boot_signed.img

The base command can be extended as follows to make it able to run without any precompiled files present on the device:

Code:
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core-oj.jar:/system/framework/core-libart.jar:/system/framework/conscrypt.jar:/system/framework/bouncycastle.jar -Xnodex2oat -Xnoimage-dex2oat -cp BootSignature_Android.jar com.android.verity.BootSignature ...

Flashable ZIP

Attached is also VerifiedBootSigner.zip, this is a flashable ZIP for FlashFire/TWRP/etc that signs the currently flashed boot image, if it isn't signed already. You can simply flash this after installing a SuperSU version or custom boot image or whatever that doesn't sign the boot image itself already.

I've tried to make it very portable (borrowing ample script from the SuperSU ZIP, as well as its signing keys), but I have only tested it on my Pixel XL.

Note that it does depend on Android files in the system partition, so if (aside from the unsigned boot image) your system isn't functional, the ZIP may not work either.

If the boot image is already signed when you flash the ZIP, it will offer to abort or force re-sign.

If you place custom.pk8 and custom.x509.der files inside the ZIP, these keys will be used for flashing instead of SuperSU's default keys. Additionally, /tmp/avb/custom.pk8 and /tmp/avb/custom.x509.der will override any keys from the ZIP.

There is some more documentation in the update-binary file inside the ZIP as well.

Note: If you're using TWRP's manual slot selection on the Pixel (XL), you must be using TWRP-v3.1.0-RC2 or newer, or it will not work as expected.

Todo
- test what happens when the bootloader is re-locked on multiple devices supporting AVB
- test what happens when dm-verity is kept enabled on a custom/modified boot image with a different image signature than dm-verity signature
 

Attachments

  • BootSignature.jar
    1.5 MB · Views: 22,838
  • BootSignature_Android.jar
    27.4 KB · Views: 18,153
  • VerifiedBootSigner-v8.zip
    37.8 KB · Views: 54,680
Last edited:

iissmart

Senior Member
Aug 7, 2010
159
228
Great write up! So I take it we can no longer distribute kernel images without first integrating them into the boot image and then signing it? That negates the whole point of being able to flash the kernel individually with fastboot!
 

methuselah

Senior Member
Aug 25, 2011
3,991
2,173
@Chainfire you not going to reply but still, you are responsible i have faith in Android... Development is most of the times happens because of you ....It always revolves around you ... One man army i would say. Thank you for all your works. We all owe you a lot... :cowboy:
 

cr2

Senior Member
Jan 15, 2005
1,671
59
Is it possible to create the signature for boot bundle with openssl alone (i.e. without this BootSignature.jar ) ?
 

Chainfire

Moderator Emeritus / Senior Recognized Developer
Oct 2, 2007
11,452
87,862
www.chainfire.eu
Is it possible to create the signature for boot bundle with openssl alone (i.e. without this BootSignature.jar ) ?

Not just with openssl, no. How the boot signature works is not properly documented, but of course you could read the source in AOSP and make your own version.

Wasn't self-signing boot images already kind of possible?

Apart from both of these things talking about signatures, they are unrelated. However, self-signing images has been supported for quite a while on several devices, it just wasn't required. CopperheadOS - as far as I know - is the only project that has actively been using it until now.
 

gubacsek

Senior Member
Jun 18, 2010
262
310
is it possible to sign the boot image in recovery?

Hi @Chainfire ! Thank you for this great find (and for everything else what you have done for us during the last years :D )!!
I would like to ask one question... Do you think it would be possible to sign the boot image on the fly in recovery? For example when changing the recovery image, before flashing the boot image back?
Your instructions use "dalvikvm" on android, and I ran the command successfully under a running android system. But what about recovery ?
I would be interested in your thoughts on this :D
Or am I completely wrong, and images "dumped" via dd can't be signed and flashed back?

I would really appreciate if you could point me in the right direction, how it could be possible to do this. (create an executable instead of the BootSignature.jar file? leave this, because it is not possible? start a java vm under recovery? ....)


Thanks in advance!
 

Chainfire

Moderator Emeritus / Senior Recognized Developer
Oct 2, 2007
11,452
87,862
www.chainfire.eu
Hi @Chainfire ! Thank you for this great find (and for everything else what you have done for us during the last years :D )!!
I would like to ask one question... Do you think it would be possible to sign the boot image on the fly in recovery? For example when changing the recovery image, before flashing the boot image back?
Your instructions use "dalvikvm" on android, and I ran the command successfully under a running android system. But what about recovery ?
I would be interested in your thoughts on this :D
Or am I completely wrong, and images "dumped" via dd can't be signed and flashed back?

I would really appreciate if you could point me in the right direction, how it could be possible to do this. (create an executable instead of the BootSignature.jar file? leave this, because it is not possible? start a java vm under recovery? ....)


Thanks in advance!

Yes, this is possible - I have already tested this on my PIxel XL. SuperSU ZIP will do exactly this in a future update, and @Dees_Troy is also aware of all of this, so I assume TWRP will be updated to do this sooner or later as well.

If I can find the time I'll make a ZIP that does this.
 

gubacsek

Senior Member
Jun 18, 2010
262
310
Yes, this is possible - I have already tested this on my PIxel XL. SuperSU ZIP will do exactly this in a future update, and @Dees_Troy is also aware of all of this, so I assume TWRP will be updated to do this sooner or later as well.

If I can find the time I'll make a ZIP that does this.

Okay! I am very curious about how you solve it... Until then, I'll experiment a bit further :D


Can't wait to see your result!

Thanks! And have a very nice weekend!
 

gubacsek

Senior Member
Jun 18, 2010
262
310
I have attached a flashable ZIP to the opening post. Just flash it after SuperSU / custom boot image / whatever to fix the current boot image.

I almost got it :D I could install TWRP and root but only by signing the boot images on my laptop...
I had a few errors (mounting /system did create a /system/system mount point, and I tried to copy the dalvikvm binary to the zip :p), and I wouldn't ever have thought of clearing LD_LIBRARY_PATH :D

Thank you very much for this solution, and your time spent on this! I learnt a lot today :D
Nice job!
 

ashyx

Inactive Recognized Contributor
Oct 14, 2012
15,055
9,944
Various Android devices support Android Verified Boot (AVB). A part of this is more commonly known as dm-verity, which verifies system (and vendor) partition integrity. AVB can however also verify boot images, and stock firmwares generally include signed boot images. Of course this does not mean that all signed boot images are using AVB, many OEMs have their own signature verification scheme.

Note: AOSP is moving towards the use of avbtool (taken from Brillo), the following is the old way for signing boot images.

Bootloaders might or might not accept unsigned boot images, and might or might not accept boot images signed with our own keys (rather than the OEM's keys). This depends on the device, bootloader version, and bootloader unlock state.

For example, with the bootloader unlocked, the Google Pixel (and XL) devices accepted unsigned boot images up to (but not including) the May 2017 release. From the May 2017 release onwards, the boot images must be signed if flashed (booted works without), but may be signed with your own key rather than the OEM's.

Note: The situation changes when you re-lock the bootloader. I have not tested this, but documentation implies that (one of) the keys used in the current boot image must be used for future flashes until it is unlocked again.

Generating custom signing keys

The following openssl commands generate all the keys we need. Execute them line-by-line rather than copying the whole block, as you will be asked for input.



For future signings, you do not need the .pem files, and they can safely be deleted once the .pk8 and .der files are generated. In AOSP's implementation, they were never even written to disk in the first place.

Security-wise, documentation states it is advisable to use a different set of keys for each device you support; though obviously this doesn't matter much if the device is running with the bootloader in unlocked state.

Signing the boot image

Download the attached BootSignature.jar file (built from AOSP sources), and sign the boot image using the keys generated above with the following commands:



Instead of /boot, /recovery and other values may be used. Their use should be obvious.

From Android

Attached is also BootSignature_Android.jar, which is a version ProGuard-reduced against SDK 21 and then dexed. Provided /system is mounted as is usual on Android (on the Pixel (XL), TWRP mounts this differently by default!), it can be used like this:



Flashable ZIP

Attached is also VerifiedBootSigner.zip, this is a flashable ZIP for FlashFire/TWRP/etc that signs the currently flashed boot image, if it isn't signed already. You can simply flash this after installing a SuperSU version or custom boot image or whatever that doesn't sign the boot image itself already.

I've tried to make it very portable (borrowing ample script from the SuperSU ZIP, as well as its signing keys), but I have only tested it on my Pixel XL.

Note that it does depend on Android files in the system partition, so if (aside from the unsigned boot image) your system isn't functional, the ZIP may not work either.

Todo
- test what happens when the bootloader is re-locked on multiple devices supporting AVB
- test what happens when dm-verity is kept enabled on a custom/modified boot image with a different image signature than dm-verity signature
So are Samsungs latest devices now using this. Reason I ask is because in the S8 and Tab S3 stock firmware there is a META-DATA folder in the AP firmware tar. Inside is a fota.zip containing various folders with all sorts of utilities and files, one of which is BootSignature.jar.
It seems it is required to flash the META-DATA folder with the boot.img in ODIN or it will not boot. So I'm guessing the boot.img is being signed as part of the flashing process?
 
Last edited:
  • Like
Reactions: adfree

Chainfire

Moderator Emeritus / Senior Recognized Developer
Oct 2, 2007
11,452
87,862
www.chainfire.eu
So are Samsungs latest devices now using this. Reason I ask is because in the S8 and Tab S3 stock firmware there is a META-DATA folder in the AP firmware tar. Inside is a fota.zip containing various folders with all sorts of utilities and files, one of which is BootSignature.jar.
It seems it is required to flash the META-DATA folder with the boot.img in ODIN or it will not boot. So I'm guessing the boot.img is being signed as part of the flashing process?

Possibly. Which S8 are you talking about? I thought there was already working TWRP for S8 Exynos that didn't require anything special?
 
  • Like
Reactions: adfree

ashyx

Inactive Recognized Contributor
Oct 14, 2012
15,055
9,944
Last edited:

Top Liked Posts

  • There are no posts matching your filters.
  • 244
    Various Android devices support Android Verified Boot (AVB). A part of this is more commonly known as dm-verity, which verifies system (and vendor) partition integrity. AVB can however also verify boot images, and stock firmwares generally include signed boot images. Of course this does not mean that all signed boot images are using AVB, many OEMs have their own signature verification scheme.

    Note: AOSP is moving towards the use of avbtool (taken from Brillo), the following is the old way for signing boot images.

    Bootloaders might or might not accept unsigned boot images, and might or might not accept boot images signed with our own keys (rather than the OEM's keys). This depends on the device, bootloader version, and bootloader unlock state.

    For example, with the bootloader unlocked, the Google Pixel (and XL) devices accepted unsigned boot images up to (but not including) the May 2017 release. From the May 2017 release onwards, the boot images must be signed if flashed (booted works without), but may be signed with your own key rather than the OEM's.

    Note: The situation changes when you re-lock the bootloader. I have not tested this, but documentation implies that (one of) the keys used in the current boot image must be used for future flashes until it is unlocked again.

    Generating custom signing keys

    The following openssl commands generate all the keys we need. Execute them line-by-line rather than copying the whole block, as you will be asked for input.

    Code:
    # private key
    openssl genrsa -f4 -out verifiedboot.pem 2048
    openssl pkcs8 -in verifiedboot.pem -topk8 -outform DER -out verifiedboot.pk8 -nocrypt
    
    # public key
    openssl req -new -x509 -sha256 -key verifiedboot.pem -out verifiedboot.x509.pem
    openssl x509 -outform DER -in verifiedboot.x509.pem -out verifiedboot.x509.der

    For future signings, you do not need the .pem files, and they can safely be deleted once the .pk8 and .der files are generated. In AOSP's implementation, they were never even written to disk in the first place.

    Security-wise, documentation states it is advisable to use a different set of keys for each device you support; though obviously this doesn't matter much if the device is running with the bootloader in unlocked state.

    Signing the boot image

    Download the attached BootSignature.jar file (built from AOSP sources), and sign the boot image using the keys generated above with the following commands:

    Code:
    java -jar BootSignature.jar /boot boot.img verifiedboot.pk8 verifiedboot.x509.der boot_signed.img
    java -jar BootSignature.jar -verify boot_signed.img

    Instead of /boot, /recovery and other values may be used. Their use should be obvious.

    From Android

    Attached is also BootSignature_Android.jar, which is a version ProGuard-reduced against SDK 21 and then dexed. Provided /system is mounted as is usual on Android (on the Pixel (XL), TWRP mounts this differently by default!), it can be used like this:

    Code:
    dalvikvm -cp BootSignature_Android.jar com.android.verity.BootSignature /boot boot.img verifiedboot.pk8 verifiedboot.x509.der boot_signed.img
    dalvikvm -cp BootSignature_Android.jar com.android.verity.BootSignature -verify boot_signed.img

    The base command can be extended as follows to make it able to run without any precompiled files present on the device:

    Code:
    /system/bin/dalvikvm -Xbootclasspath:/system/framework/core-oj.jar:/system/framework/core-libart.jar:/system/framework/conscrypt.jar:/system/framework/bouncycastle.jar -Xnodex2oat -Xnoimage-dex2oat -cp BootSignature_Android.jar com.android.verity.BootSignature ...

    Flashable ZIP

    Attached is also VerifiedBootSigner.zip, this is a flashable ZIP for FlashFire/TWRP/etc that signs the currently flashed boot image, if it isn't signed already. You can simply flash this after installing a SuperSU version or custom boot image or whatever that doesn't sign the boot image itself already.

    I've tried to make it very portable (borrowing ample script from the SuperSU ZIP, as well as its signing keys), but I have only tested it on my Pixel XL.

    Note that it does depend on Android files in the system partition, so if (aside from the unsigned boot image) your system isn't functional, the ZIP may not work either.

    If the boot image is already signed when you flash the ZIP, it will offer to abort or force re-sign.

    If you place custom.pk8 and custom.x509.der files inside the ZIP, these keys will be used for flashing instead of SuperSU's default keys. Additionally, /tmp/avb/custom.pk8 and /tmp/avb/custom.x509.der will override any keys from the ZIP.

    There is some more documentation in the update-binary file inside the ZIP as well.

    Note: If you're using TWRP's manual slot selection on the Pixel (XL), you must be using TWRP-v3.1.0-RC2 or newer, or it will not work as expected.

    Todo
    - test what happens when the bootloader is re-locked on multiple devices supporting AVB
    - test what happens when dm-verity is kept enabled on a custom/modified boot image with a different image signature than dm-verity signature
    31
    I have attached a flashable ZIP to the opening post. Just flash it after SuperSU / custom boot image / whatever to fix the current boot image.

    Okay! I am very curious about how you solve it... Until then, I'll experiment a bit further :D Can't wait to see your result!
    28
    VerifiedBootSigner-v5

    This update partially addresses the situation when flashing custom firmwares and/or to a different slot than was booted from. The Java part of this package requires dalvikvm and (minor parts of) the Android framework, which are not included, but are inside your loaded firmware.

    See the opening post of this thread for the download.

    Different slots
    This section applies only to devices with an A/B partition layout, like the Pixel and Pixel XL.

    If you select a different slot to - for example - flash TWRP to, and you run the script, there's the problem that the system partition in the current slot may not hold the requires files. This version of the script will try the other partition as well, to see if it can load the required files from there.

    Unfortunately you will need TWRP 3.1.0-RC2 or newer for the script to properly detect which slot has been selected inside TWRP's UI. If you're using RC1, you should not use this script (or any older version) in combination with TWRP's slot selection unless you boot into the selected slot first. Fastboot's slot selection command is fine.

    Firmware requirements
    This section applies to all devices
    Thanks to an idea from @osm0sis, the chicken/egg problem has been solved and is no longer relevant for v6 onwards

    There's a chicken and egg problem when using this ZIP on a freshly flashed custom firmware: it depends on boot.art/boot.oat to exist. This is not a problem with stock firmwares, because they include precompiled versions of these in the system image (in /system/framework/<arch>). Some custom firmwares do not include these precompiled versions. This poses no problem for the firmware itself, as these files are created at first boot if they are missing. This can create a circular dependency: the signing ZIP needs the firmware to have booted once because it needs those files, but the unsigned boot image will not boot.

    On some devices (like the Pixel) this can be remedied by looking for the stock /system partition in the other slot, but that is only a workaround. It would be best if custom firmwares just started to include these files.


    @mac796
    19
    Hi @Chainfire ! Thank you for this great find (and for everything else what you have done for us during the last years :D )!!
    I would like to ask one question... Do you think it would be possible to sign the boot image on the fly in recovery? For example when changing the recovery image, before flashing the boot image back?
    Your instructions use "dalvikvm" on android, and I ran the command successfully under a running android system. But what about recovery ?
    I would be interested in your thoughts on this :D
    Or am I completely wrong, and images "dumped" via dd can't be signed and flashed back?

    I would really appreciate if you could point me in the right direction, how it could be possible to do this. (create an executable instead of the BootSignature.jar file? leave this, because it is not possible? start a java vm under recovery? ....)


    Thanks in advance!

    Yes, this is possible - I have already tested this on my PIxel XL. SuperSU ZIP will do exactly this in a future update, and @Dees_Troy is also aware of all of this, so I assume TWRP will be updated to do this sooner or later as well.

    If I can find the time I'll make a ZIP that does this.
    19
    Please note that SuperSU v2.82 SR1 onwards include automatic AVB signing of the modified boot image if the input image is also AVB signed.

    In other words, if you first flash an unsigned image and then flash SuperSU over it, it will not sign it, but if you flash SuperSU over the stock signed boot image, it will.