Trong Keymaster 1, tất cả các khóa keymaster đều được liên kết bằng mật mã với thiết bị Root of Trust hoặc khóa Khởi động được xác minh. Trong Keymaster 2 và 3, tất cả các phím cũng bị ràng buộc với hệ điều hành và mức độ vá lỗi của image hệ thống. Điều này đảm bảo rằng kẻ tấn công phát hiện ra điểm yếu trong phiên bản cũ của hệ thống hoặc phần mềm TEE không thể khôi phục thiết bị về phiên bản dễ bị tấn công và sử dụng các khóa được tạo bằng phiên bản mới hơn. Ngoài ra, khi sử dụng một khóa có phiên bản và cấp bản vá nhất định trên thiết bị đã được nâng cấp lên phiên bản hoặc cấp bản vá mới hơn, thì khóa đó sẽ được nâng cấp trước khi có thể sử dụng và phiên bản trước đó của khóa sẽ không còn hiệu lực. Bằng cách này, khi thiết bị được nâng cấp, các phím sẽ "bánh cóc" về phía trước cùng với thiết bị, nhưng bất kỳ sự đảo ngược nào của thiết bị về phiên bản trước sẽ khiến các phím không thể sử dụng được.
Để hỗ trợ cấu trúc mô-đun của Treble và phá vỡ ràng buộc của system.img với boot.img, Keymaster 4 đã thay đổi mô hình liên kết phiên bản khóa để có các mức vá lỗi riêng cho từng phân vùng. Điều này cho phép mỗi phân vùng được cập nhật độc lập trong khi vẫn cung cấp khả năng bảo vệ khôi phục.
Trong Android 9, các phân boot
, system
và vendor
đều có cấp độ bản vá riêng.
- Các thiết bị có Khởi động được xác minh Android (AVB) có thể đặt tất cả các cấp độ bản vá và phiên bản hệ thống trong vbmeta, do đó bộ nạp khởi động có thể cung cấp chúng cho Keymaster. Đối với các phân vùng được xâu chuỗi, thông tin phiên bản cho phân vùng sẽ có trong vbmeta được xâu chuỗi. Nói chung, thông tin phiên bản phải nằm trong
vbmeta struct
chứa dữ liệu xác minh (hash hoặc hashtree) cho một phân vùng nhất định. - Trên các thiết bị không có AVB:
- Việc triển khai Khởi động đã được xác minh cần cung cấp hàm băm của siêu dữ liệu phiên bản cho bộ nạp khởi động để bộ nạp khởi động có thể cung cấp hàm băm cho Keymaster.
-
boot.img
có thể tiếp tục lưu trữ mức bản vá trong tiêu đề -
system.img
có thể tiếp tục lưu trữ mức bản vá và phiên bản hệ điều hành trong thuộc tính chỉ đọc -
vendor.img
lưu trữ cấp độ bản vá trong thuộc tính chỉ đọcro.vendor.build.version.security_patch
. - Bộ tải khởi động có thể cung cấp hàm băm của tất cả dữ liệu được xác thực bằng cách khởi động được xác minh cho keymaster.
- Trong Android 9, hãy sử dụng các thẻ sau để cung cấp thông tin phiên bản cho các phân vùng sau:
-
VENDOR_PATCH_LEVEL
: phân vùngvendor
-
BOOT_PATCH_LEVEL
: phân vùngboot
-
OS_PATCH_LEVEL
vàOS_VERSION
: phân vùngsystem
. (OS_VERSION
bị xóa khỏi tiêu đềboot.img
.
-
- Việc triển khai Keymaster phải xử lý tất cả các cấp độ bản vá một cách độc lập. Các khóa có thể sử dụng được nếu tất cả thông tin phiên bản khớp với các giá trị được liên kết với một khóa và
IKeymaster::upgradeDevice()
sẽ chuyển sang cấp bản vá cao hơn nếu cần.
Thay đổi HAL
Để hỗ trợ liên kết phiên bản và chứng thực phiên bản, Android 7.1 đã thêm các thẻ Tag::OS_VERSION
và Tag::OS_PATCHLEVEL
cũng như các phương thức configure
và upgradeKey
. Các thẻ phiên bản được triển khai Keymaster 2+ tự động thêm vào tất cả các khóa mới được tạo (hoặc cập nhật). Hơn nữa, mọi nỗ lực sử dụng khóa không có phiên bản hệ điều hành hoặc cấp bản vá tương ứng với phiên bản hệ điều hành hoặc cấp bản vá hiện tại đều bị từ chối bằng ErrorCode::KEY_REQUIRES_UPGRADE
.
Tag::OS_VERSION
là giá trị UINT
đại diện cho các phần chính, phụ và phụ của phiên bản hệ thống Android dưới dạng MMmmss, trong đó MM là phiên bản chính, mm là phiên bản phụ và ss là phiên bản phụ. Ví dụ: 6.1.2 sẽ được biểu thị là 060102.
Tag::OS_PATCHLEVEL
là giá trị UINT
biểu thị năm và tháng của lần cập nhật cuối cùng vào hệ thống dưới dạng YYYYMM, trong đó YYYY là năm có bốn chữ số và MM là tháng có hai chữ số. Ví dụ: tháng 3 năm 2016 sẽ được biểu thị là 201603.
Khóa nâng cấp
Để cho phép nâng cấp các khóa lên phiên bản hệ điều hành mới và mức độ vá lỗi của hình ảnh hệ thống, Android 7.1 đã thêm phương thức upgradeKey
vào HAL:
Chủ bàn phím 3
upgradeKey(vec keyBlobToUpgrade, vec upgradeParams) generates(ErrorCode error, vec upgradedKeyBlob);
Chủ bàn phím 2
keymaster_error_t (*upgrade_key)(const struct keymaster2_device* dev, const keymaster_key_blob_t* key_to_upgrade, const keymaster_key_param_set_t* upgrade_params, keymaster_key_blob_t* upgraded_key);
-
dev
là cấu trúc thiết bị -
keyBlobToUpgrade
là khóa cần được nâng cấp -
upgradeParams
là các tham số cần thiết để nâng cấp khóa. Chúng sẽ bao gồmTag::APPLICATION_ID
vàTag::APPLICATION_DATA
, cần thiết để giải mã blob khóa, nếu chúng được cung cấp trong quá trình tạo. -
upgradedKeyBlob
là tham số đầu ra, được sử dụng để trả về blob khóa mới.
Nếu upgradeKey
được gọi với một blob khóa không thể phân tích cú pháp hoặc không hợp lệ, nó sẽ trả về ErrorCode::INVALID_KEY_BLOB
. Nếu nó được gọi bằng khóa có mức vá lớn hơn giá trị hệ thống hiện tại, nó sẽ trả về ErrorCode::INVALID_ARGUMENT
. Nếu nó được gọi bằng khóa có phiên bản hệ điều hành lớn hơn giá trị hệ thống hiện tại và giá trị hệ thống khác 0, nó sẽ trả về ErrorCode::INVALID_ARGUMENT
. Cho phép nâng cấp phiên bản hệ điều hành từ khác 0 lên 0. Trong trường hợp có lỗi khi giao tiếp với thế giới bảo mật, nó sẽ trả về một giá trị lỗi thích hợp (ví dụ ErrorCode::SECURE_HW_ACCESS_DENIED
, ErrorCode::SECURE_HW_BUSY
). Nếu không, nó trả về ErrorCode::OK
và trả về một blob khóa mới trong upgradedKeyBlob
.
keyBlobToUpgrade
vẫn hợp lệ sau lệnh gọi upgradeKey
và về mặt lý thuyết có thể được sử dụng lại nếu thiết bị bị hạ cấp. Trong thực tế, kho khóa thường gọi deleteKey
trên blob keyBlobToUpgrade
ngay sau lệnh gọi upgradeKey
. Nếu keyBlobToUpgrade
có thẻ Tag::ROLLBACK_RESISTANT
thì upgradedKeyBlob
cũng phải có thẻ đó (và phải có khả năng chống khôi phục).
Cấu hình an toàn
Để triển khai liên kết phiên bản, keymaster TA cần một cách để nhận phiên bản hệ điều hành hiện tại và cấp bản vá (thông tin phiên bản) một cách an toàn, đồng thời đảm bảo rằng thông tin mà nó nhận được hoàn toàn khớp với thông tin về hệ thống đang chạy.
Để hỗ trợ phân phối an toàn thông tin phiên bản tới TA, trường OS_VERSION
đã được thêm vào tiêu đề hình ảnh khởi động. Tập lệnh xây dựng ảnh khởi động sẽ tự động điền vào trường này. OEM và người triển khai keymaster TA cần phải làm việc cùng nhau để sửa đổi bộ tải khởi động của thiết bị nhằm trích xuất thông tin phiên bản từ hình ảnh khởi động và chuyển nó tới TA trước khi hệ thống không an toàn được khởi động. Điều này đảm bảo rằng kẻ tấn công không thể can thiệp vào việc cung cấp thông tin phiên bản cho TA.
Cũng cần phải đảm bảo rằng image hệ thống có cùng thông tin phiên bản với image khởi động. Vì mục đích đó, phương thức cấu hình đã được thêm vào keymaster HAL:
keymaster_error_t (*configure)(const struct keymaster2_device* dev, const keymaster_key_param_set_t* params);
Đối số params
chứa Tag::OS_VERSION
và Tag::OS_PATCHLEVEL
. Phương thức này được các máy khách keymaster2 gọi sau khi mở HAL, nhưng trước khi gọi bất kỳ phương thức nào khác. Nếu bất kỳ phương thức nào khác được gọi trước khi định cấu hình, TA sẽ trả về ErrorCode::KEYMASTER_NOT_CONFIGURED
.
Lần configure
đầu tiên được gọi sau khi thiết bị khởi động, nó sẽ xác minh rằng thông tin phiên bản được cung cấp khớp với những gì được cung cấp bởi bộ nạp khởi động. Nếu thông tin phiên bản không khớp, configure
trả về ErrorCode::INVALID_ARGUMENT
và tất cả các phương thức keymaster khác tiếp tục trả về ErrorCode::KEYMASTER_NOT_CONFIGURED
. Nếu thông tin khớp, configure
trả về ErrorCode::OK
và các phương thức keymaster khác bắt đầu hoạt động bình thường.
Các lệnh gọi configure
tiếp theo sẽ trả về cùng một giá trị mà lệnh gọi đầu tiên trả về và không thay đổi trạng thái của keymaster. Lưu ý rằng quá trình này yêu cầu tất cả các OTA cập nhật cả ảnh hệ thống và ảnh khởi động; chúng không thể được cập nhật riêng biệt để giữ thông tin phiên bản được đồng bộ hóa.
Bởi vì configure
sẽ được gọi bởi hệ thống có nội dung được dự định xác thực, nên có rất ít cơ hội cho kẻ tấn công xâm phạm hình ảnh hệ thống và buộc nó cung cấp thông tin phiên bản khớp với hình ảnh khởi động, nhưng đó không phải là hình ảnh thực tế. phiên bản của hệ thống. Sự kết hợp giữa xác minh hình ảnh khởi động, xác thực dm-verity của nội dung hình ảnh hệ thống và thực tế là configure
được gọi từ rất sớm trong quá trình khởi động hệ thống sẽ khiến cửa sổ cơ hội này khó bị khai thác.