The device state indicates how freely software can be flashed to a device and
whether verification is enforced. Device states are LOCKED
and
UNLOCKED
. LOCKED
devices prevent you from flashing new
software to the device, whereas UNLOCKED
devices allow
modification.
When a device powers on, the bootloader first checks if a device is
LOCKED
or UNLOCKED
. If a device is
UNLOCKED
, the bootloader shows the user a warning and then proceeds
to boot even if the loaded OS isn't signed by the root of trust.
If the device is LOCKED
, the bootloader goes through the steps in
Verifying Boot to verify
the device's software. LOCKED
devices boot only if the
loaded OS is properly signed by the root of trust. For more details, see
The boot flow.
Change device state
To change a device's state, use
the fastboot flashing [unlock | lock]
command. To protect user
data, all state transitions wipe the data partitions and ask for user
confirmation before data is deleted.
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 device
manufacturer, as long as there is no warning. The LOCKED
to
UNLOCKED
transition is expected when a developer wishes to disable
verification on the device for development purposes.
Root of trust
Root of trust is the cryptographic key used to sign the copy of Android stored on the device. The private part of the root of trust is known only to the device manufacturer and is used to sign every version of Android intended for distribution. The public part of the root of trust is embedded in the device and is stored in a place so it can't be tampered with (typically read-only storage).
When it loads Android, the bootloader uses the root of trust to verify authenticity. For more details on this process, see Verifying Boot. Devices may have multiple boot loaders and as such multiple cryptographic keys may be in play.
User-settable root of trust
Devices can optionally allow the user to configure the root of trust (for example, a public key). Devices can, and Google Pixel devices do, use this user-settable root of trust for Verified Boot in addition to the built-in root of trust.
If user-settable root of trust is implemented, it should be done in a way such that:
- Physical confirmation is required to set/clear the user-settable root of trust.
- The user-settable root of trust can only be set by the end user. It can't be set at the factory or any intermediate point before the end user gets the device.
- The user-settable root of trust is stored in tamper-evident storage. Tamper-evident means that it's possible to detect if Android has tampered with the data, for example, if it has been overwritten or changed.
- If a user-settable root of trust is set, the device should allow a version of Android signed with either the built-in root of trust or the user-settable root of trust to boot.
- Every time the device boots using the user-settable root of trust, the user
should be notified that the device is loading a custom version of Android. For
example, warning screens, see
LOCKED
devices with custom key set.
One way of implementing user-settable root of trust is to have a virtual
partition that can only be flashed or cleared when the device is in the
UNLOCKED
state. The Google Pixel 2 devices use this approach and
the virtual partition is called avb_custom_key
. The format of the
data in this partition is the output of the
avbtool extract_public_key
command. Here's an example of how to set
the user-settable root of trust:
avbtool extract_public_key --key key.pem --output pkmd.bin
fastboot flash avb_custom_key pkmd.bin
The user-settable root of trust can be cleared by issuing:
fastboot erase avb_custom_key