在 Android 11 中,可以使用A/B 更新或虛擬 A/B 更新機制並結合RecoverySystem類方法來應用 OTA 更新。設備重新啟動以應用 OTA 更新後,重新啟動時恢復 (RoR) 會解鎖設備憑據加密 (CE) 存儲。
儘管合作夥伴可以將此流程與 OTA 系統功能配對,該功能在 Android 11 中預計設備空閒時應用更新,但在 Android 12 中合作夥伴不需要額外的 OTA 系統功能。 RoR 流程為用戶提供了更高的安全性和便利性,因為可以在設備空閒時間進行更新,而 Android 12 多客戶端和基於服務器的更新功能共同提供設備硬件級類型安全性。
儘管您必須為android.hardware.reboot_escrow
功能提供設備權限才能在 Android 11 中支持 RoR,但在 Android 12 及更高版本中無需執行此操作即可啟用基於服務器的 RoR,因為它們不使用 HAL。
背景
從 Android 7 開始,Android 支持直接啟動,這使得設備上的應用程序能夠在用戶解鎖 CE 存儲之前啟動。直接啟動支持的實施為用戶在啟動後需要輸入鎖屏知識因子 (LSKF) 之前提供了更好的體驗。
當 OTA 更新後啟動重新啟動時,RoR 允許解鎖設備上所有應用程序的 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。
- 發生了非 RoR 啟動的重新啟動。
如果SIM 卡的詳細信息匹配,則存儲的 SIM PIN 只能在 RoR 啟動的重啟後使用一次,並且只能使用很短的時間(20 秒)。存儲的 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)
您不需要實現此功能,因為從 Android 12 開始已棄用 HAL。
電話管理器
當 Android 12 中即將重新啟動時,OTA 客戶端會調用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 託管)。
- 如果設備硬件或 SoC 支持安全硬件飛地(具有自己的 RAM 和 ROM 的離散安全協處理器),則還必須執行以下操作:
- 能夠檢測主 CPU 重新啟動。
- 擁有一個在重新啟動後仍然存在的硬件計時器源。也就是說,Enclave 必須能夠檢測到重新啟動,並在重新啟動之前設置的計時器到期。
- 支持將託管密鑰存儲在 enclave RAM/ROM 中,使其無法通過離線攻擊恢復。它必須以一種使內部人員或攻擊者無法恢復的方式存儲 RoR 密鑰。
默認 RAM 託管
AOSP 有一個使用 RAM 持久性的 RoR HAL 實現。為此,OEM 必須確保其 SoC 支持重新啟動後的 RAM 持久性。某些 SoC 無法在重新啟動後保留 RAM 內容,因此建議 OEM 在啟用此默認 HAL 之前諮詢其 SoC 合作夥伴。下一節中對此的規範參考。
使用RoR的OTA更新流程
手機上的 OTA 客戶端應用程序必須具有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