The English version of this specification is the only normative version. Non-normative translations may also be available.
Copyright © 2013-2015 FIDO Alliance All Rights Reserved.
The document defines generic data structures that cover the semantics of FIDO Authenticator attestation. The document also provides a profile of these structures when a TPM [TPM] acts as a crypto kernel. More profiles are expected to be added as the document evolves.
Attestation refers to the capability of a FIDO Authenticator to provide a cryptographic proof about its model to a remote relying party.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current FIDO Alliance publications and the latest revision of this technical report can be found in the FIDO Alliance specifications index at https://www.fidoalliance.org/specifications/.
This document was published by the FIDO Alliance as a Proposed Standard. If you wish to make comments regarding this document, please Contact Us. All comments are welcome.
Implementation of certain elements of this Specification may require licenses under third party intellectual property rights, including without limitation, patent rights. The FIDO Alliance, Inc. and its Members and any other contributors to the Specification are not, and shall not be held, responsible in any manner for identifying or failing to identify any or all such third party intellectual property rights.
THIS FIDO ALLIANCE SPECIFICATION IS PROVIDED “AS IS” AND WITHOUT ANY WARRANTY OF ANY KIND, INCLUDING, WITHOUT LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
This document has been reviewed by FIDO Aliance Members and is endorsed as a Proposed Standard. It is a stable document and may be used as reference material or cited from another document. FIDO Alliance's role in making the Recommendation is to draw attention to the specification and to promote its widespread deployment.
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL in this specification are to be interpreted as described in [RFC2119].
A glossary of terms used here is provided in a companion document.
The term Base64url Encoding refers to the base64 encoding using the URL- and filename-safe character set defined in Section 5 of [RFC4648], with all trailing '=' characters omitted (as permitted by Section 3.2) and without the inclusion of any line breaks, whitespace, or other additional characters. This is the same encoding as used by JSON Web Signature (JWS) [JWS].
FIDO 2.0 specifies multiple attestation models:
This model is also used for FIDO UAF 1.0 and FIDO U2F 1.0.
Using this approach, the Authenticator can limit the exposure of the endorsement key (which is a global correlation handle) to Privacy CA(s). Attestation keys can be requested for each FIDO credential individually.
This concept typically leads to multiple attestation certificates. The attestation certificate requested most recently is called "active".
FIDO 2.0 supports DAA using elliptic curve cryptography and bilinear pairings, called ECDAA (see [FIDOEcdaaAlgorithm]) in this document.
Compliant FIDO Servers MUST support all attestation models. Authenticators can choose what attestation model to implement.
Relying parties can always decide what attestation models are acceptable by policy.
FIDO 2.0 attestation statements are bound to various contextual data. These data are observed, and added at different levels of the stack as a signature request passes from the server to the authenticator. In verifying a signature, the server checks these bindings against expected values.
These components can be divided into three layers:
The goals of this design can be summarized as follows.
There are two kinds of contextual bindings: Those added by the RP or the client platform, referred to as client data (see [FIDOSignatureFormat]) and those added by the authenticator, referred to as the attestation data. The client data must be signed over, but an authenticator is otherwise not interested in its contents. More specifically, the authenticator cannot attest to the correctness of such data. To save bandwidth and processing requirements on the authenticator, the client platform hashes the client data and sends only the hash result to the authenticator. The authenticator attestation statement includes the combination of this hash, and its own attestation data.
FIDO specifies pluggable attestation types, i.e., ways to serialize the data being attested to by the authenticator. The reason is to be able to support existing devices like TPMs and other platform-specific formats.
Each attestation type provides the ability to cryptographically attest to a public key, the authenticator model, and contextual data to a remote party.
When an attestation statement is required for an Authenticator, the client needs to ask the Authenticator to generate one. This section describes the attestation statement data structures. Attestation statements can also include some host and other Authenticator information.
The attestation statement consists ofheader
object, containing the signing algorithm and
additional information required to verify the attestation signature.
core
object, containing the attested data. This object
is a container and can carry multiple, authenticator model specific,
attestation rawData types (see section 3.4 Attestation Raw Data Types).
signature
object. This object contains the cryptographic
signature computed over the rawData
object.
The structure of this object depends on the signature algorithm.
How the attestationStatement is returned from an external authenticator to the computer is described in the FIDO External Authenticator Protocol [FIDOEAP].
The client platform uses an authenticator generated
attestation signature (signature
) and the
authenticator generated rawData
object to construct
the final attestation statement object (which will be returned to the RP).
This attestation statement is encoded as:
interface AttestationStatement {
readonly attribute AttestationHeader
header;
readonly attribute AttestationCore
core;
readonly attribute DOMString signature;
};
header
of type AttestationHeader
, readonly core
of type AttestationCore
, readonly rawData
and
its type
and version
.signature
of type DOMString, readonly This attestation statement is delivered to the RP according to the Client API. It contains all the information that the RP's FIDO server requires to reconstruct the signature base string, as well as to decode and validate the bindings of both the client- and authenticator data.
type
and version
).
interface AttestationCore {
readonly attribute DOMString type;
readonly attribute unsigned long version;
readonly attribute DOMString rawData;
readonly attribute DOMString clientData;
};
type
of type DOMString, readonly version
of type unsigned long, readonly rawData
of type DOMString, readonly clientDataHash
.
clientData
of type DOMString, readonly
The client platform SHALL deliver, through the EAP API, the
clientDataHash
(see [FIDOSignatureFormat]) to the authenticator.
The client platform MUST also preserve the exact encodedClientData
string (see [FIDOSignatureFormat]), for embedding
in a signature object sent back to the RP. This is necessary since multiple
JSON encodings of the same client data are possible.
interface AttestationHeader {
readonly attribute DOMString claimedAAGUID;
readonly attribute DOMString[] x5c;
readonly attribute DOMString alg;
};
claimedAAGUID
of type DOMString, readonly x5c
of type array of DOMString, readonly alg
of type DOMString, readonly See section for the signature algorithms to be implemented by FIDO Servers.
Attestation Raw Data (rawData
) is the to-be-signed object of
the attestation statement. FIDO supports pluggable attestation data types.
This allows support of TPM generated attestation data as well as support of
other FIDO authenticators.
The contents of the attestation data must be controlled (i.e., generated or at least verified) by the authenticator itself.
The attestation data encodes contextual bindings made by the authenticator itself. Unlike client data, the authenticator data has a compact but extensible encoding. This is desired since authenticators can be devices with limited capabilities and low power requirements, with much simpler software stacks than the client platform components.
For this type, only version="1" is defined at this time.
The field rawData
is the base64url encoding of the byte array.
The encoding of attestation data (for type "packed") is a byte array
of 45 bytes + length of public key + length of KeyHandle + potentially more extensions.
The first bytes before the extensions have a fixed layout as follows:
Length (in bytes) | Description |
---|---|
2 | 0xF1D0, fixed big-endian TAG to make sure this object won't be confused with other (non-FIDO) binary objects. |
1 | Flags (bit 0 is the least significant bit):
|
4 | Signature counter (signCount ), 32-bit unsigned big-endian integer. |
2 |
Public key algorithm and encoding (16-bit big-endian value).
Allowed values are:
|
2 | Byte length m of following public key bytes (16 bit value with most significant byte first). |
(length) | The public key (m bytes) according to the encoding denoted before. |
2 | Byte length l of KeyHandle |
(length) | KeyHandle (l bytes) |
2 | Byte length n of clientDataHash |
n | clientDataHash (see section 3.2.2 Client data).
This is the hash of clientData . The hash algorithm itself is stored
in the clientData object [FIDOSignatureFormat].
|
As defined by the extension map | Extension-defined authenticator data. This is a CBOR [RFC7049] map with extension identifiers as keys, and extension authenticator data values as values. See [FIDOSignatureFormat], section "Signature extensions" for a description of the extension mechanism. See section 3.4.1.2 Extensions for Packed Attestation rawData for pre-defined extensions. |
The TUP
flag SHALL be set if and only if the authenticator
detected a user through an authenticator-specific gesture. The RFU
bits in the flags byte SHALL be cleared (i.e., zeroed).
If the authenticator does not wish to add extensions, it MUST clear
the ED
flag in the third byte.
fido.aaguid
This AAGUID is used to identify the Authenticator model (Authenticator Attestation GUID).
The authenticator model (identified by the AAGUID) can be derived from (a) here, or (b) from the attestation certificate (if we have an authenticator specific or authenticator model specific attestation certificate), or (c) or from the claimed AAGUID in the client encoded attestation statement (if we have one attestation root certificate per authenticator model).
In the case of DAA there is no need for an X.509 attestation certificate hierarchy. Instead the trust anchor being known to the RP is the DAA root key (i.e. ECPoint2 X, Y). This root key must be dedicated to a single authenticator model.
fido.exts
fido.uvi
Each UVI value MUST be specific to the related key (in order to provide unlinkability). It also must contain sufficient entropy that makes guessing impractical. UVI values MUST NOT be reused by the Authenticator (for other biometric data or users).
The UVI data can be used by FIDO Servers to understand whether an authentication was authorized by the exact same biometric data as the initial key generation. This allows the detection and prevention of "friendly fraud".
As an example, the UVI could be computed as SHA256(KeyID | SHA256(rawUVI)), where the rawUVI reflects (a) the biometric reference data, (b) the related OS level user ID and (c) an identifier which changes whenever a factory reset is performed for the device, e.g. rawUVI = biometricReferenceData | OSLevelUserID | FactoryResetCounter.
FIDO Servers supporting UVI extensions MUST support a length of up to 32 bytes for the UVI value.
Example for rawData containing one UVI extension
F1 D0 -- This is a FIDO packed rawData object 81 -- TUP and ED set 00 00 00 01 -- (initial) signature counter ... -- all public key alg etc. A1 -- extension: CBOR map of one element 68 -- Key 1: CBOR text string of 8 bytes 66 69 64 6F 2E 75 76 69 -- "fido.uvi" UTF-8 string 58 20 -- Value 1: CBOR byte string with 0x20 bytes 00 43 B8 E3 BE 27 95 8C -- the UVI value itself 28 D5 74 BF 46 8A 85 CF 46 9A 14 F0 E5 16 69 31 DA 4B CF FF C1 BB 11 32 82
The signature
is computed over the base64url-decoded rawData
field.
In the case of DAA attestation [FIDOEcdaaAlgorithm] no attestation certificate is used.
The attestation certificate MUST have the following fields/extensions:
Extension OID 1 3 6 1 4 1 45724 1 1 4
(id-fido-gen-ce-aaguid) containing the AAGUID as value.
id-ad-ocsp
and
a CRL Distribution Point extension [RFC5280] are both optional as the status of attestation certificates is
available through the FIDO Metadata Service [FIDOMetadataService].
The value of rawData
is the base64url encoding of a binary object.
This binary object is either a
TPM_CERTIFY_INFO or a TPM_CERTIFY_INFO2 structure [TPMv1-2-Part2]
sections 11.1 and 11.2, if
attestationStatement.core.version
equals 1. Else, if
attestationStatement.core.version
equals 2, it MUST be
the base64url encoding of a TPMS_ATTEST structure as defined in
[TPMv2-Part2] sections 10.12.9.
The field "extraData" (in the case of TPMS_ATTEST) or the field "data"
(in the case of TPM_CERTIFY_INFO or TPM_CERTIFY_INFO2) MUST contain
the clientDataHash
(see [FIDOSignatureFormat]).
If attestationStatement.core.version
equals 1, (i.e., for
TPM 1.2), RSASSA-PKCS1-v1_5 signature algorithm (section 8.2 of
[RFC3447]) can be used by FIDO Authenticators (i.e.
attestationStatement.header.alg
="RS256").
If attestationStatement.core.version
equals 2, the
following algorithms can be used by FIDO Authenticators:
attestationStatement.header.alg
="RS256".attestationStatement.header.alg
="PS256".attestationStatement.header.alg
="ES256".attestationStatement.header.alg
="ED256".attestationStatement.header.alg
="SM256".The signature
is computed over the base64url-decoded rawData
field
See section for the signature algorithms to be implemented by FIDO Servers.
TPM attestation certificate MUST have the following fields/extensions:
id-ad-ocsp
and
a CRL Distribution Point extension [RFC5280] are both optional as the status of attestation certificates is
available through the FIDO Metadata Service [FIDOMetadataService].
When the Authenticator in question is a platform-provided Authenticator on the Android platform, the attestation statement is based on the SafetyNet API.
Android attestation statement MUST always be used in conjunction with the more
specific AndroidAttestationClientData
(see section 3.4.3.4 AndroidAttestationClientData)
in order to let the RP App store the public key in the attestation object.
Android SafetyNet returns a JWS [JWS] object (see
SafetyNet online documentation) in Compact
Serialization. A JWS in Compact Serialization consists of three segments
(each a base64url-encoded string) separated by a dot ("."). The
rawData
object is the concatenation of:
In contrast to the "packed" and "tpm" attestation types, for the
"android" attestation type, the rawData
field and the
rawData
object are the same string. (In the "packed" and
"tpm" attestation types the rawData
field is the
base64url-encoding of the rawData
object.)
The signature is directly computed over the rawData
field, as
defined above (see [JWS] for more details). The third segment of the
JWS returned by SafetyNet is the base64url encoding of this signature,
and also becomes the AttestationStatement.signature
.
The Authenticator and/or platform SHOULD use the steps outlined below to create an attestationStatement from an Android SafetyNet response. It MAY use a different algorithm, as long as the results are the same.
AttestationStatement.core.rawData
= hdr | "." | pAttestationStatement.signature
= sAttestationStatement.header.alg
= hdr-d.algAttestationStatement.header.x5c
= hdr-d.x5cAttestationStatement.header.x5c
AttestationStatement.core.type
= "android"AttestationStatement.core.version
to the
version number of Google Play Services responsible for providing the SafetyNet APIThe ClientData dictionary is extended in the following way:
dictionary AndroidAttestationClientData : ClientData {
JsonWebKey publicKey;
boolean isInsideSecureHardware;
DOMString userAuthentication;
optional unsigned long userAuthenticationValidityDurationSeconds;
};
AndroidAttestationClientData
MemberspublicKey
of type JsonWebKeyisInsideSecureHardware
of type booleantrue
if the key resides inside secure hardware (e.g.,
Trusted Execution Environment (TEE) or Secure Element (SE)).
userAuthentication
of type DOMStringuserAuthenticationValidityDurationSeconds
of type optional unsigned longuserAuthentication
is set to "keyguard", then
this parameter specifies the duration of time (seconds) for which
this key is authorized to be used after the user is successfully
authenticated.
A relying party shall verify the clientData contextual bindings (see step 4 in 3.5 Verifying an Attestation Statement as follows:
AndroidAttestationClientData.challenge
equals the
attestationChallenge that was passed into the
makeCredential
call [FIDOWebApi].
facet
and tokenBinding
parameters in the AndroidAttestationClientData
match the
RP App.
AndroidAttestationClientData.publicKey
is the same key as the one
returned in the FIDOCredentialInfo
by the
makeCredential
call.
nonce
attribute in the payload of the
safetynetResponse
JWS.
ctsProfileMatch
attribute in the payload
of the safetynetResponse
is true.
apkPackageName
attribute in the payload of the
safetynetResponse
matches package name of the application calling
SafetyNet API.
apkDigestSha256
attribute in the
payload of the safetynetResponse
matches the package hash
of the application calling SafetyNet API.
apkCertificateDigestSha256
attribute in the
payload of the safetynetResponse
matches the hash of the signing certificate
of the application calling SafetyNet API.
This section outlines the recommended algorithm for verifying an attestation statement, independent of attestation type.
Upon receiving an attestation statement, the relying party shall:
attestationSignature.alg
is not ECDAA (e.g., not "ED256" and not "ED512"):
header.claimedAAGUID
can be used for this lookup.
header.type
member). In case of a
type="tpm", this EKU shall be OID "2.23.133.8.3".
signature
on core.rawData
using the
attestation certificate public key and algorithm as identified by header.alg
.
core.rawData
syntax and that it doesn't contradict the signing
algorithm specified in header.alg
.
1 3 6 1 4 1 45724 1 1 4
(id-fido-gen-ce-aaguid) verify that the value of this extension matches
header.claimedAAGUID
. This identifies the Authenticator model.
attestationSignature.alg
is ECDAA (e.g., "ED256", "ED512"):
header.claimedAAGUID
can be used for this lookup.
signature
for core.rawData
(see [FIDOEcdaaAlgorithm]).core.rawData
syntax and that it doesn't contradict the signing
algorithm specified in header.alg
.
Verification of attestation statements requires that the relying party trusts the root of the attestation certificate chain. Also, the relying party must have access to certificate status information for the intermediate CA certificates. The relying party must also be able to build the attestation certificate chain if the client didn't provide this chain in the attestation information.
Attestation keys may be used to track users or link various online identities of the same user together. This may be mitigated in several ways, including:
When an intermediate CA or a root CA used for issuing attestation certificates is compromised, FIDO Authenticator attestation keys are still safe although their certificates can no longer be trusted. A FIDO Authenticator manufacturer that has recorded the public attestation keys for their devices can issue new attestation certificates for these keys from a new intermediate CA or from a new root CA. If the root CA changes, the relying parties must update their trusted root certificates accordingly.
A FIDO Authenticator attestation certificate must be revoked by the issuing CA if its key has been compromised. A FIDO Authenticator manufacturer may need to ship a firmware update and inject new attestation keys and certificates into already manufactured FIDO Authenticators, if the exposure was due to a firmware flaw. (The process by which this happens is out of scope for this specification.) No further valid attestation statements can be made by the affected FIDO Authenticators unless the FIDO Authenticator manufacturer has this capability.
If attestation certificate validation fails due to a revoked intermediate attestation CA certificate, and relying party policy requires rejecting the registration/authentication request in these situations, then it is recommended that the relying party also un-registers (or marks as "surrogate attestation" (see 2.1 Attestation Models), policy permitting) FIDO credentials that were registered post the CA compromise date using an attestation certificate chaining up to the same intermediate CA. It is thus recommended that relying parties remember intermediate attestation CA certificates during Authenticator registration in order to un-register related FIDO Credentials if the registration was performed after revocation of such certificates.
If a DAA attestation key has been compromised, it can be added to the RogueList (i.e., the list of revoked authenticators) maintained by the related DAA-Issuer. The relying party should verify whether an authenticator belongs to the RogueList when performing DAA-Verify. The FIDO Metadata Service [FIDOMetadataService] provides an easy way to access such information.
A 3 tier hierarchy for attestation certificates is recommended (i.e., Attestation Root, Attestation Issuing CA, Attestation Certificate). It is also recommended that for each FIDO Authenticator device line (i.e., model), a separate issuing CA is used to help facilitate isolating problems with a specific version of a device.
If the attestation root certificate is not dedicated
to a single FIDO Authenticator device line (i.e., AAGUID),
the AAGUID must be specified either in the attestation certificate itself or
as an extension in the core.rawData
.