From 23239ca66eab16d7f1248b7160f6f4acc5489f46 Mon Sep 17 00:00:00 2001
From: Kevin Hufnagle
Hardware-backed keystores provide a much safer method to create, store, -and use cryptographic keys on Android devices. They protect keys from the -Linux kernel, potential Android vulnerabilities, and extraction -from rooted devices.
++ Android N introduces key attestation, a new security tool that helps + you make sure that the key pairs stored within a device's hardware-backed + keystore properly protect the sensitive information that your app + uses. By using this tool, you gain additional confidence that your app + interacts with keys that reside in secure hardware, even if the device + running your app is rooted. If you use keys from the hardware-backed keystore + in your apps, you should use this tool, particularly if you use the keys to + verify sensitive information within your app. +
-To make it easier and more secure to use hardware-backed keystores, -Android N introduces Key Attestation. Apps and off-devices can use Key -Attestation to strongly determine whether an RSA or EC key pair is -hardware-backed, what the properties of the key pair are, and what - constraints are applied to its usage and validity.
++ Key attestation allows you to verify that an RSA or EC key pair has been + created and stored in a device’s hardware-backed keystore within the device’s + trusted execution environment (TEE). The tool also allows you to use an + off-device service, such as your app's back-end server, to determine and + strongly verify the uses and validity of the key pair. These features provide + an additional level of security that protects the key pair, even if someone + roots the device or compromises the security of the Android platform running + on the device. +
-Apps and off-device services can request information about a key pair -through an X.509 attestation certificate which must be signed by a valid -attestation key. The attestation key is an ECDSA signing key which is -injected into the device’s hardware-backed keystore at the factory. -Therefore, an attestation certificate signed by a valid attestation -key confirms the existence of a hardware-backed keystore, along with - details of key pairs in that keystore.
- -To ensure that the device is using a secure, official Android factory -image, Key Attestation requires that the device bootloader -provide the following information to the Trusted -Execution Environment (TEE):
- -For more information about the hardware-backed keystore feature, -see the guide for Hardware-backed Keystore.
- -In addition to Key Attestation, Android N also introduces - fingerprint-bound keys that are not revoked on fingerprint enrollment.
++ For more information, see the + Key Attestation + developer documentation. +
+ Key Attestation gives you more confidence that the keys you use in your app + are stored in a device's hardware-backed keystore. The following sections + describe how to verify the properties of hardware-backed keys and how to + interpret the schema of the attestation certificate's extension data. +
+ ++ During key attestation, you specify the alias of a key pair. The attestation + tool, in return, provides a certificate chain, which you can use to verify + the properties of that key pair. +
+ ++ The root certificate within this chain is signed using an attestation key, + which the device manufacturer injects into the device’s hardware-backed + keystore at the factory. +
+ ++ Note: On devices that ship with Android N and Google Play + services, the root certificate is issued by Google. You should verify that + this root certificate appears within Google’s list of root certificates. +
+ ++ To implement key attestation, complete the following steps: +
+ ++ Check each certificate’s validity using a + {@link java.security.cert.CRL CRL} object's + {@link java.security.cert.CRL#isRevoked isRevoked()} method. +
+ ++ Caution: Although you can complete this process within + your app directly, it’s safer to check the certificates’ revocation lists + on a separate server that you trust. +
+
+ Create an Attestation object, passing in the first element of
+ the certificate chain as an argument:
+// "certificates" contains the certificate chain associated with a specific key +// pair in the device's hardware-backed keystore. +X509Certificate attestationCert = (X509Certificate) certificates[0]; +Attestation hardwareKeyAttestation = new Attestation(attestationCert); ++ +
+ An attestation object extracts the extension data within this certificate + and stores this information in a more accessible format. For more details + about the schema of the extension data, see Certificate Extension Data Schema. +
+
+ Use the accessor methods within the Attestation class to
+ retrieve the extension data from the certificate. These methods use the
+ same names and structure hierarchy as in the certificate extension data
+ schema.
+
+ For example, to view the verified boot key for the device’s TEE, use the + following method sequence: +
+ ++// "hardwareKeyAttestation" contains the first element of the attestation +// certificate chain. +AuthorizationList teeAuthList = hardwareKeyAttestation.getTeeEnforced(); +RootOfTrust teeRootOfTrust = teeAuthList.getRootOfTrust(); +byte[] teeVerifiedBootKey = teeRootOfTrust.getVerifiedBootKey(); ++ +
+ Compare the extension data from the Attestation object with
+ the set of values that you expect the hardware-backed key to contain.
+
+ Caution: Although you can complete this process within + your app directly, it’s safer to check the certificate’s extension data + on a separate server that you trust. +
++ Key attestation verifies the extension data that appears in the first + certificate within the chain in a device’s hardware-backed keystore. The + certificate stores the information according to the following ASN.1 schema: +
+ +
+KeyDescription ::= SEQUENCE {
+ attestationVersion INTEGER,
+ attestationSecurityLevel SecurityLevel,
+ keymasterVersion INTEGER,
+ keymasterSecurityLevel SecurityLevel,
+ attestationChallenge OCTET_STRING,
+ reserved 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,
+ attestationChallenge [708] EXPLICIT INTEGER OPTIONAL,
+ attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL,
+}
+
+RootOfTrust ::= SEQUENCE {
+ verifiedBootKey OCTET_STRING,
+ deviceLocked BOOLEAN,
+ verifiedBootState VerifiedBootState,
+}
+
+VerifiedBootState ::= ENUMERATED {
+ Verified (0),
+ SelfSigned (1),
+ Unverified (2),
+ Failed (3),
+}
+
+
++ The following list presents a description of each element within the schema: +
+ ++ This sequence of values presents general information about the key pair being + verified through key attestation and provides easy access to additional + details. +
+ +attestationVersion
+ attestationSecurity
+ + The security + level of the attestation. +
+ +
+ Note: Although it is possible to attest keys that are
+ stored in the Android system—that is, if the
+ attestationSecurity value is set to Software—you
+ cannot trust these attestations if the Android system becomes compromised.
+
keymasterVersion
+ keymasterSecurity
+ attestationChallenge
+ reserved
+ softwareEnforced
+ teeEnforced
+ + This data structure indicates the extent to which a software feature, such as + a key pair, is protected based on its location within the device. +
+ ++ Because the data structure is an enumeration, it takes on exactly one of the + following values: +
+ ++ This data structure contains the key pair’s properties themselves, as defined + in the Keymaster hardware abstraction layer (HAL). You compare these values + to the device’s current state or to a set of expected values to verify that a + key pair is still valid for use in your app. +
+ +
+ Each field name corresponds to a similarly-named Keymaster tag. For example,
+ the keySize field in an authorization list corresponds to the
+ KM_TAG_KEY_SIZE Keymaster tag.
+
+ Each field in the following list is optional: +
+ +purpose
+
+ KM_TAG_PURPOSE Keymaster tag, which uses a tag ID value of 1.
+ algorithm
+
+ Corresponds to the
+ KM_TAG_ALGORITHM Keymaster tag, which uses a tag ID value of
+ 2.
+
+ When an AuthorizationList object is associated with key
+ attestation, this value is always KM_ALGORITHM_RSA or
+ KM_ALGORITHM_EC.
+
keySize
+
+ KM_TAG_KEY_SIZE Keymaster tag, which uses a tag ID value of 3.
+ digest
+
+ KM_TAG_DIGEST Keymaster tag, which uses a tag ID value of 5.
+ padding
+
+ KM_TAG_PADDING Keymaster tag, which uses a tag ID value of 6.
+ ecCurve
+
+ Corresponds to the KM_TAG_EC_CURVE Keymaster tag, which uses
+ a tag ID value of 10.
+
+ The set of parameters used to generate an elliptic curve (EC) key pair, + which uses ECDSA for signing and verification, within the Android system + keystore. +
+rsaPublicExponent
+
+ KM_TAG_RSA_PUBLIC_EXPONENT Keymaster tag, which uses a tag ID
+ value of 200.
+ activeDateTime
+
+ KM_TAG_ACTIVE_DATETIME Keymaster tag, which uses a tag ID value
+ of 400.
+ originationExpireDateTime
+
+ KM_TAG_ORIGINATION_EXPIRE_DATETIME Keymaster tag, which uses a
+ tag ID value of 401.
+ usageExpireDateTime
+
+ KM_TAG_USAGE_EXPIRE_DATETIME Keymaster tag, which uses a tag ID
+ value of 402.
+ noAuthRequired
+
+ Corresponds to the
+ KM_TAG_NO_AUTH_REQUIRED Keymaster tag, which uses a tag ID
+ value of 503.
+
+ When an AuthorizationList object is associated with key
+ attestation, this value is always true.
+
userAuthType
+
+ KM_TAG_USER_AUTH_TYPE Keymaster tag, which uses a tag ID value
+ of 504.
+ authTimeout
+
+ KM_TAG_AUTH_TIMEOUT Keymaster tag, which uses a tag ID value of
+ 505.
+ allowWhileOnBody
+
+ Corresponds to the KM_TAG_ALLOW_WHILE_ON_BODY Keymaster tag,
+ which uses a tag ID value of 506.
+
+ Allows the key to be used after its authentication timeout period if the + user is still wearing the device on their body. Note that a secure + on-body sensor determines whether the device is being worn on the user’s + body. +
+ +
+ When an AuthorizationList object is associated with key
+ attestation, this value is always true.
+
allApplications
+
+ Corresponds to the KM_TAG_ALL_APPLICATIONS Keymaster tag,
+ which uses a tag ID value of 600.
+
+ Indicates whether all apps on a device can access the key pair. +
+ +
+ When an AuthorizationList object is associated with key
+ attestation, this value is always true.
+
applicationId
+
+ KM_TAG_APPLICATION_ID Keymaster tag, which uses a tag ID value
+ of 601.
+ creationDateTime
+
+ KM_TAG_CREATION_DATETIME Keymaster tag, which uses a tag ID
+ value of 701.
+ origin
+
+ Corresponds to the
+ KM_TAG_ORIGIN Keymaster tag, which uses a tag ID value of 702.
+
+ When an AuthorizationList object is associated with key
+ attestation, this value is usually set to
+ KM_ORIGIN_GENERATED. If the attestation uses Keymaster
+ version 0.2 or 0.3, however, the origin may be set to
+ KM_ORIGIN_UNKNOWN instead.
+
rollbackResistant
+
+ KM_TAG_ROLLBACK_RESISTANT Keymaster tag, which uses a tag ID
+ value of 703.
+ rootOfTrust
+
+ Corresponds to the
+ KM_TAG_ROOT_OF_TRUST Keymaster tag, which uses a tag ID value
+ of 704.
+
+ For more details, see the section describing the RootOfTrust
+ data structure.
+
osVersion
+
+ Corresponds to the KM_TAG_OS_VERSION Keymaster tag, which
+ uses a tag ID value of 705.
+
+ The version of the Android operating system associated with the + Keymaster, specified as a six-digit integer. For example, version 6.0.1 + is represented as 060001. +
+ ++ Only Keymaster version 1.0 or higher includes this value in the + authorization list. +
+osPatchLevel
+
+ Corresponds to the KM_TAG_PATCHLEVEL Keymaster tag, which
+ uses a tag ID value of 706.
+
+ The month and year associated with the security patch that is being used + within the Keymaster, specified as a six-digit integer. For example, the + June 2016 patch is represented as 201606. +
+ ++ Only Keymaster version 1.0 or higher includes this value in the + authorization list. +
+attestationChallenge
+
+ Corresponds to the KM_TAG_ATTESTATION_CHALLENGE Keymaster
+ tag, which uses a tag ID value of 708.
+
+ The challenge string associated with the key pair that is defined in the + Keymaster. +
+attestationApplicationId
+
+ Corresponds to the KM_TAG_ATTESTATION_APPLICATION_ID
+ Keymaster tag, which uses a tag ID value of 709.
+
+ The unique ID of the attestation certificate that signed the key pair + that is in the Keymaster. +
++ This collection of values defines key information about the device’s status. +
+ ++ Each field in the following list is required: +
+ +verifiedBootKey
+ + A secure hash of the key that verifies the system image. It is recommended + that you use the SHA-256 algorithm for this hash. +
+deviceLocked
+ verifiedBootState
+ osVersion
+ patchMonthYear
+ + This data structure provides the device’s current boot state, which + represents the level of protection provided to the user and to apps after the + device finishes booting. For more information about this feature, see the + + Boot State section within the Verifying Boot documentation. +
+ ++ This data structure is an enumeration, so it takes on exactly one of the + following values: +
+ ++ Indicates a full chain of trust, which includes the bootloader, the boot + partition, and all verified partitions. +
+ +
+ When the device is in this boot state, the verifiedBootKey is
+ the hash of the device-embedded certificate, which the device manufacturer
+ adds to the device's ROM at the factory.
+
+ Indicates that the device-embedded certificate has verified the device’s + boot partition and that the signature is valid. +
+ +
+ When the device is in this boot state, the verifiedBootKey is
+ the hash of a user-installed certificate, which signs a boot partition
+ that the user adds to the device in place of the original,
+ manufacturer-provided boot partition.
+
VerifiedBootState.
+