重新啟動時繼續執行

在 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