| <html devsite> |
| <head> |
| <title>Key and ID Attestation</title> |
| <meta name="project_path" value="/_project.yaml" /> |
| <meta name="book_path" value="/_book.yaml" /> |
| </head> |
| <body> |
| <!-- |
| Copyright 2017 The Android Open Source Project |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| //www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| <p> |
| Keystore provides a more secure place to create, store, and use cryptographic |
| keys in a controlled way. When hardware-backed key storage is available and |
| used, key material is more secure against extraction from the device, and |
| Keymaster enforces restrictions that are difficult to subvert. |
| </p> |
| <p> |
| This is only true, however, if the keystore keys are known to be in |
| hardware-backed storage. In Keymaster 1, there was no way for apps or remote servers to |
| reliably verify if this was the case. The keystore daemon loaded the available |
| keymaster HAL and believed whatever the HAL said with respect to hardware |
| backing of keys. |
| </p> |
| <p> |
| To remedy this, Keymaster introduced key attestation in Android 7.0 (Keymaster 2) |
| and ID attestation in Android 8.0 (Keymaster 3). |
| </p> |
| <p> |
| Key attestation aims to provide a way to strongly |
| determine if an asymmetric key pair is hardware-backed, what the properties |
| of the key are, and what constraints are applied to its usage. |
| </p> |
| <p> |
| ID attestation allows the device to provide proof of its hardware identifiers, |
| such as serial number or IMEI. |
| |
| <p class="note">To support Keymaster 3's transition from the old-style C-structure |
| HAL to the C++ HAL interface generated from a definition in the new |
| Hardware Interface Definition Language (HIDL), tag and method names have changed |
| in Android 8.0. Tags, like all other keymaster enums, are now defined as C++ |
| scoped enums. For example, tags, formerly prefixed with <code>KM_TAG_</code>, |
| are now prefixed with <code>Tag::</code> and methods are in camel case. The |
| examples below use Keymaster 3 terms, unless specified otherwise. |
| </p> |
| |
| <h2 id="key-attestation">Key attestation</h2> |
| </p> |
| <p> |
| To support key attestation, Android 7.1 introduced a set of tags, type, and |
| method to the HAL. |
| </p> |
| <p> |
| <strong>Tags</strong> |
| </p> |
| <ul> |
| <li><code>Tag::ATTESTATION_CHALLENGE</code></li> |
| <li><code>Tag::INCLUDE_UNIQUE_ID</code></li> |
| <li><code>Tag::RESET_SINCE_ID_ROTATION</code></li> |
| </ul> |
| <p> |
| <strong>Type</strong> |
| </p> |
| |
| <p><strong>Keymaster 2 and below</strong></p> |
| <pre class="devsite-click-to-copy">typedef struct { |
| keymaster_blob_t* entries; |
| size_t entry_count; |
| } keymaster_cert_chain_t; |
| </pre> |
| |
| <p> |
| <strong><code>AttestKey</code> method</strong></p> |
| |
| <p><strong>Keymaster 3</strong></p> |
| <pre class="devsite-click-to-copy"> |
| attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams) |
| generates(ErrorCode error, vec<vec<uint8_t>> certChain);</pre> |
| |
| <p><strong>Keymaster 2 and below</strong></p> |
| <pre class="devsite-click-to-copy">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); |
| </pre> |
| |
| <ul> |
| <li><code>dev</code> is the keymaster device structure.</li> |
| <li><code>keyToAttest</code> is the key blob returned from |
| <code>generateKey</code> for which the attestation will be created.</li> |
| <li><code>attestParams</code> is a list of any parameters necessary for |
| attestation. This includes <code>Tag::ATTESTATION_CHALLENGE</code> and |
| possibly <code>Tag::RESET_SINCE_ID_ROTATION</code>, as well as |
| <code>Tag::APPLICATION_ID</code> and <code>Tag::APPLICATION_DATA</code>. The |
| latter two are necessary to decrypt the key blob if they were specified during |
| key generation.</li> |
| <li><code>certChain</code> is the output parameter, which returns an array of |
| certificates. Entry 0 is the attestation certificate, meaning it |
| certifies the key from <code>keyToAttest</code> and contains the |
| attestation extension.</li> |
| </ul> |
| |
| <p> |
| The <code>attestKey</code> method is considered a public key operation on the |
| attested key, because it can be called at any time and doesn't need to meet |
| authorization constraints. For example, if the attested key needs user |
| authentication for use, an attestation can be generated without user |
| authentication. |
| </p> |
| <h3 id="attestation-certificate">Attestation certificate</h3> |
| <p> |
| The attestation certificate is a standard X.509 certificate, with an optional |
| attestation extension that contains a description of the attested key. The |
| certificate is signed with a factory-provisioned <a |
| href="#attestation-keys-and-certificates">attestation key</a> that uses the same |
| algorithm as the key being attested (RSA for RSA, EC for EC). |
| </p> |
| <p> |
| The attestation certificate contains the fields in the table below and can't |
| contain any additional fields. Some fields specify a fixed field value. CTS |
| tests validate that the certificate content is exactly as defined. |
| </p> |
| <h4 id="certificate-sequence">Certificate SEQUENCE</h4> |
| <table> |
| <tr> |
| <th>Field name (see |
| <a href="https://tools.ietf.org/html/rfc5280">RFC 5280</a>) |
| </th> |
| <th>Value</th> |
| </tr> |
| <tr> |
| <td><a href="https://tools.ietf.org/html/rfc5280#section-4.1.1.1">tbsCertificate</a></td> |
| <td><a href="#tbscertificate-sequence">TBSCertificate SEQUENCE</a></td> |
| </tr> |
| <tr> |
| <td><a href="https://tools.ietf.org/html/rfc5280#section-4.1.1.2">signatureAlgorithm</a></td> |
| <td>AlgorithmIdentifier of algorithm used to sign key:<br /> |
| ECDSA for EC keys, RSA for RSA keys.</td> |
| </tr> |
| <tr> |
| <td><a href="https://tools.ietf.org/html/rfc5280#section-4.1.1.3">signatureValue</a></td> |
| <td>BIT STRING, signature computed on ASN.1 DER-encoded tbsCertificate.</td> |
| </tr> |
| </table> |
| |
| <h4 id="tbscertificate-sequence">TBSCertificate SEQUENCE</h4> |
| |
| <table> |
| <tr> |
| <th>Field name (see |
| <a href="https://tools.ietf.org/html/rfc5280">RFC 5280</a>)</th> |
| <th>Value</th> |
| </tr> |
| <tr> |
| <td><code>version</code></td> |
| <td>INTEGER 2 (means v3 certificate)</td> |
| </tr> |
| <tr> |
| <td><code>serialNumber</code></td> |
| <td>INTEGER 1 (fixed value: same on <em>all</em> certs)</td> |
| </tr> |
| <tr> |
| <td><code>signature</code></td> |
| <td>AlgorithmIdentifier of algorithm used to sign key: ECDSA for EC keys, |
| RSA for RSA keys.</td> |
| </tr> |
| <tr> |
| <td><code>issuer</code></td> |
| <td>Same as the subject field of the batch attestation key.</td> |
| </tr> |
| <tr> |
| <td><code>validity</code></td> |
| <td>SEQUENCE of two dates, containing the values of |
| <a href="/security/keystore/tags#active_datetime">Tag::ACTIVE_DATETIME</a> and |
| <a href="/security/keystore/tags#usage_expire_datetime">Tag::USAGE_EXPIRE_DATETIME</a>. |
| Those values are in milliseconds since Jan 1, 1970. |
| See <a href="https://tools.ietf.org/html/rfc5280">RFC 5280</a> for correct |
| date representations in certificates.<br /> |
| If <code>Tag::ACTIVE_DATETIME</code> is not present, use the value of |
| <code>Tag::CREATION_DATETIME</code>. If |
| <code>Tag::USAGE_EXPIRE_DATETIME</code> is not present, use the expiration |
| date of the batch attestation key certificate.</td> |
| </tr> |
| <tr> |
| <td><code>subject</code></td> |
| <td>CN = "Android Keystore Key" (fixed value: same on <em>all</em> certs)</td> |
| </tr> |
| <tr> |
| <td><code>subjectPublicKeyInfo</code></td> |
| <td>SubjectPublicKeyInfo containing attested public key.</td> |
| </tr> |
| <tr> |
| <td><code>extensions/Key Usage</code></td> |
| <td>digitalSignature: set if key has purpose <code>KeyPurpose::SIGN</code> or |
| <code>KeyPurpose::VERIFY</code>. All other bits unset.</td> |
| </tr> |
| <tr> |
| <td><code>extensions/CRL Distribution Points</code></td> |
| <td>Value TBD</td> |
| </tr> |
| <tr> |
| <td><code>extensions/"attestation"</code></td> |
| <td>The OID is 1.3.6.1.4.1.11129.2.1.17; the content is defined in the |
| Attestation Extension section below. As with all |
| X.509 certificate extensions, the content is represented as an OCTET_STRING |
| containing a DER encoding of the attestation SEQUENCE.</td> |
| </tr> |
| </table> |
| |
| <h3 id="attestation-extension">Attestation extension</h3> |
| <p> |
| The attestation extension contains a complete description of the keymaster |
| authorizations associated with the key, in a structure that directly corresponds |
| to the authorization lists as used in Android and the keymaster HAL. Each tag in |
| an authorization list is represented by an ASN.1 SEQUENCE entry, explicitly |
| tagged with the keymaster tag number, but with the type descriptor (four high |
| order bits) masked out.</p> |
| <p>For example, in Keymaster 3, <code>Tag::PURPOSE</code> is defined in |
| types.hal as <code>ENUM_REP | 1</code>. For the attestation extension, |
| the <code>ENUM_REP</code> value is removed, leaving tag <code>1</code>. |
| (For Keymaster 2 and below, <code>KM_TAG_PURPOSE</code> is defined in |
| keymaster_defs.h.) |
| </p> |
| <p> |
| Values are translated in a straightforward way to ASN.1 types, per this table: |
| </p> |
| <table> |
| <tr> |
| <th>Keymaster type</th> |
| <th>ASN.1 type</th> |
| </tr> |
| <tr> |
| <td><code>ENUM</code></td> |
| <td>INTEGER</td> |
| </tr> |
| <tr> |
| <td><code>ENUM_REP</code></td> |
| <td>SET of INTEGER</td> |
| </tr> |
| <tr> |
| <td><code>UINT</code></td> |
| <td>INTEGER</td> |
| </tr> |
| <tr> |
| <td><code>UINT_REP</code></td> |
| <td>SET of INTEGER</td> |
| </tr> |
| <tr> |
| <td><code>ULONG</code></td> |
| <td>INTEGER</td> |
| </tr> |
| <tr> |
| <td><code>ULONG_REP</code></td> |
| <td>SET of INTEGER</td> |
| </tr> |
| <tr> |
| <td><code>DATE</code></td> |
| <td>INTEGER (milliseconds since Jan 1, 1970 00:00:00 GMT)</td> |
| </tr> |
| <tr> |
| <td><code>BOOL</code></td> |
| <td>NULL (in keymaster, tag present means true, absent means false.<br /> |
| The same semantics apply to the ASN.1 encoding)</td> |
| </tr> |
| <tr> |
| <td><code>BIGNUM</code></td> |
| <td>Not presently used, so no mapping is defined</td> |
| </tr> |
| <tr> |
| <td><code>BYTES</code></td> |
| <td>OCTET_STRING</td> |
| </tr> |
| </table> |
| <p class="note"> |
| <strong>Note:</strong> Some tags are omitted from the schema and should not be |
| included in attestations. For example, the values of <code>Tag::USER_ID</code> |
| and <code>Tag::SECURE_USER_ID</code> have no meaning off-device, and |
| <code>Tag::MIN_MAC_LENGTH</code> and <code>Tag::CALLER_NONCE</code> are |
| useless with asymmetric keys. |
| </p> |
| |
| <h4 id="schema">Schema</h4> |
| <p> |
| The attestation extension content is described by the following ASN.1 schema. |
| This example also includes Keymaster 3 updates to include |
| <a href="#id-attestation">ID attestation</a> features, which are in bold with |
| comments. |
| </p> |
| |
| |
| <pre class="devsite-click-to-copy"> |
| KeyDescription ::= SEQUENCE { |
| <strong>attestationVersion INTEGER,</strong> # KM2 value is 1. KM3 value is 2. |
| attestationSecurityLevel SecurityLevel, |
| keymasterVersion INTEGER, |
| keymasterSecurityLevel SecurityLevel, |
| attestationChallenge OCTET_STRING, |
| uniqueId OCTET_STRING, |
| softwareEnforced AuthorizationList, |
| teeEnforced AuthorizationList, |
| } |
| |
| SecurityLevel ::= ENUMERATED { |
| Software (0), |
| TrustedEnvironment (1), |
| } |
| 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, |
| 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, |
| 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, |
| rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, |
| osVersion [705] EXPLICIT INTEGER OPTIONAL, |
| osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, |
| <strong>attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3 |
| <strong>attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3 |
| <strong>attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3 |
| <strong>attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3 |
| <strong>attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3 |
| <strong>attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3 |
| <strong>attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3 |
| <strong>attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3 |
| <strong>attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL,</strong> # KM3 |
| } |
| RootOfTrust ::= SEQUENCE { |
| verifiedBootKey OCTET_STRING, |
| deviceLocked BOOLEAN, |
| verifiedBootState VerifiedBootState, |
| } |
| |
| VerifiedBootState ::= ENUMERATED { |
| Verified (0), |
| SelfSigned (1), |
| Unverified (2), |
| Failed (3), |
| }</pre> |
| |
| <h4 id="keydescription-fields">KeyDescription fields</h4> |
| <p> |
| The keymasterVersion and attestationChallenge fields are identified |
| positionally, rather than by tag, so the tags in the encoded form only specify |
| field type. The remaining fields are implicitly tagged as specified in the |
| schema. |
| </p> |
| <table> |
| <tr> |
| <th>Field name</th> |
| <th>Type</th> |
| <th>Value</th> |
| </tr> |
| <tr> |
| <td><code>attestationVersion</code></td> |
| <td>INTEGER</td> |
| <td>1</td> |
| </tr> |
| <tr> |
| <td><code>attestationSecurity</code></td> |
| <td>SecurityLevel</td> |
| <td>The security level of this attestation. It is possible to get software |
| attestations of hardware-backed keys. Such attestations cannot be trusted if the |
| Android system is compromised.</td> |
| </tr> |
| <tr> |
| <td><code>keymasterVersion</code></td> |
| <td>INTEGER</td> |
| <td>Version of keymaster device, 0, 1, or 2.</td> |
| </tr> |
| <tr> |
| <td><code>keymasterSecurity</code></td> |
| <td>SecurityLevel</td> |
| <td>The security level of the keymaster implementation.</td> |
| </tr> |
| <tr> |
| <td><code>attestationChallenge</code></td> |
| <td>OCTET_STRING</td> |
| <td>Value of <code>Tag::ATTESTATION_CHALLENGE</code>, specified to |
| attestation request.</td> |
| </tr> |
| <tr> |
| <td><code>uniqueId</code></td> |
| <td>OCTET_STRING</td> |
| <td>Optional unique ID, present if key has |
| <code>Tag::INCLUDE_UNIQUE_ID</code></td> |
| </tr> |
| <tr> |
| <td><code>softwareEnforced</code></td> |
| <td>AuthorizationList</td> |
| <td>Optional, keymaster authorizations that are not enforced by the TEE, if |
| any.</td> |
| </tr> |
| <tr> |
| <td><code>teeEnforced</code></td> |
| <td>AuthorizationList</td> |
| <td>Optional, Keymaster authorizations that are enforced by the TEE, if any.</td> |
| </tr> |
| </table> |
| |
| <h4 id="authorizationlist-fields">AuthorizationList fields</h4> |
| <p> |
| AuthorizationList fields are all optional and are identified by keymaster tag |
| value, with the type bits masked out. Explicit tagging is used so the fields |
| also contain a tag indicating their ASN.1 type, for easier parsing. |
| </p> |
| <p> |
| For details on each field's values, see types.hal for Keymaster 3 and |
| keymaster_defs.h for Keymaster 2 and below. Keymaster tag names |
| were transformed into field names by omitting the KM_TAG prefix and changing the |
| remainder to camel case, so <code>Tag::KEY_SIZE</code> became |
| <code>keySize</code>. |
| </p> |
| <p class="note"> |
| <strong>Note</strong>: Many tags from types.hal and keymaster_defs.h are not included in the |
| schema. Some tags are not applicable to asymmetric keys, some have no meaning |
| off-device, etc. |
| </p> |
| |
| <h4 id="rootoftrust-fields">RootOfTrust fields</h4> |
| <p> |
| The RootOfTrust Fields are identified positionally. |
| </p> |
| <table> |
| <tr> |
| <th>Field name</th> |
| <th>Type</th> |
| <th>Value</th> |
| </tr> |
| <tr> |
| <td><code>verifiedBootKey</code></td> |
| <td>OCTET_STRING</td> |
| <td>A secure hash of the key used to verify the system image. SHA-256 |
| recommended.</td> |
| </tr> |
| <tr> |
| <td><code>deviceLocked</code></td> |
| <td>BOOLEAN</td> |
| <td>True if the bootloader is locked, which means that only signed images can |
| be flashed, and that verified boot checking is done.</td> |
| </tr> |
| <tr> |
| <td><code>verifiedBootState</code></td> |
| <td>VerifiedBootState</td> |
| <td>State of verified boot.</td> |
| </tr> |
| <tr> |
| <td><code>osVersion</code></td> |
| <td>INTEGER</td> |
| <td>The current version of the OS, as an integer in the format MMmmss, where |
| MM is a two-digit major version number, mm is a two-digit minor version number, |
| and ss is a two-digit sub-minor version number. For example, version 6.0.1 would |
| be represented as 060001</td> |
| </tr> |
| <tr> |
| <td><code>patchMonthYear</code></td> |
| <td>INTEGER</td> |
| <td>The month and year of the last patch, as an integer in the format YYYYMM, |
| where YYYY is a four-digit year and MM is a two-digit month. For example, April |
| 2016 would be represented as 201604.</td> |
| </tr> |
| </table> |
| <h4 id="verifiedbootstate-values">VerifiedBootState values</h4> |
| <p> |
| The values of <code>verifiedBootState</code> have the following meanings: |
| </p> |
| <table> |
| <tr> |
| <th>Value</th> |
| <th>Meaning</th> |
| </tr> |
| <tr> |
| <td><code>Verified</code></td> |
| <td>Indicates a full chain of trust extending from the bootloader to verified |
| partitions, including the bootloader, boot partition, and all verified |
| partitions.<br /> |
| In this state, the verifiedBootKey value is the hash of the embedded certificate, |
| meaning the unchangeable certificate burned into ROM.</td> |
| </tr> |
| <tr> |
| <td><code>SelfSigned</code></td> |
| <td>Indicates the boot partition has been verified using the embedded |
| certificate, and the signature is valid. The bootloader displays a warning and |
| the fingerprint of the public key before allowing the boot process to continue. |
| <br /> |
| In this state, the verifiedBootKey value is the hash of the self-signing |
| certificate.</td> |
| </tr> |
| <tr> |
| <td><code>Unverified</code></td> |
| <td>Indicates a device may be freely modified. Device integrity is left to |
| the user to verify out-of-band. The bootloader displays a warning to the user |
| before allowing the boot process to continue.<br /> |
| In this state the verifiedBootKey value is empty.</td> |
| </tr> |
| <tr> |
| <td><code>Failed</code></td> |
| <td>Indicates the device has failed verification. No attestation certificate |
| actually contains this value, because in this state the bootloader halts. It's |
| included here for completeness.</td> |
| </tr> |
| </table> |
| |
| <h4 id="securitylevel-values">SecurityLevel values</h4> |
| <p> |
| The values of securityLevel have the following meanings: |
| </p> |
| <table> |
| <tr> |
| <th>Value</th> |
| <th>Meaning</th> |
| </tr> |
| <tr> |
| <td><code>Software</code></td> |
| <td>The code that creates or manages the relevant element (attestation or |
| key) is implemented in the Android system and could be altered if that system is |
| compromised.</td> |
| </tr> |
| <tr> |
| <td><code>TrustedEnvironment</code></td> |
| <td>The code that creates or manages the relevant element (attestation or |
| key) is implemented in a Trusted Execution Environment (TEE). It could be |
| altered if the TEE is compromised, but the TEE is highly resistant to remote |
| compromise and moderately resistant to compromise by direct hardware attack.</td> |
| </tr> |
| </table> |
| <h3 id="unique-id">Unique ID</h3> |
| <p> |
| The Unique ID is a 128-bit value that identifies the device, but only for a |
| limited period of time. The value is computed with: |
| </p> |
| |
| <pre class="devsite-click-to-copy"> |
| HMAC_SHA256(T || C || R, HBK) |
| </pre> |
| |
| <p> |
| Where: |
| </p> |
| |
| <ul> |
| <li><code>T</code> is the "temporal counter value", computed by dividing the |
| value of <code>Tag::CREATION_DATETIME</code> by 2592000000, dropping any |
| remainder. <code>T</code> changes every 30 days (2592000000 = 30 * 24 * 60 * 60 |
| * 1000).</li> |
| <li><code>C</code> is the value of <code>Tag::APPLICATION_ID</code></li> |
| <li><code>R</code> is 1 if <code>Tag::RESET_SINCE_ID_ROTATION</code> is |
| present in the attest_params parameter to the attest_key call, or 0 if the tag |
| is not present.</li> |
| <li><code>HBK</code> is a unique hardware-bound secret known to the Trusted |
| Execution Environment and never revealed by it. The secret contains at least 128 |
| bits of entropy and is unique to the individual device (probabilistic uniqueness |
| is acceptable given the 128 bits of entropy). HBK should be derived from fused |
| key material via HMAC or AES_CMAC.</li> |
| </ul> |
| <p> |
| Truncate the HMAC_SHA256 output to 128 bits. |
| </p> |
| |
| <h3 id="attestation-keys-and-certificates">Attestation keys and |
| certificates</h3> |
| <p> |
| Two keys, one RSA and one ECDSA, and the corresponding certificate chains, are |
| securely provisioned into the device. |
| </p> |
| |
| <h2 id="id-attestation">ID attestation</h2> |
| |
| <p> |
| Android 8.0 includes optional support for ID attestation for devices with |
| Keymaster 3. ID attestation allows the device to provide proof of its hardware |
| identifiers, such as serial number or IMEI. Although an optional feature, it is |
| highly recommended that all Keymaster 3 implementations provide support for it |
| because being able to prove the device's identity enables use cases such as true |
| zero-touch remote configuration to be more secure (because the remote side can |
| be certain it is talking to the right device, not a device spoofing its |
| identity). |
| </p> |
| <p> |
| ID attestation works by creating copies of the device's hardware identifiers |
| that only the Trusted Execution Environment (TEE) can access before the device |
| leaves the factory. A user may unlock the device's bootloader and change the |
| system software and the identifiers reported by the Android frameworks. The |
| copies of the identifiers held by the TEE cannot be manipulated in this way, |
| ensuring that device ID attestation will only ever attest to the device's |
| original hardware identifiers thereby thwarting spoofing attempts. |
| </p> |
| <p> |
| The main API surface for ID attestation builds on top of the existing key |
| attestation mechanism introduced with Keymaster 2. When requesting an attestation |
| certificate for a key held by keymaster, the caller may request that the |
| device's hardware identifiers be included in the attestation certificate's |
| metadata. If the key is held in the TEE, the certificate will chain back to a |
| known root of trust. The recipient of such a certificate can verify that the |
| certificate and its contents, including the hardware identifiers, were written |
| by the TEE. When asked to include hardware identifiers in the attestation |
| certificate, the TEE attests only to the identifiers held in its storage, as |
| populated on the factory floor. |
| </p> |
| |
| <h3 id="storage-properties">Storage properties</h3> |
| <p> |
| The storage that holds the device's identifiers needs to have these properties: |
| </p> |
| <ul> |
| <li>The values derived from the device's original identifiers are copied to the |
| storage before the device leaves the factory.</li> |
| <li>The <code>destroyAttestationIds()</code> method can permanently destroy this |
| copy of the identifier-derived data. Permanent destruction means the data is |
| completely removed so neither a factory reset nor any other procedure performed |
| on the device can restore it. This is especially important for devices where |
| a user has unlocked the bootloader and changed the system software and modified |
| the identifiers returned by Android frameworks.</li> |
| <li>RMA facilities should have the ability to |
| generate fresh copies of the hardware identifier-derived data. This way, a |
| device that passes through RMA can perform ID attestation again. The mechanism |
| used by RMA facilities must be protected so that users cannot invoke it |
| themselves, as that would allow them to obtain attestations of spoofed IDs.</li> |
| <li>No code other than Keymaster trusted app in the TEE is able to read the |
| identifier-derived data kept in the storage.</li> |
| <li>The storage is tamper-evident: If the content of the storage has been |
| modified, the TEE treats it the same as if the copies of the content had been |
| destroyed and refuses all ID attestation attempts. This is implemented by |
| signing or MACing the storage <a href="#construction">as described below</a>.</li> |
| <li>The storage does not hold the original identifiers. Because ID attestation |
| involves a challenge, the caller always supplies the identifiers to be attested. |
| The TEE only needs to verify that these match the values they originally had. |
| Storing secure hashes of the original values rather than the values enables this |
| verification.</li> |
| </ul> |
| |
| <h3 id="construction">Construction</h3> |
| <p> |
| To create an implementation that has the properties listed above, store the |
| ID-derived values in the following construction S. Do not store other copies of |
| the ID values, excepting the normal places in the system, which a device owner |
| may modify by rooting: |
| </p> |
| |
| <pre class="devsite-click-to-copy">S = D || HMAC(HBK, D)</pre> |
| <p> |
| where: |
| </p> |
| <ul> |
| <li><code>D = HMAC(HBK, ID<sub>1</sub>) || HMAC(HBK, ID<sub>2</sub>) || ... || |
| HMAC(HBK, ID<sub>n</sub>)</code></li> |
| <li><code>HMAC</code> is the HMAC construction with an appropriate secure hash |
| (SHA-256 recommended)</li> |
| <li><code>HBK</code> is a hardware-bound key not used for any other purpose</li> |
| <li><code>ID<sub>1</sub>...ID<sub>n</sub></code> are the original ID values; association of a |
| particular value to a particular index is implementation-dependent, as different |
| devices will have different numbers of identifiers</li> |
| <li><code>||</code> represents concatenation</li> |
| </ul> |
| <p> |
| Because the HMAC outputs are fixed size, no headers or other structure are |
| required to be able to find individual ID hashes, or the HMAC of D. In addition |
| to checking provided values to perform attestation, implementations need to |
| validate S by extracting D from S, computing HMAC(HBK, D) and comparing it to |
| the value in S to verify that no individual IDs were modified/corrupted. Also, |
| implementations must use constant-time comparisons for all individual ID |
| elements and the validation of S. Comparison time must be constant regardless of |
| the number of IDs provided and the correct matching of any part of the test. |
| </p> |
| <h3 id="hardware-identifiers">Hardware identifiers</h3> |
| <p> |
| ID attestation supports the following hardware identifiers: |
| </p> |
| <ol> |
| <li>Brand name, as returned by <code>Build.BRAND</code> in Android</li> |
| <li>Device name, as returned by <code>Build.DEVICE</code> in Android</li> |
| <li>Product name, as returned by <code>Build.PRODUCT</code> in Android</li> |
| <li>Manufacturer name, as returned by <code>Build.MANUFACTURER</code> in Android</li> |
| <li>Model name, as returned by <code>Build.MODEL</code> in Android</li> |
| <li>Serial number</li> |
| <li>IMEIs of all radios</li> |
| <li>MEIDs of all radios</li> |
| </ol> |
| <p> |
| To support device ID attestation, a device attests to these identifiers. All |
| devices running Android have the first six and they are necessary for this |
| feature to work. If the device has any radios, it needs to support attestation |
| for the IMEIs and/or MEIDs of the radios, too. |
| </p> |
| <p> |
| ID attestation is requested by performing a key attestation and including the |
| device identifiers to attest in the request. The identifiers are tagged as: |
| </p> |
| <ul> |
| <li><code>ATTESTATION_ID_BRAND</code></li> |
| <li><code>ATTESTATION_ID_DEVICE</code></li> |
| <li><code>ATTESTATION_ID_PRODUCT</code></li> |
| <li><code>ATTESTATION_ID_MANUFACTURER</code></li> |
| <li><code>ATTESTATION_ID_MODEL</code></li> |
| <li><code>ATTESTATION_ID_SERIAL</code></li> |
| <li><code>ATTESTATION_ID_IMEI</code></li> |
| <li><code>ATTESTATION_ID_MEID</code></li> |
| </ul> |
| <p> |
| The identifier to attest is a UTF-8 encoded byte string. This format applies to |
| numerical identifiers, as well. Each identifier to attest is expressed as a |
| UTF-8 encoded string. |
| </p> |
| <p> |
| If the device does not support ID attestation (or |
| <code>destroyAttestationIds()</code> was previously called and the device can no |
| longer attest its IDs), any key attestation request that includes one or more of |
| these tags fails with <code>ErrorCode::CANNOT_ATTEST_IDS</code>. |
| </p> |
| <p> |
| If the device supports ID attestation and one or more of the above tags have |
| been included in a key attestation request, the TEE verifies the identifier |
| supplied with each of the tags matches its copy of the hardware identifiers. If |
| one or more identifiers do not match, the entire attestation fails with |
| <code>ErrorCode::CANNOT_ATTEST_IDS</code>. It is valid for the same tag to be |
| supplied multiple times. This can be useful, for example, when attesting IMEIs: |
| A device may have multiple radios with multiple IMEIs. An attestation request is |
| valid if the value supplied with each <code>ATTESTATION_ID_IMEI</code> matches |
| one of the device's radios. The same applies to all other tags. |
| </p> |
| <p> |
| If attestation is successful, the attested IDs is added to the |
| <a href="#attestation-extension">attestation extension</a> |
| (OID 1.3.6.1.4.1.11129.2.1.17) of the issued attestation certificate, |
| using the <a href="#schema">schema from above</a>. Changes from the Keymaster 2 |
| attestation schema are <strong>bolded</strong>, with comments. |
| </p> |
| |
| |
| <h2 id="java-api">Java API</h2> |
| <p> |
| This section is informational only. Keymaster implementers neither |
| implement nor use the Java API. This is provided to help implementers understand |
| how the feature is used by applications. System components may use it |
| differently, which is why it's crucial this section not be treated as normative. |
| </p> |
| |
| <section class="expandable"> |
| <h4 class="showalways">How application developers use attestation</h4> |
| <ul> |
| <li>Creates a key generation request, specifying a key alias and key generation |
| parameters for an EC or RSA key pair.</li> |
| <li>Sets the "attestation challenge" for the request, with |
| <code>KeyPairGenerator.setAttestationChallenge(byte[])</code>. This both |
| provides challenge data (which may be empty), and indicates that an attestation |
| is requested.</li> |
| <li>Generates the key pair.</li> |
| <li>Requests the certificate chain from <code>AndroidKeyStore</code>. The first |
| certificate in the chain is the attestation; the other certificates provide the |
| chain of trust back to and including the root attestation key.</li> |
| </ul> |
| <p> |
| This example generates a key pair and requests an attestation. |
| </p> |
| |
| <pre class="devsite-click-to-copy">// Create KeyPairGenerator and set generation parameters for an ECDSA key pair |
| // using the NIST P-256 curve. "Key1" is the key alias. |
| KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance( |
| KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore"); |
| keyPairGenerator.initialize( |
| new KeyGenParameterSpec.Builder("Key1", KeyProperties.PURPOSE_SIGN) |
| .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1")) |
| .setDigests(KeyProperties.DIGEST_SHA256, |
| KeyProperties.DIGEST_SHA384, |
| KeyProperties.DIGEST_SHA512) |
| // Only permit the private key to be used if the user |
| // authenticated within the last five minutes. |
| .setUserAuthenticationRequired(true) |
| .setUserAuthenticationValidityDurationSeconds(5 * 60) |
| // Request an attestation with challenge "hello world". |
| .setAttestationChallenge("hello world".toBytes()); |
| .build()); |
| // Generate the key pair. This will result in calls to both generate_key() and |
| // attest_key() at the keymaster2 HAL. |
| KeyPair keyPair = keyPairGenerator.generateKeyPair(); |
| // Get the certificate chain |
| KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); |
| keyStore.load(null); |
| Certificate[] certs = keyStore.getCertificateChain("Key1"); |
| // certs[0] is the attestation certificate. certs[1] signs certs[0], etc., |
| // up to certs[certs.length - 1]. |
| </pre> |
| </section> |
| |
| </body> |
| </html> |