基於文件的加密

Android 7.0 及更高版本支持基於文件的加密 (FBE)。基於文件的加密允許使用不同的密鑰對不同的文件進行加密,這些密鑰可以獨立解鎖。

本文介紹如何在新設備上啟用基於文件的加密,以及系統應用程序如何使用直接啟動 API 為用戶提供最佳、最安全的體驗。

所有搭載 Android 10 及更高版本的設備都需要使用基於文件的加密。

直接啟動

基於文件的加密啟用了 Android 7.0 中引入的一項稱為“直接啟動”的新功能。直接啟動允許加密設備直接啟動至鎖定屏幕。以前,在使用全盤加密(FDE) 的加密設備上,用戶需要提供憑據才能訪問任何數據,從而導致手機無法執行除最基本的操作之外的所有操作。例如,警報無法運行,無障礙服務無法使用,電話無法接聽電話,但僅限於基本的緊急撥號器操作。

隨著基於文件的加密 (FBE) 和新 API 的引入,使應用程序能夠感知加密,這些應用程序可以在有限的上下文中運行。這可能發生在用戶提供憑據之前,同時仍然保護私人用戶信息。

在啟用 FBE 的設備上,設備的每個用戶都有兩個可供應用程序使用的存儲位置:

  • 憑證加​​密 (CE) 存儲,這是默認存儲位置,僅在用戶解鎖設備後才可用。
  • 設備加密 (DE) 存儲,這是在直接啟動模式期間和用戶解鎖設備後都可用的存儲位置。

這種分離使工作配置文件更加安全,因為加密不再僅基於啟動時密碼,因此一次可以保護多個用戶。

直接啟動 API 允許加密感知應用程序訪問每個區域。應用程序生命週期發生了一些變化,以滿足在用戶的 CE 存儲響應於在鎖定屏幕上首次輸入憑據而解鎖時通知應用程序的需要,或者在工作配置文件提供工作挑戰的情況下。運行 Android 7.0 的設備必須支持這些新的 API 和生命週期,無論它們是否實現 FBE。雖然,沒有FBE,DE和CE存儲將始終處於解鎖狀態。

Android 開源項目 (AOSP) 提供了 Ext4 和 F2FS 文件系統上基於文件的加密的完整實現,並且只需在滿足要求的設備上啟用。選擇使用 FBE 的製造商可能希望探索根據所使用的片上系統 (SoC) 優化功能的方法。

AOSP 中所有必需的軟件包均已更新為可直接啟動。但是,如果設備製造商使用這些應用程序的自定義版本,他們將希望確保至少有直接啟動感知包提供以下服務:

  • 電話服務和撥號器
  • 鎖屏輸入密碼的輸入法

示例和來源

Android 提供了基於文件的加密的參考實現,其中 vold ( system/vold ) 提供了在 Android 上管理存儲設備和卷的功能。 FBE的加入為vold提供了多個新命令,支持對多個用戶的CE和DE密鑰進行密鑰管理。除了使用內核中基於文件的加密功能的核心更改之外,包括鎖屏和 SystemUI 在內的許多系統軟件包也已修改為支持 FBE 和直接啟動功能。這些包括:

  • AOSP 撥號器(包/應用程序/撥號器)
  • 桌面時鐘(程序包/應用程序/DeskClock)
  • LatinIME(包/輸入法/LatinIME)*
  • 設置應用程序(包/應用程序/設置)*
  • SystemUI(框架/基礎/包/SystemUI)*

* 使用defaultToDeviceProtectedStorage清單屬性的系統應用程序

通過在 AOSP 源代碼樹的框架或包目錄中運行命令mangrep directBootAware可以找到更多加密感知應用程序和服務的示例。

依賴關係

為了安全地使用 FBE 的 AOSP 實現,設備需要滿足以下依賴關係:

  • 內核支持Ext4 加密或 F2FS 加密。
  • Keymaster 支持HAL 版本 1.0 或更高版本。不支持 Keymaster 0.3,因為它不提供必要的功能或確保對加密密鑰提供足夠的保護。
  • Keymaster/ Keystore和 Gatekeeper必須在可信執行環境(TEE) 中實現,以便為DE 密鑰提供保護,以便未經授權的操作系統(閃存到設備上的自定義操作系統)無法簡單地請求DE 密鑰。
  • 需要綁定到 Keymaster 初始化的硬件信任根驗證啟動,以確保未經授權的操作系統無法訪問 DE 密鑰。

執行

首先,鬧鐘、電話和輔助功能等應用程序應根據直接啟動開發人員文檔製作為 android:directBootAware。

內核支持

Android 通用內核版本 3.18 及更高版本中提供了對 Ext4 和 F2FS 加密的內核支持。要在 5.1 或更高版本的內核中啟用它,請使用:

CONFIG_FS_ENCRYPTION=y

對於較舊的內核,如果您的設備的userdata文件系統是 Ext4,請使用CONFIG_EXT4_ENCRYPTION=y ;如果您的設備的userdata文件系統是 F2FS,請使用CONFIG_F2FS_FS_ENCRYPTION=y

如果您的設備支持可採用存儲或將在內部存儲上使用元數據加密,還請啟用元數據加密所需的內核配置選項,如元數據加密文檔中所述。

除了對 Ext4 或 F2FS 加密的功能支持外,設備製造商還應啟用加密加速,以加快基於文件的加密速度並改善用戶體驗。例如,在基於 ARM64 的設備上,可以通過設置以下內核配置選項來啟用 ARMv8 CE(加密擴展)加速:

CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_SHA2_ARM64_CE=y

為了進一步提高性能並降低功耗,設備製造商還可以考慮實施內聯加密硬件,該硬件在數據傳入/傳出存儲設備時對數據進行加密/解密。 Android 通用內核(版本 4.14 及更高版本)包含一個框架,允許在硬件和供應商驅動程序支持可用時使用內聯加密。可以通過設置以下內核配置選項來啟用內聯加密框架:

CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y

如果您的設備使用基於 UFS 的存儲,還需啟用:

CONFIG_SCSI_UFS_CRYPTO=y

如果您的設備使用基於 eMMC 的存儲,還需啟用:

CONFIG_MMC_CRYPTO=y

啟用基於文件的加密

在設備上啟用 FBE 需要在內部存儲 ( userdata ) 上啟用它。這還會自動在可採用的存儲上啟用 FBE;但是,如有必要,可採用的存儲上的加密格式可能會被覆蓋。

內部存儲器

通過將選項fileencryption=contents_encryption_mode[:filenames_encryption_mode[:flags]]添加到userdatafstab行的fs_mgr_flags列來啟用 FBE。此選項定義內部存儲上的加密格式。它最多包含三個以冒號分隔的參數:

  • contents_encryption_mode參數定義使用哪種加密算法來加密文件內容。它可以是aes-256-xtsadiantum 。從 Android 11 開始,它也可以留空以指定默認算法,即aes-256-xts
  • filenames_encryption_mode參數定義使用哪種加密算法來加密文件名。它可以是aes-256-ctsaes-256-hehadiantumaes-256-hctr2 。如果未指定,則如果contents_encryption_modeaes-256-cts ,則默認為aes-256-xts ;如果contents_encryption_modeadiantum ,則默認為adiantum
  • flags參數是 Android 11 中的新參數,是由+字符分隔的標誌列表。支持以下標誌:
    • v1標誌選擇版本1加密策略; v2標誌選擇版本 2 加密策略。第2版​​加密策略使用更安全、更靈活的密鑰派生函數。如果設備在 Android 11 或更高版本上啟動(由ro.product.first_api_level確定),則默認值為 v2;如果設備在 Android 10 或更低版本上啟動,則默認值為 v1。
    • inlinecrypt_optimized標誌選擇一種針對無法有效處理大量密鑰的內聯加密硬件進行優化的加密格式。它通過為每個 CE 或 DE 密鑰僅派生一個文件內容加密密鑰(而不是每個文件一個)來實現此目的。 IV(初始化向量)的生成也會相應調整。
    • emmc_optimized標誌與inlinecrypt_optimized類似,但它還選擇將 IV 限制為 32 位的 IV 生成方法。該標誌只能用在符合 JEDEC eMMC v5.2 規範的內聯加密硬件上,因此僅支持 32 位 IV。在其他內聯加密硬件上,請改用inlinecrypt_optimized 。此標誌絕不應在基於 UFS 的存儲上使用; UFS 規範允許使用 64 位 IV。
    • 在支持硬件包裝密鑰的設備上, wrappedkey_v0標誌允許對 FBE 使用硬件包裝密鑰。這只能與inlinecrypt掛載選項以及inlinecrypt_optimizedemmc_optimized標誌結合使用。

如果您不使用內聯加密硬件,則大多數設備的建議設置為fileencryption=aes-256-xts 。如果您使用內聯加密硬件,則大多數設備的建議設置為fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized (或等效的fileencryption=::inlinecrypt_optimized )。在沒有任何形式的 AES 加速的設備上,可以通過設置fileencryption=adiantum來使用Adiantum代替 AES。

自 Android 14(AOSP 實驗版)以來,AES-HCTR2 是具有加速加密指令的設備的首選文件名加密模式。但是,只有較新的 Android 內核支持 AES-HCTR2。在未來的 Android 版本中,計劃成為文件名加密的默認模式。如果您的內核支持 AES-HCTR2,則可以通過將filenames_encryption_mode設置為aes-256-hctr2來啟用文件名加密。在最簡單的情況下,可以使用fileencryption=aes-256-xts:aes-256-hctr2來完成。

在搭載 Android 10 或更低版本的設備上,還接受fileencryption=ice來指定使用FSCRYPT_MODE_PRIVATE文件內容加密模式。 Android 通用內核未實現此模式,但供應商可以使用自定義內核補丁來實現此模式。此模式生成的磁盤格式是特定於供應商的。在搭載 Android 11 或更高版本的設備上,不再允許使用此模式,必須改用標準加密格式。

默認情況下,文件內容加密是使用 Linux 內核的加密 API 完成的。如果您想改用內聯加密硬件,還需添加inlinecrypt掛載選項。例如,完整的fstab行可能如下所示:

/dev/block/by-name/userdata /data f2fs nodev,noatime,nosuid,errors=panic,inlinecrypt wait,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized

可採用的存儲方式

從Android 9開始,FBE和可採用的存儲可以一起使用。

userdata指定fileencryption fstab 選項還會自動在可採用的存儲上啟用 FBE 和元數據加密。但是,您可以通過設置PRODUCT_PROPERTY_OVERRIDES中的屬性來覆蓋可用存儲上的 FBE 和/或元數據加密格式。

在搭載 Android 11 或更高版本的設備上,使用以下屬性:

  • ro.crypto.volume.options (Android 11 中的新增功能)選擇可採用存儲上的 FBE 加密格式。它與fileencryption fstab 選項的參數具有相同的語法,並且使用相同的默認值。有關此處使用的內容,請參閱上面的fileencryption建議。
  • ro.crypto.volume.metadata.encryption選擇可用存儲上的元數據加密格式。請參閱元數據加密文檔

在搭載 Android 10 或更低版本的設備上,使用以下屬性:

  • ro.crypto.volume.contents_mode選擇內容加密模式。這相當於ro.crypto.volume.options的第一個冒號分隔字段。
  • ro.crypto.volume.filenames_mode選擇文件名加密模式。這相當於ro.crypto.volume.options的第二個以冒號分隔的字段,但使用 Android 10 或更低版本啟動的設備上的默認值是aes-256-heh 。在大多數設備上,這需要顯式覆蓋為aes-256-cts
  • ro.crypto.fde_algorithmro.crypto.fde_sector_size選擇可採用存儲上的元數據加密格式。請參閱元數據加密文檔

與 Keymaster 集成

Keymaster HAL 應作為early_hal類的一部分啟動。這是因為 FBE 要求 Keymaster 準備好處理post-fs-data引導階段的請求,此時vold設置初始密鑰。

排除目錄

init系統 DE 密鑰應用於/data的所有頂級目錄,但必須未加密的目錄除外:包含系統 DE 密鑰本身的目錄以及包含用戶 CE 或 DE 目錄的目錄。加密密鑰遞歸應用,並且不能被子目錄覆蓋。

在 Android 11 及更高版本中, init應用於目錄的密鑰可以通過 init 腳本中mkdir命令的encryption=<action>參數來控制。 <action>的可能值記錄在Android init language 的 README中。

在 Android 10 中, init加密操作被硬編碼到以下位置:

/system/extras/libfscrypt/fscrypt_init_extensions.cpp

在 Android 9 及更早版本中,該位置為:

/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp

可以添加例外以防止某些目錄被加密。如果進行此類修改,則設備製造商應包含SELinux 策略,僅授予需要使用未加密目錄的應用程序的訪問權限。這應該排除所有不受信任的應用程序。

唯一已知的可接受的用例是支持舊版 OTA 功能。

支持系統應用程序直接啟動

使應用程序能夠感知直接啟動

為了促進系統應用程序的快速遷移,可以在應用程序級別設置兩個新屬性。 defaultToDeviceProtectedStorage屬性僅適用於系統應用程序。 directBootAware屬性可供所有人使用。

<application
    android:directBootAware="true"
    android:defaultToDeviceProtectedStorage="true">

應用程序級別的directBootAware屬性是將應用程序中的所有組件標記為加密感知的簡寫。

defaultToDeviceProtectedStorage屬性將默認應用程序存儲位置重定向為指向 DE 存儲,而不是指向 CE 存儲。使用此標誌的系統應用程序必須仔細審核存儲在默認位置的所有數據,並更改敏感數據的路徑以使用 CE 存儲。使用此選項的設備製造商應仔細檢查他們存儲的數據,以確保其中不包含個人信息。

在此模式下運行時,以下系統 API 可在需要時顯式管理由 CE 存儲支持的上下文,這相當於其受設備保護的對應項。

  • Context.createCredentialProtectedStorageContext()
  • Context.isCredentialProtectedStorage()

支持多用戶

多用戶環境中的每個用戶都會獲得一個單獨的加密密鑰。每個用戶都有兩個密鑰:DE 密鑰和 CE 密鑰。用戶0必須首先登錄設備,因為它是特殊用戶。這與設備管理用途相關。

加密感知應用程序以這種方式跨用戶交互: INTERACT_ACROSS_USERSINTERACT_ACROSS_USERS_FULL允許應用程序跨設備上的所有用戶進行操作。但是,這些應用程序將只能訪問已解鎖的用戶的 CE 加密目錄。

一個應用程序可能能夠跨 DE 區域自由交互,但一個用戶解鎖並不意味著設備上的所有用戶都解鎖。應用程序應在嘗試訪問這些區域之前檢查此狀態。

每個工作配置文件用戶 ID 還獲得兩個密鑰:DE 和 CE。當工作挑戰得到滿足時,配置文件用戶被解鎖,Keymaster(在 TEE 中)可以提供配置文件的 TEE 密鑰。

處理更新

恢復分區無法訪問用戶數據分區上受 DE 保護的存儲。強烈建議實現 FBE 的設備支持使用A/B 系統更新的OTA。由於 OTA 可以在正常操作期間應用,因此無需恢復即可訪問加密驅動器上的數據。

使用舊版 OTA 解決方案時,需要恢復才能訪問userdata分區上的 OTA 文件:

  1. userdata分區中創建一個頂級目錄(例如misc_ne )。
  2. 將此頂級目錄配置為不加密(請參閱排除目錄)。
  3. 在頂級目錄中創建一個目錄來保存 OTA 包。
  4. 添加 SELinux 規則和文件上下文來控制對此目錄及其內容的訪問。只有接收 OTA 更新的進程或應用程序才應該能夠讀取和寫入此目錄。其他應用程序或進程不應有權訪問此目錄。

驗證

為了確保該功能的實現版本按預期工作,首先運行許多 CTS 加密測試,例如DirectBootHostTestEncryptionTest

如果設備運行的是 Android 11 或更高版本,還需運行vts_kernel_encryption_test

atest vts_kernel_encryption_test

或者:

vts-tradefed run vts -m vts_kernel_encryption_test

此外,設備製造商可能會執行以下手動測試。在啟用了 FBE 的設備上:

  • 檢查ro.crypto.state是否存在
    • 確保ro.crypto.state已加密
  • 檢查ro.crypto.type是否存在
    • 確保ro.crypto.type設置為file

此外,測試人員可以啟動userdebug實例,並在主用戶上設置鎖屏。然後adb shell 進入設備並使用su成為 root。確保/data/data包含加密的文件名;如果沒有,則說明有問題。

還鼓勵設備製造商探索在其設備或內核上運行fscrypt 的上游 Linux 測試。這些測試是 xfstests 文件系統測試套件的一部分。然而,這些上游測試並沒有得到 Android 的官方支持。

AOSP 實施細節

本節提供有關 AOSP 實現的詳細信息,並描述基於文件的加密的工作原理。設備製造商無需在此處進行任何更改即可在其設備上使用 FBE 和直接啟動。

fscrypt 加密

AOSP 實現在內核中使用“fscrypt”加密(受 ext4 和 f2fs 支持),通常配置為:

  • 在 XTS 模式下使用 AES-256 加密文件內容
  • 在 CBC-CTS 模式下使用 AES-256 加密文件名

還支持鐵線蕨加密。啟用 Adiantum 加密後,文件內容和文件名都會使用 Adiantum 進行加密。

fscrypt 支持兩個版本的加密策略:版本 1 和版本 2。版本 1 已棄用,使用 Android 11 及更高版本啟動的設備的 CDD 要求僅與版本 2 兼容。版本 2 加密策略使用HKDF-SHA512派生實際的加密策略來自用戶空間提供的密鑰的加密密鑰。

有關 fscrypt 的更多信息,請參閱上游內核文檔

存儲類別

下表更詳細地列出了 FBE 密鑰及其保護的目錄:

存儲等級描述目錄
系統DE設備加密數據不與特定用戶綁定/data/system/data/app以及/data的其他各種子目錄
每次啟動不需要在重新啟動後繼續存在的臨時系統文件/data/per_boot
用戶CE(內部)內部存儲上的每用戶憑證加密數據
  • /data/data/data/user/0的別名)
  • /data/media/${user_id}
  • /data/misc_ce/${user_id}
  • /data/system_ce/${user_id}
  • /data/user/${user_id}
  • /data/vendor_ce/${user_id}
用戶 DE(內部)內部存儲上的每用戶設備加密數據
  • /data/misc_de/${user_id}
  • /data/system_de/${user_id}
  • /data/user_de/${user_id}
  • /data/vendor_de/${user_id}
用戶CE(可採用)可採用存儲上的每用戶憑證加密數據
  • /mnt/expand/${volume_uuid}/media/${user_id}
  • /mnt/expand/${volume_uuid}/misc_ce/${user_id}
  • /mnt/expand/${volume_uuid}/user/${user_id}
用戶DE(可採用)可採用存儲上的每用戶設備加密數據
  • /mnt/expand/${volume_uuid}/misc_de/${user_id}
  • /mnt/expand/${volume_uuid}/user_de/${user_id}

密鑰存儲和保護

所有 FBE 密鑰均由vold管理,並加密存儲在磁盤上,但根本不存儲的每次啟動密鑰除外。下表列出了各種 FBE 密鑰的存儲位置:

鑰匙類型關鍵位置關鍵位置存儲類別
系統DE密鑰/data/unencrypted未加密
用戶 CE(內部)密鑰/data/misc/vold/user_keys/ce/${user_id}系統DE
用戶 DE(內部)密鑰/data/misc/vold/user_keys/de/${user_id}系統DE
用戶 CE(可採用)密鑰/data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid}用戶CE(內部)
用戶 DE(可採用)密鑰/data/misc_de/${user_id}/vold/volume_keys/${volume_uuid}用戶 DE(內部)

如上表所示,大多數 FBE 密鑰存儲在由另一個 FBE 密鑰加密的目錄中。在包含密鑰的存儲類被解鎖之前,密鑰無法被解鎖。

vold還對所有 FBE 密鑰應用一層加密。除用於內部存儲的 CE 密鑰外,每個密鑰均使用其自己的密鑰庫密鑰通過 AES-256-GCM 進行加密,該密鑰不會暴露在 TEE 之外。這可確保除非受信任的操作系統已啟動(由驗證啟動強制執行),否則無法解鎖 FBE 密鑰。 Keystore 密鑰還要求具有回滾阻力,這樣可以在 Keymaster 支持回滾阻力的設備上安全地刪除 FBE 密鑰。作為回滾阻力不可用時的盡力後備,存儲在與密鑰一起存儲的secdiscardable文件中的 16384 個隨機字節的 SHA-512 哈希值用作密鑰庫密鑰的應用程序 ID 標記。需要恢復所有這些字節才能恢復 FBE 密鑰。

用於內部存儲的 CE 密鑰獲得更強級別的保護,確保在不知道用戶的鎖屏知識因素 (LSKF) (PIN、圖案或密碼)、安全密碼重置令牌或客戶端的情況下無法解鎖它們以及用於“重新啟動時恢復”操作的服務器端密鑰。僅允許為工作配置文件完全託管的設備創建密碼重置令牌。

為了實現這一點, vold使用從用戶合成密碼派生的 AES-256-GCM 密鑰對用於內部存儲的每個 CE 密鑰進行加密。合成密碼是為每個用戶隨機生成的不可變的高熵加密秘密。 system_server中的LockSettingsService管理合成密碼及其保護方式。

為了使用 LSKF 保護合成密碼, LockSettingsService首先通過scrypt傳遞 LSKF 來擴展 LSKF,目標時間約為 25 毫秒,內存使用量約為 2 MiB。由於 LSKF 通常很短,因此此步驟通常不能提供太多安全性。主要的安全層是安全元件 (SE)或 TEE 強制速率限制,如下所述。

如果設備具有安全元件 (SE),則LockSettingsService使用Wea​​ver HAL將延伸的 LSKF 映射到存儲在 SE 中的高熵隨機秘密。然後, LockSettingsService對合成密碼進行兩次加密:第一次使用從延伸的 LSKF 和 Weaver 密鑰派生的軟件密鑰,第二次使用非身份驗證綁定的密鑰庫密鑰。這提供了 SE 強制的 LSKF 猜測速率限制。

如果設備沒有 SE,則LockSettingsService會使用延伸的 LSKF 作為Gatekeeper密碼。然後, LockSettingsService對合成密碼進行兩次加密:第一次使用從延伸的LSKF 和可秒丟棄文件的哈希派生的軟件密鑰,第二次使用與Gatekeeper 註冊進行身份驗證綁定的密鑰庫密鑰。這提供了 LSKF 猜測的 TEE 強制速率限制。

當 LSKF 更改時, LockSettingsService會刪除與合成密碼與舊 LSKF 的綁定相關的所有信息。在支持 Weaver 或防回滾密鑰庫密鑰的設備上,這可以保證舊綁定的安全刪除。因此,即使用戶沒有 LSKF,也會應用此處描述的保護。

,

Android 7.0 及更高版本支持基於文件的加密 (FBE)。基於文件的加密允許使用不同的密鑰對不同的文件進行加密,這些密鑰可以獨立解鎖。

本文介紹如何在新設備上啟用基於文件的加密,以及系統應用程序如何使用直接啟動 API 為用戶提供最佳、最安全的體驗。

所有搭載 Android 10 及更高版本的設備都需要使用基於文件的加密。

直接啟動

基於文件的加密啟用了 Android 7.0 中引入的一項稱為“直接啟動”的新功能。直接啟動允許加密設備直接啟動至鎖定屏幕。以前,在使用全盤加密(FDE) 的加密設備上,用戶需要提供憑據才能訪問任何數據,從而導致手機無法執行除最基本的操作之外的所有操作。例如,警報無法運行,無障礙服務無法使用,電話無法接聽電話,但僅限於基本的緊急撥號器操作。

隨著基於文件的加密 (FBE) 和新 API 的引入,使應用程序能夠感知加密,這些應用程序可以在有限的上下文中運行。這可能發生在用戶提供憑據之前,同時仍然保護私人用戶信息。

在啟用 FBE 的設備上,設備的每個用戶都有兩個可供應用程序使用的存儲位置:

  • 憑證加​​密 (CE) 存儲,這是默認存儲位置,僅在用戶解鎖設備後才可用。
  • 設備加密 (DE) 存儲,這是在直接啟動模式期間和用戶解鎖設備後都可用的存儲位置。

這種分離使工作配置文件更加安全,因為加密不再僅基於啟動時密碼,因此一次可以保護多個用戶。

直接啟動 API 允許加密感知應用程序訪問每個區域。應用程序生命週期發生了一些變化,以滿足在用戶的 CE 存儲響應於在鎖定屏幕上首次輸入憑據而解鎖時通知應用程序的需要,或者在工作配置文件提供工作挑戰的情況下。運行 Android 7.0 的設備必須支持這些新的 API 和生命週期,無論它們是否實現 FBE。雖然,沒有FBE,DE和CE存儲將始終處於解鎖狀態。

Android 開源項目 (AOSP) 提供了 Ext4 和 F2FS 文件系統上基於文件的加密的完整實現,並且只需在滿足要求的設備上啟用。選擇使用 FBE 的製造商可能希望探索根據所使用的片上系統 (SoC) 優化功能的方法。

AOSP 中所有必需的軟件包均已更新為可直接啟動。但是,如果設備製造商使用這些應用程序的自定義版本,他們將希望確保至少有直接啟動感知包提供以下服務:

  • 電話服務和撥號器
  • 鎖屏輸入密碼的輸入法

示例和來源

Android 提供了基於文件的加密的參考實現,其中 vold ( system/vold ) 提供了在 Android 上管理存儲設備和卷的功能。 FBE的加入為vold提供了多個新命令,支持對多個用戶的CE和DE密鑰進行密鑰管理。除了使用內核中基於文件的加密功能的核心更改之外,包括鎖屏和 SystemUI 在內的許多系統軟件包也已修改為支持 FBE 和直接啟動功能。這些包括:

  • AOSP 撥號器(包/應用程序/撥號器)
  • 桌面時鐘(程序包/應用程序/DeskClock)
  • LatinIME(包/輸入法/LatinIME)*
  • 設置應用程序(包/應用程序/設置)*
  • SystemUI(框架/基礎/包/SystemUI)*

* 使用defaultToDeviceProtectedStorage清單屬性的系統應用程序

通過在 AOSP 源代碼樹的框架或包目錄中運行命令mangrep directBootAware可以找到更多加密感知應用程序和服務的示例。

依賴關係

為了安全地使用 FBE 的 AOSP 實現,設備需要滿足以下依賴關係:

  • 內核支持Ext4 加密或 F2FS 加密。
  • HAL 版本 1.0 或更高版本的Keymaster 支持。不支持 Keymaster 0.3,因為它不提供必要的功能或確保對加密密鑰提供足夠的保護。
  • Keymaster/ Keystore和 Gatekeeper必須在可信執行環境(TEE) 中實現,以便為DE 密鑰提供保護,以便未經授權的操作系統(閃存到設備上的自定義操作系統)無法簡單地請求DE 密鑰。
  • 需要綁定到 Keymaster 初始化的硬件信任根驗證啟動,以確保未經授權的操作系統無法訪問 DE 密鑰。

執行

首先,鬧鐘、電話和輔助功能等應用程序應根據直接啟動開發人員文檔製作為 android:directBootAware。

內核支持

Android 通用內核版本 3.18 及更高版本中提供了對 Ext4 和 F2FS 加密的內核支持。要在 5.1 或更高版本的內核中啟用它,請使用:

CONFIG_FS_ENCRYPTION=y

對於較舊的內核,如果您的設備的userdata文件系統是 Ext4,請使用CONFIG_EXT4_ENCRYPTION=y ;如果您的設備的userdata文件系統是 F2FS,請使用CONFIG_F2FS_FS_ENCRYPTION=y

如果您的設備支持可採用存儲或將在內部存儲上使用元數據加密,還請啟用元數據加密所需的內核配置選項,如元數據加密文檔中所述。

除了對 Ext4 或 F2FS 加密的功能支持外,設備製造商還應啟用加密加速,以加快基於文件的加密速度並改善用戶體驗。例如,在基於 ARM64 的設備上,可以通過設置以下內核配置選項來啟用 ARMv8 CE(加密擴展)加速:

CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_SHA2_ARM64_CE=y

To further improve performance and reduce power usage, device manufacturers may also consider implementing inline encryption hardware , which encrypts/decrypts the data while it is on the way to/from the storage device. The Android common kernels (version 4.14 and higher) contain a framework that allows inline encryption to be used when hardware and vendor driver support is available. The inline encryption framework can be enabled by setting the following kernel configuration options:

CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y

If your device uses UFS-based storage, also enable:

CONFIG_SCSI_UFS_CRYPTO=y

If your device uses eMMC-based storage, also enable:

CONFIG_MMC_CRYPTO=y

Enabling file-based encryption

Enabling FBE on a device requires enabling it on the internal storage ( userdata ). This also automatically enables FBE on adoptable storage; however, the encryption format on adoptable storage may be overridden if necessary.

Internal storage

FBE is enabled by adding the option fileencryption=contents_encryption_mode[:filenames_encryption_mode[:flags]] to the fs_mgr_flags column of the fstab line for userdata . This option defines the encryption format on internal storage. It contains up to three colon-separated parameters:

  • The contents_encryption_mode parameter defines which cryptographic algorithm is used to encrypt file contents. It can be either aes-256-xts or adiantum . Since Android 11 it can also be left empty to specify the default algorithm, which is aes-256-xts .
  • The filenames_encryption_mode parameter defines which cryptographic algorithm is used to encrypt file names. It can be either aes-256-cts , aes-256-heh , adiantum , or aes-256-hctr2 . If not specified, it defaults to aes-256-cts if contents_encryption_mode is aes-256-xts , or to adiantum if contents_encryption_mode is adiantum .
  • The flags parameter, new in Android 11, is a list of flags separated by the + character. The following flags are supported:
    • The v1 flag selects version 1 encryption policies; the v2 flag selects version 2 encryption policies. Version 2 encryption policies use a more secure and flexible key derivation function . The default is v2 if the device launched on Android 11 or higher (as determined by ro.product.first_api_level ), or v1 if the device launched on Android 10 or lower.
    • The inlinecrypt_optimized flag selects an encryption format that is optimized for inline encryption hardware that doesn't handle large numbers of keys efficiently. It does this by deriving just one file contents encryption key per CE or DE key, rather than one per file. The generation of IVs (initialization vectors) is adjusted accordingly.
    • The emmc_optimized flag is similar to inlinecrypt_optimized , but it also selects an IV generation method that limits IVs to 32 bits. This flag should only be used on inline encryption hardware that is compliant with the JEDEC eMMC v5.2 specification and therefore supports only 32-bit IVs. On other inline encryption hardware, use inlinecrypt_optimized instead. This flag should never be used on UFS-based storage; the UFS specification allows the use of 64-bit IVs.
    • On devices that support hardware-wrapped keys , the wrappedkey_v0 flag enables the use of hardware-wrapped keys for FBE. This can only be used in combination with the inlinecrypt mount option, and either the inlinecrypt_optimized or emmc_optimized flag.

If you aren't using inline encryption hardware the recommended setting for most devices is fileencryption=aes-256-xts . If you are using inline encryption hardware the recommended setting for most devices is fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized (or equivalently fileencryption=::inlinecrypt_optimized ). On devices without any form of AES acceleration, Adiantum may be used instead of AES by setting fileencryption=adiantum .

Since Android 14 (AOSP experimental), AES-HCTR2 is the preferred mode of filenames encryption for devices with accelerated cryptography instructions. However, only newer Android kernels support AES-HCTR2. In a future Android release, it is planned to become the default mode for filenames encryption. If your kernel has AES-HCTR2 support, it can be enabled for filenames encryption by setting filenames_encryption_mode to aes-256-hctr2 . In the simplest case this would be done with fileencryption=aes-256-xts:aes-256-hctr2 .

On devices that launched with Android 10 or lower, fileencryption=ice is also accepted to specify the use of the FSCRYPT_MODE_PRIVATE file contents encryption mode. This mode is unimplemented by the Android common kernels, but it could be implemented by vendors using custom kernel patches. The on-disk format produced by this mode was vendor-specific. On devices launching with Android 11 or higher, this mode is no longer allowed and a standard encryption format must be used instead.

By default, file contents encryption is done using the Linux kernel's cryptography API. If you want to use inline encryption hardware instead, also add the inlinecrypt mount option. For example, a full fstab line might look like:

/dev/block/by-name/userdata /data f2fs nodev,noatime,nosuid,errors=panic,inlinecrypt wait,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized

Adoptable storage

Since Android 9, FBE and adoptable storage can be used together.

Specifying the fileencryption fstab option for userdata also automatically enables both FBE and metadata encryption on adoptable storage. However, you may override the FBE and/or metadata encryption formats on adoptable storage by setting properties in PRODUCT_PROPERTY_OVERRIDES .

On devices that launched with Android 11 or higher, use the following properties:

  • ro.crypto.volume.options (new in Android 11) selects the FBE encryption format on adoptable storage. It has the same syntax as the argument to the fileencryption fstab option, and it uses the same defaults. See the recommendations for fileencryption above for what to use here.
  • ro.crypto.volume.metadata.encryption selects the metadata encryption format on adoptable storage. See the metadata encryption documentation .

On devices that launched with Android 10 or lower, use the following properties:

  • ro.crypto.volume.contents_mode selects the contents encryption mode. This is equivalent to the first colon-separated field of ro.crypto.volume.options .
  • ro.crypto.volume.filenames_mode selects the filenames encryption mode. This is equivalent to the second colon-separated field of ro.crypto.volume.options , except that the default on devices that launched with Android 10 or lower is aes-256-heh . On most devices, this needs to be explicitly overridden to aes-256-cts .
  • ro.crypto.fde_algorithm and ro.crypto.fde_sector_size select the metadata encryption format on adoptable storage. See the metadata encryption documentation .

Integrating with Keymaster

The Keymaster HAL should be started as part of the early_hal class. This is because FBE requires that Keymaster be ready to handle requests by the post-fs-data boot phase, which is when vold sets up the initial keys.

Excluding directories

init applies the system DE key to all top-level directories of /data , except for directories that must be unencrypted: the directory that contains the system DE key itself, and directories that contain user CE or DE directories. Encryption keys apply recursively and cannot be overridden by subdirectories.

In Android 11 and higher, the key that init applies to directories can be controlled by the encryption=<action> argument to the mkdir command in init scripts. The possible values of <action> are documented in the README for the Android init language .

In Android 10, the init encryption actions were hardcoded into the following location:

/system/extras/libfscrypt/fscrypt_init_extensions.cpp

In Android 9 and earlier, the location was:

/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp

It is possible to add exceptions to prevent certain directories from being encrypted at all. If modifications of this sort are made then the device manufacturer should include SELinux policies that only grant access to the applications that need to use the unencrypted directory. This should exclude all untrusted applications.

The only known acceptable use case for this is in support of legacy OTA capabilities.

Supporting Direct Boot in system applications

Making applications Direct Boot aware

To facilitate rapid migration of system apps, there are two new attributes that can be set at the application level. The defaultToDeviceProtectedStorage attribute is available only to system apps. The directBootAware attribute is available to all.

<application
    android:directBootAware="true"
    android:defaultToDeviceProtectedStorage="true">

The directBootAware attribute at the application level is shorthand for marking all components in the app as being encryption aware.

The defaultToDeviceProtectedStorage attribute redirects the default app storage location to point at DE storage instead of pointing at CE storage. System apps using this flag must carefully audit all data stored in the default location, and change the paths of sensitive data to use CE storage. Device manufactures using this option should carefully inspect the data that they are storing to ensure that it contains no personal information.

When running in this mode, the following System APIs are available to explicitly manage a Context backed by CE storage when needed, which are equivalent to their Device Protected counterparts.

  • Context.createCredentialProtectedStorageContext()
  • Context.isCredentialProtectedStorage()

Supporting multiple users

Each user in a multi-user environment gets a separate encryption key. Every user gets two keys: a DE and a CE key. User 0 must log into the device first as it is a special user. This is pertinent for Device Administration uses.

Crypto-aware applications interact across users in this manner: INTERACT_ACROSS_USERS and INTERACT_ACROSS_USERS_FULL allow an application to act across all the users on the device. However, those apps will be able to access only CE-encrypted directories for users that are already unlocked.

An application may be able to interact freely across the DE areas, but one user unlocked does not mean that all the users on the device are unlocked. The application should check this status before trying to access these areas.

Each work profile user ID also gets two keys: DE and CE. When the work challenge is met, the profile user is unlocked and the Keymaster (in TEE) can provide the profile's TEE key.

Handling updates

The recovery partition is unable to access the DE-protected storage on the userdata partition. Devices implementing FBE are strongly recommended to support OTA using A/B system updates . As the OTA can be applied during normal operation there is no need for recovery to access data on the encrypted drive.

When using a legacy OTA solution, which requires recovery to access the OTA file on the userdata partition:

  1. Create a top-level directory (for example misc_ne ) in the userdata partition.
  2. Configure this top-level directory to be unencrypted (see Excluding directories ).
  3. Create a directory within the top-level directory to hold OTA packages.
  4. Add an SELinux rule and file contexts to control access to this directory and it contents. Only the process or applications receiving OTA updates should be able to read and write to this directory. No other application or process should have access to this directory.

Validation

To ensure the implemented version of the feature works as intended, first run the many CTS encryption tests, such as DirectBootHostTest and EncryptionTest .

If the device is running Android 11 or higher, also run vts_kernel_encryption_test :

atest vts_kernel_encryption_test

or:

vts-tradefed run vts -m vts_kernel_encryption_test

In addition, device manufacturers may perform the following manual tests. On a device with FBE enabled:

  • Check that ro.crypto.state exists
    • Ensure ro.crypto.state is encrypted
  • Check that ro.crypto.type exists
    • Ensure ro.crypto.type is set to file

Additionally, testers can boot a userdebug instance with a lockscreen set on the primary user. Then adb shell into the device and use su to become root. Make sure /data/data contains encrypted filenames; if it does not, something is wrong.

Device manufacturers are also encouraged to explore running the upstream Linux tests for fscrypt on their devices or kernels. These tests are part of the xfstests filesystem test suite. However, these upstream tests are not offically supported by Android.

AOSP implementation details

This section provides details on the AOSP implementation and describes how file-based encryption works. It should not be necessary for device manufacturers to make any changes here to use FBE and Direct Boot on their devices.

fscrypt encryption

The AOSP implementation uses "fscrypt" encryption (supported by ext4 and f2fs) in the kernel and normally is configured to:

  • Encrypt file contents with AES-256 in XTS mode
  • Encrypt file names with AES-256 in CBC-CTS mode

Adiantum encryption is also supported. When Adiantum encryption is enabled, both file contents and file names are encrypted with Adiantum.

fscrypt supports two versions of encryption policies: version 1 and version 2. Version 1 is deprecated, and the CDD requirements for devices launching with Android 11 and higher are only compatible with version 2. Version 2 encryption policies use HKDF-SHA512 to derive the actual encryption keys from the userspace-supplied keys.

For more information about fscrypt, see the upstream kernel documentation .

Storage classes

The following table lists the FBE keys and the directories they protect in more detail:

Storage class Description Directories
System DE Device-encrypted data not tied to a particular user /data/system , /data/app , and various other subdirectories of /data
Per-boot Ephemeral system files that don't need to survive a reboot /data/per_boot
User CE (internal) Per-user credential-encrypted data on internal storage
  • /data/data (alias of /data/user/0 )
  • /data/media/${user_id}
  • /data/misc_ce/${user_id}
  • /data/system_ce/${user_id}
  • /data/user/${user_id}
  • /data/vendor_ce/${user_id}
User DE (internal) Per-user device-encrypted data on internal storage
  • /data/misc_de/${user_id}
  • /data/system_de/${user_id}
  • /data/user_de/${user_id}
  • /data/vendor_de/${user_id}
User CE (adoptable) Per-user credential-encrypted data on adoptable storage
  • /mnt/expand/${volume_uuid}/media/${user_id}
  • /mnt/expand/${volume_uuid}/misc_ce/${user_id}
  • /mnt/expand/${volume_uuid}/user/${user_id}
User DE (adoptable) Per-user device-encrypted data on adoptable storage
  • /mnt/expand/${volume_uuid}/misc_de/${user_id}
  • /mnt/expand/${volume_uuid}/user_de/${user_id}

Key storage and protection

All FBE keys are managed by vold and are stored encrypted on-disk, except for the per-boot key which is not stored at all. The following table lists the locations in which the various FBE keys are stored:

Key type Key location Storage class of key location
System DE key /data/unencrypted Unencrypted
User CE (internal) keys /data/misc/vold/user_keys/ce/${user_id} System DE
User DE (internal) keys /data/misc/vold/user_keys/de/${user_id} System DE
User CE (adoptable) keys /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} User CE (internal)
User DE (adoptable) keys /data/misc_de/${user_id}/vold/volume_keys/${volume_uuid} User DE (internal)

As shown in the preceding table, most FBE keys are stored in directories that are encrypted by another FBE key. Keys cannot be unlocked until the storage class that contains them has been unlocked.

vold also applies a layer of encryption to all FBE keys. Every key besides CE keys for internal storage is encrypted with AES-256-GCM using its own Keystore key that is not exposed outside the TEE. This ensures that FBE keys cannot be unlocked unless a trusted operating system has booted, as enforced by Verified Boot . Rollback resistance is also requested on the Keystore key, which allows FBE keys to be securely deleted on devices where Keymaster supports rollback resistance. As a best-effort fallback for when rollback resistance is unavailable, the SHA-512 hash of 16384 random bytes stored in the secdiscardable file stored alongside the key is used as the application ID tag of the Keystore key. All these bytes need to be recovered to recover an FBE key.

CE keys for internal storage receive a stronger level of protection that ensures they cannot be unlocked without knowing either the user's Lock Screen Knowledge Factor (LSKF) (PIN, pattern, or password), a secure passcode reset token , or both the client-side and server-side keys for a Resume-on-Reboot operation. Passcode reset tokens are only allowed to be created for work profiles and fully managed devices .

To achieve this, vold encrypts each CE key for internal storage using an AES-256-GCM key derived from the user's synthetic password . The synthetic password is an immutable high-entropy cryptographic secret that is randomly generated for each user. LockSettingsService in system_server manages the synthetic password and the ways in which it is protected.

To protect the synthetic password with the LSKF, LockSettingsService first stretches the LSKF by passing it through scrypt , targeting a time of about 25 ms and a memory usage of about 2 MiB. Since LSKFs are usually short, this step usually does not provide much security. The main layer of security is the Secure Element (SE) or TEE-enforced ratelimiting described below.

If the device has a Secure Element (SE), then LockSettingsService maps the stretched LSKF to a high-entropy random secret stored in the SE using the Weaver HAL . LockSettingsService then encrypts the synthetic password twice: first with a software key derived from the stretched LSKF and the Weaver secret, and second with a non-auth-bound Keystore key. This provides SE-enforced ratelimiting of LSKF guesses.

If the device doesn't have a SE, then LockSettingsService instead uses the stretched LSKF as a Gatekeeper password. LockSettingsService then encrypts the synthetic password twice: first with a software key derived from the stretched LSKF and the hash of a secdiscardable file, and second with a Keystore key that is auth-bound to the Gatekeeper enrollment. This provides TEE-enforced ratelimiting of LSKF guesses.

When the LSKF is changed, LockSettingsService deletes all information associated with the binding of the synthetic password to the old LSKF. On devices that support Weaver or rollback resistant Keystore keys, this guarantees secure deletion of the old binding. For this reason, the protections described here are applied even when the user does not have an LSKF.