In Android 11, OTA updates can be applied using the A/B update or virtual A/B update mechanisms, combined with the RecoverySystem class methods. After a device reboots to apply an OTA update, Resume-on-Reboot (RoR) unlocks the device Credential Encrypted (CE) storage.
Although partners can pair this process with an OTA system feature that applies updates when the device is expected to be idle in Android 11, in Android 12 partners don’t need an additional OTA system feature. The RoR process provides added security and convenience to users because the updates can be made during device idle times, while Android 12 multi-client and server-based update functionalities together provide device hardware-level type security.
Although you must provide device permission for the android.hardware.reboot_escrow
feature to support RoR in Android 11, you don't need to do this to enable
server-based RoR in Android 12 and higher, because they
don't use the HAL.
Background
Beginning with Android 7, Android supported Direct Boot, which enables the apps on a device to start up before CE storage is unlocked by the user. The implementation of Direct Boot support provided Users with a better experience before the Lock Screen Knowledge Factor (LSKF) needed to be entered after a boot.
RoR allows the CE storage of all the apps on a device to be unlocked, including those that don’t support Direct Boot, when a reboot is initiated following an OTA update. This feature enables users to receive notifications from all their installed apps, post reboot.
Threat model
An implementation of RoR must ensure that when a device falls into an attacker’s hands, it’s extremely difficult for the attacker to recover the user’s CE- encrypted data, even if the device is powered on, CE storage is unlocked, and the device is unlocked by the user after receiving an OTA update. Insider attack resistance must be effective even if the attacker gains access to the broadcast cryptographic signing keys.
Specifically, CE storage must not be read by an attacker who physically has the device, and has these capabilities and limitations:
Capabilities
- Can use the signing key of any vendor or company to sign arbitrary messages.
- Can cause the device to receive an OTA update.
- Can modify the operation of any hardware (such as an application processor, or flash memory) - except as detailed in Limitations below. (However, such modification involves both a delay of at least one hour, and a power cycle that destroys RAM contents.)
Limitations
- Can’t modify the operation of tamper-resistant hardware (for example, a Titan M).
- Can’t read the RAM of the live device.
- Can’t guess the user’s credentials (PIN, pattern, password) or otherwise cause them to be entered.
Solution
The Android 12 RoR update system provides security against very sophisticated attackers, and does so while on-device passwords and PINs stay on the device—they’re never sent to or stored on Google servers. This is an overview of the process that ensures the security levels provided are similar to a hardware-based, device-level RoR system:
- Android applies cryptographic protections to data stored on a device.
- All data is protected by keys stored in the trusted execution environment (TEE).
- The TEE only releases the keys if the running operating system passes cryptographic authentication (verified boot).
- The RoR service running on Google servers secures CE data by storing a secret that can be retrieved for a limited time only. This works across the Android ecosystem.
- A cryptographic key, protected by a user’s PIN, is used to unlock the device
and decrypt CE storage.
- When an overnight reboot is scheduled, Android prompts the user to enter their PIN, then calculates a synthetic password (SP).
- It then encrypts the SP twice: once with a key
K_s
stored in RAM, and again with a keyK_k
stored in TEE. - The double-encrypted SP is stored on disk, and the SP gets wiped from RAM. Both keys are freshly generated and used for one reboot only.
- When it’s time to reboot, Android entrusts
K_s
to the server. The receipt withK_k
gets encrypted before it’s stored on disk. - After the reboot, Android uses
K_k
to decrypt the receipt, then sends it to the server to retrieveK_s
.K_k
andK_s
are used to decrypt the SP stored on disk.- Android uses the SP to unlock the CE storage and allow normal app startup.
K_k
andK_s
are discarded.
The updates that keep your phone secure can happen at a time that's convenient for you: while you sleep.
SIM-PIN replay
Under certain conditions the PIN code of a SIM card gets verified from a cache, a process called SIM-PIN replay.
A SIM card with an enabled PIN must also undergo a seamless PIN code verification (a SIM-PIN replay) after an unattended reboot to restore cellular connectivity (required for phone calls, SMS messages, and data services). The SIM PIN and its matching SIM card information (the ICCID and SIM slot number) are securely stored, together. The stored PIN can be retrieved and used for verification only after a successful unattended reboot. If the device is secured, the SIM PIN is stored with keys protected by the LSKF. If the SIM has its PIN enabled, interaction with the RoR server requires a WiFi connection for the OTA update and server-based RoR, which ensures basic functionality (with cellular connectivity) after reboot.
The SIM PIN is re-encrypted and stored each time the user successfully enables, verifies, or modifies it. The SIM PIN is discarded if any one of the following occurs:
- The SIM is removed or reset.
- The user disables the PIN.
- A non-RoR-initiated reboot has occurred.
The stored SIM PIN can only be used once after the RoR-initiated reboot, and only for a very short time duration (20 seconds)–if the details of the SIM card match. The stored SIM PIN never leaves the TelephonyManager app and it can’t be retrieved by external modules.
Implementation guidelines
In Android 12, the multi-client and server-based RoR functions provide a lighter load to partners when they push OTA updates. Necessary updates can occur during convenient device downtimes, such as during designated sleep hours.
To ensure that OTA updates during such time periods don’t interrupt users,
employ dark mode to mitigate light emissions. To do so, have the device
bootloader search for the string reason unattended
. If unattended
is true
,
put the device in dark mode. Note that it’s each OEM's responsibility to
mitigate sound and light emissions.
If you’re either upgrading to Android 12, or launching Android 12 devices, you don’t need to do anything to implement the new RoR functionality.
There’s one new call in the multi-client flow, isPreparedForUnattendedUpdate
,
shown below:
@RequiresPermission(anyOf = {android.Manifest.permission.RECOVERY,
android.Manifest.permission.REBOOT})
public static boolean isPreparedForUnattendedUpdate(@NonNull Context context)
You don’t need to implement this, because the HAL is deprecated as of Android 12.
TelephonyManager
The OTA client invokes the TelephonyManager
system API when a reboot is imminent
in Android 12. This API moves all cached PIN codes from
the AVAILABLE
state to the REBOOT_READY
state. The TelephonyManager
system
API is protected by the existing REBOOT
Manifest permission.
/**
* The unattended reboot was prepared successfully.
* @hide
*/
@SystemApi
public static final int PREPARE_UNATTENDED_REBOOT_SUCCESS = 0;
/**
* The unattended reboot was prepared, but the user will need to manually
* enter the PIN code of at least one SIM card present in the device.
* @hide
*/
@SystemApi
public static final int PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED = 1;
/**
* The unattended reboot was not prepared due to generic error.
* @hide
*/
@SystemApi
public static final int PREPARE_UNATTENDED_REBOOT_ERROR = 2;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"PREPARE_UNATTENDED_REBOOT_"},
value = {
PREPARE_UNATTENDED_REBOOT_SUCCESS,
PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED,
PREPARE_UNATTENDED_REBOOT_ERROR
})
public @interface PrepareUnattendedRebootResult {}
/**
* Prepare TelephonyManager for an unattended reboot. The reboot is
* required to be done shortly after the API is invoked.
*
* Requires system privileges.
*
* <p>Requires Permission:
* {@link android.Manifest.permission#REBOOT}
*
* @return {@link #PREPARE_UNATTENDED_REBOOT_SUCCESS} in case of success.
* {@link #PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED} if the device contains
* at least one SIM card for which the user needs to manually enter the PIN
* code after the reboot. {@link #PREPARE_UNATTENDED_REBOOT_ERROR} in case
* of error.
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.REBOOT)
@PrepareUnattendedRebootResult
public int prepareForUnattendedReboot()
The TelephonyManager system API is used by privileged APKs.
Testing
To test the new API, execute this command:
adb shell cmd phone unattended-reboot
This command only works when the shell is running as root (adb root
).
Android 11 only
The remainder of this page applies to Android 11.
As of July 2020, implementations of RoR HAL fall into two categories:
- If the SoC hardware supports RAM persistence across reboots, OEMs can use the default implementation in AOSP (Default RAM Escrow).
- If the device hardware or SoC supports a secure hardware enclave (a discrete
security coprocessor with its own RAM and ROM), additionally it must do the
following:
- Be able to detect a main CPU reboot.
- Have a hardware timer source that persists across reboots. That is, the enclave must be able to detect the reboot and expire a timer set before the reboot.
- Support storing an escrowed key in the enclave RAM/ROM such that it can't be recovered with offline attacks. It must store the RoR key in a way that makes it impossible for insiders or attackers to recover it.
Default RAM escrow
AOSP has an implementation of the RoR HAL using RAM persistence. For this to work, OEMs must ensure that their SoCs support RAM persistence across reboots. Some SoCs are unable to persist RAM contents across a reboot, so OEMs are advised to consult their SoC partners before enabling this default HAL. The canonical reference for this in the following section.
Flow of OTA update using RoR
The OTA client app on the phone must have the
Manifest.permission.REBOOT
and Manifest.permission.RECOVERY
permissions to call the necessary methods to
implement RoR. With that prerequisite in place, the flow of an
update follows these steps:
- OTA client app downloads the update.
- OTA client app calls to
RecoverySystem#prepareForUnattendedUpdate
which triggers the user to be prompted for their PIN, pattern, or password on the lock screen during the next unlock. - The user unlocks the device at the lockscreen, and the device is ready to have the update applied.
- OTA client app calls to
RecoverySystem#rebootAndApply
, which immediately triggers a reboot.
At the end of this flow, the device reboots and the RoR mechanism unlocks the credential encrypted (CE) storage. To apps, this appears as a normal user unlock, so they receive all the signals, such as ACTION_LOCKED_BOOT_COMPLETED and ACTION_BOOT_COMPLETED that they normally do.
Modify product configurations
A product marked as supporting the RoR feature in Android 11 must include an implementation of the RebootEscrow HAL and include the feature marker XML file. The default implementation works well on devices that use warm reboot (when the power to DRAM remains on during reboot).
Reboot escrow feature marker
The feature marker must also be present:
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.reboot_escrow.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.reboot_escrow.xml
Default reboot escrow HAL implementation
To use the default implementation, you must reserve 65536 (0x10000) bytes. Never write these bytes to non-volatile storage to ensure that the security properties persist.
Linux kernel device tree changes
In the Linux kernel's device tree, you must reserve memory for a pmem
region.
The following example shows 0x50000000
being reserved:
reserved-memory {
my_reservation@0x50000000 {
no-map;
reg = <0x50000000 0x10000>;
}
}
reboot_escrow@0 {
compatible = "pmem-region";
reg = <0x50000000 0x10000>;
};
Verify that you have a new device in the block directory with a name like
/dev/block/pmem0
(such as pmem1
or pmem2
).
Device.mk changes
Assuming that your new device from the previous step is named pmem0
, you must
ensure the following new entries get added to vendor/<oem>/<product>/device.mk
:
# Resume on Reboot support
PRODUCT_PROPERTY_OVERRIDES += \
ro.rebootescrow.device=/dev/block/pmem0
PRODUCT_PACKAGES += \
android.hardware.rebootescrow-service.default
SELinux rules
Add these new entries to the device's file_contexts
:
/dev/block/pmem0 u:object_r:rebootescrow_device:s0
/vendor/bin/hw/android\.hardware\.rebootescrow-service\.default u:object_r:hal_rebootescrow_default_exec:s0