在 Android 11 中,可以使用A/B 更新或虛擬 A/B 更新機制,結合RecoverySystem類方法來應用 OTA 更新。在設備重新啟動以應用 OTA 更新後,Resume-on-Reboot (RoR) 會解鎖設備憑據加密 (CE) 存儲。
儘管合作夥伴可以將此過程與 OTA 系統功能配對,當設備在 Android 11 中預計空閒時應用更新,但在 Android 12 中,合作夥伴不需要額外的 OTA 系統功能。 RoR 流程為用戶提供了額外的安全性和便利性,因為可以在設備空閒時間進行更新,而 Android 12 多客戶端和基於服務器的更新功能共同提供了設備硬件級別的類型安全性。
儘管您必須為android.hardware.reboot_escrow
功能提供設備權限以支持 Android 11 中的 RoR,但您無需這樣做即可在 Android 12 及更高版本中啟用基於服務器的 RoR,因為它們不使用 HAL。
為android.hardware.reboot_escrow
功能提供設備權限。您無需執行任何操作即可在 Android 12 中啟用基於服務器的 RoR,因為 Android 12 及更高版本不使用 HAL。
背景
從 Android 7 開始,Android 支持Direct Boot ,這使設備上的應用程序能夠在用戶解鎖 CE 存儲之前啟動。直接啟動支持的實施為用戶在啟動後需要輸入鎖屏知識因子 (LSKF) 之前提供了更好的體驗。
RoR 允許在 OTA 更新後啟動重新啟動時解鎖設備上所有應用程序的 CE 存儲,包括那些不支持直接啟動的應用程序。此功能使用戶能夠在重新啟動後接收來自所有已安裝應用程序的通知。
威脅模型
RoR 的實現必須確保當設備落入攻擊者手中時,攻擊者很難恢復用戶的 CE 加密數據,即使設備上電,CE 存儲被解鎖,設備被收到OTA更新後的用戶。即使攻擊者獲得了廣播加密簽名密鑰的訪問權限,內部攻擊抵抗也必須有效。
具體來說,CE 存儲不能被物理上擁有設備的攻擊者讀取,並且具有以下功能和限制:
能力
- 可以使用任何供應商或公司的簽名密鑰對任意消息進行簽名。
- 可能導致設備接收 OTA 更新。
- 可以修改任何硬件(例如應用處理器或閃存)的操作 - 除非下面的限制中詳細說明。 (但是,這種修改涉及至少一小時的延遲,以及破壞 RAM 內容的電源循環。)
限制
- 無法修改防篡改硬件(例如 Titan M)的操作。
- 無法讀取活動設備的 RAM。
- 無法猜測用戶的憑據(PIN、圖案、密碼)或以其他方式導致它們被輸入。
解決方案
Android 12 RoR 更新系統可針對非常老練的攻擊者提供安全保護,並且在設備上的密碼和 PIN 保留在設備上的同時,它們不會發送到或存儲在 Google 服務器上。這是確保提供的安全級別類似於基於硬件的設備級 RoR 系統的過程概述:
- Android 對存儲在設備上的數據應用加密保護。
- 所有數據都由存儲在可信執行環境(TEE) 中的密鑰保護。
- TEE 僅在運行的操作系統通過密碼驗證(驗證啟動)時才釋放密鑰。
- 在 Google 服務器上運行的 RoR 服務通過存儲只能在有限時間內檢索的秘密來保護 CE 數據。這適用於整個 Android 生態系統。
- 受用戶 PIN 保護的加密密鑰用於解鎖設備和解密 CE 存儲。
- 當安排夜間重啟時,Android 會提示用戶輸入他們的 PIN,然後計算合成密碼 (SP)。
- 然後它對 SP 進行兩次加密:一次使用存儲在 RAM 中的密鑰
K_s
,另一次使用存儲在 TEE 中的密鑰K_k
。 - 雙重加密的 SP 存儲在磁盤上,並且 SP 從 RAM 中擦除。這兩個密鑰都是新生成的,僅用於一次重新啟動。
- 當需要重新啟動時,Android 將
K_s
委託給服務器。帶有K_k
的收據在存儲到磁盤之前會被加密。 - 重啟後,Android 使用
K_k
解密收據,然後將其發送到服務器以檢索K_s
。-
K_k
和K_s
用於解密存儲在磁盤上的 SP。 - Android 使用 SP 解鎖 CE 存儲並允許正常的應用啟動。
-
K_k
和K_s
被丟棄。
-
確保手機安全的更新可以在您方便的時候進行:在您睡覺時。
SIM-PIN 重播
在某些情況下,SIM 卡的 PIN 碼會從緩存中得到驗證,這一過程稱為 SIM-PIN 重放。
啟用 PIN 的 SIM 卡還必須在無人值守重啟後進行無縫 PIN 碼驗證(SIM-PIN 重放)以恢復蜂窩連接(電話、短信和數據服務需要)。 SIM PIN 及其匹配的 SIM 卡信息(ICCID 和 SIM 插槽號)被安全地存儲在一起。只有在無人值守重啟成功後,才能檢索存儲的 PIN 並將其用於驗證。如果設備受到保護,SIM PIN 將與受 LSKF 保護的密鑰一起存儲。如果 SIM 卡啟用了 PIN,則與 RoR 服務器的交互需要WiFi 連接以進行 OTA 更新和基於服務器的 RoR,從而確保重啟後的基本功能(通過蜂窩連接)。
每次用戶成功啟用、驗證或修改 SIM PIN 時,都會重新加密和存儲 SIM PIN。如果發生以下任何一種情況,SIM PIN 將被丟棄:
- SIM 被移除或重置。
- 用戶禁用 PIN。
- 發生了非 RoR 啟動的重新啟動。
存儲的 SIM PIN 只能在 RoR 啟動的重新啟動後使用一次,並且只能在很短的持續時間(20 秒)內使用 -如果SIM 卡的詳細信息匹配。存儲的 SIM PIN 永遠不會離開 TelephonyManager 應用程序,並且無法由外部模塊檢索。
實施指南
在 Android 12 中,多客戶端和基於服務器的 RoR 功能為合作夥伴推送 OTA 更新時提供了更輕的負載。必要的更新可以在設備方便的停機時間內進行,例如在指定的睡眠時間。
為確保此類時間段內的 OTA 更新不會中斷用戶,請使用暗模式來減少光發射。為此,請讓設備引導加載程序搜索字符串 reason unattended
。如果unattended
為true
,則將設備置於暗模式。請注意,減少聲光發射是每個 OEM 的責任。
如果您要升級到 Android 12 或啟動 Android 12 設備,則無需執行任何操作即可實現新的 RoR 功能。
多客戶端流程中有一個新調用isPreparedForUnattendedUpdate
,如下所示:
@RequiresPermission(anyOf = {android.Manifest.permission.RECOVERY,
android.Manifest.permission.REBOOT})
public static boolean isPreparedForUnattendedUpdate(@NonNull Context context)
您不需要實現這一點,因為 HAL 自 Android 12 起已棄用。
電話經理
OTA 客戶端在 Android 12 中即將重啟時調用TelephonyManager
系統 API。此 API 將所有緩存的 PIN 碼從AVAILABLE
狀態移動到REBOOT_READY
狀態。 TelephonyManager
系統 API 受現有REBOOT
Manifest 權限的保護。
/**
* 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()
TelephonyManager 系統 API 由特權 APK 使用。
測試
要測試新 API,請執行以下命令:
adb shell cmd phone unattended-reboot
此命令僅在 shell 以 root ( adb root
) 運行時有效。
僅限安卓 11
本頁的其餘部分適用於 Android 11。
截至 2020 年 7 月,RoR HAL 的實現分為兩類:
- 如果 SoC 硬件在重啟後支持 RAM 持久性,OEM 可以使用 AOSP 中的默認實現(默認 RAM Escrow )。
- 如果設備硬件或 SoC 支持安全硬件飛地(具有自己的 RAM 和 ROM 的離散安全協處理器),它還必須執行以下操作:
- 能夠檢測到主 CPU 重啟。
- 有一個在重新啟動後仍然存在的硬件計時器源。即,飛地必須能夠檢測到重新啟動並且使在重新啟動之前設置的計時器到期。
- 支持將託管密鑰存儲在 enclave RAM/ROM 中,使其無法通過離線攻擊恢復。它必須以某種方式存儲 RoR 密鑰,使內部人員或攻擊者無法恢復它。
默認 RAM 託管
AOSP 使用 RAM 持久性實現了 RoR HAL。為此,OEM 必須確保其 SoC 支持跨重啟的 RAM 持久性。某些 SoC 無法在重新啟動後保留 RAM 內容,因此建議 OEM 在啟用此默認 HAL 之前諮詢其 SoC 合作夥伴。下一節中對此的規範參考。
使用 RoR 的 OTA 更新流程
手機上的OTA客戶端app必須擁有Manifest.permission.REBOOT和Manifest.permission.RECOVERY
權限,才能調用必要的方法來實現RoR。有了這個先決條件,更新流程遵循以下步驟:
- OTA 客戶端應用程序下載更新。
- OTA 客戶端應用程序調用
RecoverySystem#prepareForUnattendedUpdate
,這會觸髮用戶在下次解鎖期間在鎖定屏幕上被提示輸入其 PIN 碼、圖案或密碼。 - 用戶在鎖定屏幕上解鎖設備,並且設備已準備好應用更新。
- OTA 客戶端應用程序調用
RecoverySystem#rebootAndApply
,這會立即觸發重啟。
在此流程結束時,設備重新啟動並且 RoR 機制解鎖憑證加密 (CE) 存儲。對於應用程序來說,這顯示為普通用戶解鎖,因此他們會收到所有信號,例如他們通常會收到的ACTION_LOCKED_BOOT_COMPLETED和ACTION_BOOT_COMPLETED 。
修改產品配置
在 Android 11 中標記為支持 RoR 功能的產品必須包含 RebootEscrow HAL 的實現並包含功能標記 XML 文件。默認實現在使用熱重啟的設備上運行良好(當重啟期間 DRAM 的電源保持打開時)。
重新啟動託管功能標記
特徵標記也必須存在:
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.reboot_escrow.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.reboot_escrow.xml
默認重啟託管 HAL 實現
要使用默認實現,您必須保留 65536 (0x10000) 個字節。切勿將這些字節寫入非易失性存儲以確保安全屬性持續存在。
Linux 內核設備樹更改
在 Linux 內核的設備樹中,您必須為pmem
區域保留內存。以下示例顯示0x50000000
被保留:
reserved-memory {
my_reservation@0x50000000 {
no-map;
reg = <0x50000000 0x10000>;
}
}
reboot_escrow@0 {
compatible = "pmem-region";
reg = <0x50000000 0x10000>;
};
驗證您在塊目錄中是否有一個名稱類似於/dev/block/pmem0
的新設備(例如pmem1
或pmem2
)。
Device.mk 更改
假設上一步中的新設備名為pmem0
,您必須確保將以下新條目添加到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 規則
將這些新條目添加到設備的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