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

Android 7.0 trở lên hỗ trợ tính năng mã hoá dựa trên tệp (FBE). Tính năng mã hoá dựa trên tệp cho phép mã hoá các tệp khác nhau bằng các khoá khác nhau có thể được 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 ứng dụng hệ thống có thể sử dụng Direct Boot API để 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ả các thiết bị khởi chạy bằng Android 10 trở lên đều phải sử dụng phương thức mã hoá dựa trên tệp.

Direct Boot

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

Với việc ra mắt tính năng 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 hoạt động mã hoá, những ứ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 đăng nhập mà vẫn bảo vệ thông tin riêng tư của người dùng.

Trên thiết bị có FBE, mỗi người dùng thiết bị có 2 vị trí lưu trữ mà ứng dụng có thể truy cập:

  • Bộ nhớ được mã hoá dành cho thông tin đăng nhập (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 tách biệt 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 do quy trình mã hoá không còn chỉ dựa vào mật khẩu khi khởi động nữa.

Direct Boot API cho phép các ứng dụng có khả năng nhận biết quá trình mã hoá truy cập vào từng khu vực này. Vòng đời của ứng dụng có những thay đổi để đá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 đăng nhập lần đầu 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ợ những 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ù 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 tính năng 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 những thiết bị đáp ứng các yêu cầu. Các nhà sản xuất chọn sử dụng FBE có thể tìm hiểu cách tối ưu hoá tính năng này dựa trên hệ thống trên chip (SoC) được dùng.

Tất cả các gói cần thiết trong AOSP đều đã được cập nhật để nhận biết chế độ 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 tuỳ chỉnh của những ứng dụng này, họ muốn đảm bảo rằng ít nhất phải có các gói hỗ trợ khởi động trực tiếp cung cấp những 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 một quy trình triển khai tham chiếu về tính năng mã hoá dựa trên tệp, trong đó vold (system/vold) cung cấp chức năng quản lý các thiết bị và ổ 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ợ việc 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 cốt lõi để sử dụng các chức 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 (packages/inputmethods/LatinIME)*
  • Ứng dụng Cài đặt (packages/apps/Settings)*
  • SystemUI (frameworks/base/packages/SystemUI)*

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

Bạn có thể tìm thấy thêm các ví dụ về ứng dụng và dịch vụ có hỗ trợ mã hoá 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ần phụ thuộc

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

  • Hỗ trợ nhân cho hoạt động mã hoá Ext4 hoặc mã hoá F2FS.
  • KeyMint (hoặc Keymaster 1.0 trở lên) Hỗ trợ. Không có hỗ trợ cho 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 đủ khả năng bảo vệ cho khoá mã hoá.
  • Bạn phải triển khai KeyMint/Keymaster và Gatekeeper trong Môi trường thực thi đáng tin cậy (TEE) để bảo vệ các khoá DE, nhờ đó, một hệ điều hành trái phép (hệ điều hành tuỳ chỉnh được cài đặt vào thiết bị) không thể chỉ cần yêu cầu các khoá DE.
  • Bạn phải có Gốc tin cậy phần cứngQuy trình khởi động đã xác minh được liên kết với quá trình khởi tạo KeyMint để đảm bảo rằng hệ điều hành trái phép không truy cập được vào các khoá DE.

Triển khai

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 hỗ trợ tiếp cận phải được đặt thành android:directBootAware theo tài liệu dành cho nhà phát triển Direct Boot (Khởi động trực tiếp).

Hỗ trợ kernel

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

Ngoài việc hỗ trợ chức năng mã hoá Ext4 hoặc F2FS, các 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ã hoá) bằng cách đặt các lựa chọn cấu hình sau đây cho nhân:

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 điện năng, các nhà sản xuất thiết bị cũng có thể cân nhắc triển khai phần cứng mã hoá nội tuyến. Phần cứng này sẽ 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 chung của Android (phiên bản 4.14 trở lên) có chứa một khung cho phép sử dụng tính năng mã hoá nội tuyến khi có phần cứng và trình điều khiển của nhà cung cấp hỗ trợ. Bạn có thể bật khung mã hoá nội tuyến bằng cách thiết lập các lựa chọn cấu hình sau đây cho nhân:

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, 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

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

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

Bộ nhớ trong

FBE được bật bằng cách thêm lựa 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. Nó 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ã hoá nào được 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ã hoá nào được 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 bạn không chỉ định, giá trị mặc định sẽ là aes-256-cts nếu contents_encryption_modeaes-256-xts hoặc là adiantum nếu 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ã hoá phiên bản 1; cờ v2 chọn chính sách mã hoá phiên bản 2. Phiên bản 2 của chính sách mã hoá sử dụng hàm phái sinh khoá linh hoạt và an toàn hơn. Giá trị mặc định là v2 nếu thiết bị chạy Android 11 trở lên (theo ro.product.first_api_level) hoặc v1 nếu thiết bị chạy 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á nội tuyến không xử lý hiệu quả số lượng lớn khoá. Việc này được thực hiện 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. Việc tạo IV (vectơ khởi tạo) sẽ được điều chỉnh cho phù hợp.
    • Cờ emmc_optimized tương tự như inlinecrypt_optimized, nhưng cờ này 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á nội tuyến tuân thủ quy cách JEDEC eMMC phiên bản 5.2 và do đó chỉ hỗ trợ IV 32 bit. Trên phần cứng mã hoá cùng dòng khác, hãy 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; quy cách UFS cho phép sử dụng IV 64 bit.
    • Trên những thiết bị hỗ trợ các khoá được bao bọc bằng phần cứng, cờ wrappedkey_v0 cho phép sử dụng các khoá được bao bọc bằng phần cứng cho FBE. Bạn chỉ có thể sử dụng lựa chọn này kết hợp với lựa 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ã hoá 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à độ chi tiết của quá trình mã hoá nội dung tệp. Cờ này có từ Android 15. Cờ này chỉ nên được dùng để cho phép sử dụng phần cứng mã hoá nội tuyến 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 không sử dụng phần cứng mã hoá nội tuyến, thì chế độ cài đặt được đề xuất cho hầu hết các thiết bị là fileencryption=aes-256-xts. Nếu đang dùng phần cứng mã hoá nội tuyến, thì 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 tương đương với 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, bạn có thể dùng Adiantum thay vì 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á được 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, chế độ này dự kiến sẽ trở thành chế độ mặc định để mã hoá tên tệp. Nếu nhân của bạn có hỗ trợ AES-HCTR2, bạn có thể bật tính năng này để 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 triển khai bởi các nhân chung của Android, nhưng các nhà cung cấp có thể triển khai chế độ này bằng cách sử dụng các bản vá nhân 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 phép sử dụng và bạn phải sử dụng một định dạng mã hoá tiêu chuẩn.

Theo mặc định, nội dung tệp được mã hoá bằng API mật mã của nhân hệ điều hành Linux. Nếu bạn muốn sử dụng phần cứng mã hoá nội tuyến, hãy thêm lựa 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

Bộ nhớ thích ứng

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

Việc chỉ định tuỳ chọn fileencryption fstab cho userdata cũng tự động bật cả FBE và hoạt động 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á FBE hoặc siêu dữ liệu trên bộ nhớ có thể nhận bằng cách thiết lập 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ể sử dụng. Nó có cùng cú pháp với đối số cho lựa chọn fileencryption fstab 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 những gì cần sử dụng ở đây.
  • ro.crypto.volume.metadata.encryption chọn định dạng mã hoá siêu dữ liệu trên bộ nhớ tương thích. Hãy xem tài liệu 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. 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ị, bạn cần phải ghi đè một cách rõ ràng giá trị này thành aes-256-cts.
  • ro.crypto.fde_algorithmro.crypto.fde_sector_size chọn định dạng mã hoá siêu dữ liệu trên bộ nhớ tương thích. Hãy xem tài liệu mã hoá siêu dữ liệu.

Tích hợp với KeyMint

HAL KeyMint phải được khởi động trong lớp early_hal. Điều này là do FBE yêu cầu KeyMint phải sẵn sàng xử lý các yêu cầu theo giai đoạn khởi động post-fs-data. Đây là thời điểm 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 tất cả các thư mục cấp cao nhất của /data, ngoại trừ những thư mục phải được giải mã, chẳng hạn như thư mục chứa chính khoá 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. Khoá mã hoá được áp dụng đệ quy và không thể bị các thư mục con ghi đè.

Trong Android 11 trở lên, bạn có thể kiểm soát khoá mà init áp dụng cho các thư mục 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 cho ngôn ngữ khởi động 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

Trên Android 9 trở xuống, vị trí 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 bị mã hoá. Nếu thực hiện các sửa đổi thuộc loại này, thì nhà sản xuất thiết bị phải thêm các chính sách SELinux chỉ cấp quyền truy cập cho những ứ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 đã biết cho việc này là hỗ trợ các chức năng OTA cũ.

Hỗ trợ chế độ 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

Để tạo điều kiện di chuyển nhanh các ứng dụng hệ thống, có 2 thuộc tính mới mà bạn có thể đặt ở cấp ứng dụng. Thuộc tính defaultToDeviceProtectedStorage chỉ dành cho các ứng dụng hệ thống. Thuộc tính directBootAware được cung cấp 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à có khả năng nhận biết quá trình mã hoá.

Thuộc tính defaultToDeviceProtectedStorage chuyển hướng vị trí lưu trữ mặc định của ứng dụng để 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 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ộ nhớ CE. Các nhà sản xuất thiết bị sử dụng lựa chọn này phải 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 có sẵn để quản lý rõ ràng một Context được hỗ trợ bởi bộ nhớ CE khi cần, tương đương với các API được Bảo vệ trên 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 sẽ có hai khoá: khoá DE và khoá CE. Người dùng 0 phải đăng nhập vào thiết bị trước vì đây là một người dùng đặc biệt. Điều này có liên quan đến việc sử dụng Quản trị thiết bị.

Các ứng dụng có hỗ trợ tiền mã hoá tương tác giữa những người dùng theo cách sau: 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 đó chỉ có thể truy cập vào các thư mục được mã hoá bằng CE đối với những người dùng đã mở khoá.

Một ứng dụng có thể tương tác thoải mái trên các vùng 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 đã mở khoá. Ứng dụng nên kiểm tra trạng thái này trước khi cố gắng truy cập vào các khu vực này.

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

Xử lý thông tin 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 dữ liệu người dùng. Các thiết bị triển khai FBE nên hỗ trợ OTA bằng cách sử dụ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 không cần khôi phục để truy cập vào dữ liệu trên ổ đĩa được mã hoá.

Khi sử dụng giải pháp OTA cũ, bạn cần có quyền khôi phục để truy cập vào 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ã 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 trữ các gói OTA.
  4. Thêm một 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 thư mục. Chỉ quy trình hoặc ứng dụng nhận bản cập nhật qua mạng 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 phép truy cập vào thư mục này.

Xác nhận kết quả

Để đảm bảo phiên bản đã 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 kiểm thử mã hoá 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, các 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 xem ro.crypto.state có tồn tại hay không
    • Đảm bảo ro.crypto.state đã được mã hoá
  • Kiểm tra xem ro.crypto.type có tồn tại hay không
    • Đả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 các thiết bị không phải Automotive), 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 các tên tệp được liệt kê được mã hoá bằng Base64, cho biết rằng tên tệp được mã hoá và khoá để giải mã tên tệp đó hiện chưa có. Nếu tên tệp được liệt kê dưới dạng văn bản thuần tuý, thì có nghĩa là đã xảy ra lỗi.

Nhà sản xuất thiết bị cũng nên tìm hiểu cách chạy các kiểm thử Linux ngược dòng cho fscrypt trên thiết bị hoặc nhân của họ. Các kiểm thử này thuộc 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ử ngược dòng 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ề việc triển khai AOSP và mô tả cách hoạt động của phương thức mã hoá dựa trên tệp. 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à Direct Boot trên thiết bị của họ.

Mã hoá fscrypt

Quy trình triển khai AOSP sử dụng phương thức mã hoá "fscrypt" (được 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 bạn bật công nghệ mã hoá Adiantum, cả nội dung và tên tệp đều được mã hoá bằng Adiantum.

fscrypt hỗ trợ 2 phiên bản chính sách mã hoá: 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 trong 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 các 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ề hạt nhân nguồn mở.

Lớp lưu trữ

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

Lớp lưu trữ 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 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ả cá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} đều 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.
System DE 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ả các thư mục con khác của /data mà bảng này không đề cập đến việc 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
CE người dùng (nội bộ) Dữ liệu được mã hoá bằng 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á 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ể áp dụng) Dữ liệu được mã hoá bằng thông tin đăng nhập cho mỗi người dùng trên bộ nhớ thích ứng
  • /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á trên thiết bị cho 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ệ 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á khởi động không được lưu trữ. Bảng sau đây liệt kê các vị trí lưu trữ nhiều khoá FBE:

Loại khoá Vị trí chính Lớp lưu trữ của vị trí khoá
Khoá DE 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} System DE
Khoá DE (nội bộ) của người dùng /data/misc/vold/user_keys/de/${user_id} System DE
Khoá CE (có thể di chuyển) của người dùng /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} CE người dùng (nội bộ)
Khoá DE (có thể chuyể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ư trong bảng trước, hầu hết các khoá FBE đều được lưu trữ trong các 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 mở khoá lớp lưu trữ chứa các khoá đó.

vold cũng áp dụng một lớp mã hoá cho tất cả cá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 riêng. Khoá này không được 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 một hệ điều hành đáng tin cậy đã khởi động, theo quy định của Verified Boot (Khởi động đã xác minh). Tính năng chống quay lại cũng được yêu cầu trên kho khoá, cho phép xoá các khoá FBE một cách an toàn trên những thiết bị mà KeyMint hỗ trợ tính năng chống quay lại. Là một giải pháp dự phòng tốt nhất khi không có tính năng chống quay 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 khoá sẽ được dùng làm Tag::APPLICATION_ID 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.

Các khoá CE cho bộ nhớ trong được bảo vệ ở mức độ cao hơn, đảm bảo rằng các khoá này không thể mở khoá nếu không biết Yếu tố kiến thức về màn hình khoá (LSKF) (mã PIN, hình mở khoá 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ả khoá phía máy khách và phía máy chủ cho thao tác Tiếp tục khi khởi động lại. Bạn 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ã hoá từng khoá CE cho bộ nhớ trong bằ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 giả là một khoá bí mật mật mã có entropy cao, không thay đổi và đượ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 giả tạo và các cách bảo vệ mật khẩu đó.

Để bảo vệ mật khẩu giả tạo bằng LSKF, trước tiên, LockSettingsService sẽ kéo dài LSKF bằng cách truyền mật khẩu này qua scrypt, nhắm đến 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 tính bảo mật. Lớp bảo mật chính là Phần tử bảo mật (SE) hoặc tính năng giới hạn tốc độ do TEE thực thi như mô tả bên dưới.

Nếu thiết bị có một Phần tử bảo mật (SE), thì LockSettingsService sẽ ánh xạ LSKF được kéo dài đến 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 HAL Weaver. Sau đó, LockSettingsService sẽ 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 kéo dài và bí mật Weaver, lần thứ hai bằng khoá Kho khoá không liên kết với hoạt động xác thực. Điều này giúp thực thi việc giới hạn tốc độ dựa trên SE đối với các lượt đoán LSKF.

Nếu thiết bị không có SE, thì LockSettingsService sẽ sử dụng LSKF kéo dài làm mật khẩu Gatekeeper. Sau đó, LockSettingsService sẽ 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 kéo dài và hàm băm của một tệp có thể loại bỏ, và lần thứ hai bằng khoá Kho khoá được liên kết với quá trình đăng ký Gatekeeper. Điều này giúp giới hạn tốc độ dựa trên TEE đối với các lượt đoán LSKF.

Khi LSKF thay đổi, LockSettingsService sẽ xoá tất cả thông tin liên kết với 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ợ kho khoá Weaver hoặc kho khoá có khả năng chống hạ cấp, điều này đảm bảo việc xoá an toàn mối liên kết cũ. Vì lý do này, các biện pháp bảo vệ được mô tả ở đây sẽ được áp dụng ngay cả khi người dùng không có LSKF.