Chứng thực khóa và ID

Keystore cung cấp một nơi an toàn hơn để tạo, lưu trữ và sử dụng khóa mật mã một cách có kiểm soát. Khi có sẵn và sử dụng bộ lưu trữ khóa dựa trên phần cứng, tài liệu khóa sẽ an toàn hơn trước việc trích xuất từ ​​thiết bị và Keymaster thực thi các hạn chế khó phá bỏ.

Tuy nhiên, điều này chỉ đúng nếu các khóa kho khóa được biết là nằm trong bộ lưu trữ được hỗ trợ bằng phần cứng. Trong Keymaster 1, không có cách nào để ứng dụng hoặc máy chủ từ xa xác minh một cách đáng tin cậy xem trường hợp này có xảy ra hay không. Trình nền kho khóa đã tải HAL keymaster có sẵn và tin vào bất cứ điều gì HAL nói liên quan đến việc hỗ trợ phần cứng của khóa.

Để khắc phục điều này, Keymaster đã giới thiệu chứng thực khóa trong Android 7.0 (Keymaster 2) và chứng thực ID trong Android 8.0 (Keymaster 3).

Chứng thực khóa nhằm mục đích cung cấp một cách để xác định rõ ràng xem cặp khóa bất đối xứng có được hỗ trợ bằng phần cứng hay không, thuộc tính của khóa là gì và những ràng buộc nào được áp dụng cho việc sử dụng nó.

Chứng thực ID cho phép thiết bị cung cấp bằng chứng về số nhận dạng phần cứng của thiết bị, chẳng hạn như số sê-ri hoặc IMEI.

Chứng thực chính

Để hỗ trợ chứng thực khóa, Android 7.1 đã giới thiệu một bộ thẻ, loại và phương thức cho HAL.

Thẻ

  • Tag::ATTESTATION_CHALLENGE
  • Tag::INCLUDE_UNIQUE_ID
  • Tag::RESET_SINCE_ID_ROTATION

Kiểu

Keymaster 2 trở xuống

typedef struct {
    keymaster_blob_t* entries;
    size_t entry_count;
} keymaster_cert_chain_t;

Phương thức AttestKey

Chủ bàn phím 3

    attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams)
        generates(ErrorCode error, vec<vec<uint8_t>> certChain);

Keymaster 2 trở xuống

keymaster_error_t (*attest_key)(const struct keymaster2_device* dev,
        const keymaster_key_blob_t* key_to_attest,
        const keymaster_key_param_set_t* attest_params,
        keymaster_cert_chain_t* cert_chain);
  • dev là cấu trúc thiết bị keymaster.
  • keyToAttest là blob khóa được trả về từ generateKey mà chứng thực sẽ được tạo.
  • attestParams là danh sách mọi thông số cần thiết để chứng thực. Điều này bao gồm Tag::ATTESTATION_CHALLENGE và có thể Tag::RESET_SINCE_ID_ROTATION , cũng như Tag::APPLICATION_IDTag::APPLICATION_DATA . Hai cái sau là cần thiết để giải mã blob khóa nếu chúng được chỉ định trong quá trình tạo khóa.
  • certChain là tham số đầu ra, trả về một loạt chứng chỉ. Mục 0 là chứng chỉ chứng thực, nghĩa là nó chứng nhận khóa từ keyToAttest và chứa phần mở rộng chứng thực.

Phương thức attestKey được coi là một thao tác khóa công khai trên khóa được chứng thực, vì nó có thể được gọi bất kỳ lúc nào và không cần đáp ứng các ràng buộc ủy quyền. Ví dụ: nếu khóa được chứng thực cần xác thực người dùng để sử dụng thì chứng thực có thể được tạo mà không cần xác thực người dùng.

Giấy chứng nhận

Chứng chỉ chứng thực là chứng chỉ X.509 tiêu chuẩn, có phần mở rộng chứng thực tùy chọn chứa mô tả về khóa chứng thực. Chứng chỉ được ký bằng khóa chứng thực được chứng nhận. Khóa chứng thực có thể sử dụng thuật toán khác với khóa được chứng thực.

Chứng chỉ chứng thực chứa các trường trong bảng bên dưới và không thể chứa bất kỳ trường bổ sung nào. Một số trường chỉ định một giá trị trường cố định. Các cuộc kiểm tra CTS xác nhận rằng nội dung chứng chỉ chính xác như được xác định.

TRÌNH TỰ chứng chỉ

Tên trường (xem RFC 5280 ) Giá trị
tbsChứng chỉ TRÌNH TỰ chứng chỉ TBS
thuật toán chữ ký AlgorithmIdentifier của thuật toán dùng để ký khóa:
ECDSA cho khóa EC, RSA cho khóa RSA.
giá trị chữ ký CHUỖI BIT, chữ ký được tính toán trên chứng chỉ tbsCertificate được mã hóa DER ASN.1.

TRÌNH TỰ chứng chỉ TBS

Tên trường (xem RFC 5280 ) Giá trị
version INTEGER 2 (có nghĩa là chứng chỉ v3)
serialNumber INTEGER 1 (giá trị cố định: giống nhau trên tất cả các chứng chỉ)
signature AlgorithmIdentifier của thuật toán dùng để ký khóa: ECDSA cho khóa EC, RSA cho khóa RSA.
issuer Tương tự như trường chủ đề của khóa chứng thực hàng loạt.
validity SEQUENCE trong hai ngày, chứa các giá trị của Tag::ACTIVE_DATETIMETag::USAGE_EXPIRE_DATETIME . Các giá trị đó tính bằng mili giây kể từ ngày 1 tháng 1 năm 1970. Xem RFC 5280 để biết cách trình bày ngày chính xác trong chứng chỉ.
Nếu không có Tag::ACTIVE_DATETIME , hãy sử dụng giá trị của Tag::CREATION_DATETIME . Nếu không có Tag::USAGE_EXPIRE_DATETIME , hãy sử dụng ngày hết hạn của chứng chỉ khóa chứng thực hàng loạt.
subject CN = "Khóa kho khóa Android" (giá trị cố định: giống nhau trên tất cả các chứng chỉ)
subjectPublicKeyInfo Chủ đềPublicKeyInfo chứa khóa công khai được chứng thực.
extensions/Key Usage digitalSignature: đặt nếu khóa có mục đích KeyPurpose::SIGN hoặc KeyPurpose::VERIFY . Tất cả các bit khác không được đặt.
extensions/CRL Distribution Points Giá trị TBD
extensions/"attestation" OID là 1.3.6.1.4.1.11129.2.1.17; nội dung được xác định trong phần Gia hạn chứng thực bên dưới. Giống như tất cả các tiện ích mở rộng chứng chỉ X.509, nội dung được biểu thị dưới dạng OCTET_STRING chứa mã hóa DER của SEQUENCE chứng thực.

Phần mở rộng chứng thực

Tiện ích mở rộng attestation chứa mô tả đầy đủ về các ủy quyền của keymaster được liên kết với khóa, trong cấu trúc tương ứng trực tiếp với danh sách ủy quyền như được sử dụng trong Android và HAL của keymaster. Mỗi thẻ trong danh sách ủy quyền được thể hiện bằng một mục nhập ASN.1 SEQUENCE , được gắn thẻ rõ ràng bằng số thẻ keymaster, nhưng với bộ mô tả loại (bốn bit thứ tự cao) bị che đi.

Ví dụ: trong Keymaster 3, Tag::PURPOSE được xác định trong type.hal là ENUM_REP | 1 . Đối với tiện ích mở rộng chứng thực, giá trị ENUM_REP bị xóa, để lại thẻ 1 . (Đối với Keymaster 2 trở xuống, KM_TAG_PURPOSE được xác định trong keymaster_defs.h.)

Các giá trị được dịch theo cách đơn giản sang các loại ASN.1, theo bảng này:

Loại chủ bàn phím loại ASN.1
ENUM số nguyên
ENUM_REP BỘ INTEGER
UINT số nguyên
UINT_REP BỘ INTEGER
ULONG số nguyên
ULONG_REP BỘ INTEGER
DATE INTEGER (mili giây kể từ ngày 1 tháng 1 năm 1970 00:00:00 GMT)
BOOL NULL (trong keymaster, thẻ hiện tại có nghĩa là đúng, vắng mặt có nghĩa là sai.
Ngữ nghĩa tương tự áp dụng cho mã hóa ASN.1)
BIGNUM Hiện không được sử dụng nên không có ánh xạ nào được xác định
BYTES OCTET_STRING

Lược đồ

Nội dung mở rộng chứng thực được mô tả bằng lược đồ ASN.1 sau.

KeyDescription ::= SEQUENCE {
  attestationVersion         INTEGER, # KM2 value is 1. KM3 value is 2. KM4 value is 3.
  attestationSecurityLevel   SecurityLevel,
  keymasterVersion           INTEGER,
  keymasterSecurityLevel     SecurityLevel,
  attestationChallenge       OCTET_STRING,
  uniqueId                   OCTET_STRING,
  softwareEnforced           AuthorizationList,
  teeEnforced                AuthorizationList,
}

SecurityLevel ::= ENUMERATED {
  Software                   (0),
  TrustedEnvironment         (1),
  StrongBox                  (2),
}

AuthorizationList ::= SEQUENCE {
  purpose                     [1] EXPLICIT SET OF INTEGER OPTIONAL,
  algorithm                   [2] EXPLICIT INTEGER OPTIONAL,
  keySize                     [3] EXPLICIT INTEGER OPTIONAL.
  digest                      [5] EXPLICIT SET OF INTEGER OPTIONAL,
  padding                     [6] EXPLICIT SET OF INTEGER OPTIONAL,
  ecCurve                     [10] EXPLICIT INTEGER OPTIONAL,
  rsaPublicExponent           [200] EXPLICIT INTEGER OPTIONAL,
  rollbackResistance          [303] EXPLICIT NULL OPTIONAL, # KM4
  activeDateTime              [400] EXPLICIT INTEGER OPTIONAL
  originationExpireDateTime   [401] EXPLICIT INTEGER OPTIONAL
  usageExpireDateTime         [402] EXPLICIT INTEGER OPTIONAL
  noAuthRequired              [503] EXPLICIT NULL OPTIONAL,
  userAuthType                [504] EXPLICIT INTEGER OPTIONAL,
  authTimeout                 [505] EXPLICIT INTEGER OPTIONAL,
  allowWhileOnBody            [506] EXPLICIT NULL OPTIONAL,
  trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, # KM4
  trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, # KM4
  unlockedDeviceRequired      [509] EXPLICIT NULL OPTIONAL, # KM4
  allApplications             [600] EXPLICIT NULL OPTIONAL,
  applicationId               [601] EXPLICIT OCTET_STRING OPTIONAL,
  creationDateTime            [701] EXPLICIT INTEGER OPTIONAL,
  origin                      [702] EXPLICIT INTEGER OPTIONAL,
  rollbackResistant           [703] EXPLICIT NULL OPTIONAL, # KM2 and KM3 only.
  rootOfTrust                 [704] EXPLICIT RootOfTrust OPTIONAL,
  osVersion                   [705] EXPLICIT INTEGER OPTIONAL,
  osPatchLevel                [706] EXPLICIT INTEGER OPTIONAL,
  attestationApplicationId    [709] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdBrand          [710] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdDevice         [711] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdProduct        [712] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdSerial         [713] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdImei           [714] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdMeid           [715] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdManufacturer   [716] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdModel          [717] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  vendorPatchLevel            [718] EXPLICIT INTEGER OPTIONAL, # KM4
  bootPatchLevel              [719] EXPLICIT INTEGER OPTIONAL, # KM4
}

RootOfTrust ::= SEQUENCE {
  verifiedBootKey            OCTET_STRING,
  deviceLocked               BOOLEAN,
  verifiedBootState          VerifiedBootState,
  verifiedBootHash           OCTET_STRING, # KM4
}

VerifiedBootState ::= ENUMERATED {
  Verified                   (0),
  SelfSigned                 (1),
  Unverified                 (2),
  Failed                     (3),
}

Các trường mô tả khóa

Các trường keymasterVersionattestationChallenge được xác định theo vị trí chứ không phải theo thẻ, do đó, các thẻ ở dạng được mã hóa chỉ xác định loại trường. Các trường còn lại được gắn thẻ ngầm như được chỉ định trong lược đồ.

Tên trường Kiểu Giá trị
attestationVersion số nguyên Phiên bản sơ đồ chứng thực: 1, 2 hoặc 3.
attestationSecurity Cấp độ bảo mật Mức độ bảo mật của chứng thực này. Có thể nhận được chứng thực phần mềm của các khóa được hỗ trợ bằng phần cứng. Những chứng thực như vậy không thể tin cậy được nếu hệ thống Android bị xâm phạm.
keymasterVersion số nguyên Phiên bản của thiết bị keymaster: 0, 1, 2, 3 hoặc 4.
keymasterSecurity Cấp độ bảo mật Mức độ bảo mật của việc triển khai keymaster.
attestationChallenge OCTET_STRING Giá trị của Tag::ATTESTATION_CHALLENGE , được chỉ định cho yêu cầu chứng thực.
uniqueId OCTET_STRING ID duy nhất tùy chọn, xuất hiện nếu khóa có Tag::INCLUDE_UNIQUE_ID
softwareEnforced Danh sách ủy quyền Các ủy quyền tùy chọn của keymaster không được TEE thực thi, nếu có.
teeEnforced Danh sách ủy quyền Tùy chọn, ủy quyền của Keymaster do TEE thực thi, nếu có.

Các trường Danh sách ủy quyền

Tất cả các trường AuthorizationList đều là tùy chọn và được xác định bằng giá trị thẻ keymaster, với các bit loại bị che đi. Gắn thẻ rõ ràng được sử dụng để các trường cũng chứa thẻ cho biết loại ASN.1 của chúng, để phân tích cú pháp dễ dàng hơn.

Để biết chi tiết về giá trị của từng trường, hãy xem types.hal cho Keymaster 3 và keymaster_defs.h cho Keymaster 2 trở xuống. Tên thẻ Keymaster đã được chuyển đổi thành tên trường bằng cách bỏ tiền tố KM_TAG và thay đổi phần còn lại thành dạng lạc đà, do đó Tag::KEY_SIZE trở thành keySize .

Các trường RootOfTrust

Các trường RootOfTrust được xác định theo vị trí.

Tên trường Kiểu Giá trị
verifiedBootKey OCTET_STRING Hàm băm an toàn của khóa được sử dụng để xác minh hình ảnh hệ thống. Khuyến nghị SHA-256.
deviceLocked BOOLEAN Đúng nếu bộ nạp khởi động bị khóa, điều đó có nghĩa là chỉ những hình ảnh đã ký mới có thể được flash và quá trình kiểm tra khởi động đã xác minh được thực hiện.
verifiedBootState Đã xác minhBootState Trạng thái khởi động đã được xác minh.
verifiedBootHash OCTET_STRING Bản tóm tắt tất cả dữ liệu được bảo vệ bởi Verify Boot. Đối với các thiết bị sử dụng triển khai Khởi động đã xác minh trên Android của Khởi động đã xác minh, giá trị này chứa thông báo của cấu trúc VBMeta hoặc cấu trúc siêu dữ liệu Khởi động đã xác minh. Để tìm hiểu thêm về cách tính giá trị này, hãy xemThông báo VBMeta

Giá trị đã xác minhBootState

Các giá trị của verifiedBootState có ý nghĩa như sau:

Giá trị Nghĩa
Verified Biểu thị toàn bộ chuỗi tin cậy mở rộng từ bộ nạp khởi động đến các phân vùng đã được xác minh, bao gồm bộ nạp khởi động, phân vùng khởi động và tất cả các phân vùng đã được xác minh.
Ở trạng thái này, giá trị verifiedBootKey là hàm băm của chứng chỉ được nhúng, nghĩa là chứng chỉ không thể thay đổi được ghi vào ROM.
Trạng thái này tương ứng với trạng thái khởi động màu xanh lá cây như được ghi trong tài liệu về quy trình khởi động đã được xác minh .
SelfSigned Cho biết phân vùng khởi động đã được xác minh bằng chứng chỉ nhúng và chữ ký là hợp lệ. Bộ nạp khởi động hiển thị cảnh báo và dấu vân tay của khóa chung trước khi cho phép quá trình khởi động tiếp tục.
Ở trạng thái này, giá trị verifiedBootKey là hàm băm của chứng chỉ tự ký.
Trạng thái này tương ứng với trạng thái khởi động màu vàng như được ghi trong tài liệu về quy trình khởi động đã được xác minh .
Unverified Cho biết một thiết bị có thể được sửa đổi tự do. Tính toàn vẹn của thiết bị được để lại cho người dùng xác minh ngoài băng tần. Bộ nạp khởi động hiển thị cảnh báo cho người dùng trước khi cho phép quá trình khởi động tiếp tục.
Ở trạng thái này, giá trị verifiedBootKey trống.
Trạng thái này tương ứng với trạng thái khởi động màu cam như được ghi trong tài liệu quy trình khởi động đã được xác minh .
Failed Cho biết thiết bị đã xác minh không thành công. Không có chứng chỉ chứng thực nào thực sự chứa giá trị này vì ở trạng thái này bộ nạp khởi động sẽ tạm dừng. Nó được bao gồm ở đây cho đầy đủ.
Trạng thái này tương ứng với trạng thái khởi động đỏ như được ghi trong tài liệu về luồng khởi động đã được xác minh .

Giá trị cấp độ bảo mật

Các giá trị của securityLevel có ý nghĩa sau:

Giá trị Nghĩa
Software Mã tạo hoặc quản lý phần tử liên quan (chứng thực hoặc khóa) được triển khai trong hệ thống Android và có thể bị thay đổi nếu hệ thống đó bị xâm phạm.
TrustedEnvironment Mã tạo hoặc quản lý phần tử liên quan (chứng thực hoặc khóa) được triển khai trong Môi trường thực thi tin cậy (TEE). Nó có thể bị thay đổi nếu TEE bị xâm phạm, nhưng TEE có khả năng chống lại sự xâm phạm từ xa rất cao và có khả năng chống lại sự xâm phạm ở mức vừa phải do tấn công phần cứng trực tiếp.
StrongBox Mã tạo hoặc quản lý phần tử liên quan (chứng thực hoặc khóa) được triển khai trong mô-đun bảo mật phần cứng chuyên dụng. Nó có thể bị thay đổi nếu mô-đun bảo mật phần cứng bị xâm phạm, nhưng nó có khả năng chống xâm phạm từ xa cao và có khả năng chống xâm phạm cao do tấn công phần cứng trực tiếp.

ID duy nhất

ID duy nhất là giá trị 128 bit để nhận dạng thiết bị nhưng chỉ trong một khoảng thời gian giới hạn. Giá trị được tính bằng:

HMAC_SHA256(T || C || R, HBK)

Ở đâu:

  • T là "giá trị bộ đếm thời gian", được tính bằng cách chia giá trị của Tag::CREATION_DATETIME cho 2592000000, bỏ đi phần còn lại. T thay đổi cứ sau 30 ngày (2592000000 = 30 * 24 * 60 * 60 * 1000).
  • C là giá trị của Tag::APPLICATION_ID
  • R là 1 nếu Tag::RESET_SINCE_ID_ROTATION có trong tham số attest_params đối với lệnh gọi attest_key hoặc 0 nếu không có thẻ.
  • HBK là một bí mật duy nhất liên quan đến phần cứng được biết đến trong Môi trường thực thi đáng tin cậy và chưa bao giờ được tiết lộ. Bí mật chứa ít nhất 128 bit entropy và là duy nhất cho từng thiết bị (tính duy nhất xác suất được chấp nhận với 128 bit entropy). HBK phải được lấy từ vật liệu khóa hợp nhất thông qua HMAC hoặc AES_CMAC.

Cắt bớt đầu ra HMAC_SHA256 thành 128 bit.

Khóa chứng thực và chứng chỉ

Hai khóa, một RSA và một ECDSA, cùng chuỗi chứng chỉ tương ứng, được cung cấp an toàn vào thiết bị.

Android 12 giới thiệu tính năng Cấp phép khóa từ xa và Android 13 yêu cầu các thiết bị phải triển khai tính năng này. Cung cấp khóa từ xa cung cấp cho các thiết bị tại hiện trường chứng chỉ chứng thực ECDSA P256 cho mỗi ứng dụng. Các chứng chỉ này có thời hạn sử dụng ngắn hơn so với chứng chỉ do nhà máy cung cấp.

Nhiều IMEI

Android 14 bổ sung hỗ trợ cho nhiều IMEI trong bản ghi Chứng thực khóa Android. Các OEM có thể triển khai tính năng này bằng cách thêm thẻ KeyMint cho IMEI thứ hai. Việc các thiết bị có nhiều sóng di động ngày càng trở nên phổ biến và các OEM hiện có thể hỗ trợ các thiết bị có hai IMEI.

Các OEM bắt buộc phải có IMEI phụ, nếu có trên thiết bị của họ, thì phải được cung cấp cho (các) triển khai KeyMint để những triển khai đó có thể chứng thực điều đó giống như cách họ chứng thực IMEI đầu tiên

chứng thực ID

Android 8.0 bao gồm hỗ trợ tùy chọn để chứng thực ID cho các thiết bị có Keymaster 3. Chứng thực ID cho phép thiết bị cung cấp bằng chứng về số nhận dạng phần cứng của thiết bị, chẳng hạn như số sê-ri hoặc IMEI. Mặc dù là một tính năng tùy chọn nhưng chúng tôi khuyên bạn nên hỗ trợ tất cả quá trình triển khai Keymaster 3 vì khả năng chứng minh danh tính của thiết bị sẽ giúp các trường hợp sử dụng như cấu hình từ xa không chạm thực sự trở nên an toàn hơn (vì phía từ xa có thể chắc chắn rằng đang nói chuyện với đúng thiết bị chứ không phải thiết bị giả mạo danh tính của nó).

Chứng thực ID hoạt động bằng cách tạo các bản sao của mã nhận dạng phần cứng của thiết bị mà chỉ Môi trường thực thi tin cậy (TEE) mới có thể truy cập trước khi thiết bị rời khỏi nhà máy. Người dùng có thể mở khóa bộ nạp khởi động của thiết bị và thay đổi phần mềm hệ thống cũng như số nhận dạng do hệ thống Android báo cáo. Bản sao của số nhận dạng do TEE nắm giữ không thể bị thao túng theo cách này, đảm bảo rằng chứng thực ID thiết bị sẽ chỉ chứng thực cho số nhận dạng phần cứng ban đầu của thiết bị, từ đó ngăn chặn các nỗ lực giả mạo.

Bề mặt API chính để chứng thực ID được xây dựng dựa trên cơ chế chứng thực khóa hiện có được giới thiệu với Keymaster 2. Khi yêu cầu chứng chỉ chứng thực cho khóa do keymaster nắm giữ, người gọi có thể yêu cầu đưa số nhận dạng phần cứng của thiết bị vào siêu dữ liệu của chứng chỉ chứng thực. Nếu khóa được giữ trong TEE, chứng chỉ sẽ quay trở lại nguồn tin cậy đã biết. Người nhận chứng chỉ như vậy có thể xác minh rằng chứng chỉ và nội dung của nó, bao gồm cả mã định danh phần cứng, được viết bởi TEE. Khi được yêu cầu đưa số nhận dạng phần cứng vào chứng chỉ chứng thực, TEE chỉ chứng thực những số nhận dạng được lưu giữ trong bộ lưu trữ của nó, như được điền trên sàn nhà máy.

Thuộc tính lưu trữ

Bộ lưu trữ chứa số nhận dạng của thiết bị cần phải có các thuộc tính sau:

  • Các giá trị lấy từ số nhận dạng ban đầu của thiết bị sẽ được sao chép vào bộ lưu trữ trước khi thiết bị rời khỏi nhà máy.
  • Phương thức destroyAttestationIds() có thể hủy vĩnh viễn bản sao dữ liệu có nguồn gốc từ mã định danh này. Phá hủy vĩnh viễn có nghĩa là dữ liệu bị xóa hoàn toàn nên việc khôi phục cài đặt gốc hay bất kỳ quy trình nào khác được thực hiện trên thiết bị đều không thể khôi phục dữ liệu đó. Điều này đặc biệt quan trọng đối với các thiết bị mà người dùng đã mở khóa bộ nạp khởi động và thay đổi phần mềm hệ thống cũng như sửa đổi số nhận dạng do khung Android trả về.
  • Các cơ sở RMA phải có khả năng tạo ra các bản sao mới của dữ liệu có nguồn gốc từ mã định danh phần cứng. Bằng cách này, một thiết bị đi qua RMA có thể thực hiện lại chứng thực ID. Cơ chế được các cơ sở RMA sử dụng phải được bảo vệ để người dùng không thể tự mình gọi nó vì điều đó sẽ cho phép họ có được chứng thực ID giả mạo.
  • Không có mã nào ngoài ứng dụng đáng tin cậy của Keymaster trong TEE có thể đọc dữ liệu có nguồn gốc từ mã định danh được lưu trong bộ lưu trữ.
  • Bộ lưu trữ có bằng chứng giả mạo: Nếu nội dung của bộ lưu trữ đã bị sửa đổi, TEE sẽ xử lý nội dung đó giống như khi các bản sao của nội dung đã bị hủy và từ chối mọi nỗ lực chứng thực ID. Điều này được thực hiện bằng cách ký hoặc lập địa chỉ MAC cho bộ lưu trữ như được mô tả bên dưới .
  • Bộ lưu trữ không giữ số nhận dạng ban đầu. Vì việc chứng thực ID liên quan đến thách thức nên người gọi luôn cung cấp số nhận dạng để được chứng thực. TEE chỉ cần xác minh rằng những giá trị này khớp với các giá trị ban đầu mà chúng có. Việc lưu trữ các giá trị băm an toàn của các giá trị ban đầu thay vì các giá trị sẽ cho phép xác minh này.

Sự thi công

Để tạo một triển khai có các thuộc tính được liệt kê ở trên, hãy lưu trữ các giá trị bắt nguồn từ ID trong cấu trúc S sau. Không lưu trữ các bản sao khác của giá trị ID, ngoại trừ những vị trí thông thường trong hệ thống mà chủ sở hữu thiết bị có thể sửa đổi bằng cách root:

S = D || HMAC(HBK, D)

Ở đâu:

  • D = HMAC(HBK, ID 1 ) || HMAC(HBK, ID 2 ) || ... || HMAC(HBK, ID n )
  • HMAC là cấu trúc HMAC với hàm băm an toàn thích hợp (khuyến nghị SHA-256)
  • HBK là khóa giới hạn phần cứng không được sử dụng cho bất kỳ mục đích nào khác
  • ID 1 ...ID n là các giá trị ID gốc; Việc liên kết một giá trị cụ thể với một chỉ mục cụ thể phụ thuộc vào việc triển khai, vì các thiết bị khác nhau sẽ có số lượng mã định danh khác nhau
  • || đại diện cho sự nối

Vì đầu ra HMAC có kích thước cố định nên không cần có tiêu đề hoặc cấu trúc nào khác để có thể tìm thấy các giá trị băm ID riêng lẻ hoặc HMAC của D. Ngoài việc kiểm tra các giá trị được cung cấp để thực hiện chứng thực, quá trình triển khai cần xác thực S bằng cách trích xuất D từ S , tính toán HMAC(HBK, D) và so sánh nó với giá trị trong S để xác minh rằng không có ID riêng lẻ nào bị sửa đổi/hỏng. Ngoài ra, việc triển khai phải sử dụng so sánh theo thời gian không đổi cho tất cả các thành phần ID riêng lẻ và xác thực S. Thời gian so sánh phải không đổi bất kể số lượng ID được cung cấp và kết quả khớp chính xác của bất kỳ phần nào của thử nghiệm.

Số nhận dạng phần cứng

Chứng thực ID hỗ trợ các mã định danh phần cứng sau:

  1. Tên thương hiệu do Build.BRAND trả về trong Android
  2. Tên thiết bị, được trả về bởi Build.DEVICE trong Android
  3. Tên sản phẩm được trả về bởi Build.PRODUCT trong Android
  4. Tên nhà sản xuất, do Build.MANUFACTURER trả về trong Android
  5. Tên mẫu, được trả về bởi Build.MODEL trong Android
  6. Số seri
  7. IMEI của tất cả các đài
  8. MEID của tất cả các đài

Để hỗ trợ chứng thực ID thiết bị, thiết bị sẽ chứng thực những số nhận dạng này. Tất cả các thiết bị chạy Android đều có sáu tính năng đầu tiên và chúng cần thiết để tính năng này hoạt động. Nếu thiết bị có bất kỳ sóng di động tích hợp nào thì thiết bị cũng phải hỗ trợ chứng thực IMEI và/hoặc MEID của sóng vô tuyến.

Chứng thực ID được yêu cầu bằng cách thực hiện chứng thực khóa và bao gồm số nhận dạng thiết bị để chứng thực trong yêu cầu. Các mã định danh được gắn thẻ là:

  • ATTESTATION_ID_BRAND
  • ATTESTATION_ID_DEVICE
  • ATTESTATION_ID_PRODUCT
  • ATTESTATION_ID_MANUFACTURER
  • ATTESTATION_ID_MODEL
  • ATTESTATION_ID_SERIAL
  • ATTESTATION_ID_IMEI
  • ATTESTATION_ID_MEID

Mã định danh để chứng thực là chuỗi byte được mã hóa UTF-8. Định dạng này cũng áp dụng cho số nhận dạng số. Mỗi mã định danh để chứng thực được thể hiện dưới dạng chuỗi được mã hóa UTF-8.

Nếu thiết bị không hỗ trợ chứng thực ID (hoặc destroyAttestationIds() đã được gọi trước đó và thiết bị không còn có thể chứng thực ID của nó nữa), mọi yêu cầu chứng thực khóa bao gồm một hoặc nhiều thẻ này đều không thành công với ErrorCode::CANNOT_ATTEST_IDS .

Nếu thiết bị hỗ trợ chứng thực ID và một hoặc nhiều thẻ trên đã được đưa vào yêu cầu chứng thực khóa, thì TEE sẽ xác minh mã định danh được cung cấp cùng với mỗi thẻ khớp với bản sao của mã định danh phần cứng. Nếu một hoặc nhiều số nhận dạng không khớp thì toàn bộ quá trình chứng thực sẽ không thành công với ErrorCode::CANNOT_ATTEST_IDS . Nó có giá trị khi cùng một thẻ được cung cấp nhiều lần. Điều này có thể hữu ích, chẳng hạn như khi chứng thực IMEI: Một thiết bị có thể có nhiều đài với nhiều IMEI. Yêu cầu chứng thực hợp lệ nếu giá trị được cung cấp cùng với mỗi ATTESTATION_ID_IMEI khớp với một trong các sóng vô tuyến của thiết bị. Điều tương tự cũng áp dụng cho tất cả các thẻ khác.

Nếu chứng thực thành công, ID đã chứng thực sẽ được thêm vào phần mở rộng chứng thực (OID 1.3.6.1.4.1.11129.2.1.17) của chứng chỉ chứng thực đã cấp, sử dụng lược đồ ở trên . Những thay đổi từ lược đồ chứng thực Keymaster 2 được in đậm cùng với các nhận xét.

API Java

Phần này chỉ mang tính thông tin. Những người triển khai Keymaster không triển khai cũng như không sử dụng API Java. Điều này được cung cấp để giúp người triển khai hiểu cách các ứng dụng sử dụng tính năng này. Các thành phần hệ thống có thể sử dụng nó một cách khác nhau, đó là lý do tại sao điều quan trọng là phần này không được coi là quy chuẩn.