重新啟動時恢復

在 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_kK_s用來解密儲存在磁碟上的SP。
    • Android 使用 SP 解鎖 CE 儲存空間並允許正常應用程式啟動。
    • K_kK_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 。如果unattendedtrue ,請將裝置置於深色模式。請注意,減少聲音和光排放是每個 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 的實作分為兩類:

  1. 如果 SoC 硬體支援重新啟動後的 RAM 持久性,OEM 可以使用 AOSP 中的預設實作(預設 RAM 託管)。
  2. 如果裝置硬體或 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.REBOOTManifest.permission.RECOVERY權限才能呼叫實現 RoR 所需的方法。滿足此先決條件後,更新流程將遵循以下步驟:

  1. OTA 用戶端應用程式下載更新。
  2. OTA 用戶端應用程式呼叫RecoverySystem#prepareForUnattendedUpdate ,這會觸發使用者在下次解鎖期間在鎖定畫面上提示輸入 PIN、圖案或密碼。
  3. 用戶在鎖定螢幕介面解鎖設備,並且設備已準備好應用程式更新。
  4. OTA 用戶端應用程式呼叫RecoverySystem#rebootAndApply ,這會立即觸發重新啟動。

在此流程結束時,裝置重新啟動,RoR 機制解鎖憑證加密 (CE) 儲存。對於應用程式來說,這顯示為普通用戶解鎖,因此它們會收到所有訊號,例如它們通常執行的ACTION_LOCKED_BOOT_COMPLETEDACTION_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的新裝置(例如pmem1pmem2 )。

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