Trong Keymaster 1, tất cả khoá keymaster đều được liên kết bằng phương thức mã hoá với Gốc tin cậy của thiết bị hoặc khoá Xác minh quy trình khởi động. Trong Keymaster 2 và 3, tất cả các khoá cũng được liên kết với hệ điều hành và cấp bản vá của hình ảnh 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ể đưa thiết bị trở lại phiên bản dễ bị tấn công và sử dụng các khoá được tạo bằng phiên bản mới hơn. Ngoài ra, khi một khoá có phiên bản và cấp bản vá nhất định được sử dụng trên một 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, khoá đó sẽ được nâng cấp trước khi có thể sử dụng và phiên bản trước của khoá sẽ mất hiệu lực. Bằng cách này, khi thiết bị được nâng cấp, các khoá sẽ *chuyển tiếp* cùng với thiết bị, nhưng mọi thao tác quay lại thiết bị về một bản phát hành trước đó sẽ khiến các khoá không thể sử dụng được.
Để hỗ trợ cấu trúc mô-đun của Treble và huỷ liên kết system.img với boot.img, Keymaster 4 đã thay đổi mô hình liên kết phiên bản chính để có các cấp bản vá riêng cho từng phân vùng. Điều này cho phép cập nhật từng phân vùng một cách độc lập, trong khi vẫn cung cấp tính năng bảo vệ tính năng quay lại phiên bản cũ.
Trong Android 9, các phân vùng boot
, system
và vendor
đều có cấp bản vá riêng.
- Các thiết bị có tính năng Khởi động được xác minh của Android (AVB) có thể đặt tất cả các cấp độ bản vá và phiên bản hệ thống vào vbmeta để trình tải khởi động có thể cung cấp các cấp độ bản vá và phiên bản hệ thống đó cho Keymaster. Đối với các phân vùng theo chuỗi, thông tin phiên bản cho phân vùng nằm trong vbmeta theo chuỗi. Nhìn chung, thông tin phiên bản phải nằm trong
vbmeta struct
chứa dữ liệu xác minh (hàm băm hoặc cây băm) 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 tính năng Xác minh quy trình khởi động cần cung cấp hàm băm của siêu dữ liệu phiên bản cho trình tải khởi động để trình tải 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ữ cấp độ bản vá trong tiêu đềsystem.img
có thể tiếp tục lưu trữ cấp độ bản vá và phiên bản hệ điều hành trong các thuộc tính chỉ có thể đọcvendor.img
lưu trữ cấp độ bản vá trong thuộc tính chỉ có thể đọcro.vendor.build.version.security_patch
.- Trình 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 tính năng xác minh quy trình khởi động 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ị xoá 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. Bạn có thể sử dụng khoá nếu tất cả thông tin phiên bản khớp với các giá trị liên kết với khoá và
IKeymaster::upgradeDevice()
sẽ chuyển sang cấp bản vá cao hơn nếu cần.
Thay đổi về 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 tự động thêm bằng cách triển khai Keymaster 2 trở lên vào tất cả khoá mới tạo (hoặc đã cập nhật). Ngoài ra, mọi nỗ lực sử dụng khoá 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 của hệ thống sẽ bị từ chối bằng ErrorCode::KEY_REQUIRES_UPGRADE
.
Tag::OS_VERSION
là một giá trị UINT
đại diện cho các phần chính, phụ và phụ 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ụ phụ. Ví dụ: 6.1.2 sẽ được biểu thị là 060102.
Tag::OS_PATCHLEVEL
là một giá trị UINT
đại diện cho năm và tháng của bản cập nhật gần đây nhất cho hệ thống dưới dạng YYYYMM, trong đó YYYY là năm gồm 4 chữ số và MM là tháng gồm 2 chữ số. Ví dụ: Tháng 3 năm 2016 sẽ được trình bày là 201603.
UpgradeKey
Để cho phép nâng cấp khoá lên phiên bản hệ điều hành mới và cấp bản vá của hình ảnh hệ thống, Android 7.1 đã thêm phương thức upgradeKey
vào HAL:
Keymaster 3
upgradeKey(vec keyBlobToUpgrade, vec upgradeParams) generates(ErrorCode error, vec upgradedKeyBlob);
Keymaster 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à khoá cần được nâng cấpupgradeParams
là các tham số cần thiết để nâng cấp khoá. Các khoá này bao gồmTag::APPLICATION_ID
vàTag::APPLICATION_DATA
, cần thiết để giải mã blob khoá nếu các khoá này được cung cấp trong quá trình tạo.upgradedKeyBlob
là tham số đầu ra, dùng để trả về khối khoá mới.
Nếu upgradeKey
được gọi bằng một blob khoá không thể phân tích cú pháp hoặc không hợp lệ, thì hàm này sẽ trả về ErrorCode::INVALID_KEY_BLOB
. Nếu được gọi bằng một khoá có cấp độ bản vá lớn hơn giá trị hệ thống hiện tại, thì hàm này sẽ trả về ErrorCode::INVALID_ARGUMENT
. Nếu được gọi bằng một khoá 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, thì hàm này 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 thành 0. Trong trường hợp xảy ra lỗi khi giao tiếp với thế giới bảo mật, phương thức này 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, phương thức này sẽ trả về ErrorCode::OK
và trả về một blob khoá mới trong upgradedKeyBlob
.
keyBlobToUpgrade
vẫn hợp lệ sau lệnh gọi upgradeKey
và theo lý thuyết, bạn có thể sử dụng lại nếu thiết bị bị hạ cấp. Trong thực tế, kho khoá thường gọi deleteKey
trên blob keyBlobToUpgrade
ngay sau lệnh gọi đến upgradeKey
. Nếu keyBlobToUpgrade
có thẻ Tag::ROLLBACK_RESISTANT
, thì upgradedKeyBlob
cũng phải có thẻ này (và phải có khả năng chống rollback).
Cấu hình bảo mật
Để triển khai tính năng liên kết phiên bản, TA keymaster cần có một cách để nhận phiên bản hệ điều hành và cấp độ bản vá hiện tại (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 khớp chính xác với thông tin về hệ thống đang chạy.
Để hỗ trợ việc phân phối an toàn thông tin phiên bản cho TA, một trường OS_VERSION
đã được thêm vào tiêu đề hình ảnh khởi động. Tập lệnh bản dựng hình ảnh khởi động sẽ tự động điền trường này. Nhà sản xuất thiết bị gốc (OEM) và người triển khai TA keymaster cần phối hợp với nhau để sửa đổi trình tải khởi động 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 thông tin đó đến TA trước khi khởi động hệ thống không an toàn. Đ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.
Bạn cũng cần đảm bảo rằng hình ảnh hệ thống có cùng thông tin phiên bản với hình ảnh khởi động. Để đạt được mục tiêu đó, phương thức định cấu hình đã được thêm vào HAL keymaster:
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 ứng dụng 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 đầu tiên configure
được gọi sau khi thiết bị khởi động, hàm này sẽ xác minh rằng thông tin phiên bản được cung cấp khớp với thông tin do trình tải khởi động cung cấp. Nếu thông tin phiên bản không khớp, configure
sẽ trả về ErrorCode::INVALID_ARGUMENT
và tất cả các phương thức keymaster khác sẽ tiếp tục trả về ErrorCode::KEYMASTER_NOT_CONFIGURED
. Nếu thông tin khớp, configure
sẽ trả về ErrorCode::OK
và các phương thức keymaster khác sẽ bắt đầu hoạt động bình thường.
Các lệnh gọi tiếp theo đến configure
sẽ trả về cùng một giá trị do lệnh gọi đầu tiên trả về và không thay đổi trạng thái của keymaster.
Vì configure
được hệ thống gọi với nội dung cần xác thực, nên kẻ tấn công có cơ hội hẹp để xâm phạm hình ảnh hệ thống và buộc hình ảnh đó 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à phiên bản thực tế của hệ thống. Việc kết hợp 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à việc configure
được gọi rất sớm trong quá trình khởi động hệ thống sẽ khiến bạn khó khai thác cơ hội này.