中繼資料加密

支援 Android 7.0 以上版本 檔案型加密 (FBE)。FBE 可讓您使用可以解鎖的不同金鑰來加密不同的檔案 以便獨立作業這些金鑰可用於加密檔案內容和檔案名稱。 使用 FBE 時,其他資訊如目錄版面配置、檔案大小 權限,以及建立/修改時間都不會加密。我們將 這些其他資訊稱為「檔案系統中繼資料」。

Android 9 開始支援中繼資料加密。 透過中繼資料加密,開機時當下的單一金鑰會加密任何項目 內容並未由 FBE 加密。這組金鑰受 Keymaster 保護, 會由驗證開機程序保護。

啟用 FBE 時,一律在採用儲存空間中啟用中繼資料加密。 您也可以在內部儲存空間啟用中繼資料加密。啟動的裝置數 搭載 Android 11 以上版本,必須對中繼資料加密 已啟用內部儲存空間

在內部儲存空間實作

您可以在新裝置的內部儲存空間上設定中繼資料加密,步驟如下: 設定 metadata 檔案系統、變更 init 序列,以及 在裝置的 fstab 檔案中啟用中繼資料加密。

必要條件

必須先將資料分區,才能設定中繼資料加密 格式化。因此,這項功能僅適用於新裝置。這不是 OTA 應該變更。

中繼資料加密要求 dm-default-key 模組必須是 已在核心中啟用在 Android 11 以上版本中, Android 通用核心版本支援 dm-default-key 4.14 以及更高版本。這個 dm-default-key 版本使用了硬體, 廠商獨立加密的架構,稱為 blk-crypto

如要啟用 dm-default-key,請使用:

CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y
CONFIG_DM_DEFAULT_KEY=y

dm-default-key 使用內嵌加密硬體 (符合以下條件的硬體) 在資料傳輸至儲存裝置中,或從儲存裝置傳輸資料時,於 廣告。如果您「不會」使用內嵌加密硬體,那麼 啟用退回核心密碼編譯 API 的替代方案:

CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y

不使用內嵌加密硬體時,您也應啟用所有可用的 FBE 說明文件中建議以 CPU 為基礎的加速功能。

在 Android 10 以下版本中,dm-default-key 則不受 Android 通用核心支援因此,供應商可以自行決定 實作 dm-default-key

設定中繼資料檔案系統

因為在中繼資料前,一律無法讀取使用者資料分區中的內容 當存在加密金鑰,分區表必須將 名為「中繼資料分區」儲存金鑰的 blob 確保這組金鑰安全無虞中繼資料分區應為 16MB。

fstab.hardware 必須包含中繼資料檔案系統的項目 掛接於該分區上,包括掛接到 /metadata formattable 標記,以確保在啟動時格式化。 f2fs 檔案系統不適用於較小的分區;建議使用 ext4 。例如:

/dev/block/bootdevice/by-name/metadata              /metadata          ext4        noatime,nosuid,nodev,discard                          wait,check,formattable

為確保 /metadata 掛接點確實存在,請新增下列這一行 至 BoardConfig-common.mk

BOARD_USES_METADATA_PARTITION := true

init 序列的變更

使用中繼資料加密時,必須先執行 vold /data 已掛接。為確保初期要求能提早開始,請新增 下列片段給 init.hardware.rc

# We need vold early for metadata encryption
on early-fs
    start vold

init 必須先在執行中並準備就緒,才能在 init 嘗試掛接 /data

init.hardware.rc 中應該已經包含 mount_all 指示將 /data 本身掛接在 on late-fs 節中。在這個行前,新增指令以執行 wait_for_keymaster 服務:

on late-fs
    
    # Wait for keymaster
    exec_start wait_for_keymaster

    # Mount RW partitions which need run fsck
    mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --late

啟用中繼資料加密功能

最後將 keydirectory=/metadata/vold/metadata_encryption 新增至 以下項目的 fstab 項目 fs_mgr_flags 資料欄: userdata。例如,完整的 fstab 行看起來可能像這樣:

/dev/block/bootdevice/by-name/userdata              /data              f2fs        noatime,nosuid,nodev,discard,inlinecrypt latemount,wait,check,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized,keydirectory=/metadata/vold/metadata_encryption,quota,formattable

根據預設,內部儲存空間的中繼資料加密演算法為 AES-256-XTS。如要覆寫這項設定,請設定 metadata_encryption 選項,也包含在 fs_mgr_flags 資料欄:

  • 在不支援 AES 加速的裝置上,Adiantum 加密 透過設定 metadata_encryption=adiantum 即可啟用。
  • 在支援硬體包裝金鑰的裝置上, 對中繼資料加密金鑰 metadata_encryption=aes-256-xts:wrappedkey_v0 (或 等於 metadata_encryption=:wrappedkey_v0aes-256-xts 是預設演算法)。

因為 Android 中 dm-default-key 的核心介面已變更 11,您還必須確保 正確的PRODUCT_SHIPPING_API_LEVELdevice.mk。舉例來說,如果裝置啟動時搭載的是 Android 11 (API 級別 30),device.mk 應 包含:

PRODUCT_SHIPPING_API_LEVEL := 30

你也可以設定下列系統屬性,強制使用新的 dm-default-key API (無論運送 API 級別為何):

PRODUCT_PROPERTY_OVERRIDES += \
    ro.crypto.dm_default_key.options_format.version=2

驗證

如要驗證中繼資料加密功能是否已啟用且可正常運作,請執行 測試。也請留意一般的 問題 (請參閱下方說明)。

測試

請先執行下列指令,確認中繼資料加密是否 在內部儲存空間上啟用:

adb root
adb shell dmctl table userdata

畫面上應該會顯示類似以下的輸出內容:

Targets in the device-mapper table for userdata:
0-4194304: default-key, aes-xts-plain64 - 0 252:2 0 3 allow_discards sector_size:4096 iv_large_sectors

如果您透過設定 裝置 fstab 中的metadata_encryption選項,然後 輸出內容會稍有不同舉例來說,如果您啟用 Adiantum 加密,則第三個 欄位將會是 xchacha12,aes-adiantum-plain64,而不是 aes-xts-plain64

接著,執行 vts_kernel_encryption_test ,驗證中繼資料加密和 FBE 的正確性:

atest vts_kernel_encryption_test

或:

vts-tradefed run vts -m vts_kernel_encryption_test

常見問題

呼叫 mount_all 時,該容器會掛接中繼資料加密 /data 分區,init 會執行 vdc 工具。vDC 工具會透過 binder 連線至 vold,以設定 並掛接分區。在這個情境中 呼叫,init 遭到封鎖,嘗試讀取或設定 init 屬性會遭到封鎖,直到 mount_all 結束為止。 如果在這個階段,vold 作業的任何部分直接或 間接阻擋他人讀取或設定資源,就會造成死結。是 請務必確保 vold 可完成讀取作業 存取 Keymaster 及掛接資料目錄,而沒有 進一步與 init 互動

如果 mount_all 執行時未完全啟動 Keymaster,則不會 回應 vold 直到它讀到 init,因此可確切導致說明的死結。位置 高於相關門檻的 exec_start wait_for_keymaster 設定 mount_all 叫用,確保 Keymaster 已完整 所以可以避免這個死結

採用可採用儲存空間的設定

從 Android 9 開始,這種中繼資料加密方式為 一律在採用儲存空間上啟用 啟用 FBE 時 (即使未啟用中繼資料加密功能) 內部儲存空間

在 Android 開放原始碼計畫中,採用中繼資料加密機制有兩種實作方式 storage:依據 dm-crypt 淘汰的項目,再依據更新的版本 在 dm-default-key。為了確保正確實作 請確定您已為裝置設定正確的值 PRODUCT_SHIPPING_API_LEVELdevice.mk。例如: 如果您的裝置搭載 Android 11 (API 級別 30), device.mk 應包含:

PRODUCT_SHIPPING_API_LEVEL := 30

你也可以設定下列系統屬性,強制使用新的 磁碟區中繼資料加密方法 (以及新的預設 FBE 政策版本) ,無論運送 API 級別為何:

PRODUCT_PROPERTY_OVERRIDES += \
    ro.crypto.volume.metadata.method=dm-default-key \
    ro.crypto.dm_default_key.options_format.version=2 \
    ro.crypto.volume.options=::v2

目前方法

在搭載 Android 11 以上版本的裝置上 在採用的儲存空間中對中繼資料加密時,會使用 dm-default-key 核心模組,就像內部儲存空間一樣。瞭解核心設定的必要條件。 選項。請注意, 裝置的內部儲存空間可能無法在採用的儲存體上無法使用, 可能需要 CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y

根據預設,dm-default-key 磁碟區中繼資料加密方法 採用 AES-256-XTS 加密演算法和 4096 位元組加密編譯。 只要設定 ro.crypto.volume.metadata.encryption 系統屬性。這個 屬性值的語法與 metadata_encryption 相同 Fstab 選項。舉例來說,若裝置不支援 AES 加速、Adiantum 加密 可以透過設定啟用 ro.crypto.volume.metadata.encryption=adiantum

舊版方法

在搭載 Android 10 以下版本的裝置上,中繼資料 採用型儲存空間上的加密功能會使用 dm-crypt 核心模組 而不是 dm-default-key

CONFIG_DM_CRYPT=y

dm-default-key 方法不同,dm-crypt 方法 會使檔案內容被加密兩次:一次使用 FBE 金鑰,另一次是使用 中繼資料加密金鑰這種雙重加密機制會降低效能, 不必達到中繼資料加密機制的安全性目標。自 Android 級別起, 確保 FBE 金鑰至少和中繼資料一樣不易入侵 加密金鑰供應商可自訂核心來避免重複 尤其是實作 allow_encrypt_override 選項,Android 會傳入 系統屬性為 dm-crypt ro.crypto.allow_encrypt_override已設為 true。 Android 通用核心不支援這些自訂項目。

根據預設,dm-crypt 磁碟區中繼資料加密方法會使用 採用 ESSIV 和 512 位元組加密編譯的 AES-128-CBC 加密演算法。這個 如要覆寫,請設定下列系統屬性 用於 FDE):

  • ro.crypto.fde_algorithm會選取中繼資料加密功能 演算法。選項包括 aes-128-cbcadiantumAdiantum 僅限使用 裝置缺少 AES 加速功能。
  • ro.crypto.fde_sector_size 會選取加密部門大小。 選項包括 512、1024、2048 和 4096。如需 Adiantum 加密,請使用 4096。