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 để mang đến 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ị chạy 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 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 xác thực trước khi có thể truy cập bất kỳ dữ liệu nào, điều này ngăn đ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 thức được mã hóa, các ứng dụng này có thể hoạt động trong một bối 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 riêng tư của người dùng.

Trên thiết bị hỗ trợ FBE, mỗi người dùng thiết bị có hai vị trí lưu trữ dành cho ứ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 một lúc vì việc mã hóa không còn chỉ dựa vào mật khẩu thời gian khởi động nữa.

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 vào từng khu vực này. Có những thay đổi đối với vòng đời ứ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 thông tin đăng nhập lần đầu tiên ở màn hình khóa hoặc trong trường hợp hồ sơ công việc đưa ra thách thức 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 thì kho 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 mã 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 để có khả năng khởi động trực tiếp. Tuy nhiên, khi các nhà sản xuất thiết bị sử dụng 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 mật khẩu vào màn hình khóa

Ví dụ và nguồn

Android cung cấp triển khai tham chiếu về mã hóa dựa trên tệp, 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 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 kernel , 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à Direct Boot. 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)*
  • Ứng dụng Cài đặt (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 frameworks hoặc packages 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ỗ trợ hạt nhân cho 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ì nó không cung cấp các khả năng cần thiết hoặc đảm bảo bảo vệ đầy đủ 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 đáng tin cậy (TEE) để cung cấp khả năng bảo vệ cho các khóa DE để 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ể đơn giản yêu cầu khóa DE.
  • Cần có Root of Trust của phần cứngKhởi động được xác minh được liên kết với quá trình khởi tạo Keymaster để đảm bảo rằng các khóa DE không thể truy cập được bởi hệ điều hành trái phép.

Thực hiện

Đầu tiên và quan trọng nhấ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 android:directBootAware theo tài liệu của 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 phổ biến 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 hạt nhân cũ hơn, hãy sử dụng CONFIG_EXT4_ENCRYPTION=y nếu hệ thống tệp userdata trên thiết bị của bạn là Ext4 hoặc sử dụng CONFIG_F2FS_FS_ENCRYPTION=y nếu hệ thống tệp userdata trên thiết bị của bạn là F2FS.

Nếu thiết bị của bạn hỗ trợ bộ nhớ có thể sử dụng 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 việc 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 khả năng tăng tốc mật mã để 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 khả năng tăng tốc ARMv8 CE (Tiện ích mã hóa) bằng cách đặt các tùy chọn cấu hình hạt nhân 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, 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 khi dữ liệu đang trên đường đến/từ thiết bị lưu trữ. Các nhân phổ biến của Android (phiên bản 4.14 trở lên) chứa một khung cho phép sử dụng mã hóa nội tuyến khi có hỗ trợ trình điều khiển phần cứng và nhà cung cấp. Khung mã hóa nội tuyến có thể được kích hoạ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ộ lưu trữ 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

Việc bật FBE trên thiết bị yêu cầu bật FBE trên bộ nhớ trong ( userdata ). Điều này cũng tự động kích hoạt FBE trên bộ lưu trữ có thể chấp nhận được; tuy nhiên, định dạng mã hóa trên bộ nhớ được 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 nếu contents_encryption_modeaes-256-xts hoặc thành adiantum nếu contents_encryption_modeadiantum .
  • Tham số flags , tính năng 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 đượ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. Mặc định là v2 nếu thiết bị khởi chạy trên Android 11 trở lên (đượ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ý số lượng lớn khóa một cách hiệu quả. 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 thức tạo IV giới hạn IV ở mức 32 bit. Cờ này chỉ nên được sử dụng trên phần cứng mã hóa nội tuyến tuân thủ thông số kỹ thuậ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 tả UFS cho phép sử dụng IV 64-bit.
    • Trên các thiết bị hỗ trợ khóa 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 kết inlinecrypt và cờ inlinecrypt_optimized hoặc emmc_optimized .
    • Cờ dusize_4k buộc kích thước đơn vị dữ liệu mã hóa là 4096 byte ngay cả khi kích thước khối hệ thống tệp không phải là 4096 byte. Kích thước đơn vị dữ liệu mã hóa là mức độ chi tiết của mã hóa nội dung tệp. Cờ này có sẵn kể từ Android 15 (thử nghiệm AOSP). Cờ này chỉ nên được sử dụng để cho phép sử dụng phần cứng mã hóa nội tuyến không hỗ trợ đơn vị dữ liệu lớn hơn 4096 byte, trên thiết bị sử dụng kích thước trang lớn hơn 4096 byte và sử dụng hệ thống tệp f2fs.

Nếu bạn không sử dụng phần cứng mã hóa nội tuyến thì 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, AES-HCTR2 là chế độ mã hóa tên tệp ưu tiên dành cho các thiết bị có hướng dẫn mã hóa nhanh. Tuy nhiên, chỉ các nhân Android mới hơn mới hỗ trợ AES-HCTR2. Trong 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, nó có thể được kích hoạ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, việc 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 không được triển khai bởi các nhân phổ biến của Android, 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 nữa 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 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

Bộ nhớ có thể chấp nhận

Kể từ Android 9, FBE và bộ lưu trữ có thể chấp nhận 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ộ lưu trữ có thể sử dụng. Tuy nhiên, bạn có thể ghi đè các định dạng mã hóa FBE và/hoặc siêu dữ liệu trên bộ lưu trữ có thể sử dụng bằng cách đặt các 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ể sử dụng. Nó có cú pháp giống như đối số của tùy chọn fstab fileencryption 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 nội dung cần 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ể sử dụng. 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 được phân tách bằng dấu hai chấm đầu tiên của ro.crypto.volume.options .
  • ro.crypto.volume.filenames_mode chọn chế độ mã hóa tên tệp. Điều 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ừ 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ộ lưu trữ có thể sử dụng. Xem tài liệu mã hóa siêu dữ liệu .

Tích hợp với Keymaster

Keymaster HAL phải đượ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 phải 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ừ thư mục

init áp dụng khóa DE của 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 phải không được mã hóa, chẳng hạn như thư mục chứa chính khóa DE của hệ thống và các thư mục chứa thư mục CE hoặc DE của người dùng. Khóa mã hóa áp dụng đệ 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> của 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ữ init của 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 chặn một số thư mục nhất định bị mã hóa. Nếu các sửa đổi kiểu này được thực hiện thì nhà sản xuất thiết bị nên đưa vào các chính sách SELinux chỉ cấp quyền truy cập vào 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 việc 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

Làm cho ứng dụng nhận biết Direct Boot

Để 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ả mọi người.

<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 được 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ộ lưu trữ DE thay vì trỏ đến bộ lưu trữ 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 phải 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 có sẵn để quản lý rõ ràng Ngữ cảnh được hỗ trợ bởi bộ lưu trữ CE khi cần, tương đương với các đối tác được Bảo vệ 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ẽ có một khóa mã hóa riêng. Mỗi người dùng sẽ 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 phù 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 ứng dụng hoạt động với 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 đối với những 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 đáp ứng được thử thách công việc, người dùng hồ sơ 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 vào bộ lưu trữ được bảo vệ 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 nghị 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à bối 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ỉ tiến 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 đã triển khai của tính năng này hoạt động như dự định, 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 vts_kernel_encryption_test :

atest vts_kernel_encryption_test

hoặc:

vts-tradefed run vts -m vts_kernel_encryption_test

Ngoài ra, nhà sản xuất thiết bị có thể thực hiện các kiểm tra thủ công sau đây. Trên thiết bị đã 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ể xác minh rằng bộ lưu trữ CE đã bị khóa trước khi thiết bị được mở khóa lần đầu tiên kể từ khi khởi động. Để thực hiện việc này, hãy sử dụng bản dựng userdebug hoặc eng , đặt mã PIN, hình mở khóa hoặc mật khẩu cho người dùng chính và khởi động lại thiết bị. Trước khi mở khóa thiết bị, hãy chạy lệnh sau để kiểm tra bộ lưu trữ CE của người dùng chính. Nếu thiết bị sử dụng Chế độ người dùng hệ thống không đầu (hầu hết các thiết bị Ô tô), người dùng chính là người dùng 10, vì vậy hãy chạy:

adb root; adb shell ls /data/user/10

Trên các thiết bị khác (hầu hết các thiết bị không phải Ô tô), người dùng chính là người dùng 0, vì vậy hãy chạy:

adb root; adb shell ls /data/user/0

Xác minh rằng tên tệp được liệt kê được mã hóa Base64, cho biết tên tệp đã được mã hóa và chưa có khóa để giải mã chúng. Nếu tên tệp được liệt kê ở dạng văn bản gốc thì có gì đó không ổn.

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 thử nghiệm này là một phần của bộ thử nghiệm hệ thống tập tin 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 chi tiết về cách triển khai AOSP và mô tả cách mã hóa dựa trên tệp hoạt động. Các nhà sản xuất thiết bị không cần thiết phải thực hiện bất kỳ thay đổi nào ở đây để sử dụng FBE và Direct Boot 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 kernel và thường được 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 bật mã hóa Adiantum, 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 kết quả thực tế 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 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
Không được mã hóa Các thư mục trong /data không thể hoặc không cần được FBE bảo vệ. Trên các thiết bị sử dụng mã hóa siêu dữ liệu , các thư mục này không thực sự không được mã hóa mà được bảo vệ bằng khóa mã hóa siêu dữ liệu tương đương với System DE.
  • /data/apex , không bao gồm /data/apex/decompressed/data/apex/ota_reserved là hệ thống DE
  • /data/lost+found
  • /data/preloads
  • /data/unencrypted
  • Tất cả các thư mục có thư mục con sử dụng các khóa FBE khác nhau. Ví dụ: vì mỗi thư mục /data/user/${user_id} sử dụng khóa cho mỗi người dùng nên /data/user không sử dụng khóa đó.
Hệ thống DE Dữ liệu được mã hóa thiết bị không bị ràng buộc với một người dùng cụ thể
  • /data/apex/decompressed
  • /data/apex/ota_reserved
  • /data/app
  • /data/misc
  • /data/system
  • /data/vendor
  • Tất cả các thư mục con khác của /data mà bảng này không đề cập đến là có một lớp khác
Mỗi lần khởi động Các tệp hệ thống tạm thời không cần tồn tại sau khi 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 của 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 theo 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 thông tin xác thực của mỗi người dùng trên bộ lưu trữ 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ể chấp nhận) Dữ liệu được mã hóa theo thiết bị của mỗi người dùng trên bộ nhớ có thể sử dụng
  • /mnt/expand/${volume_uuid}/misc_de/${user_id}
  • /mnt/expand/${volume_uuid}/user_de/${user_id}

Lưu trữ và bảo vệ 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 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
Khóa DE hệ thống /data/unencrypted Không được mã hóa
Khóa CE (nội bộ) của người dùng /data/misc/vold/user_keys/ce/${user_id} Hệ thống DE
Khóa DE của người dùng (nội bộ) /data/misc/vold/user_keys/de/${user_id} Hệ thống DE
Khóa CE của người dùng (có thể chấp nhận) /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} Người dùng CE (nội bộ)
Khóa DE của người dùng (có thể chấp nhận) /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ằng 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 đượ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 để lưu trữ nội bộ đều được mã hóa bằng AES-256-GCM bằng khóa Kho khóa riêng của nó không bị lộ ra bên ngoài TEE. Điều này đảm bảo rằng các khóa FBE không thể được mở khóa trừ khi một hệ điều hành đáng tin cậy đã khởi động, như được thực thi bởi Added Boot . Khả năng chống khôi phục cũng được yêu cầu trên khóa Keystore, cho phép xóa 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 khôi phục. Là giải pháp dự phòng nỗ lực tốt nhất khi không có khả năng chống khôi phục, hàm băm SHA-512 gồm 16384 byte ngẫu nhiên được lưu trữ trong tệp secdiscardable loại bỏ đượ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 Kho khóa. Tất cả các byte này cần được khôi phục để khôi phục khóa FBE.

Khóa CE dành cho bộ nhớ trong nhận được mức độ bảo vệ mạnh hơn để đảm bảo chúng không thể bị mở khóa nếu không biết Yếu tố kiến ​​thức màn hình khóa (LSKF) (mã 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 mã an toàn hoặc cả phía máy khách và các khóa phía máy chủ cho thao tác Tiếp tục khi khởi động lại . Chỉ được phép tạo mã thông báo đặt lại mật mã 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 để lưu trữ nội bộ bằng khóa AES-256-GCM 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ật mã có 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 thức bảo vệ mật khẩu đó.

Để bảo vệ mật khẩu tổng hợp bằng LSKF, LockSettingsService trước tiên sẽ mở rộng 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ì LSKF thường ngắn nên bước này thường không mang lại 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ốc độ 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 ánh xạ LSKF đã kéo dài tới một 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 lấy từ LSKF kéo dài và bí mật Weaver, lần thứ hai bằng khóa Kho khóa không được xác thực. Điều này cung cấp khả năng 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ẽ 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 bắt nguồn từ LSKF kéo dài và hàm băm của tệp có thể loại bỏ được, và lần thứ hai bằng khóa Kho khóa được xác thực ràng buộc với đăng ký Gatekeeper. Điều này cung cấp khả năng giới hạn tốc độ do TEE thực thi đối với các dự đoán LSKF.

Khi LSKF được thay đổi, LockSettingsService sẽ xóa tất cả thông tin liên quan đến việc ràng buộc mật khẩu tổng hợp với LSKF cũ. Trên các thiết bị hỗ trợ khóa Keystore chống Weaver hoặc khôi phục, đ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.