Phiên bản Ràng buộc

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 , systemvendor đề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ỉ đọc ro.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ùng vendor
    • BOOT_PATCH_LEVEL : phân vùng boot
    • OS_PATCH_LEVELOS_VERSION : phân vùng system . ( 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_VERSIONTag::OS_PATCHLEVEL cũng như các phương thức configureupgradeKey . 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ồm Tag::APPLICATION_IDTag::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_VERSIONTag::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.