blob: 7b03c2500b7ae89dfeb10852fcc07bb68e526071 [file] [log] [blame]
<html devsite>
<head>
<title>Key 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
keymaster1 enforces restrictions in a hard-to-subvert way.
</p>
<p>
This is only true, however, if the keystore keys are known to be in
hardware-backed storage. There is presently no way for apps or remote servers to
reliably verify if this is the case. The keystore daemon loads the available
keymaster HAL and believes whatever the HAL says with respect to hardware
backing of keys.
</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>
<h2 id="java-api">Java API</h2>
<p class="note">
Note: This section is informational only. Keymaster2 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="prettyprint">// 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>
<h2 id="hal-changes">HAL changes</h2>
<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>KM_TAG_ATTESTATION_CHALLENGE</code></li>
<li><code>KM_TAG_INCLUDE_UNIQUE_ID</code></li>
<li><code>KM_TAG_RESET_SINCE_ID_ROTATION</code> </li>
</ul>
<p>
<strong>Type</strong>
</p>
<pre class="prettyprint">typedef struct {
keymaster_blob_t* entries;
size_t entry_count;
} keymaster_cert_chain_t;
</pre>
<p>
<strong><code>Attest_key</code> method</strong></p>
<pre class="prettyprint">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>key_to_attest</code> is the key blob returned from
<code>generate_key</code> for which the attestation will be created.</li>
<li><code>attest_params</code> is a list of any parameters necessary for
attestation. This includes <code>KM_TAG_ATTESTATION_CHALLENGE</code> and
possibly <code>KM_TAG_RESET_SINCE_ID_ROTATION</code>, as well as
<code>KM_TAG_APPLICATION_ID</code> and <code>KM_TAG_APPLICATION_DATA</code>. The
latter two are necessary to decrypt the key blob if they were specified during
key generation.</li>
<li><code>cert_chain</code> is the output parameter, which returns an array of
certificates. Entry 0 is the attestation certificate, meaning it
certifies the key from <code>key_to_attest</code> and contains the
attestation extension.</li>
</ul>
<p>
The <code>attest_key</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>
<h2 id="attestation-certificate">Attestation certificate</h2>
<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>
<h3 id="certificate-sequence">Certificate SEQUENCE</h3>
<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>
<h3 id="tbscertificate-sequence">TBSCertificate SEQUENCE</h3>
<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
<code>KM_TAG_ACTIVE_DATETIME</code> and
<code>KM_TAG_USAGE_EXPIRE_DATETIME</code>. 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>KM_TAG_ACTIVE_DATETIME</code> is not present, use the value of
<code>KM_TAG_CREATION_DATETIME</code>. If
<code>KM_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>KM_PURPOSE_SIGN</code> or
<code>KM_PURPOSE_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>
<h2 id="attestation-extension">Attestation extension</h2>
<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. For example, <code>KM_TAG_PURPOSE</code> is defined in
keymaster_defs.h as <code>KM_ENUM_REP</code> | 1. For the attestation extension,
the <code>KM_ENUM_REP</code> value is removed, leaving tag 1.
</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>KM_ENUM</code></td>
<td>INTEGER</td>
</tr>
<tr>
<td><code>KM_ENUM_REP</code></td>
<td>SET of INTEGER</td>
</tr>
<tr>
<td><code>KM_UINT</code></td>
<td>INTEGER</td>
</tr>
<tr>
<td><code>KM_UINT_REP</code></td>
<td>SET of INTEGER</td>
</tr>
<tr>
<td><code>KM_ULONG</code></td>
<td>INTEGER</td>
</tr>
<tr>
<td><code>KM_ULONG_REP</code></td>
<td>SET of INTEGER</td>
</tr>
<tr>
<td><code>KM_DATE</code></td>
<td>INTEGER (milliseconds since Jan 1, 1970 00:00:00 GMT)</td>
</tr>
<tr>
<td><code>KM_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>KM_BIGNUM</code></td>
<td>Not presently used, so no mapping is defined</td>
</tr>
<tr>
<td><code>KM_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>KM_TAG_USER_ID</code>
and <code>KM_TAG_SECURE_USER_ID</code> have no meaning off-device, and
<code>KM_TAG_MIN_MAC_LENGTH</code> and <code>KM_TAG_CALLER_NONCE</code> are
useless with asymmetric keys.
</p>
<h3 id="schema">Schema</h3>
<p>
The attestation extension content is described by the following ASN.1 schema:
</p>
<pre class="prettyprint">
KeyDescription ::= SEQUENCE {
attestationVersion INTEGER,
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,
}
RootOfTrust ::= SEQUENCE {
verifiedBootKey OCTET_STRING,
deviceLocked BOOLEAN,
verifiedBootState VerifiedBootState,
}
VerifiedBootState ::= ENUMERATED {
Verified (0),
SelfSigned (1),
Unverified (2),
Failed (3),
}</pre>
<h3 id="keydescription-fields">KeyDescription fields</h3>
<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>KM_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>KM_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>
<h3 id="authorizationlist-fields">AuthorizationList fields</h3>
<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>
See keymaster_defs.h for details on each field's values. Keymaster tag names
were transformed into field names by omitting the KM_TAG prefix and changing the
remainder to camel case, so <code>KM_TAG_KEY_SIZE</code> became
<code>keySize</code>.
</p>
<p class="note">
<strong>Note</strong>: Many tags from 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>
<h3 id="rootoftrust-fields">RootOfTrust fields</h3>
<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>
<h3 id="verifiedbootstate-values">VerifiedBootState values</h3>
<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>
<h3 id="securitylevel-values">SecurityLevel values</h3>
<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>
<h2 id="unique-id">Unique ID</h2>
<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="prettyprint">
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>KM_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>KM_TAG_APPLICATION_ID</code></li>
<li><code>R</code> is 1 if <code>KM_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>
<h2 id="attestation-keys-and-certificates">Attestation keys and
certificates</h2>
<p>
Two keys, one RSA and one ECDSA, and the corresponding certificate chains, are
securely provisioned into the device.
</p>
</body>
</html>