重新啟動時繼續執行

在 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 以上版本中,您不必這樣做,因為這些版本不會使用 HAL。

背景

自 Android 7 起,Android 支援「直接啟動」功能,可讓裝置上的應用程式在使用者解鎖 CE 儲存空間前啟動。實作直接啟動支援功能後,使用者在啟動後需要輸入螢幕鎖定知識因素 (LSKF) 前,可享有更優質的體驗。

在 OTA 更新後啟動重新啟動時,RoR 會允許解鎖裝置上所有應用程式的 CE 儲存空間,包括不支援直接啟動的應用程式。這項功能可讓使用者在重新啟動後,收到所有已安裝應用程式的通知。

威脅模式

實作 RoR 時,必須確保裝置落入攻擊者手中時,攻擊者即使開啟裝置、解鎖 CE 儲存空間,並在收到 OTA 更新後解鎖裝置,也難以復原使用者以 CE 加密的資料。即使攻擊者取得廣播加密編譯簽署金鑰的存取權,內部攻擊防禦機制也必須有效。

具體來說,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 伺服器的互動需要 Wi-Fi 連線,才能進行 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。如果 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)

您不需要實作此功能,因為 HAL 已在 Android 12 中淘汰。

TelephonyManager

在 Android 12 中,OTA 用戶端會在即將重新啟動時叫用 TelephonyManager 系統 API。這個 API 會將所有快取的 PIN 碼從 AVAILABLE 狀態移至 REBOOT_READY 狀態。TelephonyManager 系統 API 受到現有 REBOOT 資訊清單權限的保護。

 /**
    * 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()

特權 APK 會使用 TelephonyManager 系統 API。

測試

如要測試新的 API,請執行下列指令:

    adb shell cmd phone unattended-reboot

只有在殼層以 root 權限 (adb root) 執行時,這項指令才會生效。

僅限 Android 11

本頁其餘部分適用於 Android 11。

截至 2020 年 7 月,RoR HAL 實作項目分為兩類:

  1. 如果 SoC 硬體支援重新啟動時的 RAM 持續性,原始設備製造商 (OEM) 可以使用 AOSP 中的預設實作方式 (預設 RAM 擔保)。
  2. 如果裝置硬體或 SoC 支援安全硬體區塊 (具有專屬 RAM 和 ROM 的獨立安全輔助處理器),則必須執行下列操作:
    • 能夠偵測主 CPU 重新啟動。
    • 硬體計時器來源會在重新啟動後持續存在。也就是說,Enclave 必須能夠偵測重新啟動,並在重新啟動前讓計時器到期。
    • 支援將分離式金鑰儲存在特區 RAM/ROM 中,以免遭受離線攻擊而復原。必須以無法讓內部人員或攻擊者復原的方式儲存 RoR 金鑰。

預設的 RAM 擔保金

Android 開放原始碼計畫已實作使用 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>;
  };

確認 block 目錄中是否有名稱為 /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