重新啟動後繼續

在 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 以上版本並未使用 HAL,因此您不必執行這項操作,即可啟用伺服器型 RoR。

背景

從 Android 7 開始,Android 支援直接啟動功能,這項功能可讓裝置上的應用程式在使用者解鎖 CE 儲存空間前啟動。導入直接啟動支援功能,可以讓使用者在啟動後必須先進入螢幕鎖定知識係數 (LSKF) 之前,獲得更好的體驗。

允許在 OTA 更新後重新啟動時,針對裝置上的所有應用程式 (包括不支援直接啟動功能) 解鎖 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 伺服器互動時,「需要」Wi-Fi 連線才能進行 OTA 更新和伺服器型 RoR,以確保在重新啟動後,基本功能 (需有行動網路連線) 才能進行。

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

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

儲存的 SIM 卡 PIN 碼只能在 RoR 啟動重新啟動後使用「一次」,而且只能用於極短時間 (20 秒),而且 SIM 卡詳細資料相符。儲存的 SIM 卡 PIN 碼永遠不會離開 TelephonyManager 應用程式,也無法由外部模組擷取。

導入指南

在 Android 12 中,當合作夥伴推送 OTA 更新時,多重用戶端和伺服器型 RoR 函式可以減輕負載。在方便的裝置停機時間 (例如指定的睡眠時段) 期間,可能會進行必要的更新。

為確保這類期間的 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

這個指令只有在殼層以根使用者的身分執行 (adb root) 時才有效。

僅限 Android 11

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

自 2020 年 7 月起,RR 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 內容,因此建議原始設備製造商 (OEM) 諮詢 SoC 合作夥伴,然後再啟用這個預設 HAL。下一節的標準參考資料。

使用 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>;
  };

確認區塊目錄中有新裝置,名為 /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