在 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_k
和K_s
用於解密儲存在磁碟上的 SP。- Android 會使用 SP 解鎖 CE 儲存空間,並允許一般應用程式啟動。
- 已捨棄
K_k
和K_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
字串原因。如果 unattended
是 true
,請將裝置設為深色模式。請注意,每家原始設備製造商 (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 實作項目可分為兩類:
- 如果 SoC 硬體在重新啟動時支援 RAM 持續性,原始設備製造商 (OEM) 可以使用 Android 開放原始碼計畫中的預設實作項目 (預設 RAM Escrow)。
- 如果裝置硬體或 SoC 支援安全的硬體安全區 (具備專屬 RAM 和 ROM 的獨立安全性輔助處理器),還必須執行以下作業:
- 能夠偵測主 CPU 重新啟動。
- 具備硬體計時器來源,在重新啟動後仍會持續顯示。也就是說,安全框必須能夠偵測重新啟動,並在重新啟動前設定的計時器失效。
- 支援將託管金鑰儲存在安全區 RAM/ROM 中,使其無法透過離線攻擊復原。必須以無法讓內部人員或攻擊者復原的方式儲存 RoR 金鑰。
預設的 RAM 擔保金
Android 開放原始碼計畫已利用 RAM 持續性實作 RoR HAL。為使這項功能順利運作,原始設備製造商 (OEM) 必須確保其 SoC 在重新啟動時支援 RAM 持續性。部分 SoC 無法在重新啟動後保留 RAM 內容,因此建議在啟用這個預設 HAL 前,建議原始設備製造商 (OEM) 合作夥伴諮詢。下一節的標準參考資料。
使用 RoR 的 OTA 更新流程
手機上的 OTA 用戶端應用程式必須具備 Manifest.permission.REBOOT 和 Manifest.permission.RECOVERY
權限,才能呼叫實作 RoR 所需的方法。瞭解必要條件後,更新流程的步驟如下:
- OTA 用戶端應用程式會下載更新。
- OTA 用戶端應用程式會呼叫
RecoverySystem#prepareForUnattendedUpdate
,藉此在使用者下次解鎖時,在螢幕鎖定畫面上提示輸入 PIN 碼、解鎖圖案或密碼。 - 使用者在螢幕鎖定畫面解鎖裝置,裝置即可開始套用更新。
- OTA 用戶端應用程式會呼叫
RecoverySystem#rebootAndApply
,並立即觸發重新啟動。
在這個流程結束時,裝置會重新啟動,RR 機制則會解鎖憑證加密 (CE) 儲存空間。對應用程式而言,這會顯示為一般使用者解鎖,因此應用程式會收到所有信號,例如通常會收到的 ACTION_LOCKED_BOOT_COMPLETED 和 ACTION_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
的新裝置 (例如 pmem1
或 pmem2
)。
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