重新啟動後繼續

在 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,因此您不必執行這項操作,即可啟用伺服器型 RoR。

背景

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

允許在 OTA 更新後重新啟動時,針對裝置上的所有應用程式 (包括不支援直接啟動功能) 解鎖 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 卡。發生下列任一情況時,系統就會捨棄 SIM PIN:

  • 取出或重設 SIM 卡。
  • 使用者停用 PIN。
  • 發生非 RoR 啟動的重新啟動作業。

儲存的 SIM PIN 只能在 RoR 啟動的重新啟動後使用一次,且只能在非常短的時間 (20 秒) 內使用,前提是 SIM 卡的詳細資料相符。儲存的 SIM PIN 不會離開 TelephonyManager 應用程式,且無法由外部模組擷取。

導入指南

在 Android 12 中,多用戶端和伺服器 RoR 函式可在合作夥伴推送 OTA 更新時,為他們提供較輕的負載。必要的更新可在裝置閒置期間執行,例如在指定的睡眠時間。

為確保這類期間的 OTA 更新不會對使用者造成乾擾,請採用深色模式來減少光排放量。方法是在裝置系統啟動載入程式搜尋 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 中淘汰。

電話管理工具

當 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) 可以使用 Android 開放原始碼計畫中的預設實作項目 (預設 RAM Escrow)。
  2. 如果裝置硬體或 SoC 支援安全的硬體安全區 (具備專屬 RAM 和 ROM 的獨立安全性輔助處理器),還必須執行以下作業:
    • 能夠偵測主 CPU 重新啟動。
    • 具備硬體計時器來源,在重新啟動後仍會持續顯示。也就是說,安全框必須能夠偵測重新啟動,並在重新啟動前設定的計時器失效。
    • 支援將託管金鑰儲存在安全區 RAM/ROM 中,使其無法透過離線攻擊復原。必須以無法讓內部人員或攻擊者復原的方式儲存 RoR 金鑰。

預設的 RAM 擔保金

Android 開放原始碼計畫已利用 RAM 持續性實作 RoR HAL。為使這項功能順利運作,原始設備製造商 (OEM) 必須確保其 SoC 在重新啟動時支援 RAM 持續性。部分 SoC 無法在重新啟動後保留 RAM 內容,因此建議在啟用這個預設 HAL 前,建議原始設備製造商 (OEM) 合作夥伴諮詢。下一節的標準參考資料。

使用 RoR 的 OTA 更新流程

手機上的 OTA 用戶端應用程式必須具備 Manifest.permission.REBOOTManifest.permission.RECOVERY 權限,才能呼叫實作 RoR 所需的方法。瞭解必要條件後,更新流程的步驟如下:

  1. OTA 用戶端應用程式會下載更新。
  2. OTA 用戶端應用程式會呼叫 RecoverySystem#prepareForUnattendedUpdate,藉此在使用者下次解鎖時,在螢幕鎖定畫面上提示輸入 PIN 碼、解鎖圖案或密碼。
  3. 使用者在螢幕鎖定畫面解鎖裝置,裝置即可開始套用更新。
  4. OTA 用戶端應用程式會呼叫 RecoverySystem#rebootAndApply,並立即觸發重新啟動。

在這個流程結束時,裝置會重新啟動,RR 機制則會解鎖憑證加密 (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

預設重新啟動 Escrow HAL 實作

如要使用預設實作,您必須保留 65536 (0x10000) 位元組。請勿將這些位元組寫入非揮發性儲存空間,以確保安全性屬性持續存在。

Linux 核心裝置樹狀結構異動

在 Linux kernel 的裝置樹狀結構中,您必須為 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