元數據加密

Android的7.0和更高版本支持基於文件的加密(FBE)。 FBE 允許使用可以獨立解鎖的不同密鑰加密不同的文件。這些密鑰用於加密文件內容和文件名。使用 FBE 時,其他信息(例如目錄佈局、文件大小、權限和創建/修改時間)不會加密。這些其他信息統稱為文件系統元數據。

Android 9 引入了對元數據加密的支持。使用元數據加密,啟動時存在的單個密鑰可以加密 FBE 未加密的任何內容。此密鑰受 Keymaster 保護,而後者又受已驗證啟動的保護。

元數據加密總是啟用可採用存儲每當啟用FBE。也可以在內部存儲上啟用元數據加密。搭載 Android 11 或更高版本的設備必須在內部存儲上啟用元數據加密。

在內部存儲上的實現

您可以通過設置成立了新設備的內部存儲元數據加密的metadata文件系統,改變了初始化序列,並使得在設備的fstab文件元數據加密。

先決條件

只有在第一次格式化數據分區時才能設置元數據加密。因此,此功能僅適用於新設備;這不是 OTA 應該改變的事情。

元數據加密要求dm-default-key模塊在內核中啟用。在Android中11及以上, dm-default-key是由Android的共同內核,版本4.14或更高版本支持。這個版本的dm-default-key使用硬件和獨立於供應商的加密框架調用BLK-加密

為了使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

當不使用內嵌硬件加密還應啟用任何可用的基於CPU的加速度中推薦的FBE文檔

在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試圖安裝前準備/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到的fs_mgr_flagsfstab入境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加速設備,鐵線蕨加密可以通過設置來啟用metadata_encryption=adiantum
  • 的裝置上支持硬件包裹密鑰,元數據的加密密鑰可以由硬件包裹通過設置metadata_encryption=aes-256-xts:wrappedkey_v0 (或等效metadata_encryption=:wrappedkey_v0 ,如aes-256-xts是默認算法)。

由於內核接口dm-default-key在Android的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

如果你推翻通過設置默認的加密設置metadata_encryption在設備的選擇fstab ,則輸出將略微不同於上述。例如,如果啟用了鐵線蕨加密,那麼第三場將是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的工具連接到voldbinder來設置元數據的加密設備和安裝的分區。對於此呼叫的持續時間, init被阻塞,並嘗試要么讀取或設置init屬性將阻塞,直到mount_all飾面。如果,在這個階段,任何部分vold直接或間接地阻斷上讀取或設置一個屬性的工作,死鎖將導致。以確保它是重要vold可以完成讀取鑰匙,用鑰匙大師互動,並安裝數據目錄中的工作,而與另一個交互init

如果當鑰匙大師沒有完全啟動mount_all運行時,它不會作出回應vold直到它讀取某些屬性init ,導致完全僵局描述。配售exec_start wait_for_keymaster上述相關mount_all調用所載確保鑰匙大師完全提前運行的,因此避免了這種僵局。

可採用存儲的配置

由於Android 9元數據加密的窗體上總是使能的可採用的存儲每當使能FBE,甚至當在內部儲存空間未啟用元數據加密。

在AOSP,還有對存儲可採用元數據加密兩種實現:基於已經被廢棄的一個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體積元數據加密方法使用具有4096字節的加密扇區中的AES-256-XTS加密算法。該算法可以通過設置覆蓋ro.crypto.volume.metadata.encryption系統屬性。此屬性值具有相同的語法metadata_encryption上述fstab中的選項。例如,在缺乏AES加速設備,鐵線蕨加密可以通過設置使能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-cbcadiantum鐵線可以僅當設備缺少AES加速度使用。
  • ro.crypto.fde_sector_size選擇加密扇區大小。選項為 512、1024、2048 和 4096。對於 Adiantum 加密,請使用 4096。