blob: 80d55d332f8a0be74918ee9044452ef924e03b6a [file] [log] [blame]
<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&lt;uint8_t&gt; keyToAttest, vec&lt;KeyParameter&gt; attestParams)
generates(ErrorCode error, vec&lt;vec&lt;uint8_t&gt;&gt; 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>