Unlocking and Trusty
All Google-branded devices should be made unlockable so that all partitions
listed above can be reflashed. This unlocked mode is set with
flashing unlock, and once set this mode should persist across reboots.
Devices should deny the
fastboot flashing unlock command
fastboot flashing get_unlock_ability is: "1" If
get_unlock_ability is "0" the user needs to boot to the home
screen, go into the Settings > System > Developer
options menu and enable the OEM unlocking option to
unlock_ability to: "1" That flag should be persistent across
reboots and across factory data resets.
fastboot flashing unlock command is sent, the device should
prompt users to warn them that they may encounter problems with unofficial
images. After acknowledging, a factory data reset should be done to prevent
unauthorized data access. The bootloader should reset the device even if it is not
able to reformat it properly. Only after reset can the persistent flag be set so
that the device can be reflashed.
fastboot flashing lock command relocks and resets the device so
that future flash/unlock attempts require another data reset.
All RAM not already overwritten should be reset during the
unlock process. This measure prevents attacks that read leftover RAM
contents from the previous boot. Similarly, unlocked devices should clear RAM at
every boot if this does not create an unacceptable delay, but should leave the
region used for the kernel's
Devices intended for retail should be shipped in the locked state (and with
get_unlock_ability returning "0"). This is to ensure an attacker
cannot compromise the device by installing their own system or boot image.
ro.oem_unlock_supported property should be set at build time
based on whether the device supports flashing unlock.
ro.oem_unlock_supported should be set to "0" if flashing unlock is
not supported on the device or "1" if flashing unlock is supported.
If the device supports flashing unlock (i.e.
1), then the bootloader should indicate the lock status by setting the
kernel command line variable
androidboot.flash.locked (or the
/firmware/android/flash.locked DT property) to "1" if locked or "0"
Note: For devices that support dm-verity,
you can instead use
ro.boot.verifiedbootstate to set the value of
ro.boot.flash.locked where the value is "0" i.e. unlocked if the
verified boot state is orange.
The device should support locking and unlocking of critical sections. Those critical sections are defined as whatever is needed to boot the device into the bootloader. This might include fuses, virtual partitions for a sensor hub, first-stage bootloader, and more.
Locking of critical sections is defined as preventing any code (kernel, recovery image, OTA code, etc.) running on the device from deliberately modifying any critical section. This implies that OTAs should fail to update critical sections if the device is in lock critical state. Transitioning from locked to unlocked state should require a physical interaction with the device.
The physical interaction is similar to what
unlock would cause: the user would have to press some physical buttons on the
device. The design should not allow programmatically transitioning from
lock critical to
unlock critical without physical
interaction. Devices should ship in the
unlock critical state.
Designation of critical partitions/data
Any partitions or data needed for the device to run, need to be either:
- Re-flashable - either re-buildable, provided, or extractable via some
- fully-protected (i.e. considered critical per the previous section)
This includes per-device factory-specific settings, serial numbers, calibration data, etc.
If a device supports "off-mode charging" or otherwise autoboots into a
special mode when power is applied,
fastboot oem off-mode-charge 0
should bypass these special modes and boot as if the user had pressed the power
Bootloader for Trusty
Trusty is Google's implementation of a Trusted Execution Environment (TEE) OS that runs alongside Android. This is the specification for devices using ARM TrustzoneTM technology to provide a TEE.
If Trusty is used as the secure OS solution on your ARM device, the bootloader should be implemented as described within the following sections.
In order to load and initialize the Trusty OS (TOS), a bootloader should:
- Set up and configure all available RAM
- Initialize at least one serial port
- Verify signature of TOS image
- Load TOS into RAM (execution from flash or TCM is not supported)
- Jump to the first instruction in the TOS image after setting up the state and registers as described in the next section
Calling into TOS image
The following state should be configured at entry:
- MMU turned off
- Data cache flushed and turned off (instruction cache can be on or off)
- All interrupts (IRQs and FIQs) disabled
- CPU in SVC mode on ARM v7 and EL3 on ARM v8
- Registers in the following state:
- r0/x0: size of memory allocated to TOS.
- r1/x1: physical address of a contiguous block of memory that contains platform-specific boot parameters. The layout of this block is platform specific.
- r2/x2: size of the above block of memory.
- r14/x30: return address to jump to (in non-secure mode) after TOS initializes.
Note: r0-r3/x0-x3 also serve as scratch registers to TOS. Do not expect their values to be preserved upon return.
On a 64-bit platform:
- Only w0-w2 are used for parameters, so x0-x2 should contain only 32-bit values.
- x30 can contain a 64-bit value.
- The value in x0 when added to the base address of TOS entry-point should result in a 32-bit value. The same applies to the size in register x2 when added to the address of boot parameter block in x1.
Return from TOS
TOS will return to the bootloader in non-secure mode (SCR.NS set to "1") when it is done initializing so that the bootloader may continue loading the primary operating system (e.g., Android).