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 siêu dữ liệu

Android 7.0 và hỗ trợ cao hơn mã hóa tập tin dựa trên (FBE). FBE 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. Các khóa này được sử dụng để mã hóa cả nội dung tệp và tên tệp. Khi FBE được sử dụng, các thông tin khác, chẳng hạn như bố cục thư mục, kích thước tệp, quyền và thời gian tạo / sửa đổi, không được mã hóa. 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 đã giới thiệu hỗ trợ mã hóa siêu dữ liệu. Với mã hóa siêu dữ liệu, một khóa duy nhất có tại thời điểm khởi động sẽ mã hóa bất kỳ nội dung nào không được FBE mã hóa. Khóa này được bảo vệ bởi Keymaster, đến lượt nó được bảo vệ bằng khởi động đã xác minh.

Mã hóa siêu dữ liệu luôn được bật trên lưu trữ nhận làm con nuôi bất cứ khi nào FBE được kích hoạt. Mã hóa siêu dữ liệu cũng có thể được bật trên bộ nhớ trong.

Triển khai trên bộ nhớ trong

Bạn có thể thiết lập mã hóa 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 các metadata hệ thống tập tin, thay đổi trình tự init, và cho phép mã hóa siêu dữ liệu trong tập tin fstab của thiết bị.

Điều kiện tiên quyết

Mã hóa siêu dữ liệu chỉ có thể được thiết lập khi phân vùng dữ liệu được định dạng lần đầu tiên. 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 mà OTA nên thay đổi.

Mã hóa siêu dữ liệu đòi hỏi dm-default-key mô-đun được cho phép trong kernel. Trong Android 11 trở lên, dm-default-key được hỗ trợ bởi hạt nhân phổ biến Android, phiên bản 4.14 và cao hơn. Phiên bản này của dm-default-key sử dụng một phần cứng và khung mã hóa nhà cung cấp độc lập gọi là blk-crypto.

Để kích hoạt dm-default-key , 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 inline phần cứng mã hóa (phần cứng mã hóa / giải mã dữ liệu trong khi nó đang trên đường đến / từ các thiết bị lưu trữ) khi có sẵn. Nếu bạn sẽ không được sử dụng phần cứng mã hóa nội tuyến, nó cũng là cần thiết để cho phép một dự phòng để API mật mã của kernel:

CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y

Khi không sử dụng phần cứng mã hóa inline bạn cũng nên cho phép bất kỳ khả năng tăng tốc CPU dựa trên sẵn theo khuyến cáo trong tài liệu hướng dẫn FBE .

Trong Android 10 và thấp hơn, dm-default-key không được hỗ trợ bởi hạt nhân phổ biến Android. Do đó, nó đã lên đến nhà cung cấp để thực hiện dm-default-key .

Thiết lập hệ thống tệp siêu dữ liệu

Bởi vì không có gì trong phân vùng dữ liệu người dùng có thể được đọc cho đến khi có khóa mã hóa siêu dữ liệu, bảng phân vùng phải dành một phân vùng riêng biệt được gọi là "phân vùng siêu dữ liệu" để lưu trữ các đốm màu quản trị khóa bảo vệ khóa này. Phân vùng siêu dữ liệu phải là 16MB.

fstab.hardware phải bao gồm một mục nhập cho hệ thống tập tin siêu dữ liệu mà cuộc sống trên phân vùng đó gắn nó vào /metadata , bao gồm cả formattable cờ để đảm bảo nó được định dạng vào lúc khởi động. Hệ thống tệp f2fs không hoạt động trên các phân vùng nhỏ hơn; chúng tôi khuyên bạn nên sử 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 tính /metadata gắn kết điểm tồn tại, thêm dòng sau vào BoardConfig-common.mk :

BOARD_USES_METADATA_PARTITION := true

Các thay đổi đối với chuỗi init

Khi mã hóa siêu dữ liệu được sử dụng, vold phải chạy trước /data được gắn kết. Để đảm bảo rằng nó được bắt đầu đủ sớm, thêm đoạn thơ sau đây để init.hardware.rc :

# We need vold early for metadata encryption
on early-fs
    start vold

Keymaster phải chạy và sẵn sàng trước những nỗ lực init để mount /data .

init.hardware.rc nên đã chứa một mount_all hướng dẫn mà gắn kết /data riêng của mình trong on late-fs đoạn thơ. Trước khi dòng này, thêm các chỉ thị để exec wait_for_keymaster dịch vụ:

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

Chuyển sang mã hóa siêu dữ liệu

Cuối cùng thêm keydirectory=/metadata/vold/metadata_encryption đến fs_mgr_flags cột của fstab nhập cảnh cho userdata . Ví dụ: một dòng fstab đầy đủ có thể trô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ã hóa siêu dữ liệu trên bộ nhớ trong là AES-256-XTS. Điều này có thể ghi đè bằng cách thiết lập metadata_encryption tùy chọn, cũng trong cột fs_mgr_flags:

  • Trên các thiết bị thiếu AES tăng tốc, mã hóa Adiantum thể được kích hoạt bằng cách thiết lập metadata_encryption=adiantum .
  • Trên các thiết bị đó hỗ trợ các phím phần cứng bao bọc , metadata khóa mã hóa có thể được thực hiện phần cứng bọc bằng cách thiết lập metadata_encryption=aes-256-xts:wrappedkey_v0 (hoặc tương đương metadata_encryption=:wrappedkey_v0 , như aes-256-xts là thuật toán mặc định).

Bởi vì giao diện hạt nhân để dm-default-key thay đổi trong Android 11, bạn cũng cần phải đảm bảo rằng bạn đã thiết lập các giá trị chính xác cho PRODUCT_SHIPPING_API_LEVEL trong device.mk . Ví dụ, nếu ra mắt điện thoại với Android 11 (cấp API 30), device.mk nên 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 để buộc việc sử dụng các mới dm-default-key API không phụ thuộc vận chuyển cấp độ API:

PRODUCT_PROPERTY_OVERRIDES += \
    ro.crypto.dm_default_key.options_format.version=2

Thẩm định

Để xác minh rằng mã hóa siêu dữ liệu đã được bật và đang hoạt động chính xác, hãy chạy các bài kiểm tra được mô tả bên dưới. Ngoài ra hãy chú ý đến các vấn đề chung được mô tả dưới đây.

Kiểm tra

Bắt đầu bằng cách chạy lệnh sau để xác minh rằng mã hóa siêu dữ liệu được bật trên bộ nhớ trong:

adb root
adb shell dmctl table userdata

Đầu ra phải 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 overrode các thiết lập mã hóa mặc định bằng cách thiết lập metadata_encryption tùy chọn trong của thiết bị fstab , sau đó sản lượng sẽ khác nhau chút ít so với ở trên. Ví dụ, nếu bạn kích hoạt mã hóa Adiantum , sau đó lĩnh vực thứ ba sẽ xchacha12,aes-adiantum-plain64 thay vì aes-xts-plain64 .

Tiếp theo, chạy vts_kernel_encryption_test để xác minh tính chính xác của mã hóa 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 đề chung

Trong lời kêu gọi mount_all , trong đó gắn các siêu dữ liệu được mã hóa /data phân vùng, init thực hiện các công cụ vdc. Sẽ kết nối công cụ vdc để vold trên binder để thiết lập thiết bị siêu dữ liệu được mã hóa và gắn kết phân vùng. Trong suốt thời gian của cuộc gọi này, init bị chặn, và cố gắng hoặc đọc hoặc bộ init tính sẽ 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 của vold việc 's được trực tiếp hoặc gián tiếp bị chặn trên đọc hoặc thiết lập một tài sản, bế tắc sẽ cho kết quả. Điều quan trọng là để đảm bảo rằng vold có thể hoàn thành công việc của việc đọc các phím, tương tác với Keymaster, và gắn kết các thư mục dữ liệu mà không tương tác hơn nữa với init .

Nếu Keymaster là không hoàn toàn bắt đầu khi mount_all chạy, nó sẽ không đáp ứng với vold cho đến khi nó đã đọc tính chất nhất định từ init , kết quả chính xác bế tắc mô tả. Đặt exec_start wait_for_keymaster phía trên có liên quan mount_all gọi như quy định đảm bảo rằng: Keymaster là hoàn toàn chạy trước và do đó tránh được bế tắc này.

Cấu hình trên bộ nhớ có thể sử dụng

Kể từ khi Android 9, một hình thức mã hóa siêu dữ liệu luôn được bật trên lưu trữ nhận làm con nuôi bất cứ khi nào FBE được kích hoạt, ngay cả khi mã hóa siêu dữ liệu không được kích hoạt trên bộ nhớ trong.

Trong AOSP, có hai hiện thực của mã hóa siêu dữ liệu vào lưu trữ nhận làm con nuôi: một NỮA dựa trên dm-crypt , và một phiên bản mới hơn dựa trên dm-default-key . Để đảm bảo rằng việc thực hiện chính xác được chọn để thiết bị của bạn, đảm bảo rằng bạn đã thiết lập các giá trị chính xác cho PRODUCT_SHIPPING_API_LEVEL trong device.mk . Ví dụ, nếu ra mắt điện thoại với Android 11 (cấp API 30), device.mk nên chứa:

PRODUCT_SHIPPING_API_LEVEL := 30

Bạn cũng có thể đặt các thuộc tính hệ thống sau để buộc sử dụng phương pháp mã hóa siêu dữ liệu khối lượng mới (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 pháp hiện tại

Trên các thiết bị ra mắt với Android 11 hoặc cao hơn, mã hóa siêu dữ liệu vào lưu trữ nhận làm con nuôi sử dụng dm-default-key mô-đun hạt nhân, giống như trên bộ nhớ trong. Xem các điều kiện tiên quyết trên mà tùy chọn cấu hình kernel cho phép. Lưu ý rằng phần cứng mã hóa nội tuyến mà các công trình trên bộ nhớ trong của thiết bị có thể không có sẵn trên kho nhận làm con nuôi, và do đó CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y có thể được yêu cầu.

Theo mặc định, dm-default-key phương pháp mã hóa khối lượng siêu dữ liệu sử dụng AES-256-XTS thuật toán mã hóa với các ngành crypto 4096-byte. Thuật toán có thể được ghi đè bằng cách thiết lập ro.crypto.volume.metadata.encryption sở hữu hệ thống. Giá trị của tài sản này có cú pháp tương tự như metadata_encryption tùy chọn fstab mô tả ở trên. Ví dụ, trên các thiết bị thiếu AES tăng tốc, mã hóa Adiantum thể được kích hoạt bằng cách thiết lập ro.crypto.volume.metadata.encryption=adiantum .

Phương pháp kế thừa

Trên các thiết bị ra mắt với Android 10 hoặc thấp hơn, mã hóa siêu dữ liệu vào lưu trữ nhận làm con nuôi sử dụng dm-crypt mô-đun hạt nhân chứ không phải là dm-default-key :

CONFIG_DM_CRYPT=y

Không giống như dm-default-key phương pháp, các dm-crypt phương pháp gây ra nội dung tập tin được mã hóa hai lần: một lần với một chìa khóa FBE và một lần với khóa mã hóa siêu dữ liệu. Mã hóa kép này làm giảm hiệu suất và không cần thiết để đạt được mục tiêu bảo mật của mã hóa siêu dữ liệu, vì Android đảm bảo rằng khóa FBE ít nhất khó bị xâm phạm như khóa mã hóa siêu dữ liệu. Các nhà cung cấp có thể làm cho các tùy chỉnh kernel để tránh sự mã hóa gấp đôi, đặc biệt bằng cách thực hiện các allow_encrypt_override tùy chọn mà Android sẽ vượt qua dm-crypt khi sở hữu hệ thống ro.crypto.allow_encrypt_override được thiết lập để true . Các tùy chỉnh này không được hỗ trợ bởi nhân chung của Android.

Theo mặc định, dm-crypt phương pháp mã hóa siêu dữ liệu khối lượng sử dụng thuật toán mã hóa AES-128-CBC với ESSIV và các ngành crypto 512-byte. Điều này có thể được ghi đè bằng cách đặt các thuộc tính hệ thống sau (cũng được sử dụng cho FDE):

  • ro.crypto.fde_algorithm chọn thuật toán mã hóa siêu dữ liệu. Các lựa chọn là aes-128-cbcadiantum . Adiantum chỉ được sử dụng nếu thiết bị thiếu AES tăng tốc.
  • ro.crypto.fde_sector_size chọn kích thước ngành crypto. Các lựa chọn là 512, 1024, 2048 và 4096. Đối với mã hóa Adiantum, hãy sử dụng 4096.