硬體包裝金鑰

如同大多數的磁碟與檔案加密軟體,Android 的儲存空間加密機制一樣 通常依賴系統記憶體中的原始加密金鑰 才能加密即使已進行加密 相較於軟體,軟體一般而言 管理原始加密金鑰

傳統上來說,這不會視為問題,因為鍵沒有 離線攻擊期間,儲存空間主要的攻擊類型 加密機制旨在防範各種威脅不過,仍希望 針對其他類型的攻擊 (例如冷啟動) 強化防護 ,以及攻擊者可能基於安全目的洩漏系統的線上攻擊 而不破壞裝置

為解決這個問題,Android 11 導入了支援功能 「硬體包裝金鑰」,其中必須有硬體支援。 硬體包裝的金鑰是原始形式的儲存金鑰 專用硬體;軟體只能在已包裝的金鑰中查看和處理這些金鑰 (加密) 表單。這個硬體必須能夠產生及匯入 儲存空間金鑰、以暫時和長期形式包裝儲存金鑰, 子鍵,直接將一個子金鑰編寫為內嵌加密引擎,以及 傳回另一個子鍵到軟體。

注意內嵌加密引擎 (或內嵌加密引擎) 加密硬體) 是指將資料加密/解密 收發檔案。通常是 UFS 或 eMMC 主機 控制器,可實作由對應的 JEDEC 規格。

設計

本節會說明硬體包裝的金鑰功能設計,包括 所需的硬體支援本討論著重於檔案型加密 (FBE),但 解決方案適用於中繼資料 加密

如要避免需要使用系統記憶體中的原始加密金鑰, 這些金鑰只儲存在內嵌加密引擎的金鑰運算單元中。不過, 方法會產生一些問題

  • 加密金鑰的數量可能會超過金鑰運算單元數量。
  • 內嵌加密貨幣引擎只能用於加密/解密 也就是磁碟上的資料不過,就 FBE 而言,軟體仍要能 執行其他加密編譯作業,例如檔案名稱加密和衍生金鑰 識別碼軟體仍須存取原始 FBE 金鑰,才能 執行其他工作

為避免這類問題,系統會將儲存空間金鑰改為 「硬體包裝的金鑰」,這類金鑰只能解開包裝, 專屬硬體因此可支援的金鑰數量沒有限制。於 此外,金鑰階層經過修改,部分移至這個硬體 如此一來,如果工作沒有採用 內嵌加密引擎。

金鑰階層

您可以使用 KDF (金鑰衍生函式) 從其他鍵衍生金鑰,例如 HKDF。 產生「索引鍵階層」

下圖描述 FBE 在 「不會」使用硬體包裝的金鑰:

FBE 金鑰階層 (標準)
圖 1:FBE 金鑰階層 (標準)
,瞭解如何調查及移除這項存取權。

FBE 類別金鑰是 Android 傳送給 Linux 的原始加密金鑰 來解鎖一組特定加密目錄,例如 特定 Android 使用者的憑證加密儲存空間。(在核心中, 稱為 fscrypt 主金鑰)。從這組金鑰中,核心 下列子鍵:

  • 金鑰 ID。這個值會用於加密,而不會用於加密。 用於識別特定檔案或目錄的金鑰 並受到妥善保護
  • 檔案內容加密金鑰
  • 檔案名稱加密金鑰

相反地,下圖描述 FBE 的 使用的是硬體包裝的金鑰:

FBE 金鑰階層 (含硬體包裝金鑰)
圖 2 FBE 金鑰階層 (含硬體包裝金鑰)
,瞭解如何調查及移除這項存取權。

與先前的案例相比,額外在索引鍵中新增了層級 階層,且檔案內容加密金鑰重新位置。根目錄 節點仍代表 Android 傳遞給 Linux 以解鎖一組 加密目錄不過,現在金鑰採用暫時包裝的格式 您必須先傳遞至專屬硬體,才能使用這項功能。這個硬體必須 實作兩個介面,以使用暫時包裝的金鑰:

  • 產生 inline_encryption_key 並直接衍生的一個介面 將其編寫至內嵌加密引擎的金鑰位置。允許附加檔案 軟體,無法存取原始檔案或軟體 鍵。在 Android 常用核心中,這個介面會對應至 blk_crypto_ll_ops::keyslot_program 作業,必須是 由儲存驅動程式實作
  • 擷取並傳回 sw_secret (「軟體」) 的一個介面 秘密」(也稱為「原始密鑰」)其中的關鍵 Linux 會使用非檔案內容衍生所有內容的子鍵 加密。在 Android 常用核心中,這個介面會對應至 blk_crypto_ll_ops::derive_sw_secret 作業,必須是 由儲存驅動程式實作

導出 inline_encryption_keysw_secret 原始儲存金鑰,硬體必須使用經過加密的高強度 KDF。這個 KDF 必須遵循密碼學最佳做法。其安全強度只有 至少 256 位元,也就是說,已經足以供稍後使用的演算法。而且必須使用 不重複標籤、背景資訊和/或應用程式專屬資訊字串 衍生各類型的子鍵,藉此確保產生的子鍵 需要經過加密編譯,因此知道其中任何一項資料都不會洩漏 其他。不需要延展金鑰,因為原始儲存金鑰已經是 完全隨機的隨機金鑰

就技術層面而言,您可以使用任何符合安全性需求的 KDF。 不過,基於測試目的,務必在測試時重新導入相同的 KDF。 測試程式碼目前已審查並實施一個 KDF。可以找到 vts_kernel_encryption_test 原始碼。 我們建議硬體使用這個 KDF,其使用 NIST SP 800-108 "KDF in Counter Mode" 搭配 AES-256-CMAC 做為 PRF。請注意,您必須能夠相容 演算法的部分必須相同,包括選擇的 KDF 結構定義 為每個子鍵建立和標籤

金鑰包裝

為達到硬體包裝金鑰的安全性目標,我們有兩種金鑰包裝 定義:

  • 暫時包裝:硬體會使用金鑰加密原始金鑰 這組 ID 在每次啟動時隨機產生,不會直接公開 硬體元件
  • 長期包裝:硬體會使用 專屬永久金鑰,並非直接內建於硬體中 暴露於硬體外

系統會將所有傳遞至 Linux kernel 來解鎖儲存空間的金鑰, 進行臨時包裝這確保如果攻擊者能夠擷取 系統記憶體的使用中金鑰,那麼該金鑰也將無法使用 、重新開機後顯示於裝置上。

此外,Android 仍須能夠儲存加密版本 這些金鑰就能一開始就解鎖原始 就是基於這個目的不過,最好永不 金鑰存在於系統記憶體中 會在裝置端使用 (即使在啟動時擷取)。所以這個概念 而不是「長期包裝」

為了支援管理用這兩種不同方式包裝的金鑰,硬體必須 實作以下介面:

  • 產生及匯入儲存金鑰的介面,以此方式傳回這些金鑰 這些介面可經由 KeyMint,而且與 TAG_STORAGE_KEY KeyMint 標記相對應。 「產生」「vold」會使用這些功能來產生新的儲存空間 供 Android 使用的金鑰,而「匯入」功能 執行 vts_kernel_encryption_test 即可匯入測試金鑰。
  • 這個介面可將長期包裝的儲存金鑰轉換為 臨時包裝的儲存金鑰這會對應至 convertStorageKeyToEphemeral KeyMint 方法。我們會使用這個方法 由 voldvts_kernel_encryption_test 建立 解鎖儲存空間

金鑰包裝演算法是實作詳細資料,但應使用 高強度 AEAD,例如 AES-256-GCM 與隨機 IV。

必須變更軟體

Android 開放原始碼計畫已有支援硬體包裝金鑰的基本架構。這個 包括支援使用者空間元件,例如 vold 做為 blk-cryptofscrypt 的 Linux kernel 支援,以及 dm-default-key

不過,您需要對導入作業進行一些變更。

KeyMint 異動

必須修改裝置的 KeyMint 實作,才能支援 TAG_STORAGE_KEY,並導入 convertStorageKeyToEphemeral 方法。

在 Keymaster 中,系統使用的是 exportKey convertStorageKeyToEphemeral

Linux kernel 變更

必須修改裝置內嵌加密引擎的 Linux 核心驅動程式 可支援硬體包裝的金鑰

對於 android14 以上核心, 設定BLK_CRYPTO_KEY_TYPE_HW_WRAPPED 位於blk_crypto_profile::key_types_supported, CANNOT TRANSLATEblk_crypto_ll_ops::keyslot_programblk_crypto_ll_ops::keyslot_evict 支援程式設計/撤銷硬體包裝金鑰; 並實作 blk_crypto_ll_ops::derive_sw_secret

對於 android12android13 核心, 設定BLK_CRYPTO_FEATURE_WRAPPED_KEYS 位於blk_keyslot_manager::features, CANNOT TRANSLATEblk_ksm_ll_ops::keyslot_programblk_ksm_ll_ops::keyslot_evict 支援程式設計/撤銷硬體包裝金鑰; 並實作 blk_ksm_ll_ops::derive_raw_secret

對於 android11 核心, 設定BLK_CRYPTO_FEATURE_WRAPPED_KEYS 位於keyslot_manager::features, CANNOT TRANSLATEkeyslot_mgmt_ll_ops::keyslot_programkeyslot_mgmt_ll_ops::keyslot_evict 支援程式設計/撤銷硬體包裝金鑰; 並實作 keyslot_mgmt_ll_ops::derive_raw_secret

測試

雖然使用硬體包裝的金鑰加密會比加密更難測試 您可以匯入測試金鑰 重新實作硬體確實執行的關鍵衍生工具在這個 在 vts_kernel_encryption_test 中。如要執行這項測試 執行:

atest -v vts_kernel_encryption_test

閱讀測試記錄,並驗證硬體包裝的主要測試案例 (例如 「FBEPolicyTest.TestAesInlineCryptOptimizedHwWrappedKeyPolicy」和 DmDefaultKeyTest.TestHwWrappedKey) 提供支援,因此並未略過 測試失敗,因為測試結果仍會 「通過」在此情況下

啟用中

一旦裝置的硬體包裝金鑰支援功能正常運作,您就可以 對裝置的 fstab 檔案進行下列變更 Android 用來加密 FBE 和中繼資料:

  • FBE:將 wrappedkey_v0 標記新增至 fileencryption 參數。舉例來說,請使用 fileencryption=::inlinecrypt_optimized+wrappedkey_v0。適用對象 如需更多詳細資料,請參閱 FBE 說明文件
  • 中繼資料加密:將 wrappedkey_v0 標記新增至 metadata_encryption 參數。舉例來說,請使用 metadata_encryption=:wrappedkey_v0。詳情請參閱 中繼資料 加密說明文件