page.title=Verifying Boot @jd:body
Verified boot guarantees the integrity of the device software starting from a hardware root of trust up to the system partition. During boot, each stage verifies the integrity and authenticity of the next stage before executing it.
This capability can be used to warn users of unexpected changes to the software when they acquire a used device, for example. It will also provide an additional signal of device integrity for remote attestation, and together with encryption and Trusted Execution Environment (TEE) root of trust binding, adds another layer of protection for user data against malicious system software.
Note that if verification fails at any stage, the user must be visibly notified and always be given an option to continue using the device at their own discretion.
Table 1. Glossary of terms related to verified boot
|
Term |
Definition |
|
Boot state |
The boot state of the device describes the level of protection provided to the end user if the device boots. Boot states are GREEN, YELLOW, ORANGE, and RED. |
|
Device state |
The device state indicates how freely software can be flashed to the device. Device states are LOCKED and UNLOCKED. |
|
dm-verity |
Linux kernel driver for verifying the integrity of a partition at runtime using a hash tree and signed metadata. |
|
Keystore |
A keystore is a signed collection of public keys. |
|
OEM key |
The OEM key is a fixed, tamper-protected key available to the bootloader that must be used to verify the boot image. |
In addition to device state - which already exists in devices and controls whether the bootloader allows new software to be flashed - we introduce the concept of boot state that indicates the state of device integrity.
We define two implementation classes for verified boot depending on how fully the device implements this specification, as follows:
Class A implements verified boot with full chain of trust up to verified partitions. This implementation must support the LOCKED device state, and GREEN and RED boot states.
Class B implements Class A and additionally supports the UNLOCKED device state and the ORANGE boot state.
Bootloader integrity must be verified using a hardware root of trust. For verifying boot and recovery partitions, the bootloader must have a fixed OEM key available to it. It must always attempt to verify the boot partition using the OEM key first and try other possible keys only if this verification fails.
In Class B implementations, it must be possible for the user to flash software signed with other keys when the device is UNLOCKED. If the device is then LOCKED and verification using the OEM key fails, the bootloader must try verification using the certificate embedded in the partition signature. However, using a partition signed with anything other than the OEM key must result in a notification or a warning, as described below.
A verified device will ultimately boot into one of four states during each boot attempt:
The recovery partition must also be verified in the exact same way.
The device is required to be in one of two states at all times:
Figure 1. Verified boot flow
Achieving full chain of trust requires support from both the bootloader and the software on the boot partition, which is responsible for mounting further partitions. Verification metadata must also be appended to the system partition and any additional partitions whose integrity should be verified.
The bootloader is the guardian of the device state and is responsible for initializing the TEE and binding its root of trust.
Most importantly, the bootloader must verify the integrity of the boot and/or recovery partition before moving execution to the kernel and display the warnings specified in the section Boot state.
State changes are performed using the fastboot flashing [unlock |
lock] command. And to protect user data, all
state transitions require a data wipe. Note the user must be asked for
confirmation before data is deleted.
Requirements for fastboot commands that alter device state are listed in the table below:
Table 2. fastboot commands
|
|
Requirements |
flashing lock |
|
flashing unlock |
|
When altering partition contents, the bootloader must check the bits set by the above commands as described in the following table:
Table 3. fastboot command requirements
|
|
Requirements |
flash <partition> |
If the bit set by
|
The same checks should be performed for any fastboot command
that can be used to change the contents of partitions.
Note: Class B implementations must support changing device state.
If TEE is available, the bootloader should pass the following information to the TEE to bind the Keymaster root of trust, after partition verification and TEE initialization:
This changes the keys derived by the TEE. Taking disk encryption as an example, this prevents user data from being decrypted when the device state changes.
Note: This means if the system software or the device state changes, encrypted user data will no longer be accessible as the TEE will attempt to use a different key to decrypt the data.
The recovery partition should be verified in exactly the same manner as the boot partition.
System software needs to be able to determine the verification status of
previous stages. The bootloader must specify the current boot state as a
parameter on the kernel command line (or through the device tree under
firmware/android/verifiedbootstate) as described in the table
below:
Table 4. Kernel command line parameters
| Kernel command line parameter | Description |
|---|---|
androidboot.verifiedbootstate=green |
Device has booted into GREEN boot state. Boot partition has been verified using the OEM key and it’s valid. |
androidboot.verifiedbootstate=yellow |
Device has booted into YELLOW boot state. Boot partition has been verified using the certificate embedded into the signature and it’s valid. |
androidboot.verifiedbootstate=orange |
Device has booted into ORANGE boot state. The device is unlocked and no verification has been performed. |
androidboot.verifiedbootstate=red |
Device has booted into RED boot state. The device has failed verification. |
Once execution has moved to the boot partition, the software there is responsible for setting up verification of further partitions. Due to its large size, the system partition typically cannot be verified similarly to previous parts but must be verified as it’s being accessed instead using the dm-verity kernel driver or a similar solution.
If dm-verity is used to verify large partitions, the signature of the verity metadata appended to each verified partition must be verified before the partition is mounted and dm-verity is set up for it.
By default, dm-verity operates in enforcing mode and verifies each block read from the partition against a hash tree passed to it during setup. If it comes across a block that fails to verify, it returns an I/O error and makes the block with unexpected contents inaccessible to user space. Depending on which block is corrupted, this may cause some of the programs that reside on the partition to malfunction.
If dm-verity is always enforcing against correctly signed metadata, nothing more needs be done. However, using an optional verity table parameter, dm-verity can be configured to function in a logging mode where it detects and logs errors but allows I/O to be completed despite them. If dm-verity is not started in enforcing mode for any reason, or verity metadata cannot be verified, a warning must be displayed to the user if the device is allowed to boot, similar to the one shown before booting into the RED state.
Figure 2. dm-verity management
Since the system partition is by far larger than the boot partition, the probability of verification errors is also higher. Specifically, there is a larger probability of unintentional disk corruption, which will cause a verification failure and can potentially make an otherwise functional device unusable if a critical block in the partition can no longer be accessed.
If dm-verity is always in enforcing mode, nothing further needs to be done. If logging mode is implemented and dm-verity detects an error while in enforcing mode, the device must be rebooted and dm-verity must be started in logging mode during all subsequent restarts until any of the verified partitions is reflashed or changed by an OTA update. This means dm-verity state should be stored in a persistent flag. When a verified partition has been changed, the flag must be cleared and dm-verity must again be started in enforcing mode. Anytime dm-verity is not started in enforcing mode, a warning must be shown to the user before any of the verified partitions are mounted. No unverified data must be allowed to leak to user space without the user being warned.
In a verified device, the system partition must always be verified. But any other read-only partition should also be set to be verified, as well. Any read-only partition that contains executable code must be verified on a verified device. This includes vendor and OEM partitions, if they exist, for example.
In order for a partition to be verified, signed verity metadata must be appended to it. The metadata consists of a hash tree of the partition contents and a verity table containing signed parameters and the root of the hash tree. If this information is missing or invalid when dm-verity is set up for the partition, the user must be warned.
The OEM key is recommended to be an RSA key with a modulus of 2048 bits or higher and a public exponent of 65537 (F4). The OEM key is required to be of equivalent or greater strength than such a key.
The signature on an Android verifiable boot image is an ASN.1 DER-encoded
message, which can be parsed with a decoder similar to the one found at: platform/bootable/recovery/asn1_decoder.cpp
The message format itself is as follows:
AndroidVerifiedBootSignature DEFINITIONS ::=
BEGIN
FormatVersion ::= INTEGER
Certificate ::= Certificate OPTIONAL
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL
}
AuthenticatedAttributes ::= SEQUENCE {
target CHARACTER STRING,
length INTEGER
}
Signature ::= OCTET STRING
END
The Certificate field is the full X.509 certificate containing
the public key used for signing, as defined by RFC5280 section
4.1. When LOCKED, the bootloader must always use the OEM key for verification
first, and only boot to YELLOW or RED states if the embedded certificate is
used for verification instead.
The remaining structure is similar to that defined by RFC5280 sections
4.1.1.2 and 4.1.1.3 with the exception of the
AuthenticatedAttributes field. This field contains the length of
the image to be verified as an integer and the partition where the image can
be found (boot, recovery, etc.).
To produce a signed image:
AuthenticatedAttributes section
above based on the padded image and desired target partition.
AuthenticatedAttributes structure above to the image.
To verify the image:
AuthenticatedAttributes field.
If these values do not validate, treat it as a signature validation error.
AuthenticatedAttributes sections.
A user in the GREEN boot state should see no additional user interaction besides that required by normal device boot. In other boot states, the user must see a warning for at least five seconds. Should the user interact with the device during this time, the warning must remain visible at least 30 seconds longer, or until the user dismisses the warning.
Sample user interaction screens for other states are shown in the following table:
Table 5. Sample user interaction screens
|
Device state |
Sample UX |
|
|
YELLOW (before and after user interaction) |
Figure 3. Yellow state example 1 UI |
Figure 4. Yellow state example 2 UI |
|
ORANGE |
Figure 5. Orange state example UI |
|
|
RED |
Figure 6. Red state example UI |