Mã hoá dựa trên tệp

Android 7.0 trở lên hỗ trợ phương thức mã hoá dựa trên tệp (FBE). Phương thức mã hoá dựa trên tệp cho phép mã hoá nhiều tệp bằng nhiều khoá có thể mở khoá độc lập.

Bài viết này mô tả cách bật tính năng mã hoá 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 và an toàn nhất có thể.

Tất cả thiết bị chạy Android 10 trở lên đều bắt buộc phải sử dụng phương thức mã hoá dựa trên tệp.

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

Phương thức mã hoá dựa trên tệp bật một tính năng mới ra mắt trong Android 7.0 có tên là Khởi động trực tiếp. Tính năng Khởi động trực tiếp cho phép các thiết bị đã mã hoá khởi động thẳng vào màn hình khoá. Trước đây, trên các thiết bị được mã hoá bằng tính năng mã hoá 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 vào bất kỳ dữ liệu nào, ngăn điện thoại thực hiện mọi thao tác ngoại trừ các thao tác cơ bản nhất. Ví dụ: chuông báo không hoạt động, không có dịch vụ hỗ trợ tiếp cận và điện thoại không nhận được cuộc gọi mà chỉ có thể thực hiện các thao tác cơ bản của trình quay số khẩn cấp.

Với việc giới thiệu phương thức mã hoá dựa trên tệp (FBE) và các API mới để giúp ứng dụng nhận biết được phương thức mã hoá, 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, đồng thời 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 của thiết bị có hai vị trí lưu trữ dành cho ứng dụng:

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

Việc phân tách này giúp hồ sơ công việc an toàn hơn vì cho phép bảo vệ nhiều người dùng cùng một lúc vì quá trình mã hoá 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 được phương thức mã hoá truy cập vào từng khu vực trong số này. Có một số 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ộ nhớ CE của người dùng được mở khoá để phản hồi việc nhập thông tin xác thực lần đầu tiên trên màn hình khoá, hoặc trong trường hợp hồ sơ công việc cung cấp 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. Tuy nhiên, nếu không có FBE, bộ nhớ DE và CE luôn ở trạng thái mở khoá.

Việc triển khai hoàn chỉnh phương thức mã hoá 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ể tìm hiểu các cách tối ưu hoá tính năng này 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 được tính năng khởi động trực tiếp. Tuy nhiên, khi sử dụng các phiên bản tuỳ chỉnh của những ứng dụng này, nhà sản xuất thiết bị 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 khoá

Ví dụ và nguồn

Android cung cấp phương thức triển khai tham chiếu của phương thức mã hoá dựa trên tệp, trong đó vold (system/vold) cung cấp chức năng quản lý phương tiện lưu trữ và phương tiện lưu trữ trên Android. Việc thêm FBE cung cấp cho vold một số lệnh mới để hỗ trợ quản lý khoá cho các khoá CE và DE của nhiều người dùng. Ngoài những thay đổi chính để sử dụng khả năng mã hoá dựa trên tệp trong nhân, nhiều gói hệ thống (bao gồm cả màn hình khoá 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:

  • Trình quay số AOSP (packages/apps/Dialer)
  • Đồng hồ để bàn (packages/apps/DeskClock)
  • LatinIME (gói/phương thức nhập/Mỹ Latinh)*
  • Ứng dụng Cài đặt (packages/apps/Settings)*
  • SystemUI (frameworks/base/packages/SystemUI)*

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

Bạn có thể xem thêm ví dụ về các ứng dụng và dịch vụ có khả năng nhận biết quá trình mã hoá bằng cách chạy lệnh mangrep directBootAware trong thư mục khung hoặc thư mục gói của cây nguồn AOSP.

Phần phụ thuộc

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

  • Hỗ trợ kernel để mã hoá Ext4 hoặc mã hoá F2FS.
  • Hỗ trợ Keymaster với HAL phiên bản 1.0 trở lên. Không hỗ trợ Keymaster 0.3 vì phiên bản này không cung cấp các chức năng cần thiết hoặc đảm bảo bảo vệ đầy đủ cho các khoá mã hoá.
  • Bạn phải triển khai Keymaster/Keystore và Cổng vào trong một Môi trường thực thi đáng tin cậy (TEE) nhằm bảo vệ các khoá DE sao cho một hệ điều hành chưa được uỷ quyền (hệ điều hành tuỳ chỉnh được cài đặt ROM trên thiết bị) không thể chỉ yêu cầu khoá DE.
  • Hardware Root of Trust (Gốc phần cứng) và Xác minh quy trình khởi động được liên kết với quá trình khởi chạy Keymaster là bắt buộc để đảm bảo rằng hệ điều hành trái phép không thể truy cập vào các khoá DE.

Triển khai

Trước tiên, các ứng dụng như đồng hồ báo thức, điện thoại và các tính năng hỗ trợ tiếp cận phải được tạo android:directBootAware theo tài liệu dành cho nhà phát triển về tính năng Khởi động trực tiếp.

Hỗ trợ nhân

Hỗ trợ hạt nhân cho phương thức mã hoá Ext4 và F2FS có trong các hạt nhân phổ biến của Android, phiên bản 3.18 trở lên. Để bật tính năng này trong một hạt nhân 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ãy dùng CONFIG_EXT4_ENCRYPTION=y nếu hệ thống tệp userdata của thiết bị là Ext4 hoặc 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ể sử dụng hoặc sử dụng tính năng mã hoá siêu dữ liệu trên bộ nhớ trong, bạn cũng nên bật các tuỳ chọn cấu hình hạt nhân cần thiết để mã hoá siêu dữ liệu như mô tả trong tài liệu về mã hoá siêu dữ liệu.

Ngoài việc hỗ trợ chức năng cho phương thức mã hoá Ext4 hoặc F2FS, nhà sản xuất thiết bị cũng nên bật tính năng tăng tốc mã hoá để tăng tốc độ mã hoá 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, bạn có thể bật tính năng tăng tốc ARMv8 CE (Tiện ích mật mã) bằng cách đặt các tuỳ 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 hiệu suất hơn nữa và giảm mức sử dụng điện năng, nhà sản xuất thiết bị cũng có thể cân nhắc việc triển khai phần cứng mã hoá nội tuyến, giúp mã hoá/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 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 phương thức mã hoá cùng dòng khi có dịch vụ hỗ trợ trình điều khiển phần cứng và nhà cung cấp. Bạn có thể bật khung mã hoá cùng dòng bằng cách đặt các tuỳ chọn cấu hình nhân hệ điều hành sau đây:

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ộ nhớ dựa trên UFS, bạn cũng hãy bật:

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

Bật tính năng mã hoá dựa trên tệp

Để bật FBE trên thiết bị, bạn phải bật tính năng này trên bộ nhớ trong (userdata). Thao tác này cũng tự động bật FBE trên bộ nhớ có thể chuyển đổi; tuy nhiên, bạn có thể ghi đè định dạng mã hoá trên bộ nhớ có thể chuyển đổi nếu cần.

Bộ nhớ trong

Bạn có thể bật FBE bằng cách thêm tuỳ chọn fileencryption=contents_encryption_mode[:filenames_encryption_mode[:flags]] vào cột fs_mgr_flags của dòng fstab cho userdata. Tuỳ chọn này xác định định dạng mã hoá trên bộ nhớ trong. Tệp này chứa tối đa 3 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ật mã dùng để mã hoá nội dung tệp. Đó có thể là aes-256-xts hoặc adiantum. Kể từ Android 11, bạ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ật mã dùng để mã hoá tên tệp. Giá trị này có thể là aes-256-cts, aes-256-heh, adiantum hoặc aes-256-hctr2. Nếu không được chỉ định, giá trị mặc định sẽ là aes-256-cts nếu contents_encryption_modeaes-256-xts hoặc adiantum nếu contents_encryption_modeadiantum.
  • Tham số flags, mới có trong Android 11, là danh sách các cờ được phân tách bằng ký tự +. Sau đây là các cờ được hỗ trợ:
    • Cờ v1 chọn các chính sách mã hoá phiên bản 1; cờ v2 chọn các chính sách mã hoá phiên bản 2. Chính sách mã hoá phiên bản 2 sử dụng hàm dẫn xuất khoá an toàn và linh hoạt hơn. Mặc định là phiên bản 2 nếu thiết bị chạy trên Android 11 trở lên (do ro.product.first_api_level xác định) hoặc phiên bản 1 nếu thiết bị chạy trên Android 10 trở xuống.
    • Cờ inlinecrypt_optimized chọn một định dạng mã hoá được tối ưu hoá cho phần cứng mã hoá cùng dòng không xử lý hiệu quả một lượng lớn khoá. Thư viện này thực hiện việc này bằng cách chỉ lấy một khoá mã hoá nội dung tệp cho mỗi khoá CE hoặc DE, thay vì một khoá cho mỗi tệp. Quá trình tạo IV (vectơ khởi tạo) được điều chỉnh cho phù hợp.
    • Cờ emmc_optimized tương tự như inlinecrypt_optimized, nhưng cũng chọn một phương thức tạo IV giới hạn IV ở 32 bit. Bạn chỉ nên sử dụng cờ này trên phần cứng mã hoá cùng dòng tuân thủ thông số kỹ thuật JEDEC eMMC phiên bản 5.2 nên chỉ hỗ trợ IV 32 bit. Trên các phần cứng mã hoá cùng dòng khác, hãy sử dụng inlinecrypt_optimized. Bạn không bao giờ được sử dụng cờ này trên bộ nhớ dựa trên UFS; thông số kỹ thuật UFS cho phép sử dụng IV 64 bit.
    • Trên các thiết bị hỗ trợ khoá gói phần cứng, cờ wrappedkey_v0 cho phép sử dụng khoá bọc phần cứng cho FBE. Bạn chỉ có thể sử dụng tính năng này kết hợp với tuỳ chọn gắn inlinecrypt và cờ inlinecrypt_optimized hoặc emmc_optimized.
    • Cờ dusize_4k buộc kích thước đơn vị dữ liệu mã hoá phải 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ã hoá là mức độ chi tiết của quá trình mã hoá nội dung tệp. Cờ này có từ Android 15. Bạn chỉ nên sử dụng cờ này để cho phép sử dụng phần cứng mã hoá cùng dòng không hỗ trợ các đơn vị dữ liệu lớn hơn 4096 byte, trên một 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ã hoá cùng dòng, chế độ cài đặt nên dùng cho hầu hết thiết bị là fileencryption=aes-256-xts. Nếu bạn đang sử dụng phần cứng mã hoá cùng dòng, chế độ 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 fileencryption=::inlinecrypt_optimized tương đương). Trên các thiết bị không hỗ trợ tính năng tăng tốc AES bất kỳ, bạn có thể dùng Adiantum thay cho AES bằng cách đặt fileencryption=adiantum.

Kể từ Android 14, AES-HCTR2 là chế độ mã hoá tên tệp ưu tiên cho các thiết bị có hướng dẫn mã hoá tăng tốc. Tuy nhiên, chỉ các hạt nhân Android mới hơn mới hỗ trợ AES-HCTR2. Trong một bản phát hành Android sau này, chế độ này được lên kế hoạch trở thành chế độ mặc định cho hoạt động mã hoá tên tệp. Nếu nhân hệ điều hành của bạn hỗ trợ AES-HCTR2, thì bạn có thể bật tính năng mã hoá 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 bằng 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ã hoá nội dung tệp FSCRYPT_MODE_PRIVATE. Chế độ này chưa được các nhân phổ biến của Android triển khai, nhưng các nhà cung cấp có thể triển khai bằng cách sử dụng bản vá nhân hệ điều hành tuỳ 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 cho phép và bạn phải dùng định dạng mã hoá tiêu chuẩn.

Theo mặc định, quá trình mã hoá nội dung tệp được thực hiện bằng API mã hoá của nhân Linux. Nếu bạn muốn sử dụng phần cứng mã hoá cùng dòng, hãy thêm cả lựa chọn gắn kết inlinecrypt. Ví dụ: dòng fstab đầy đủ có thể có dạ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ớ thích ứng

Kể từ Android 9, bạn có thể dùng FBE và bộ nhớ tích hợp cùng nhau.

Việc chỉ định tuỳ chọn fstab fileencryption cho userdata cũng tự động bật cả FBE và mã hoá siêu dữ liệu trên bộ nhớ có thể sử dụng. Tuy nhiên, bạn có thể ghi đè các định dạng mã hoá siêu dữ liệu hoặc FBE trên bộ nhớ 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ã hoá FBE trên bộ nhớ có thể chuyển đổi. Thành phần này có cú pháp giống với đối số cho tuỳ chọn thẻ fstab fileencryption và sử dụng cùng các giá trị mặc định. Hãy xem các đề xuất cho 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ã hoá siêu dữ liệu trên bộ nhớ có thể chuyển đổi. Xem tài liệu về việc mã hoá 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ã hoá nội dung. Giá trị 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ã hoá tên tệp. Giá trị 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ừ giá 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 thiết bị, bạn cần ghi đè giá trị này thành aes-256-cts một cách rõ ràng.
  • ro.crypto.fde_algorithmro.crypto.fde_sector_size chọn định dạng mã hoá siêu dữ liệu trên bộ nhớ có thể chuyển đổi. Hãy xem tài liệu về mã hoá siêu dữ liệu.

Tích hợp với Keymaster

Bạn nên bắt đầu Keymaster HAL trong 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 theo giai đoạn khởi động post-fs-data, tức là khi vold thiết lập các khoá ban đầu.

Loại trừ thư mục

init áp dụng khoá DE hệ thống cho mọi thư mục cấp cao nhất của /data, ngoại trừ các thư mục phải chưa được mã hoá, chẳng hạn như thư mục chứa chính khoá 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. Khoá mã hoá áp dụng theo quy tắc đệ quy và không thể bị thư mục con ghi đè.

Trong Android 11 trở lên, khoá mà init áp dụng cho các thư mục có thể được kiểm soát bằng đối số encryption=<action> cho lệnh mkdir trong tập lệnh khởi động. 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 thao tác mã hoá init được mã hoá cứng vào vị trí sau:

/system/extras/libfscrypt/fscrypt_init_extensions.cpp

Trong Android 9 trở xuống, vị trí này là:

/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp

Bạn có thể thêm các trường hợp ngoại lệ để ngăn một số thư mục nhất định không được mã hoá. Nếu thực hiện các sửa đổi loại này, nhà sản xuất thiết bị phải đưa vào 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 chưa mã hoá. Thao tác 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 tính năng OTA cũ.

Hỗ trợ tính năng Khởi động trực tiếp trong các ứng dụng hệ thống

Giúp ứng dụng nhận biết chế độ Khởi động trực tiếp

Để hỗ trợ di chuyển nhanh các ứng dụng hệ thống, bạn có thể đặt hai thuộc tính mới ở cấp ứng dụng. Thuộc tính defaultToDeviceProtectedStorage chỉ dành cho các ứng dụng hệ thống. Tất cả mọi người đều có thể sử dụng thuộc tính directBootAware.

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

Thuộc tính directBootAware ở cấp ứng dụng là viết tắt để đánh dấu tất cả các thành phần trong ứng dụng là có khả năng nhận biết quá trình mã hoá.

Thuộc tính defaultToDeviceProtectedStorage sẽ chuyển hướng vị trí lưu trữ ứng dụng mặc định để trỏ đến bộ nhớ DE thay vì trỏ đến bộ nhớ CE. Các ứng dụng hệ thống sử dụng cờ này phải kiểm tra kỹ 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ộ nhớ CE. Các nhà sản xuất thiết bị sử dụng tuỳ chọn này nên kiểm tra kỹ 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 sẽ có sẵn để quản lý rõ ràng Ngữ cảnh được bộ nhớ CE hỗ trợ khi cần, tương đương với các API được bảo vệ của thiết bị.

  • 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 khoá mã hoá riêng. Mỗi người dùng nhận được 2 khoá: khoá DE và CE. Người dùng 0 phải đăng nhập vào thiết bị trước vì đó là người dùng đặc biệt. Điều này phù hợp với việc sử dụng Quản lý thiết bị.

Các ứng dụng nhận biết tiền mã hoá tương tác với người dùng theo cách sau: INTERACT_ACROSS_USERSINTERACT_ACROSS_USERS_FULL cho phép một ứng dụng hành động với tất cả người dùng trên thiết bị. Tuy nhiên, các ứng dụng đó chỉ có thể truy cập vào các thư mục được mã hoá bằng CE cho những người dùng đã được mở khoá.

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 đã mở khoá không có nghĩa là tất cả người dùng trên thiết bị đều được mở khoá. Ứng dụng phải kiểm tra trạng thái này trước khi cố gắng truy cập vào những khu vực này.

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

Xử lý nội dung cập nhật

Phân vùng khôi phục không thể truy cập vào bộ nhớ được bảo vệ bằng DE trên phân vùng userdata. Các thiết bị triển khai FBE nên hỗ trợ OTA bằng 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 bạn không cần khôi phục để truy cập vào dữ liệu trên ổ đĩa đã mã hoá.

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

  1. Tạo 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ã hoá (xem phần Loại trừ thư mục).
  3. Tạo một thư mục trong thư mục cấp cao nhất để lưu giữ 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 thư mục. 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 ứ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.

Xác nhận kết quả

Để đảm bảo rằng phiên bản được triển khai của tính năng hoạt động như mong đợi, trước tiên, hãy chạy nhiều loại hình kiểm thử mã hoá CTS, chẳng hạn như DirectBootHostTestEncodingTest.

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, nhà sản xuất thiết bị có thể thực hiện các kiểm thử thủ công sau đây. Trên thiết bị đã bật FBE:

  • Kiểm tra để đảm bảo rằng ro.crypto.state tồn tại
    • Đảm bảo ro.crypto.state đã được mã hoá
  • Kiểm tra để đảm bảo rằng ro.crypto.type tồn tại
    • Đảm bảo bạn đã đặt ro.crypto.type thành file

Ngoài ra, người kiểm thử có thể xác minh rằng bộ nhớ CE đã bị khoá trước khi thiết bị được mở khoá 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ở khoá hoặc mật khẩu cho người dùng chính rồi khởi động lại thiết bị. Trước khi mở khoá thiết bị, hãy chạy lệnh sau để kiểm tra bộ nhớ 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 có giao diện người dùng (hầu hết các thiết bị ô tô), thì 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 là thiết bị không dùng ô 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ã hoá Base64, cho biết rằng tên tệp đã được mã hoá và chưa có khoá để giải mã. Nếu tên tệp được liệt kê ở dạng văn bản thuần tuý, thì có gì đó không ổn.

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

Thông tin chi tiết về việc triển khai AOSP

Phần này cung cấp thông tin chi tiết về cách triển khai AOSP và mô tả cách hoạt động của tính năng mã hoá dựa trên tệp. 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 tại đây để sử dụng FBE và Khởi động trực tiếp trên thiết bị của họ.

Mã hoá fscrypt

Việc triển khai AOSP sử dụng phương thức mã hoá "fscrypt" (do ext4 và f2fs hỗ trợ) trong nhân và thường được định cấu hình để:

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

Công nghệ mã hoá Adiantum cũng được hỗ trợ. Khi tính năng mã hoá Adiantum bật, cả nội dung tệp và tên tệp đều được mã hoá 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òn được dùng nữa và các yêu cầu của CDD đối với 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ã hoá phiên bản 2 sử dụng HKDF-SHA512 để lấy khoá mã hoá thực tế từ các khoá 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 về nhân cấp trên.

Lớp bộ nhớ

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

Lớp bộ nhớ Mô 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 bảo vệ bằng FBE. Trên các thiết bị sử dụng tính năng mã hoá siêu dữ liệu, các thư mục này không thực sự được mã hoá mà được bảo vệ bằng khoá mã hoá siêu dữ liệu tương đương với DE hệ thống.
  • /data/apex, ngoại trừ /data/apex/decompressed/data/apex/ota_reserved là DE hệ thống
  • /data/lost+found
  • /data/preloads
  • /data/unencrypted
  • Tất cả thư mục có thư mục con sử dụng các khoá FBE khác nhau. Ví dụ: vì mỗi thư mục /data/user/${user_id} sử dụng một khoá cho mỗi người dùng, nên /data/user không sử dụng khoá nào.
DE hệ thống Dữ liệu được mã hoá trên thiết bị không liên kết 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ả thư mục con khác của /data mà bảng này không đề cập 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ã hoá thông tin đăng nhập 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ã hoá trên thiết bị theo từng 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}
CE của người dùng (có thể sử dụng) Dữ liệu được mã hoá thông tin đăng nhập cho mỗi người dùng trên bộ nhớ cho phép
  • /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ã hoá theo thiết bị cho mỗi người dùng trên bộ nhớ cho phép
  • /mnt/expand/${volume_uuid}/misc_de/${user_id}
  • /mnt/expand/${volume_uuid}/user_de/${user_id}

Lưu trữ và bảo vệ khoá

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

Loại khoá Vị trí khoá Lớp bộ nhớ của vị trí khoá
Khoá DE của hệ thống /data/unencrypted Không được mã hóa
Khoá CE (nội bộ) của người dùng /data/misc/vold/user_keys/ce/${user_id} Hệ thống DE
Khoá người dùng DE (nội bộ) /data/misc/vold/user_keys/de/${user_id} Hệ thống DE
Khoá CE (có thể áp dụng) của người dùng /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} Người dùng CE (nội bộ)
Khoá DE (có thể áp dụng) 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ư hiển thị trong bảng trước, hầu hết các khoá FBE được lưu trữ trong thư mục được mã hoá bằng một khoá FBE khác. Bạn không thể mở khoá các khoá cho đến khi lớp bộ nhớ chứa các khoá đó được mở khoá.

vold cũng áp dụng một lớp mã hoá cho tất cả khoá FBE. Mọi khoá ngoại trừ khoá CE cho bộ nhớ trong đều được mã hoá bằng AES-256-GCM bằng khoá Keystore (Kho khoá) riêng không hiển thị bên ngoài TEE. Điều này đảm bảo rằng không thể mở khoá các khoá FBE trừ phi hệ điều hành đáng tin cậy đã khởi động, như được thực thi bởi tính năng Khởi động được xác minh. Khả năng chống khôi phục cũng được yêu cầu trên khoá Kho khoá, cho phép xoá các khoá FBE một cách an toàn trên các thiết bị mà Keymaster hỗ trợ tính năng chống khôi phục. Là phương án dự phòng nỗ lực tối đa 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 được lưu trữ cùng với khoá sẽ được dùng làm thẻ mã ứng dụng của khoá Kho khoá. Bạn cần khôi phục tất cả các byte này để khôi phục khoá FBE.

Khoá CE cho bộ nhớ trong có mức độ bảo vệ mạnh hơn để đảm bảo không thể mở khoá nếu không biết Yếu tố kiến thức màn hình khoá (LSKF) của người dùng (mã PIN, hình mở khoá hoặc mật khẩu), mã thông báo đặt lại mật mã bảo mật hoặc cả khoá phía máy khách lẫn phía máy chủ cho thao tác Tiếp tục khi khởi động lại. Bạn chỉ được tạo mã đặ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ã hoá từng khoá CE cho bộ nhớ trong bằng cách sử dụng khoá AES-256-GCM bắt nguồn 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 khoá mật mã có độ hỗn loạn cao, không thể thay đổi đượ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ác 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 sẽ kéo dài LSKF bằng cách truyền LSKF qua scrypt, nhắm đến khoảng thời gian khoảng 25 mili giây và mức sử dụng bộ nhớ là 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 tính bảo mật. Lớp bảo mật chính là Thành phần 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 sẽ ánh xạ LSKF đã kéo dài với khoá bí mật ngẫu nhiên có entropy cao được lưu trữ trong SE bằng HAL của Weaver. Sau đó, LockSettingsService mã hoá mật khẩu tổng hợp hai lần: lần đầu tiên bằng khoá phần mềm bắt nguồn từ LSKF được kéo giãn và khoá bí mật Weaver, lần thứ hai bằng khoá Kho khoá không liên kết với 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 lần đoán LSKF.

Nếu thiết bị không có SE, thì LockSettingsService sẽ sử dụng LSKF được kéo dài làm mật khẩu Gatekeeper (Người trực điện thoại). Sau đó, LockSettingsService sẽ mã hoá mật khẩu tổng hợp hai lần: lần đầu tiên bằng một khoá phần mềm lấy từ LSKF được kéo giãn và hàm băm của một tệp có thể tách rời, rồi thứ hai bằng khoá Kho khoá có khả năng liên kết xác thực với quá trình đăng ký của Người trực điện thoại. Điều này giúp giới hạn tỷ lệ được thực thi bởi TEE của các dự đoán LSKF.

Khi LSKF thay đổi, LockSettingsService sẽ xoá mọi 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 khoá Kho khoá chống rollback, việc này đảm bảo xoá 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ệ mô tả ở đây được áp dụng ngay cả khi người dùng không có LSKF.