重新啟動時繼續執行

在 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 儲存空間已解鎖,且使用者在收到 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 碼重播。

如果 SIM 卡已啟用 PIN 碼,在無人看管的情況下重新啟動後,也必須通過無縫 PIN 碼驗證 (重新輸入 SIM 卡 PIN 碼),才能還原行動網路連線 (撥打電話、傳送簡訊和使用數據服務時必須連線)。系統會將 SIM 卡 PIN 碼和相符的 SIM 卡資訊 (ICCID 和 SIM 卡插槽號碼) 一併安全儲存。成功無人看管重新啟動後,才能擷取儲存的 PIN 碼並用於驗證。如果裝置已受保護,系統會將 SIM 卡 PIN 碼連同受 LSKF 保護的金鑰一併儲存。如果 SIM 卡已啟用 PIN 碼,與 RoR 伺服器互動需要 Wi-Fi 連線,才能進行 OTA 更新和伺服器型 RoR,確保重新啟動後的基本功能 (使用行動網路連線)。

每次使用者成功啟用、驗證或修改 SIM 卡 PIN 碼時,系統都會重新加密並儲存 PIN 碼。如果發生下列任一情況,系統就會捨棄 SIM 卡 PIN 碼:

  • SIM 卡已移除或重設。
  • 使用者停用 PIN 碼。
  • 發生非 RoR 啟動的重新啟動作業。

RoR 啟動重新啟動後,儲存的 SIM 卡 PIN 碼只能使用一次,且只能在極短的時間內 (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

只有在 Shell 以根目錄 (adb root) 形式執行時,這個指令才會生效。

僅限 Android 11

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

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

  1. 如果 SoC 硬體支援在重新啟動時保留 RAM,原始設備製造商可以使用 AOSP 中的預設實作 (預設 RAM 託管)。
  2. 如果裝置硬體或 SoC 支援安全硬體 Enclave (具有專屬 RAM 和 ROM 的獨立安全協同處理器),則必須執行下列操作:
    • 能夠偵測主要 CPU 重新啟動。
    • 擁有在重新啟動後仍會保留的硬體計時器來源。也就是說,安全區必須能夠偵測重新啟動,並在重新啟動前使計時器過期。
    • 支援在 Enclave RAM/ROM 中儲存託管金鑰,確保無法透過離線攻擊復原金鑰。必須以內部人員或攻擊者無法復原的方式儲存 RoR 金鑰。

預設 RAM 託管

Android 開放原始碼計畫 (AOSP) 實作了使用 RAM 持續性的 RoR HAL。如要使用這項功能,原始設備製造商必須確保 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