Google cam kết thúc đẩy công bằng chủng tộc cho Cộng đồng người da đen. Xem cách thực hiện.

Mã hóa dựa trên tệp

Android 7.0 trở lên hỗ trợ mã hóa dựa trên tệp (FBE). Mã hóa dựa trên tệp cho phép các tệp khác nhau được mã hóa bằng các khóa khác nhau có thể được mở khóa độc lập.

Bài viết này mô tả cách bật mã hóa dựa trên tệp trên các thiết bị mới và cách các ứng dụng hệ thống có thể sử dụng API khởi động trực tiếp để cung cấp cho người dùng trải nghiệm tốt nhất, an toàn nhất có thể.

Tất cả các thiết bị khởi chạy với Android 10 trở lên đều phải sử dụng mã hóa dựa trên tệp.

Khởi động trực tiếp

Mã hóa dựa trên tệp cho phép một tính năng mới được giới thiệu trong Android 7.0 có tên là Khởi động trực tiếp . Direct Boot cho phép các thiết bị được mã hóa khởi động thẳng vào màn hình khóa. Trước đây, trên các thiết bị được mã hóa sử dụng mã hóa toàn bộ ổ đĩa (FDE), người dùng cần cung cấp thông tin đăng nhập trước khi có thể truy cập bất kỳ dữ liệu nào, ngăn không cho điện thoại thực hiện tất cả trừ những thao tác cơ bản nhất. Ví dụ: chuông báo không thể hoạt động, dịch vụ trợ năng không khả dụng và điện thoại không thể nhận cuộc gọi mà chỉ giới hạn ở các thao tác quay số khẩn cấp cơ bản.

Với việc giới thiệu mã hóa dựa trên tệp (FBE) và các API mới giúp các ứng dụng nhận biết mã hóa, các ứng dụng này có thể hoạt động trong một ngữ cảnh hạn chế. Điều này có thể xảy ra trước khi người dùng cung cấp thông tin xác thực của họ trong khi vẫn bảo vệ thông tin cá nhân của người dùng.

Trên thiết bị hỗ trợ FBE, mỗi người dùng thiết bị có sẵn hai vị trí lưu trữ cho các ứng dụng:

  • Bộ lưu trữ được mã hóa thông tin xác thực (CE), là vị trí lưu trữ mặc định và chỉ khả dụng sau khi người dùng đã mở khóa thiết bị.
  • Bộ lưu trữ được mã hóa thiết bị (DE), là vị trí lưu trữ khả dụng cả trong chế độ Khởi động trực tiếp và sau khi người dùng đã mở khóa thiết bị.

Sự tách biệt này làm cho hồ sơ công việc trở nên an toàn hơn vì nó cho phép nhiều người dùng được bảo vệ cùng lúc vì mã hóa không còn chỉ dựa trên mật khẩu thời gian khởi động.

API khởi động trực tiếp cho phép các ứng dụng nhận biết mã hóa truy cập từng khu vực này. Có những thay đổi đối với vòng đời của ứng dụng để đáp ứng nhu cầu thông báo cho ứng dụng khi bộ lưu trữ CE của người dùng được mở khóa để phản hồi lại lần đầu tiên nhập thông tin đăng nhập ở màn hình khóa hoặc trong trường hợp hồ sơ công việc đưa ra thử thách công việc . Các thiết bị chạy Android 7.0 phải hỗ trợ các API và vòng đời mới này bất kể chúng có triển khai FBE hay không. Mặc dù, nếu không có FBE, bộ lưu trữ DE và CE sẽ luôn ở trạng thái mở khóa.

Việc triển khai hoàn chỉnh mã hóa dựa trên tệp trên hệ thống tệp Ext4 và F2FS được cung cấp trong Dự án nguồn mở Android (AOSP) và chỉ cần được bật trên các thiết bị đáp ứng yêu cầu. Các nhà sản xuất chọn sử dụng FBE có thể muốn khám phá các cách tối ưu hóa tính năng dựa trên hệ thống trên chip (SoC) được sử dụng.

Tất cả các gói cần thiết trong AOSP đã được cập nhật để nhận biết khởi động trực tiếp. Tuy nhiên, khi các nhà sản xuất thiết bị sử dụng các phiên bản tùy chỉnh của các ứng dụng này, họ sẽ muốn đảm bảo ở mức tối thiểu có các gói nhận biết khởi động trực tiếp cung cấp các dịch vụ sau:

  • Dịch vụ điện thoại và Trình quay số
  • Phương thức nhập để nhập mật khẩu vào màn hình khóa

Ví dụ và nguồn

Android cung cấp triển khai mã hóa dựa trên tệp tham chiếu, trong đó vold ( system/vold ) cung cấp chức năng quản lý ổ đĩa và thiết bị lưu trữ trên Android. Việc bổ sung FBE cung cấp cho vold một số lệnh mới để hỗ trợ quản lý khóa cho các khóa CE và DE của nhiều người dùng. Ngoài những thay đổi cốt lõi để sử dụng khả năng mã hóa dựa trên tệp trong nhân , nhiều gói hệ thống bao gồm màn hình khóa và SystemUI đã được sửa đổi để hỗ trợ các tính năng FBE và Khởi động trực tiếp. Bao gồm các:

  • Trình quay số AOSP (gói/ứng dụng/Trình quay số)
  • Đồng hồ để bàn (gói/ứng dụng/DeskClock)
  • LatinIME (gói/phương thức nhập/LatinIME)*
  • Cài đặt Ứng dụng (gói/ứng dụng/Cài đặt)*
  • SystemUI (khung/cơ sở/gói/SystemUI)*

* Các ứng dụng hệ thống sử dụng thuộc tính tệp kê khai defaultToDeviceProtectedStorage

Có thể tìm thấy nhiều ví dụ khác về các ứng dụng và dịch vụ nhận biết mã hóa bằng cách chạy lệnh mangrep directBootAware trong thư mục khung hoặc gói của cây nguồn AOSP.

phụ thuộc

Để sử dụng triển khai AOSP của FBE một cách an toàn, thiết bị cần đáp ứng các yếu tố phụ thuộc sau:

  • Hạt nhân Hỗ trợ mã hóa Ext4 hoặc mã hóa F2FS.
  • Hỗ trợ Keymaster với HAL phiên bản 1.0 trở lên. Không có hỗ trợ cho Keymaster 0.3 vì điều đó không cung cấp các khả năng cần thiết hoặc đảm bảo đủ khả năng bảo vệ cho các khóa mã hóa.
  • Keymaster/ Keystore và Gatekeeper phải được triển khai trong Môi trường thực thi tin cậy (TEE) để cung cấp khả năng bảo vệ cho các khóa DE sao cho một hệ điều hành trái phép (hệ điều hành tùy chỉnh được cài đặt trên thiết bị) không thể yêu cầu các khóa DE một cách đơn giản.
  • Root phần cứng đáng tin cậyKhởi động được xác minh ràng buộc với khởi tạo Keymaster là bắt buộc để đảm bảo rằng các khóa DE không thể truy cập được bởi một hệ điều hành trái phép.

Thực hiện

Trước hết, các ứng dụng như đồng hồ báo thức, điện thoại và các tính năng trợ năng phải được tạo thành android:directBootAware theo tài liệu dành cho nhà phát triển Direct Boot .

hỗ trợ hạt nhân

Hỗ trợ hạt nhân cho mã hóa Ext4 và F2FS có sẵn trong các hạt nhân thông thường của Android, phiên bản 3.18 trở lên. Để kích hoạt nó trong kernel phiên bản 5.1 trở lên, hãy sử dụng:

CONFIG_FS_ENCRYPTION=y

Đối với các nhân cũ hơn, hãy sử dụng CONFIG_EXT4_ENCRYPTION=y nếu hệ thống tệp userdata của thiết bị là Ext4 hoặc sử dụng CONFIG_F2FS_FS_ENCRYPTION=y nếu hệ thống tệp userdata của thiết bị là F2FS.

Nếu thiết bị của bạn hỗ trợ bộ nhớ có thể chấp nhận hoặc sẽ sử dụng mã hóa siêu dữ liệu trên bộ nhớ trong, hãy bật các tùy chọn cấu hình hạt nhân cần thiết để mã hóa siêu dữ liệu như được mô tả trong tài liệu mã hóa siêu dữ liệu .

Ngoài hỗ trợ chức năng cho mã hóa Ext4 hoặc F2FS, các nhà sản xuất thiết bị cũng nên kích hoạt tính năng tăng tốc mã hóa để tăng tốc độ mã hóa dựa trên tệp và cải thiện trải nghiệm người dùng. Ví dụ: trên các thiết bị dựa trên ARM64, có thể bật tính năng tăng tốc ARMv8 CE (Tiện ích mở rộng mật mã) bằng cách đặt các tùy chọn cấu hình kernel sau:

CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_SHA2_ARM64_CE=y

Để cải thiện hơn nữa hiệu suất và giảm mức sử dụng năng lượng, các nhà sản xuất thiết bị cũng có thể xem xét triển khai phần cứng mã hóa nội tuyến , giúp mã hóa/giải mã dữ liệu trong khi dữ liệu đang trên đường đến/từ thiết bị lưu trữ. Các nhân chung của Android (phiên bản 4.14 trở lên) chứa một khung cho phép mã hóa nội tuyến được sử dụng khi có hỗ trợ trình điều khiển của nhà cung cấp và phần cứng. Khung mã hóa nội tuyến có thể được bật bằng cách đặt các tùy chọn cấu hình kernel sau:

CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y

Nếu thiết bị của bạn sử dụng bộ lưu trữ dựa trên UFS, hãy bật cả:

CONFIG_SCSI_UFS_CRYPTO=y

Nếu thiết bị của bạn sử dụng bộ nhớ dựa trên eMMC, hãy bật cả:

CONFIG_MMC_CRYPTO=y

Kích hoạt mã hóa dựa trên tập tin

Kích hoạt FBE trên thiết bị yêu cầu kích hoạt nó trên bộ nhớ trong ( userdata ). Điều này cũng tự động kích hoạt FBE trên bộ nhớ có thể chấp nhận được; tuy nhiên, định dạng mã hóa trên bộ lưu trữ có thể chấp nhận có thể bị ghi đè nếu cần.

Lưu trữ nội bộ

FBE được bật bằng cách thêm tùy chọn fileencryption=contents_encryption_mode[:filenames_encryption_mode[:flags]] vào cột fs_mgr_flags của dòng fstab cho userdata . Tùy chọn này xác định định dạng mã hóa trên bộ nhớ trong. Nó chứa tối đa ba tham số được phân tách bằng dấu hai chấm:

  • Tham số contents_encryption_mode xác định thuật toán mã hóa nào được sử dụng để mã hóa nội dung tệp. Nó có thể là aes-256-xts hoặc adiantum . Kể từ Android 11, nó cũng có thể để trống để chỉ định thuật toán mặc định, đó là aes-256-xts .
  • Tham số filenames_encryption_mode xác định thuật toán mã hóa nào được sử dụng để mã hóa tên tệp. Nó có thể là aes-256-cts , aes-256-heh , adiantum hoặc aes-256-hctr2 . Nếu không được chỉ định, nó sẽ mặc định là aes-256-cts contents_encryption_modeaes-256-xts hoặc là adiantum contents_encryption_modeadiantum .
  • Tham số flags , mới trong Android 11, là danh sách các cờ được phân tách bằng ký tự + . Các cờ sau đây được hỗ trợ:
    • Cờ v1 chọn chính sách mã hóa phiên bản 1; cờ v2 chọn chính sách mã hóa phiên bản 2. Chính sách mã hóa phiên bản 2 sử dụng chức năng dẫn xuất khóa linh hoạt và an toàn hơn. Giá trị mặc định là v2 nếu thiết bị khởi chạy trên Android 11 trở lên (như được xác định bởi ro.product.first_api_level ) hoặc v1 nếu thiết bị khởi chạy trên Android 10 trở xuống.
    • Cờ inlinecrypt_optimized chọn định dạng mã hóa được tối ưu hóa cho phần cứng mã hóa nội tuyến không xử lý hiệu quả số lượng lớn khóa. Nó thực hiện điều này bằng cách chỉ lấy một khóa mã hóa nội dung tệp cho mỗi khóa CE hoặc DE, thay vì một khóa cho mỗi tệp. Việc tạo IV (vectơ khởi tạo) được điều chỉnh tương ứng.
    • Cờ emmc_optimized tương tự như inlinecrypt_optimized nhưng nó cũng chọn phương pháp tạo IV giới hạn IV ở 32 bit. Chỉ nên sử dụng cờ này trên phần cứng mã hóa nội tuyến tuân thủ đặc tả JEDEC eMMC v5.2 và do đó chỉ hỗ trợ IV 32 bit. Trên phần cứng mã hóa nội tuyến khác, thay vào đó hãy sử dụng inlinecrypt_optimized . Cờ này không bao giờ được sử dụng trên bộ lưu trữ dựa trên UFS; đặc điểm kỹ thuật UFS cho phép sử dụng IV 64 bit.
    • Trên các thiết bị hỗ trợ phím bọc phần cứng , cờ wrappedkey_v0 cho phép sử dụng khóa bọc phần cứng cho FBE. Điều này chỉ có thể được sử dụng kết hợp với tùy chọn gắn inlinecrypt và cờ inlinecrypt_optimized hoặc emmc_optimized .

Nếu bạn không sử dụng phần cứng mã hóa nội tuyến, cài đặt được đề xuất cho hầu hết các thiết bị là fileencryption=aes-256-xts . Nếu bạn đang sử dụng phần cứng mã hóa nội tuyến, cài đặt được đề xuất cho hầu hết các thiết bị là fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized (hoặc tương đương fileencryption=::inlinecrypt_optimized ). Trên các thiết bị không có bất kỳ hình thức tăng tốc AES nào, Adiantum có thể được sử dụng thay vì AES bằng cách đặt fileencryption=adiantum .

Kể từ Android 14 (AOSP thử nghiệm), AES-HCTR2 là chế độ mã hóa tên tệp ưu tiên cho các thiết bị có hướng dẫn mã hóa tăng tốc. Tuy nhiên, chỉ các nhân Android mới hơn mới hỗ trợ AES-HCTR2. Trong một bản phát hành Android trong tương lai, nó được lên kế hoạch trở thành chế độ mặc định để mã hóa tên tệp. Nếu hạt nhân của bạn có hỗ trợ AES-HCTR2, thì hạt nhân đó có thể được bật để mã hóa tên tệp bằng cách đặt filenames_encryption_mode thành aes-256-hctr2 . Trong trường hợp đơn giản nhất, điều này sẽ được thực hiện với fileencryption=aes-256-xts:aes-256-hctr2 .

Trên các thiết bị chạy Android 10 trở xuống, fileencryption=ice cũng được chấp nhận để chỉ định việc sử dụng chế độ mã hóa nội dung tệp FSCRYPT_MODE_PRIVATE . Chế độ này chưa được các nhân thông thường của Android triển khai, nhưng nó có thể được các nhà cung cấp triển khai bằng cách sử dụng các bản vá nhân tùy chỉnh. Định dạng trên đĩa do chế độ này tạo ra là dành riêng cho nhà cung cấp. Trên các thiết bị chạy Android 11 trở lên, chế độ này không còn được phép và thay vào đó phải sử dụng định dạng mã hóa tiêu chuẩn.

Theo mặc định, mã hóa nội dung tệp được thực hiện bằng API mật mã của nhân Linux. Thay vào đó, nếu bạn muốn sử dụng phần cứng mã hóa nội tuyến, hãy thêm tùy chọn gắn inlinecrypt . Ví dụ: một dòng fstab đầy đủ có thể trông như sau:

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

lưu trữ có thể chấp nhận

Kể từ Android 9, FBE và bộ nhớ có thể sử dụng được có thể được sử dụng cùng nhau.

Việc chỉ định tùy chọn fstab fileencryption tệp cho userdata cũng tự động bật cả mã hóa FBE và siêu dữ liệu trên bộ nhớ có thể chấp nhận. Tuy nhiên, bạn có thể ghi đè định dạng mã hóa FBE và/hoặc siêu dữ liệu trên bộ nhớ có thể chấp nhận bằng cách đặt thuộc tính trong PRODUCT_PROPERTY_OVERRIDES .

Trên các thiết bị chạy Android 11 trở lên, hãy sử dụng các thuộc tính sau:

  • ro.crypto.volume.options (mới trong Android 11) chọn định dạng mã hóa FBE trên bộ nhớ có thể chấp nhận. Nó có cùng một cú pháp như đối số cho tùy chọn fileencryption fstab và nó sử dụng cùng các giá trị mặc định. Xem các đề xuất về fileencryption ở trên để biết cách sử dụng tại đây.
  • ro.crypto.volume.metadata.encryption chọn định dạng mã hóa siêu dữ liệu trên bộ lưu trữ có thể chấp nhận. Xem tài liệu mã hóa siêu dữ liệu .

Trên các thiết bị chạy Android 10 trở xuống, hãy sử dụng các thuộc tính sau:

  • ro.crypto.volume.contents_mode chọn chế độ mã hóa nội dung. Điều này tương đương với trường đầu tiên được phân tách bằng dấu hai chấm của ro.crypto.volume.options .
  • ro.crypto.volume.filenames_mode chọn chế độ mã hóa tên tệp. Trường này tương đương với trường thứ hai được phân tách bằng dấu hai chấm của ro.crypto.volume.options , ngoại trừ trường mặc định trên các thiết bị chạy Android 10 trở xuống là aes-256-heh . Trên hầu hết các thiết bị, điều này cần được ghi đè rõ ràng thành aes-256-cts .
  • ro.crypto.fde_algorithmro.crypto.fde_sector_size chọn định dạng mã hóa siêu dữ liệu trên bộ nhớ có thể chấp nhận. Xem tài liệu mã hóa siêu dữ liệu .

Tích hợp với Keymaster

Keymaster HAL nên được bắt đầu như một phần của lớp early_hal . Điều này là do FBE yêu cầu Keymaster sẵn sàng xử lý các yêu cầu ở giai đoạn khởi động post-fs-data , đó là khi vold thiết lập các khóa ban đầu.

Loại trừ các thư mục

init áp dụng khóa DE hệ thống cho tất cả các thư mục cấp cao nhất của /data , ngoại trừ các thư mục không được mã hóa: thư mục chứa chính khóa DE hệ thống và các thư mục chứa thư mục CE hoặc DE của người dùng. Các khóa mã hóa được áp dụng theo cách đệ quy và không thể bị ghi đè bởi các thư mục con.

Trong Android 11 trở lên, khóa init áp dụng cho các thư mục có thể được kiểm soát bằng đối encryption=<action> cho lệnh mkdir trong tập lệnh init. Các giá trị có thể có của <action> được ghi lại trong README dành cho ngôn ngữ khởi tạo Android .

Trong Android 10, các hành động mã hóa init được mã hóa cứng vào vị trí sau:

/system/extras/libfscrypt/fscrypt_init_extensions.cpp

Trong Android 9 trở về trước, vị trí là:

/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp

Có thể thêm các ngoại lệ để ngăn một số thư mục nhất định không được mã hóa. Nếu các sửa đổi thuộc loại này được thực hiện thì nhà sản xuất thiết bị nên bao gồm các chính sách SELinux chỉ cấp quyền truy cập cho các ứng dụng cần sử dụng thư mục không được mã hóa. Điều này sẽ loại trừ tất cả các ứng dụng không đáng tin cậy.

Trường hợp sử dụng duy nhất được chấp nhận cho điều này là hỗ trợ các khả năng OTA cũ.

Hỗ trợ Direct Boot trong các ứng dụng hệ thống

Nhận biết các ứng dụng Khởi động trực tiếp

Để tạo điều kiện di chuyển nhanh chóng các ứng dụng hệ thống, có hai thuộc tính mới có thể được đặt ở cấp ứng dụng. Thuộc tính defaultToDeviceProtectedStorage chỉ khả dụng cho các ứng dụng hệ thống. Thuộc tính directBootAware có sẵn cho tất cả.

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

Thuộc tính directBootAware ở cấp ứng dụng là cách viết tắt để đánh dấu tất cả các thành phần trong ứng dụng là nhận biết mã hóa.

Thuộc tính defaultToDeviceProtectedStorage chuyển hướng vị trí lưu trữ ứng dụng mặc định trỏ đến bộ nhớ DE thay vì trỏ vào bộ nhớ CE. Các ứng dụng hệ thống sử dụng cờ này phải kiểm tra cẩn thận tất cả dữ liệu được lưu trữ ở vị trí mặc định và thay đổi đường dẫn của dữ liệu nhạy cảm để sử dụng bộ lưu trữ CE. Các nhà sản xuất thiết bị sử dụng tùy chọn này nên kiểm tra cẩn thận dữ liệu mà họ đang lưu trữ để đảm bảo rằng dữ liệu đó không chứa thông tin cá nhân.

Khi chạy ở chế độ này, các API hệ thống sau đây có sẵn để quản lý rõ ràng Ngữ cảnh được lưu trữ CE hỗ trợ khi cần, tương đương với các đối tác được Bảo vệ bởi thiết bị của chúng.

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

Hỗ trợ nhiều người dùng

Mỗi người dùng trong môi trường nhiều người dùng sẽ nhận được một khóa mã hóa riêng. Mỗi người dùng nhận được hai khóa: khóa DE và khóa CE. Người dùng 0 phải đăng nhập vào thiết bị trước vì đây là người dùng đặc biệt. Điều này thích hợp cho việc sử dụng Quản trị thiết bị .

Các ứng dụng nhận biết tiền điện tử tương tác giữa những người dùng theo cách này: INTERACT_ACROSS_USERSINTERACT_ACROSS_USERS_FULL cho phép một ứng dụng hoạt động trên tất cả người dùng trên thiết bị. Tuy nhiên, những ứng dụng đó sẽ chỉ có thể truy cập các thư mục được mã hóa CE cho người dùng đã được mở khóa.

Một ứng dụng có thể tương tác tự do trên các khu vực DE, nhưng một người dùng được mở khóa không có nghĩa là tất cả người dùng trên thiết bị đều được mở khóa. Ứng dụng nên kiểm tra trạng thái này trước khi thử truy cập vào các khu vực này.

Mỗi ID người dùng hồ sơ công việc cũng nhận được hai khóa: DE và CE. Khi hoàn thành thử thách công việc, người dùng hồ sơ được mở khóa và Keymaster (trong TEE) có thể cung cấp khóa TEE của hồ sơ.

Xử lý cập nhật

Phân vùng khôi phục không thể truy cập bộ lưu trữ được bảo vệ bằng DE trên phân vùng dữ liệu người dùng. Các thiết bị triển khai FBE được khuyến khích mạnh mẽ để hỗ trợ OTA bằng cách sử dụng các bản cập nhật hệ thống A/B . Vì OTA có thể được áp dụng trong quá trình hoạt động bình thường nên không cần khôi phục để truy cập dữ liệu trên ổ đĩa được mã hóa.

Khi sử dụng giải pháp OTA cũ, giải pháp này yêu cầu khôi phục để truy cập tệp OTA trên phân vùng userdata :

  1. Tạo một thư mục cấp cao nhất (ví dụ misc_ne ) trong phân vùng userdata .
  2. Định cấu hình thư mục cấp cao nhất này để không được mã hóa (xem Loại trừ thư mục ).
  3. Tạo một thư mục trong thư mục cấp cao nhất để chứa các gói OTA.
  4. Thêm quy tắc SELinux và ngữ cảnh tệp để kiểm soát quyền truy cập vào thư mục này và nội dung của nó. Chỉ quy trình hoặc ứng dụng nhận bản cập nhật OTA mới có thể đọc và ghi vào thư mục này. Không có ứng dụng hoặc quy trình nào khác có quyền truy cập vào thư mục này.

Thẩm định

Để đảm bảo phiên bản được triển khai của tính năng này hoạt động như dự kiến, trước tiên hãy chạy nhiều thử nghiệm mã hóa CTS, chẳng hạn như DirectBootHostTestEncryptionTest .

Nếu thiết bị đang chạy Android 11 trở lên, hãy chạy cả vts_kernel_encryption_test :

atest vts_kernel_encryption_test

hoặc:

vts-tradefed run vts -m vts_kernel_encryption_test

Ngoài ra, các nhà sản xuất thiết bị có thể thực hiện các kiểm tra thủ công sau. Trên thiết bị có bật FBE:

  • Kiểm tra xem ro.crypto.state có tồn tại không
    • Đảm bảo ro.crypto.state được mã hóa
  • Kiểm tra xem ro.crypto.type có tồn tại không
    • Đảm bảo ro.crypto.type được đặt thành file

Ngoài ra, người kiểm tra có thể khởi động phiên bản userdebug với màn hình khóa được đặt trên người dùng chính. Sau đó adb shell vào thiết bị và sử dụng su để trở thành root. Đảm bảo /data/data chứa tên tệp được mã hóa; nếu không, một cái gì đó là sai.

Các nhà sản xuất thiết bị cũng được khuyến khích khám phá việc chạy thử nghiệm Linux ngược dòng cho fscrypt trên thiết bị hoặc nhân của họ. Các bài kiểm tra này là một phần của bộ kiểm tra hệ thống tệp xfstests. Tuy nhiên, các thử nghiệm ngược dòng này không được Android hỗ trợ chính thức.

Chi tiết triển khai AOSP

Phần này cung cấp thông tin chi tiết về việc triển khai AOSP và mô tả cách hoạt động của mã hóa dựa trên tệp. Các nhà sản xuất thiết bị không cần thực hiện bất kỳ thay đổi nào ở đây để sử dụng FBE và Khởi động trực tiếp trên thiết bị của họ.

mã hóa fscrypt

Việc triển khai AOSP sử dụng mã hóa "fscrypt" (được hỗ trợ bởi ext4 và f2fs) trong nhân và thường được định cấu hình để:

  • Mã hóa nội dung tệp bằng AES-256 ở chế độ XTS
  • Mã hóa tên tệp bằng AES-256 ở chế độ CBC-CTS

Mã hóa Adiantum cũng được hỗ trợ. Khi mã hóa Adiantum được bật, cả nội dung tệp và tên tệp đều được mã hóa bằng Adiantum.

fscrypt hỗ trợ hai phiên bản chính sách mã hóa: phiên bản 1 và phiên bản 2. Phiên bản 1 không được dùng nữa và các yêu cầu CDD đối với các thiết bị chạy Android 11 trở lên chỉ tương thích với phiên bản 2. Chính sách mã hóa phiên bản 2 sử dụng HKDF-SHA512 để lấy giá trị thực tế các khóa mã hóa từ các khóa do không gian người dùng cung cấp.

Để biết thêm thông tin về fscrypt, hãy xem tài liệu kernel ngược dòng .

lớp lưu trữ

Bảng sau đây liệt kê các khóa FBE và các thư mục mà chúng bảo vệ chi tiết hơn:

lớp lưu trữ Sự miêu tả thư mục
Hệ thống DE Dữ liệu mã hóa thiết bị không bị ràng buộc với một người dùng cụ thể /data/system , /data/app và nhiều thư mục con khác của /data
mỗi lần khởi động Các tệp hệ thống tạm thời không cần phải khởi động lại /data/per_boot
Người dùng CE (nội bộ) Dữ liệu được mã hóa thông tin xác thực cho mỗi người dùng trên bộ nhớ trong
  • /data/data (bí danh của /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}
Người dùng DE (nội bộ) Dữ liệu được mã hóa trên thiết bị của mỗi người dùng trên bộ nhớ trong
  • /data/misc_de/${user_id}
  • /data/system_de/${user_id}
  • /data/user_de/${user_id}
  • /data/vendor_de/${user_id}
Người dùng CE (có thể chấp nhận) Dữ liệu được mã hóa bằng thông tin xác thực của mỗi người dùng trên bộ nhớ có thể chấp nhận
  • /mnt/expand/${volume_uuid}/media/${user_id}
  • /mnt/expand/${volume_uuid}/misc_ce/${user_id}
  • /mnt/expand/${volume_uuid}/user/${user_id}
Người dùng DE (có thể áp dụng) Dữ liệu được mã hóa trên thiết bị của mỗi người dùng trên bộ nhớ có thể chấp nhận
  • /mnt/expand/${volume_uuid}/misc_de/${user_id}
  • /mnt/expand/${volume_uuid}/user_de/${user_id}

Lưu trữ và bảo vệ chìa khóa

Tất cả các khóa FBE được quản lý bởi vold và được lưu trữ được mã hóa trên đĩa, ngoại trừ khóa mỗi lần khởi động hoàn toàn không được lưu trữ. Bảng sau đây liệt kê các vị trí lưu trữ các khóa FBE khác nhau:

Loại chính vị trí quan trọng Lớp lưu trữ của vị trí quan trọng
Phím DE hệ thống /data/unencrypted không được mã hóa
Phím CE (nội bộ) của người dùng /data/misc/vold/user_keys/ce/${user_id} Hệ thống DE
Phím DE (nội bộ) của người dùng /data/misc/vold/user_keys/de/${user_id} Hệ thống DE
Phím CE (có thể chấp nhận) của người dùng /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} Người dùng CE (nội bộ)
Phím DE (có thể chấp nhận) của người dùng /data/misc_de/${user_id}/vold/volume_keys/${volume_uuid} Người dùng DE (nội bộ)

Như được hiển thị trong bảng trước, hầu hết các khóa FBE được lưu trữ trong các thư mục được mã hóa bởi một khóa FBE khác. Không thể mở khóa khóa cho đến khi lớp lưu trữ chứa chúng chưa được mở khóa.

vold cũng áp dụng một lớp mã hóa cho tất cả các khóa FBE. Mọi khóa ngoài khóa CE dành cho bộ nhớ trong đều được mã hóa bằng AES-256-GCM bằng cách sử dụng khóa Kho lưu trữ khóa riêng không được hiển thị bên ngoài TEE. Điều này đảm bảo rằng không thể mở khóa các khóa FBE trừ khi hệ điều hành đáng tin cậy đã khởi động, như được thực thi bởi Khởi động được xác minh . Khả năng chống quay ngược cũng được yêu cầu trên khóa Kho khóa, cho phép xóa các khóa FBE một cách an toàn trên các thiết bị mà Keymaster hỗ trợ khả năng chống quay ngược. Là một phương án dự phòng với nỗ lực tốt nhất khi không có tính năng kháng lùi, hàm băm SHA-512 gồm 16384 byte ngẫu nhiên được lưu trữ trong tệp secdiscardable được lưu trữ cùng với khóa được sử dụng làm thẻ ID ứng dụng của khóa Keystore. Tất cả các byte này cần được khôi phục để khôi phục khóa FBE.

Các khóa CE dành cho bộ nhớ trong nhận được mức độ bảo vệ mạnh hơn để đảm bảo rằng chúng không thể được mở khóa nếu không biết Yếu tố Kiến thức Màn hình Khóa (LSKF) (PIN, hình mở khóa hoặc mật khẩu) của người dùng, mã thông báo đặt lại mật khẩu an toàn hoặc cả hai mã phía máy khách và các phím phía máy chủ cho thao tác Resume-on-Reboot . Mã thông báo đặt lại mật mã chỉ được phép tạo cho hồ sơ công việcthiết bị được quản lý hoàn toàn .

Để đạt được điều này, vold mã hóa từng khóa CE cho bộ nhớ trong bằng khóa AES-256-GCM được lấy từ mật khẩu tổng hợp của người dùng . Mật khẩu tổng hợp là một bí mật mã hóa entropy cao bất biến được tạo ngẫu nhiên cho mỗi người dùng. LockSettingsService trong system_server quản lý mật khẩu tổng hợp và cách bảo vệ mật khẩu đó.

Để bảo vệ mật khẩu tổng hợp bằng LSKF, trước tiên, LockSettingsService kéo dài LSKF bằng cách chuyển nó qua scrypt , nhắm mục tiêu thời gian khoảng 25 mili giây và mức sử dụng bộ nhớ khoảng 2 MiB. Vì các LSKF thường ngắn nên bước này thường không cung cấp nhiều bảo mật. Lớp bảo mật chính là Phần tử bảo mật (SE) hoặc giới hạn tỷ lệ do TEE thực thi được mô tả bên dưới.

Nếu thiết bị có Phần tử bảo mật (SE), thì LockSettingsService sẽ ánh xạ LSKF kéo dài thành bí mật ngẫu nhiên có entropy cao được lưu trữ trong SE bằng cách sử dụng Weaver HAL . LockSettingsService sau đó mã hóa mật khẩu tổng hợp hai lần: lần đầu tiên bằng khóa phần mềm có nguồn gốc từ LSKF kéo dài và bí mật của Weaver, lần thứ hai bằng khóa Keystore không bị ràng buộc xác thực. Điều này cung cấp giới hạn tốc độ do SE thực thi đối với các dự đoán LSKF.

Nếu thiết bị không có SE, thì LockSettingsService thay vào đó sử dụng LSKF kéo dài làm mật khẩu Gatekeeper . LockSettingsService sau đó mã hóa mật khẩu tổng hợp hai lần: lần đầu tiên bằng khóa phần mềm được lấy từ LSKF kéo dài và hàm băm của tệp có thể loại bỏ được, lần thứ hai bằng khóa Keystore được xác thực liên kết với đăng ký Gatekeeper. Điều này cung cấp giới hạn tỷ lệ dự đoán LSKF do TEE thực thi.

Khi LSKF được thay đổi, LockSettingsService sẽ xóa tất cả thông tin liên quan đến việc liên kết mật khẩu tổng hợp với LSKF cũ. Trên các thiết bị hỗ trợ Weaver hoặc khóa Keystore chống rollback, điều này đảm bảo xóa liên kết cũ một cách an toàn. Vì lý do này, các biện pháp bảo vệ được mô tả ở đây được áp dụng ngay cả khi người dùng không có LSKF.

,

Android 7.0 trở lên hỗ trợ mã hóa dựa trên tệp (FBE). Mã hóa dựa trên tệp cho phép các tệp khác nhau được mã hóa bằng các khóa khác nhau có thể được mở khóa độc lập.

Bài viết này mô tả cách bật mã hóa dựa trên tệp trên các thiết bị mới và cách các ứng dụng hệ thống có thể sử dụng API khởi động trực tiếp để cung cấp cho người dùng trải nghiệm tốt nhất, an toàn nhất có thể.

Tất cả các thiết bị khởi chạy với Android 10 trở lên đều phải sử dụng mã hóa dựa trên tệp.

Khởi động trực tiếp

Mã hóa dựa trên tệp cho phép một tính năng mới được giới thiệu trong Android 7.0 có tên là Khởi động trực tiếp . Direct Boot cho phép các thiết bị được mã hóa khởi động thẳng vào màn hình khóa. Trước đây, trên các thiết bị được mã hóa sử dụng mã hóa toàn bộ ổ đĩa (FDE), người dùng cần cung cấp thông tin đăng nhập trước khi có thể truy cập bất kỳ dữ liệu nào, ngăn không cho điện thoại thực hiện tất cả trừ những thao tác cơ bản nhất. Ví dụ: chuông báo không thể hoạt động, dịch vụ hỗ trợ tiếp cận không khả dụng và điện thoại không thể nhận cuộc gọi nhưng chỉ giới hạn ở các thao tác quay số khẩn cấp cơ bản.

Với việc giới thiệu mã hóa dựa trên tệp (FBE) và các API mới giúp các ứng dụng nhận biết mã hóa, các ứng dụng này có thể hoạt động trong một ngữ cảnh hạn chế. Điều này có thể xảy ra trước khi người dùng cung cấp thông tin xác thực của họ trong khi vẫn bảo vệ thông tin cá nhân của người dùng.

Trên thiết bị hỗ trợ FBE, mỗi người dùng thiết bị có sẵn hai vị trí lưu trữ cho các ứng dụng:

  • Bộ lưu trữ được mã hóa thông tin xác thực (CE), là vị trí lưu trữ mặc định và chỉ khả dụng sau khi người dùng đã mở khóa thiết bị.
  • Bộ lưu trữ được mã hóa thiết bị (DE), là vị trí lưu trữ khả dụng cả trong chế độ Khởi động trực tiếp và sau khi người dùng đã mở khóa thiết bị.

Sự tách biệt này làm cho hồ sơ công việc trở nên an toàn hơn vì nó cho phép nhiều người dùng được bảo vệ cùng lúc vì mã hóa không còn chỉ dựa trên mật khẩu thời gian khởi động.

API khởi động trực tiếp cho phép các ứng dụng nhận biết mã hóa truy cập từng khu vực này. Có những thay đổi đối với vòng đời của ứng dụng để đáp ứng nhu cầu thông báo cho ứng dụng khi bộ lưu trữ CE của người dùng được mở khóa để phản hồi lại lần đầu tiên nhập thông tin đăng nhập ở màn hình khóa hoặc trong trường hợp hồ sơ công việc đưa ra thử thách công việc . Các thiết bị chạy Android 7.0 phải hỗ trợ các API và vòng đời mới này bất kể chúng có triển khai FBE hay không. Mặc dù, nếu không có FBE, bộ lưu trữ DE và CE sẽ luôn ở trạng thái mở khóa.

Việc triển khai hoàn chỉnh mã hóa dựa trên tệp trên hệ thống tệp Ext4 và F2FS được cung cấp trong Dự án nguồn mở Android (AOSP) và chỉ cần được bật trên các thiết bị đáp ứng yêu cầu. Các nhà sản xuất chọn sử dụng FBE có thể muốn khám phá các cách tối ưu hóa tính năng dựa trên hệ thống trên chip (SoC) được sử dụng.

Tất cả các gói cần thiết trong AOSP đã được cập nhật để nhận biết khởi động trực tiếp. Tuy nhiên, khi các nhà sản xuất thiết bị sử dụng các phiên bản tùy chỉnh của các ứng dụng này, họ sẽ muốn đảm bảo ở mức tối thiểu có các gói nhận biết khởi động trực tiếp cung cấp các dịch vụ sau:

  • Dịch vụ điện thoại và Trình quay số
  • Phương thức nhập để nhập mật khẩu vào màn hình khóa

Ví dụ và nguồn

Android cung cấp triển khai mã hóa dựa trên tệp tham chiếu, trong đó vold ( system/vold ) cung cấp chức năng quản lý ổ đĩa và thiết bị lưu trữ trên Android. Việc bổ sung FBE cung cấp cho vold một số lệnh mới để hỗ trợ quản lý khóa cho các khóa CE và DE của nhiều người dùng. Ngoài những thay đổi cốt lõi để sử dụng khả năng mã hóa dựa trên tệp trong nhân , nhiều gói hệ thống bao gồm màn hình khóa và SystemUI đã được sửa đổi để hỗ trợ các tính năng FBE và Khởi động trực tiếp. Bao gồm các:

  • Trình quay số AOSP (gói/ứng dụng/Trình quay số)
  • Đồng hồ để bàn (gói/ứng dụng/DeskClock)
  • LatinIME (gói/phương thức nhập/LatinIME)*
  • Cài đặt Ứng dụng (gói/ứng dụng/Cài đặt)*
  • SystemUI (khung/cơ sở/gói/SystemUI)*

* Các ứng dụng hệ thống sử dụng thuộc tính tệp kê khai defaultToDeviceProtectedStorage

Có thể tìm thấy nhiều ví dụ khác về các ứng dụng và dịch vụ nhận biết mã hóa bằng cách chạy lệnh mangrep directBootAware trong thư mục khung hoặc gói của cây nguồn AOSP.

phụ thuộc

Để sử dụng triển khai AOSP của FBE một cách an toàn, thiết bị cần đáp ứng các yếu tố phụ thuộc sau:

  • Hạt nhân Hỗ trợ mã hóa Ext4 hoặc mã hóa F2FS.
  • Hỗ trợ Keymaster với HAL phiên bản 1.0 trở lên. Không có hỗ trợ cho Keymaster 0.3 vì điều đó không cung cấp các khả năng cần thiết hoặc đảm bảo đủ khả năng bảo vệ cho các khóa mã hóa.
  • Keymaster/ Keystore và Gatekeeper phải được triển khai trong Môi trường thực thi tin cậy (TEE) để cung cấp khả năng bảo vệ cho các khóa DE sao cho một hệ điều hành trái phép (hệ điều hành tùy chỉnh được cài đặt trên thiết bị) không thể yêu cầu các khóa DE một cách đơn giản.
  • Root phần cứng đáng tin cậyKhởi động được xác minh ràng buộc với khởi tạo Keymaster là bắt buộc để đảm bảo rằng các khóa DE không thể truy cập được bởi một hệ điều hành trái phép.

Thực hiện

Trước hết, các ứng dụng như đồng hồ báo thức, điện thoại và các tính năng trợ năng phải được tạo thành android:directBootAware theo tài liệu dành cho nhà phát triển Direct Boot .

hỗ trợ hạt nhân

Hỗ trợ hạt nhân cho mã hóa Ext4 và F2FS có sẵn trong các hạt nhân thông thường của Android, phiên bản 3.18 trở lên. Để kích hoạt nó trong kernel phiên bản 5.1 trở lên, hãy sử dụng:

CONFIG_FS_ENCRYPTION=y

Đối với các nhân cũ hơn, hãy sử dụng CONFIG_EXT4_ENCRYPTION=y nếu hệ thống tệp userdata của thiết bị là Ext4 hoặc sử dụng CONFIG_F2FS_FS_ENCRYPTION=y nếu hệ thống tệp userdata của thiết bị là F2FS.

Nếu thiết bị của bạn hỗ trợ bộ nhớ có thể chấp nhận hoặc sẽ sử dụng mã hóa siêu dữ liệu trên bộ nhớ trong, hãy bật tùy chọn cấu hình nhân cần thiết để mã hóa siêu dữ liệu như được mô tả trong tài liệu mã hóa siêu dữ liệu .

Ngoài hỗ trợ chức năng cho mã hóa Ext4 hoặc F2FS, các nhà sản xuất thiết bị cũng nên kích hoạt tăng tốc mã hóa để tăng tốc độ mã hóa dựa trên tệp và cải thiện trải nghiệm người dùng. Ví dụ: trên các thiết bị dựa trên ARM64, có thể bật tính năng tăng tốc ARMv8 CE (Tiện ích mở rộng mật mã) bằng cách đặt các tùy chọn cấu hình kernel sau:

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.

Thẩm định

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 Sự miêu tả 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.