Hỗ trợ Android 7.0 trở lên mã hoá dựa trên tệp (FBE). FBE cho phép mã hoá các tệp khác nhau bằng các khoá khác nhau mà có thể mở khoá một cách độc lập. Các khoá này dùng để mã hoá cả nội dung tệp và tên tệp. Khi sử dụng FBE, các thông tin khác như bố cục thư mục, kích thước tệp, quyền truy cập và thời gian tạo/sửa đổi thì không được mã hoá. Nói chung, thông tin khác này được gọi là siêu dữ liệu hệ thống tệp.
Android 9 ra mắt tính năng hỗ trợ tính năng mã hoá siêu dữ liệu. Với tính năng mã hoá siêu dữ liệu, một khoá duy nhất có tại thời điểm khởi động sẽ mã hoá mọi thông tin nội dung không được FBE mã hoá. Khoá này được bảo vệ bởi Keymaster, được bảo vệ bằng quy trình khởi động xác minh.
Tính năng mã hoá siêu dữ liệu luôn bật trên bộ nhớ cho phép bất cứ khi nào tính năng FBE được bật. Bạn cũng có thể bật tính năng mã hoá siêu dữ liệu trên bộ nhớ trong. Thiết bị đã ra mắt với Android 11 trở lên phải mã hoá siêu dữ liệu trên bộ nhớ trong.
Triển khai trên bộ nhớ trong
Bạn có thể thiết lập lớp mã hoá siêu dữ liệu trên bộ nhớ trong của thiết bị mới bằng cách
thiết lập hệ thống tệp metadata
, thay đổi trình tự khởi tạo và
bật tính năng mã hoá siêu dữ liệu trong tệp fstab của thiết bị.
Điều kiện tiên quyết
Bạn chỉ có thể thiết lập phương thức mã hoá siêu dữ liệu khi phân vùng dữ liệu được thiết lập trước đã định dạng. Do đó, tính năng này chỉ dành cho các thiết bị mới; đây không phải là điều gì đó mà OTA nên thay đổi.
Việc mã hoá siêu dữ liệu yêu cầu mô-đun dm-default-key
bật trong nhân của mình. Trong Android 11 trở lên,
dm-default-key
được hỗ trợ bởi các nhân hệ điều hành phổ biến của Android, phiên bản
4.14 trở lên. Phiên bản dm-default-key
này sử dụng phần cứng và
khung mã hoá độc lập với nhà cung cấp có tên là blk-Crypto.
Để bật dm-default-key
, hãy sử dụng:
CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_DM_DEFAULT_KEY=y
dm-default-key
sử dụng phần cứng mã hoá nội tuyến (phần cứng
mã hoá/giải mã dữ liệu trong quá trình truyền đến/từ thiết bị lưu trữ) khi
sẵn có. Nếu bạn không sử dụng phần cứng mã hoá cùng dòng, thì
cũng cần bật tính năng dự phòng cho API mã hoá của nhân:
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
Khi không sử dụng phần cứng mã hoá cùng dòng, bạn cũng nên bật mọi tuỳ chọn Tăng tốc dựa trên CPU theo đề xuất trong tài liệu FBE.
Trong Android 10 trở xuống, dm-default-key
không được nhân hệ điều hành chung của Android hỗ trợ. Vì vậy, nhà cung cấp có trách nhiệm
để triển khai dm-default-key
.
Thiết lập hệ thống tệp siêu dữ liệu
Bởi vì không có dữ liệu nào trong phân vùng dữ liệu người dùng có thể được đọc cho đến khi siêu dữ liệu có khoá mã hoá, bảng phân vùng phải dành riêng một khoá được gọi là "phân vùng siêu dữ liệu" để lưu trữ các blob keymaster bảo vệ khoá này. Phân vùng siêu dữ liệu phải có kích thước 16MB.
fstab.hardware
phải bao gồm một mục nhập cho hệ thống tệp siêu dữ liệu
nằm trên phân vùng đó, gắn kết nó tại /metadata
, bao gồm
cờ formattable
để đảm bảo mã được định dạng vào thời điểm khởi động. Chiến lược phát hành đĩa đơn
Hệ thống tệp f2fs không hoạt động trên các phân vùng nhỏ hơn; bạn nên dùng ext4
thay thế. Ví dụ:
/dev/block/bootdevice/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard wait,check,formattable
Để đảm bảo điểm gắn /metadata
đã tồn tại, hãy thêm dòng sau
đến BoardConfig-common.mk
:
BOARD_USES_METADATA_PARTITION := true
Các thay đổi đối với trình tự khởi tạo
Khi sử dụng tính năng mã hoá siêu dữ liệu, vold
phải chạy trước
/data
đã được gắn kết. Để đảm bảo sự kiện bắt đầu đủ sớm, hãy thêm
đoạn thơ sau cho init.hardware.rc
:
# We need vold early for metadata encryption on early-fs start vold
Keymaster phải đang chạy và sẵn sàng trước khi bắt đầu cố gắng gắn kết
/data
.
init.hardware.rc
phải chứa mount_all
lệnh gắn /data
chính nó trong khổ on
late-fs
. Trước dòng này, thêm lệnh để thực thi
Dịch vụ wait_for_keymaster
:
on late-fs … # Wait for keymaster exec_start wait_for_keymaster # Mount RW partitions which need run fsck mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --late
Bật tính năng mã hóa siêu dữ liệu
Cuối cùng, hãy thêm keydirectory=/metadata/vold/metadata_encryption
vào
Cột fs_mgr_flags của mục nhập fstab
cho
userdata
. Ví dụ: một dòng fstab đầy đủ có thể có dạng như sau:
/dev/block/bootdevice/by-name/userdata /data f2fs noatime,nosuid,nodev,discard,inlinecrypt latemount,wait,check,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized,keydirectory=/metadata/vold/metadata_encryption,quota,formattable
Theo mặc định, thuật toán mã hoá siêu dữ liệu trên bộ nhớ trong là
AES-256-XTS. Bạn có thể ghi đè lựa chọn này bằng cách đặt giá trị
metadata_encryption
, cũng trong
Cột fs_mgr_flags:
- Trên các thiết bị không hỗ trợ tăng tốc AES, tính năng mã hoá Adiantum có thể
được bật bằng cách đặt
metadata_encryption=adiantum
. - Trên các thiết bị hỗ trợ khoá gói phần cứng,
thì khoá mã hoá siêu dữ liệu có thể được gói phần cứng bằng cách cài đặt
metadata_encryption=aes-256-xts:wrappedkey_v0
(hoặc tương đương vớimetadata_encryption=:wrappedkey_v0
, vìaes-256-xts
là thuật toán mặc định).
Do giao diện kernel thành dm-default-key
đã thay đổi trong Android
11, bạn cũng cần đảm bảo rằng bạn đã đặt
giá trị chính xác cho PRODUCT_SHIPPING_API_LEVEL
trong
device.mk
. Ví dụ: nếu thiết bị của bạn chạy cùng với Android
11 (API cấp 30), device.mk
phải
chứa:
PRODUCT_SHIPPING_API_LEVEL := 30
Bạn cũng có thể thiết lập thuộc tính hệ thống sau đây để buộc sử dụng thuộc tính mới
API dm-default-key
bất kể cấp độ API vận chuyển:
PRODUCT_PROPERTY_OVERRIDES += \ ro.crypto.dm_default_key.options_format.version=2
Xác nhận kết quả
Để xác minh rằng tính năng mã hoá siêu dữ liệu đã được bật và hoạt động chính xác, các thử nghiệm được mô tả bên dưới. Ngoài ra, hãy lưu ý đến thông tin chung như mô tả dưới đây.
Kiểm thử
Bắt đầu bằng cách chạy lệnh sau để xác minh rằng mã hoá siêu dữ liệu đã bật trên bộ nhớ trong:
adb root
adb shell dmctl table userdata
Nội dung xuất sẽ tương tự như:
Targets in the device-mapper table for userdata: 0-4194304: default-key, aes-xts-plain64 - 0 252:2 0 3 allow_discards sector_size:4096 iv_large_sectors
Nếu bạn ghi đè các chế độ cài đặt mã hoá mặc định bằng cách đặt
metadata_encryption
trong fstab
của thiết bị, sau đó
kết quả sẽ hơi khác so với kết quả ở trên. Ví dụ: nếu bạn bật mã hóa Adiantum, thì
sẽ là xchacha12,aes-adiantum-plain64
thay vì
aes-xts-plain64
.
Tiếp theo, hãy chạy lệnh vts_kernel_encryption_test để xác minh tính chính xác của mã hoá siêu dữ liệu và FBE:
atest vts_kernel_encryption_test
hoặc:
vts-tradefed run vts -m vts_kernel_encryption_test
Các vấn đề thường gặp
Trong lệnh gọi đến mount_all
, lệnh này gắn siêu dữ liệu đã mã hoá
Phân vùng /data
, init
sẽ thực thi công cụ vdc. Vdc
công cụ kết nối với vold
qua binder
để thiết lập
thiết bị được mã hoá siêu dữ liệu và gắn kết phân vùng. Trong khoảng thời gian này
cuộc gọi, init
bị chặn và cố gắng đọc hoặc đặt
Các thuộc tính init
sẽ bị chặn cho đến khi mount_all
kết thúc.
Nếu ở giai đoạn này, bất kỳ phần nào trong công việc của vold
trực tiếp hoặc
bị chặn gián tiếp khi đọc hoặc đặt thuộc tính, thì tình trạng tắc nghẽn sẽ xảy ra. Đó là
để đảm bảo rằng vold
có thể hoàn tất thao tác đọc
khoá, tương tác với Keymaster và gắn thư mục dữ liệu mà không cần
tương tác nhiều hơn với init
.
Nếu Keymaster chưa khởi động hoàn toàn khi mount_all
chạy, thì Keymaster sẽ không
phản hồi vold
cho đến khi đọc một số thuộc tính nhất định từ
init
, dẫn đến tình trạng tắc nghẽn chính xác được mô tả. Đặt hàng
exec_start wait_for_keymaster
trên mức có liên quan
Lệnh gọi mount_all
như đã đề ra đảm bảo rằng Keymaster hoàn toàn
chạy trước nên tránh được tình trạng tắc nghẽn này.
Cấu hình trên bộ nhớ có thể sử dụng
Kể từ Android 9, một hình thức mã hoá siêu dữ liệu được luôn bật trên bộ nhớ tích hợp bất cứ khi nào FBE được bật, ngay cả khi chế độ mã hoá siêu dữ liệu không được bật trên bộ nhớ trong.
Trong AOSP, có hai cách triển khai mã hoá siêu dữ liệu trên
bộ nhớ: một bộ nhớ không dùng nữa dựa trên dm-crypt
và một bộ nhớ mới hơn dựa trên
vào ngày dm-default-key
. Để đảm bảo rằng triển khai chính xác
cho thiết bị của bạn, hãy đảm bảo rằng bạn đã đặt giá trị chính xác cho
PRODUCT_SHIPPING_API_LEVEL
trong device.mk
. Ví dụ:
nếu thiết bị chạy Android 11 (API cấp 30),
device.mk
phải chứa:
PRODUCT_SHIPPING_API_LEVEL := 30
Bạn cũng có thể thiết lập các thuộc tính hệ thống sau để buộc sử dụng thuộc tính mới phương thức mã hoá siêu dữ liệu thể tích (và phiên bản chính sách FBE mặc định mới) bất kể cấp độ API vận chuyển:
PRODUCT_PROPERTY_OVERRIDES += \ ro.crypto.volume.metadata.method=dm-default-key \ ro.crypto.dm_default_key.options_format.version=2 \ ro.crypto.volume.options=::v2
Phương thức hiện tại
Trên các thiết bị chạy Android 11 trở lên,
việc mã hoá siêu dữ liệu trên bộ nhớ có thể sử dụng sử dụng dm-default-key
nhân, giống như trên bộ nhớ trong. Xem các điều kiện tiên quyết ở trên đối với cấu hình nhân hệ điều hành
để bật. Lưu ý rằng phần cứng mã hoá nội tuyến hoạt động trên
bộ nhớ trong của thiết bị có thể không có sẵn trên bộ nhớ có thể chấp nhận và do đó
Bạn có thể cần phải nhập CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
.
Theo mặc định, phương thức mã hoá siêu dữ liệu ổ đĩa dm-default-key
sử dụng thuật toán mã hóa AES-256-XTS với các lĩnh vực mật mã 4096 byte. Chiến lược phát hành đĩa đơn
bạn có thể ghi đè thuật toán bằng cách đặt
Thuộc tính hệ thống ro.crypto.volume.metadata.encryption
. Chiến dịch này
giá trị của thuộc tính có cú pháp giống như metadata_encryption
fstab được mô tả ở trên. Ví dụ: trên các thiết bị không có AES
tăng tốc, mã hoá Adiantum
có thể được bật bằng cách cài đặt
ro.crypto.volume.metadata.encryption=adiantum
.
Phương thức cũ
Trên các thiết bị chạy Android 10 trở xuống, siêu dữ liệu
mã hoá trên bộ nhớ áp dụng sử dụng mô-đun nhân dm-crypt
thay vì dm-default-key
:
CONFIG_DM_CRYPT=y
Không giống như phương thức dm-default-key
, phương thức dm-crypt
khiến nội dung tệp được mã hoá hai lần: một lần bằng khoá FBE và một lần bằng khoá
khoá mã hoá siêu dữ liệu. Phương thức mã hoá kép này làm giảm hiệu suất và
không cần thiết để đạt được các mục tiêu bảo mật của việc mã hoá siêu dữ liệu, vì Android
đảm bảo rằng khoá FBE ít nhất cũng khó bị xâm phạm như siêu dữ liệu
khoá mã hoá. Các nhà cung cấp có thể tuỳ chỉnh nhân hệ điều hành để tránh trường hợp
mã hoá, cụ thể là bằng cách triển khai
Tuỳ chọn allow_encrypt_override
mà Android sẽ truyền đến
dm-crypt
khi thuộc tính hệ thống
ro.crypto.allow_encrypt_override
được đặt thành true
.
Nhân hệ điều hành thông thường của Android không hỗ trợ những tuỳ chỉnh này.
Theo mặc định, phương thức mã hoá siêu dữ liệu ổ đĩa dm-crypt
sử dụng
Thuật toán mã hoá AES-128-CBC với các lĩnh vực tiền mã hoá 512 byte và ESSIV. Chiến dịch này
có thể bị ghi đè bằng cách đặt các thuộc tính hệ thống sau (cũng nằm
được sử dụng cho FDE):
ro.crypto.fde_algorithm
chọn phương thức mã hoá siêu dữ liệu thuật toán. Các lựa chọn làaes-128-cbc
vàadiantum
Chỉ có thể sử dụng Adiantum nếu thiết bị thiếu tính năng tăng tốc AES.ro.crypto.fde_sector_size
chọn quy mô khu vực tiền mã hoá. Các lựa chọn là 512, 1024, 2048 và 4096. Đối với mã hoá Adiantum, hãy sử dụng 4096.