| page.title=Verifying Boot |
| @jd:body |
| |
| <!-- |
| Copyright 2015 The Android Open Source Project |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| <h2>In this document</h2> |
| <ol id="auto-toc"> |
| </ol> |
| </div> |
| </div> |
| |
| <h2 id=objective>Objective</h2> |
| <p>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.</p> |
| |
| <p>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.</p> |
| |
| <p>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.</p> |
| |
| <h2 id=glossary>Glossary</h2> |
| |
| <table> |
| <tr> |
| <td> |
| <p><strong>Term</strong></p> |
| </td> |
| <td> |
| <p><strong>Definition</strong></p> |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <p>Boot state</p> |
| </td> |
| <td> |
| <p>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.</p> |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <p>Device state</p> |
| </td> |
| <td> |
| <p>The device state indicates how freely software can be flashed to the device. |
| Device states are LOCKED, UNLOCKED, or VERIFIED.</p> |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <p>dm-verity</p> |
| </td> |
| <td> |
| <p>Linux kernel driver for verifying the integrity of a partition at runtime using |
| a hash tree and signed metadata.</p> |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <p>Keystore</p> |
| </td> |
| <td> |
| <p>A keystore is a signed collection of public keys.</p> |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <p>OEM key</p> |
| </td> |
| <td> |
| <p>The OEM key is a fixed, tamper-protected key available to the bootloader that |
| must be used to verify the boot image.</p> |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <p>User provided keystore</p> |
| </td> |
| <td> |
| <p>The user keystore is a keystore flashed to the device via <code>fastboot |
| flash keystore <path></code>.</p> |
| </td> |
| </tr> |
| </table> |
| |
| <h2 id=overview>Overview</h2> |
| |
| <p>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 also |
| add a third device state, which allows developers for example, to flash the |
| software more frequently without a data wipe while still benefiting from |
| verification.</p> |
| |
| <h3 id=verification_keys>Verification keys</h3> |
| |
| <p>Bootloader integrity must be verified using a hardware root of trust. For |
| verifying boot and recovery images, the bootloader must have a fixed OEM key |
| available to it. It must always attempt to verify the boot image using the OEM |
| key and only try other possible keys if this verification fails.</p> |
| |
| <p>It must be possible for the user to flash alternative image verification keys |
| to the device, and the bootloader must try verification using these keys if |
| verification using the OEM key fails. However, using an image signed with the |
| user-provided keystore must result in a notification to be shown, as described |
| below.</p> |
| |
| <h3 id=boot_state>Boot state</h3> |
| |
| <p>A verified device will ultimately boot into one of four states during each boot |
| attempt:</p> |
| |
| <ul> |
| <li> GREEN, indicating a full chain of trust extending from the bootloader to the |
| system partition, including the bootloader, boot partition, and system |
| partition. |
| </ul> |
| |
| <ul> |
| <li> YELLOW, indicating a chain of trust starting from a user-provided keystore |
| and extending up. To enable users to acquire trust in their keystore, |
| bootloaders are required to display a partial hash of the verifying keystore |
| during boot. |
| </ul> |
| |
| <ul> |
| <li> ORANGE, indicating a device may be freely modified. Device integrity is |
| left to the user to verify out-of-band. |
| </ul> |
| |
| <ul> |
| <li> RED, indicating the device has failed verification. This must display a |
| warning to the user before allowing the boot process to continue. |
| </ul> |
| |
| <p>The recovery partition must also be verified and should be verified in the |
| exact same way.</p> |
| |
| <img src="../images/verified_boot.png" alt="Verified boot flow" id="figure1" /> |
| <p class="img-caption"><strong>Figure 1.</strong> Verified boot flow</p> |
| |
| <h3 id=device_state>Device state</h3> |
| |
| <p>The device is required to be in one of three states at all times:</p> |
| |
| <ol> |
| <li>LOCKED, indicating the device cannot currently be flashed. In the image |
| above, a LOCKED device must boot into the GREEN state, YELLOW state, or RED |
| state during any attempted boot. It must not be possible to alter the user |
| keystore in the LOCKED state. |
| |
| <li>VERIFIED, indicating someone in physical control of the device may perform |
| limited actions intended to change the state of the device but may not break |
| its current chain of trust. In the image above, a VERIFIED device must boot |
| into the GREEN state, YELLOW state, or RED state during each attempted boot. It |
| must not be possible to alter the user keystore in the VERIFIED state. It must |
| be possible to: |
| <ol> |
| <li> Flash the following partitions: |
| <ol> |
| <li> bootloader |
| <li> boot partition |
| <li> system partition |
| <li> vendor partition |
| <li> recovery partition |
| </ol> |
| <li> Erase the following partitions: |
| <ol> |
| <li> userdata |
| <li> cache |
| </ol> |
| </ol> |
| |
| <p>Boot and recovery image signatures may be verified during the flashing process, |
| and the bootloader may reject images that do not validate against the OEM key |
| or the user-provided keystore at this point. However, signatures must also be |
| verified again at every boot. |
| |
| <li>UNLOCKED, indicating the device may be flashed freely and is not intended |
| to be verified. |
| </ol> |
| |
| <h2 id=detailed_design>Detailed design</h2> |
| |
| <p>Achieving full chain of trust requires support from both the bootloader and the |
| software on the boot partition, specifically <code>init</code>, which is responsible for |
| mounting additional partitions. Verification metadata must also be appended to the |
| system partition and any additional partitions whose integrity should be |
| verified.</p> |
| |
| <h3 id=bootloader_requirements>Bootloader requirements</h3> |
| |
| <p>The bootloader is the guardian of the device state, manages the user-provided |
| keystore, and is responsible for initializing the TEE and binding its root of |
| trust.</p> |
| |
| <p>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 or notifications in the section <a href="#boot_state">Boot state</a>.</p> |
| |
| <h4 id=changing_device_state><strong>Changing device state</strong></h4> |
| |
| <p>State changes are performed using the <code>fastboot flashing [unlock | |
| verified | lock]</code> command. And to protect user data, <strong>all</strong> |
| state transitions require a data wipe. Note the user must be asked for |
| confirmation before data is deleted.</p> |
| |
| <img src="../images/device_states.png" alt="Changing device states" id="figure2" /> |
| <p class="img-caption"><strong>Figure 2.</strong> Changing device states</p> |
| |
| <ol> |
| <li>The UNLOCKED to LOCKED transition is anticipated when a user buys a used |
| development device. As a result of locking the device, the user should have |
| confidence that it is in a state produced by the OEM. |
| |
| <li>The LOCKED to UNLOCKED transition is expected in the case where a developer |
| wishes to disable verification on the device. |
| |
| <li>The LOCKED to VERIFIED transition is expected in the case where a developer |
| wishes to do development on the device and doesn’t want to wipe data frequently. |
| |
| <li>The VERIFIED to LOCKED transition is idempotent with the above. |
| |
| <li>The UNLOCKED to VERIFIED transition is anticipated when a user wishes to put a |
| development device in a more secure state but may not want to prevent |
| themselves from flashing new system images. |
| |
| <li> The VERIFIED to UNLOCKED transition is idempotent with the above. |
| </ol> |
| |
| <p>Requirements for <code>fastboot</code> commands that alter device state are listed in the table below:</p> |
| <table> |
| <tr> |
| <td> |
| <p><strong><code>fastboot</code> command</strong></p> |
| </td> |
| <td> |
| <p><strong>Requirements</strong></p> |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <code> |
| flashing lock</code></td> |
| <td> |
| <ul> |
| <li>Wipe data after asking the user for confirmation |
| <li>Clear a write-protected bit indicating the device is unlocked |
| <li>Clear a write-protected bit indicating the device is verified |
| </ul> |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <code> |
| flashing unlock</code></td> |
| <td> |
| <ul> |
| <li>Wipe data after asking the user for confirmation |
| <li>Set a write-protected bit indicating the device is unlocked |
| <li>Clear a write-protected bit indicating the device is verified |
| </ul> |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <code> |
| flashing verified</code></td> |
| <td> |
| <ul> |
| <li>Wipe data after asking the user for confirmation |
| <li>Clear a write-protected bit indicating the device is unlocked |
| <li>Set a write-protected bit indicating the device is verified |
| </ul> |
| </td> |
| </tr> |
| </table> |
| |
| <p>When altering partition contents, the bootloader must check the bits set by |
| the above commands as described in the following table:</p> |
| <table> |
| <tr> |
| <td> |
| <p><strong><code>fastboot</code> command</strong></p> |
| </td> |
| <td> |
| <p><strong>Requirements</strong></p> |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <code> |
| flash <partition></code></td> |
| <td> |
| <ul> |
| <li>If the bit set by <code>flashing unlock</code> is set, flash the partition as normal |
| <li>If this bit is not set, check the bit set by <code>flashing verified</code> |
| <ul> |
| <li>If this bit is not set, exit with an error |
| <li>If this bit is set and <partition> is on the list provided in |
| the section <a href="#device_state">Device state</a>, flash the partition as normal. |
| </ul> |
| </ul> |
| </td> |
| </tr> |
| </table> |
| |
| <p>The same checks should be performed for any <code>fastboot</code> command that can be used to change the contents of partitions.</p> |
| |
| <h4 id=managing_user_provided_keystore><strong>Managing user-provided keystore</strong></h4> |
| |
| <p>Users can flash their own verification keys to the device, which must be |
| used to verify the integrity of boot and recovery images if verification |
| against the OEM key fails. This allows a developer to change the system |
| software frequently, for example, while still keeping verified boot enabled.</p> |
| |
| <p>The bootloader is responsible for maintaining the integrity of the user |
| keystore. It must not be possible to change the contents of the keystore unless |
| the device is UNLOCKED. When the user flashes a new keystore to the device, the |
| bootloader must sign it using the TEE and store the signed keystore. Before |
| using keys from the keystore, the bootloader must use the TEE to verify the |
| signature.</p> |
| |
| <p>Requirements for <code>fastboot</code> commands used to manage the user-provided keystore are listed in the table |
| below:</p> |
| <table> |
| <tr> |
| <td> |
| <p><strong><code>fastboot</code> command</strong></p> |
| </td> |
| <td> |
| <p>Requirements</p> |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <code> |
| flash keystore <filename></code></td> |
| <td> |
| <ul> |
| <li>Check the bit set by <code>flashing unlock</code>; if not set, exit with an error |
| <li>Validate the given keystore against the format provided in section <a href="#keystore_format">Keystore format</a> |
| <li>Pass the keystore to the TEE for signing |
| <li>Write the signed keystore to the write-protected user keystore storage |
| area (location to be determined by the OEM) |
| </ul> |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <code> |
| erase keystore</code></td> |
| <td> |
| <ul> |
| <li>Check the bit set by <code>flashing unlock</code>; if not set, exit with an error |
| <li>Erase the keystore stored in the write-protected user keystore storage area |
| </ul> |
| </td> |
| </tr> |
| </table> |
| |
| <h4 id=binding_tee_root_of_trust><strong>Binding TEE root of trust</strong></h4> |
| |
| <p>After the bootloader has initialized the TEE and performed boot image |
| verification steps, it must pass the following information to the TEE Keymaster |
| as the root of trust:</p> |
| |
| <ol> |
| <li>The public key that was used to sign the boot image |
| <li>The current device state (LOCKED, VERIFIED, or UNLOCKED) |
| </ol> |
| |
| <p>This changes the keys derived by the TEE. For disk encryption, for example, |
| this prevents user data from being decrypted when the device is booted using a |
| potentially untrusted image signed with a different key.</p> |
| |
| <p class="note"><strong>Note:</strong> 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.</p> |
| |
| <h4 id=booting_into_recovery><strong>Booting into recovery</strong></h4> |
| |
| <p>The recovery image should be verified in exactly the same manner as the boot |
| image.</p> |
| |
| <h3 id=boot_partition>Boot partition</h3> |
| |
| <p>Once execution has moved to the boot and/or recovery image, <code>init</code> is responsible |
| for setting up verification for further partitions. Due to its large size, the |
| system partition cannot be verified similarly to previous parts but must be |
| verified in real time as it’s being accessed by using the dm-verity kernel |
| driver.</p> |
| |
| <p>When <code>fs_mgr</code> flags in the device’s <code>fstab</code> indicate a partition should be |
| verified, <code>init</code> will verify the signed verity metadata appended to the partition |
| before mounting it and set up the dm-verity device for the partition.</p> |
| |
| <h4 id=managing_dm-verity><strong>Managing dm-verity</strong></h4> |
| |
| <p>By default, dm-verity operates in verifying mode and verifies each block read |
| from the device against a hash tree passed to it by <code>init</code> during set up. 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.</p> |
| |
| <p>Using a persistent flag, dm-verity can also be configured to function in |
| logging mode. This flag is read by <code>init</code> when setting up dm-verity. And if the |
| mode flag is set to logging or verity metadata cannot be verified, a warning |
| must be displayed to the user, similar to the warning the bootloader shows |
| before booting into RED state.</p> |
| |
| <img src="../images/dm-verity_mgmt.png" alt="dm-verity management" id="figure3" /> |
| <p class="img-caption"><strong>Figure 3.</strong> dm-verity management</p> |
| |
| <h4 id=recovering_from_dm-verity_errors><strong>Recovering from dm-verity errors</strong></h4> |
| |
| <p>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.</p> |
| |
| <p>It’s generally not possible to distinguish disk corruption from malicious |
| changes, so any change to the system partition must result in the user being |
| notified, and no unverified data must leak to user space until a warning has |
| been shown. However, we must also assume most verification failures are |
| not the result of malicious behavior; so the user must also have an option to |
| continue using the device without verification.</p> |
| |
| <p>If dm-verity is in verifying mode and a block of a partition fails to verify, |
| it will send a <code>uevent</code> to notify user space of the error. This event must be |
| handled by software in the boot partition as potentially any program residing |
| on the verified partition may not function anymore. When the event is received, |
| the persistent dm-verity state must be updated to set the mode flag to logging |
| mode, and the device must be rebooted. When the device restarts, |
| <code>init</code> will warn the user of changes to the partition before mounting it.</p> |
| |
| <h3 id=verified_partition>Verified partition</h3> |
| |
| <p>In a verified device, the system partition must always be verified. But any |
| other read-only partition can also be set to be verified, as well. Specifically, |
| any read-only partition that contains executable code must be verified on a |
| verified device. This include the vendor partition, if one exists, for example.</p> |
| |
| <p>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 <code>init</code> attempts to |
| mount the device, the user must be warned.</p> |
| |
| <h2 id=implementation_details>Implementation details</h2> |
| |
| <h3 id=key_types_and_sizes>Key types and sizes</h3> |
| |
| <p>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.</p> |
| |
| <h3 id=signature_format>Signature format</h3> |
| |
| |
| <p>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: <a |
| href="https://android.googlesource.com/platform/bootable/recovery/+/f4a6ab27b335b69fbc419a9c1ef263004b561265/asn1_decoder.cpp">platform/bootable/recovery/asn1_decoder.cpp</a><br/> |
| The message format itself is as follows:</p> |
| |
| <pre> |
| 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 |
| </pre> |
| |
| <p>The <code>Certificate</code> field is the full X.509 certificate containing |
| the public key used for signing, as defined by <a |
| href="http://tools.ietf.org/html/rfc5280#section-4.1.1.2">RFC5280</a> section |
| 4.1. The bootloader must ignore this field and must NOT use the key |
| specified in the certificate to verify the signature. Signatures must always be |
| verified against the OEM key or the user-provided keystore only.</p> |
| |
| <p>The remaining structure is similar to that defined by <a |
| href="http://tools.ietf.org/html/rfc5280#section-4.1.1.2">RFC5280</a> sections |
| 4.1.1.2 and 4.1.1.3 with the exception of the |
| <code>AuthenticatedAttributes</code> 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.).</p> |
| |
| <h3 id=signing_and_verifying_an_image>Signing and verifying an image</h3> |
| |
| <p>To produce a signed image:</p> |
| <ol> |
| <li>Generate the unsigned image. |
| <li>0-pad the image to the next page size boundary (omit this step if already |
| aligned). |
| <li>Populate the fields of the <code>AuthenticatedAttributes</code> section above based on the padded image and desired target partition. |
| <li>Append the <code>AuthenticatedAttributes</code> structure above to the image. |
| <li>Sign the image. |
| </ol> |
| |
| <p>To verify the image:</p> |
| <ol> |
| <li>Determine the size of the image to be loaded including padding (eg, by reading |
| a header). |
| <li>Read the signature located at the offset above. |
| <li>Validate the contents of the <code>AuthenticatedAttributes</code> field. |
| If these values do not validate, treat it as a signature validation error. |
| <li>Verify the image and <code>AuthenticatedAttributes</code> sections. |
| </ol> |
| |
| <h3 id=keystore_format>Keystore format</h3> |
| |
| <p>The Android verified boot keystore format is an ASN.1 DER-encoded document. Its |
| specification follows:</p> |
| |
| <pre> |
| AndroidVerifiedBootKeystore DEFINITIONS ::= |
| BEGIN |
| FormatVersion ::= INTEGER |
| KeyBag ::= SEQUENCE { |
| Key ::= SEQUENCE { |
| AlgorithmIdentifier ::= SEQUENCE { |
| algorithm OBJECT IDENTIFIER, |
| parameters ANY DEFINED BY algorithm |
| OPTIONAL |
| } |
| KeyMaterial ::= RSAPublicKey |
| } |
| } |
| Signature ::= AndroidVerifiedBootSignature OPTIONAL |
| END |
| </pre> |
| |
| <p>Where <code>RSAPublicKey</code>, <code>AlgorithmIdentifier</code>, and |
| parameters are as specified in <a |
| href="http://tools.ietf.org/html/rfc3279#section-2.3.1">RFC3279</a>. Other key |
| types specified in RFC3279 section 2.3 may optionally be supported, |
| in which case the appropriate type for <code>Key</code> must be used.</p> |
| |
| <h3 id=keystore_location>Keystore location</h3> |
| |
| <p>The location of the keystore is not specified here, but that location must be |
| known to the bootloader and both readable and writable by it. Reading should |
| happen as per the above; writing a new keystore should be accomplished through |
| <code>fastboot flash keystore <path></code>. Sufficient storage must be |
| provided for at least one key, with storage for additional keys recommended.</p> |
| |
| <h3 id=user_experience>User experience</h3> |
| |
| <p>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 should see a |
| warning for at least five seconds. Should the user interact with the device during |
| this time, the warning should remain visible until the user agrees to continue.</p> |
| |
| <p>Sample user interaction screens for other states are shown in the following table:</p> |
| <table> |
| <tr> |
| <td> |
| <p><strong>Device state</strong></p> |
| </td> |
| <td> |
| <p><strong>Sample UX</strong></p> |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <p>YELLOW (before and after user interaction)</p> |
| </td> |
| <td> |
| <img src="../images/boot_yellow1.png" alt="Yellow device state 1" id="figure4" /> |
| <p class="img-caption"><strong>Figure 4.</strong> Yellow state example 1 UI</p> |
| </td> |
| <td> |
| <img src="../images/boot_yellow2.png" alt="Yellow device state 2" id="figure5" /> |
| <p class="img-caption"><strong>Figure 5.</strong> Yellow state example 2 UI</p> |
| </td> |
| |
| </tr> |
| <tr> |
| <td> |
| <p>ORANGE</p> |
| </td> |
| <td> |
| <img src="../images/boot_orange.png" alt="Orange device state" id="figure6" /> |
| <p class="img-caption"><strong>Figure 6.</strong> Orange state example UI</p> |
| </td> |
| </tr> |
| <tr> |
| <td> |
| <p>RED</p> |
| </td> |
| <td> |
| <img src="../images/boot_red.png" alt="Red device state" id="figure7" /> |
| <p class="img-caption"><strong>Figure 7.</strong> Red state example UI</p> |
| </td> |
| </tr> |
| </table> |