Android 4.4 trở lên hỗ trợ Khởi động đã xác minh thông qua tính năng nhân thiết bị-mapper-verity (dm-verity) tùy chọn, cung cấp tính năng kiểm tra tính toàn vẹn minh bạch của các thiết bị khối. dm-verity giúp ngăn chặn các rootkit liên tục có thể giữ đặc quyền root và xâm phạm thiết bị. Tính năng này giúp người dùng Android chắc chắn rằng khi khởi động thiết bị, thiết bị đó ở trạng thái giống như lần 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 root có thể ẩn khỏi các chương trình phát hiện và nếu không sẽ tự che giấu chúng. Phần mềm root có thể làm điều này vì nó thường có nhiều đặc quyền hơn các phần mềm phát hiện, cho phép phần mềm "nói dối" các chương trình phát hiện.
Tính năng dm-verity cho phép bạn xem thiết bị khối, lớp lưu trữ bên dưới của hệ thống tệp và xác định xem nó có khớp với cấu hình mong đợi hay không. Nó thực hiện điều này bằng cách sử dụng một cây băm mật mã. Đối với mỗi khối (thường là 4k), có một hàm băm SHA256.
Vì các giá trị băm được lưu trữ trong một cây các trang, nên chỉ mã băm "gốc" cấp cao nhất phải được 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 sơ đồ sau để mô tả cấu trúc này.

Hình 1. Bảng băm dm-verity
Khoá công khai được bao gồm trên phân vùng khởi động, khoá này phải được xác minh bên ngoài bởi nhà sản xuất thiết bị. Khóa đó được sử dụng để xác minh chữ ký cho hàm băm đó và 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
bảo vệ dm-verity sống trong nhân. Vì vậy, nếu phần mềm root làm tổn hại hệ thống trước khi hạt nhân xuất hiện, nó sẽ giữ lại quyền truy cập đó. Để giảm thiểu rủi ro này, hầu hết các nhà sản xuất xác minh hạt nhân bằng cách sử dụng một khóa được ghi vào thiết bị. Khóa đó không thể thay đổi sau khi thiết bị rời khỏi nhà máy.
Các nhà sản xuất sử dụng khóa đó để xác minh chữ ký trên bộ nạp khởi động cấp đầu tiên, lần lượt xác minh chữ ký trên các cấp tiếp theo, bộ nạp khởi động ứng dụng và cuối cùng là hạt nhân. Mỗi nhà sản xuất muốn tận dụng khả năng khởi động đã được xác minh phải có một phương pháp để xác minh tính toàn vẹn của hạt nhân. Giả sử hạt nhân đã được xác minh, hạt nhân có thể nhìn vào thiết bị khối và xác minh khi nó được gắn kết.
Một cách để xác minh thiết bị khối là băm trực tiếp nội dung của nó và so sánh chúng với 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ể mất nhiều thời gian và tiêu tốn nhiều năng lượng của thiết bị. Các thiết bị sẽ mất nhiều thời gian để khởi động và sau đó sẽ bị cạn kiệt đáng kể trước khi sử dụng.
Thay vào đó, dm-verity xác minh các khối riêng lẻ và chỉ khi từng khối được truy cập. Khi được đọc vào bộ nhớ, khối được băm song song. Sau đó băm được xác minh trên cây. Và vì việc đọc khối là một hoạt động tốn kém như vậy, độ trễ được giới thiệu bởi xác minh cấp khối này là tương đối trên danh nghĩa.
Nếu xác minh không thành công, thiết bị sẽ tạo ra lỗi I / O cho biết không thể đọc khối. Nó sẽ xuất hiện như thể hệ thống tệp đã bị hỏng, như mong đợi.
Các ứ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 các kết quả đó không được yêu cầu đố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 mà không có dữ liệu, nó sẽ bị lỗi.
Chuyển tiếp sửa lỗi
Android 7.0 trở lên cải thiện độ mạnh của dm-verity với tính năng sửa lỗi chuyển tiếp (FEC). Việc triển khai AOSP bắt đầu với mã sửa lỗi phổ biến Reed-Solomon và áp dụng một kỹ thuật được gọi là xen kẽ để giảm chi phí không gian và tăng số lượng khối bị hỏng có thể được khôi phục. Để biết thêm chi tiết về FEC, hãy xem Khởi động được xác minh được thực thi nghiêm ngặt với sửa lỗi .Thực hiện
Bản tóm tắt
- Tạo hình ảnh hệ thống ext4.
- Tạo một cây băm cho hình ảnh đó.
- Xây dựng một bảng dm-verity cho cây băm đó.
- Ký vào bảng dm-verity đó để tạo ra một chữ ký bảng.
- Nhóm chữ ký bảng và bảng dm-verity thành siêu dữ liệu verity.
- Kết hợp hình ảnh hệ thống, siêu dữ liệu thực và cây băm.
XemDự án Chromium - Khởi động đã xác minh để biết mô tả chi tiết về cây băm và bảng dm-verity.
Tạo cây băm
Như được mô tả trong phần giới thiệu, cây băm là không thể thiếu đối với dm-verity. Công cụ cryptsetup sẽ tạo ra một cây băm cho bạn. Ngoài ra, một cái tương thích được xác định ở đâ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, hình ảnh hệ thống được chia ở lớp 0 thành 4k khối, mỗi khối được gán một hàm băm SHA256. Lớp 1 được hình thành bằng cách chỉ ghép các 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 các hàm băm SHA256 của Lớp 1.
Điều này được thực hiện cho đến khi các băm SHA256 của lớp trước có thể nằm gọn trong một khối duy nhất. Khi lấy SHA256 của khối đó, bạn có 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 không gian đĩa tương ứng) thay đổi theo kích thước của phân vùng đã được xác minh. Trong thực tế, kích thước của cây băm có xu hướng nhỏ, thường nhỏ hơn 30 MB.
Nếu bạn có một khối trong một lớp không hoàn toàn được lấp đầy một cách tự nhiên bởi các hàm băm của lớp trước đó, bạn nên chèn nó bằng các số 0 để đạt được 4k như mong đợi. Điều này cho phép bạn biết cây băm chưa bị xóa và thay vào đó được hoàn thành với dữ liệu trống.
Để tạo cây băm, hãy nối các băm lớp 2 với các băm cho lớp 1, lớp 3 các băm với các băm của lớp 2, v.v. Ghi tất cả những điều này ra đĩa. Lưu ý rằng điều này không tham chiếu đến lớp 0 của mã băm gốc.
Tóm lại, thuật toán chung để xây dựng cây băm như sau:
- Chọn một muối ngẫu nhiên (mã hóa thập lục phân).
- Hủy phân tích hình ảnh hệ thống của bạn thành 4k khối.
- Đối với mỗi khối, lấy hàm băm SHA256 (muối) của nó.
- Nối các hàm băm này để tạo thành một cấp độ
- Chuyển mức bằng 0 đến ranh giới khối 4k.
- Nối cấp độ với cây băm của bạn.
- Lặp lại các bước 2-6 bằng cách sử dụng mức trước đó làm nguồn cho bước tiếp theo cho đến khi 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à muối của bạn được sử dụng trong quá trình xây dựng bảng lập bản đồ dm-verity của bạn.
Xây dựng bảng ánh xạ dm-verity
Xây dựng bảng ánh xạ dm-verity, xác định thiết bị khối (hoặc đích) cho hạt nhân và vị trí của cây băm (có cùng giá trị.) Ánh xạ này được sử dụng để tạo và khởi động fstab
. Bảng 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 của nó từ đầu hình ảnh).
Xem cryptsetup để biết mô tả chi tiết về các trường của bảng ánh xạ mục tiêu thực sự.
Ký vào bảng dm-verity
Ký vào bảng dm-verity để tạo ra một chữ ký bảng. Khi xác minh một phân vùng, chữ ký bảng được xác nhận trước. Điều này được thực hiện dựa trên một khóa trên hình ảnh khởi động của bạn ở một vị trí cố định. Các phím thường được bao gồm trong hệ thống xây dựng của nhà sản xuất để tự động đưa vào các thiết bị ở một vị trí cố định.
Để xác minh phân vùng bằng tổ hợp phím và chữ ký này:
- Thêm khóa RSA-2048 ở định dạng tương thích với libmincrypt vào phân vùng
/boot
tại/verity_key
. Xác định vị trí của khóa được sử dụng để xác minh cây băm. - Trong fstab cho mục nhập có liên quan, hãy thêm
verify
vào các cờfs_mgr
.
Nhóm chữ ký bảng thành siêu dữ liệu
Nhóm chữ ký bảng và bảng dm-verity thành siêu dữ liệu verity. Toàn bộ khối siêu dữ liệu được tạo phiên bản để nó có thể được mở rộng, chẳng hạn như để thêm loại chữ ký thứ hai hoặc thay đổi một số thứ tự.
Khi kiểm tra độ tỉnh táo, 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 bao gồm trong tiêu đề hình ảnh hệ thống ext4, điều này cung cấp 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 rằng bạn chưa chọn xác minh một phân vùng chưa được xác minh. Nếu vậy, sự vắng mặt của con số kỳ diệu này sẽ làm ngừng quá trình xác minh. Con số này giống như:
0xb001b001
Các giá trị byte trong hex là:
- byte đầu tiên = b0
- byte thứ hai = 01
- byte thứ ba = b0
- byte thứ tư = 01
Sơ đồ sau mô tả sự phân tích của siêu dữ liệu 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. Các trường siêu dữ liệu Verity
Đồng ruộng | Mục đích | Kích thước | Giá trị |
---|---|---|---|
con số kỳ diệu | được sử dụng bởi fs_mgr như một kiểm tra sự tỉnh táo | 4 byte | 0xb001b001 |
phiên bản | được sử dụng để 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 ở dạng đệm PKCS1.5 | 256 byte | |
chiều dài bàn | chiều 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ước đó | byte chiều dài bảng | |
đệm lót | cấu trúc này có độ dài từ 0 đến 32k | 0 |
Tối ưu hóa dm-verity
Để có được hiệu suất tốt nhất từ dm-verity, bạn nên:
- Trong nhân, bật NEON SHA-2 cho ARMv7 và phần mở rộng SHA-2 cho ARMv8.
- Thử nghiệm với các cài đặt read-before và prefetch_cluster khác nhau để tìm ra cấu hình tốt nhất cho thiết bị của bạn.