Triển khai dm-verity

Android 4.4 trở lên hỗ trợ tính năng Xác minh quy trình khởi động thông qua tuỳ chọn tính năng hạt nhân của ánh xạ thiết bị (dm-verity), mang lại tính minh bạch kiểm tra tính toàn vẹn của thiết bị khối. dm-verity giúp ngăn chặn các bộ công cụ gốc (rootkit) tồn tại lâu dài có thể giữ lại đặc quyền gốc và xâm phạm thiết bị. Chiến dịch này giúp người dùng Android biết chắc rằng khi khởi động một thiết bị, thiết bị đó sẽ trạng thái như thời điểm sử dụng gần đây nhất.

Các ứng dụng có khả năng gây hại (PHA) có đặc quyền gốc có thể ẩn khỏi các chương trình phát hiện khác nhau và tự che giấu. Phần mềm can thiệp vào hệ thống có thể điều này vì nó thường có đặc quyền hơn các trình phát hiện, cho phép phần mềm để "nói dối" chương trình phát hiện.

Tính năng dm-verity cho phép bạn xem một thiết bị khối, bộ nhớ cơ bản lớp của hệ thống tệp và xác định xem lớp này có phù hợp dự kiến không . Việc này được thực hiện bằng cách sử dụng cây băm mật mã. Đối với mỗi khối (thường là 4k), có hàm băm SHA256.

Vì các giá trị hàm băm được lưu trữ trong một cây trang nên chỉ có cấp cao nhất "gốc" phải đáng tin cậy để xác minh phần còn lại của cây. Khả năng sửa đổi bất kỳ khối nào sẽ tương đương với việc phá vỡ hàm băm mật mã. Xem biểu đồ sau để xem mô tả cấu trúc này.

bảng-hàm băm dm-verity

Hình 1. Bảng băm dm-verity

Phân vùng khởi động có một khoá công khai và khoá này phải được xác minh do nhà sản xuất thiết bị đưa ra bên ngoài. Khoá đó được dùng để xác minh chữ ký cho hàm băm đó, đồng thời xác nhận phân vùng hệ thống của thiết bị được bảo vệ và không thay đổi.

Hoạt động

Tính năng bảo vệ dm-verity nằm trong nhân. Vì vậy, nếu việc can thiệp vào hệ thống của phần mềm ảnh hưởng đến trước khi nhân hệ điều hành xuất hiện, thì hệ thống sẽ giữ lại quyền truy cập đó. Để giảm thiểu điều này hầu hết các nhà sản xuất đều xác minh nhân hệ điều hành bằng cách dùng khoá đã đốt cháy trong thiết bị. Bạn sẽ không thể thay đổi khoá đó sau khi thiết bị xuất xưởng.

Các nhà sản xuất sử dụng khoá đó để xác minh chữ ký ở cấp đầu tiên trình tải khởi động, từ đó xác minh chữ ký ở các cấp tiếp theo, trình tải khởi động ứng dụng và cuối cùng là kernel. Mỗi nhà sản xuất muốn tận dụng các cơ chế xác minh khởi động phải có phương thức để xác minh tính toàn vẹn của nhân. Giả sử hạt nhân đã được xác minh, hạt nhân hệ điều hành có thể xem xét một thiết bị khối và xác minh nó khi nó được gắn kết.

Một cách để xác minh thiết bị khối là trực tiếp băm nội dung của thiết bị đó rồi so sánh chúng thành một giá trị được lưu trữ. Tuy nhiên, việc cố gắng xác minh toàn bộ thiết bị khối có thể sẽ mất một khoảng thời gian dài và tiêu thụ nhiều năng lượng của thiết bị. Số thiết bị sẽ mất mất nhiều thời gian để khởi động, sau đó tiêu hao pin đáng kể trước khi sử dụng.

Thay vào đó, dm-verity xác minh từng khối riêng lẻ và chỉ khi mỗi khối truy cập. Khi được đọc vào bộ nhớ, khối này sẽ được băm song song. Hàm băm là sau đó xác minh cây xanh. Và vì việc đọc khối là một việc tốn kém thì độ trễ do xác minh cấp khối này đưa ra là tương đối danh nghĩa.

Nếu xác minh không thành công, thiết bị sẽ tạo lỗi I/O cho biết khối Không thể đọc được. Có vẻ như hệ thống tệp đã bị hỏng, như dự kiến.

Ứng dụng có thể chọn tiếp tục mà không có dữ liệu kết quả, chẳng hạn như khi những kết quả đó không bắt buộc đối với chức năng chính của ứng dụng. Tuy nhiên, nếu ứng dụng không thể tiếp tục khi không có dữ liệu thì ứng dụng sẽ không thành công.

Sửa lỗi tiến

Android 7.0 trở lên cải thiện độ mạnh của dm-verity với lỗi chuyển tiếp sửa đổi (FEC). Việc triển khai AOSP bắt đầu với phần tử chung Reed-Solomon và áp dụng một mã sửa lỗi có tên là xen kẽ để giảm mức hao tổn không gian và tăng số lượng khối bị lỗi có thể khôi phục được. Để biết thêm chi tiết về FEC, hãy xem Thực thi nghiêm ngặt quy trình Xác minh quy trình khởi động có sửa lỗi.

Triển khai

Tóm tắt

  1. Tạo hình ảnh hệ thống có định dạng ext4.
  2. Tạo cây băm cho hình ảnh đó.
  3. Tạo bảng dm-verity cho cây băm đó.
  4. Ký bảng dm-verity đó để tạo một bảng của bạn.
  5. Nhóm chữ ký trong bảng và bảng dm-verity vào siêu dữ liệu chính xác.
  6. Hãy nối hình ảnh hệ thống, siêu dữ liệu xác thực và cây băm.

Xem Dự án Chromium – Xác minh quy trình khởi động để xem nội dung mô tả chi tiết về cây băm và bảng dm-verity.

Tạo cây băm

Như đã mô tả trong phần giới thiệu, cây băm là phần không thể thiếu đối với dm-verity. Chiến lược phát hành đĩa đơn công cụ cryptsetup sẽ để tạo cây băm cho bạn. Ngoài ra, một thuộc tính tương thích cũng được xác định tại đây:

<your block device name> <your block device name> <block size> <block size> <image size in blocks> <image size in blocks + 8> <root hash> <salt>

Để tạo thành hàm băm, ảnh hệ thống được chia tại lớp 0 thành 4 khối, mỗi khối gán một hàm băm SHA256. Lớp 1 được hình thành bằng cách chỉ kết hợp các hàm băm SHA256 đó thành các khối 4k, dẫn đến hình ảnh nhỏ hơn nhiều. Lớp 2 được hình thành giống hệt nhau, với hàm băm SHA256 của Lớp 1.

Việc này được thực hiện cho đến khi các hàm băm SHA256 của lớp trước có thể vừa trong một chặn. Khi lấy SHA256 của khối đó, bạn sẽ có hàm băm gốc của cây.

Kích thước của cây băm (và mức sử dụng dung lượng ổ đĩa tương ứng) thay đổi theo kích thước của phân vùng đã xác minh. Trong thực tế, kích thước của cây băm có xu hướng nhỏ, thường dưới 30 MB.

Nếu bạn có một khối trong một lớp không được lấp đầy hoàn toàn bởi hàm băm của lớp trước, bạn nên thêm các số 0 vào để đạt được chất lượng 4K dự kiến. Điều này cho bạn biết cây băm chưa bị xoá và thay vào đó được hoàn tất bằng dữ liệu trống.

Để tạo cây băm, hãy nối hàm băm lớp 2 với các hàm cho lớp đó 1, lớp 3 băm vào các băm của lớp 2, v.v. Viết tất cả những nội dung này ra đĩa. Lưu ý rằng lớp này không tham chiếu đến lớp 0 của hàm băm gốc.

Tóm lại, thuật toán chung để xây dựng cây băm như sau:

  1. Chọn một dữ liệu ngẫu nhiên (mã hoá thập lục phân).
  2. Không phân tích thư mục hình ảnh hệ thống thành 4 nghìn khối.
  3. Đối với mỗi khối, hãy lấy hàm băm SHA256 (có muối) của khối đó.
  4. Nối các hàm băm này để tạo một cấp độ
  5. Điều chỉnh cho cấp độ từ 0 giây đến ranh giới khối 4k.
  6. Liên kết cấp độ với cây băm.
  7. Lặp lại các bước từ 2 đến 6 sử dụng cấp độ trước đó làm nguồn cho các bước tiếp theo cho đến bạn chỉ có một hàm băm duy nhất.

Kết quả của việc này là một hàm băm duy nhất, là hàm băm gốc của bạn. Điều này và dữ liệu ngẫu nhiên của bạn được dùng trong quá trình tạo bảng lập bản đồ dm-verity.

Tạo bảng liên kết dm-verity

Tạo bảng ánh xạ dm-verity, trong đó xác định thiết bị khối (hoặc mục tiêu) cho nhân và vị trí của cây băm (có cùng giá trị). Chiến dịch này ánh xạ được dùng để tạo và khởi động fstab. Bảng này cũng xác định kích thước của các khối và hash_start, vị trí bắt đầu của cây băm (cụ thể là số khối tính từ đầu hình ảnh).

Xem phần thiết lập mật mã để biết nội dung mô tả chi tiết về các trường trong bảng liên kết mục tiêu của tính xác thực.

Ký bảng dm-verity

Ký bảng dm-verity để tạo chữ ký bảng. Khi xác minh một thì chữ ký của bảng sẽ được xác thực trước. Thao tác này được thực hiện với một phím trên hình ảnh khởi động của bạn ở một vị trí cố định. Khoá thường có trong phần của nhà sản xuất hệ thống xây dựng để tự động đưa vào vị trí.

Cách xác minh phân vùng bằng chữ ký và tổ hợp phím này:

  1. Thêm khoá RSA-2048 ở định dạng tương thích với libmincrypt vào /boot phân vùng lúc /verity_key. Xác định vị trí của khoá dùng để xác minh cây băm.
  2. Trong thẻ fstab cho mục nhập có liên quan, hãy thêm verify cho các cờ fs_mgr.

Nhóm chữ ký trong bảng vào siêu dữ liệu

Nhóm chữ ký bảng và bảng dm-verity vào siêu dữ liệu xác thực. Toàn bộ khối siêu dữ liệu được tạo phiên bản để có thể mở rộng, chẳng hạn như thêm một giây hoặc thay đổi thứ tự nào đó.

Để kiểm tra mức độ hợp lý, một số ma thuật được liên kết với mỗi bộ siêu dữ liệu của bảng giúp xác định bảng. Vì độ dài được đưa vào hệ thống ext4 tiêu đề hình ảnh, đây là một cách tìm kiếm siêu dữ liệu mà không cần biết nội dung của chính dữ liệu đó.

Điều này đảm bảo bạn chưa chọn xác minh một phân vùng chưa được xác minh. Nếu có, nếu không có số thần kỳ này thì quá trình xác minh sẽ bị tạm dừng. Số này giống với:
0xb001b001

Giá trị byte theo hệ thập lục phân là:

  • byte đầu tiên = b0
  • byte thứ hai = 01
  • byte thứ ba = b0
  • byte thứ tư = 01

Biểu đồ dưới đây mô tả bảng chi tiết về siêu dữ liệu xác thực:

<magic number>|<version>|<signature>|<table length>|<table>|<padding>
\-------------------------------------------------------------------/
\----------------------------------------------------------/   |
                            |                                  |
                            |                                 32K
                       block content

Và bảng này mô tả các trường siêu dữ liệu đó.

Bảng 1. Trường siêu dữ liệu xác thực

Trường Mục đích Kích thước Giá trị
số ma thuật được fs_mgr sử dụng làm bước kiểm tra tính hợp lý 4 byte 0xb001b001
version dùng để tạo phiên bản khối siêu dữ liệu 4 byte hiện tại là 0
Chữ ký chữ ký của bảng trong mẫu có đệm PKCS1.5 256 byte
chiều dài bảng độ dài của bảng dm-verity tính bằng byte 4 byte
bàn bảng dm-verity được mô tả ở trên byte có độ dài bảng
padding cấu trúc này có độ dài từ 0 đến 32k 0

Đang tối ưu hoá độ phân giải dm

Để có hiệu suất tốt nhất trong dm-verity, bạn nên:

  • Trong nhân hệ điều hành, hãy bật NEON SHA-2 cho ARMv7 và SHA-2 các tiện ích cho ARMv8.
  • Thử nghiệm với các giá trị đọc trước và Preview_cluster để tìm ra cấu hình phù hợp nhất cho thiết bị của bạn.