1. Introduction
This section is not normative.
This protocol is intended to be used in scenarios where a user interacts with a relying party (a website or native app) on some platform (e.g., a PC) which prompts the user to interact with a roaming authenticator (e.g., a smartphone).
In order to provide evidence of user interaction, a roaming authenticator implementing this protocol is expected to have a mechanism to obtain a user gesture. Possible examples of user gestures include: as a consent button, password, a PIN, a biometric or a combination of these.
Prior to executing this protocol, the client/platform (referred to as host hereafter) and roaming authenticator (referred to as authenticator hereafter) must establish a confidential and mutually authenticated data transport channel. This specification does not specify the details of how such a channel is established, nor how transport layer security must be achieved.
1.1. Relationship to Other Specifications
This specification is part of the FIDO2 project which includes this CTAP and the [FIDOServerGuidelines] specifications, and is related to the W3C [WebAuthn] specification. This specification refers to two CTAP protocol versions:
-
The CTAP1/U2F protocol, which is defined by the U2F Raw Messages specification [U2FRawMsgs]. CTAP1/U2F messages are recognizable by their APDU-like binary structure. CTAP1/U2F may also be referred to as CTAP 1.2 or U2F 1.2. The latter was the U2F specification version used as the basis for several portions of this specification. Authenticators implementing CTAP1/U2F are typically referred to as U2F authenticators or CTAP1 authenticators.
-
The CTAP2 protocol, whose messages are encoded in the CTAP2 canonical CBOR encoding form. Authenticators implementing CTAP2 are referred to as CTAP2 authenticators, FIDO2 authenticators, or WebAuthn Authenticators.
Both CTAP1 and CTAP2 share the same underlying transports: USB Human Interface Device (USB HID), Near Field Communication (NFC), and Bluetooth Smart / Bluetooth Low Energy Technology (BLE).
The [U2FUsbHid], [U2FNfc], [U2FBle], and [U2FRawMsgs] specifications, specifically, are superseded by this specification.
Occasionally, the term "CTAP" may be used without clarifying whether it is referring to CTAP1 or CTAP2. In such cases, it should be understood to be referring to the entirety of this specification or portions of this specification that are not specific to either CTAP1 or CTAP2. For example, some error messages begin with the term "CTAP" without clarifying whether they are CTAP1- or CTAP2-specific because they are applicable to both CTAP protocol versions. CTAP protocol-specific error messages are prefixed with either "CTAP1" or "CTAP2" as appropriate.
Using CTAP2 with CTAP1/U2F authenticators is defined in Interoperating with CTAP1/U2F authenticators.
1.2. Data Elements Referenced by Other Specifications
The following data elements might be referenced by other specifications and hence should not be changed in their fundamental data type or high-level semantics without liaising with the other specifications:
-
aaguid, data type byte string and identifying the authenticator model, i.e. identical values mean that they refer to the same authenticator model and different values mean they refer to different authenticator models.
-
rpId, data type string representing the Relying party identifier, i.e. identical values mean that they refer to the same relying party.
-
credentialID, data type byte string identifying a specific public key credential source, i.e. identical values mean that they refer to the same credential and different values mean they refer to different credentials. Note that there might be a very small probability that different credentials get assigned the same credentialID.
-
up and uv, data type boolean indicating whether user presence (up) or user verification (uv) was performed by the authenticator.
Note: Some of the data elements might have an internal structure that might change. Other specifications shall not rely on such internal structure.
2. Conformance
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", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this specification are to be interpreted as described in [RFC2119].
3. Protocol Structure
This protocol is specified in three parts:
-
Authenticator API: At this level of abstraction, each authenticator operation is defined similarly to an API call - it accepts input parameters and returns either an output or error code. Note that this API level is conceptual and does not represent actual APIs. The actual APIs will be provided by each implementing platform.
-
Message Encoding: In order to invoke a method in the authenticator API, the host must construct and encode a request and send it to the authenticator over the chosen transport protocol. The authenticator will then process the request and return an encoded response.
-
Transport-specific Binding: Requests and responses are conveyed to roaming authenticators over specific transports (e.g., USB, NFC, Bluetooth). For each transport technology, message bindings are specified for this protocol.
This document specifies all three of the above pieces for roaming FIDO2 authenticators.
4. Protocol Overview
The general protocol between a Relying Party application, a client platform, and an authenticator is as follows:
-
A Relying Party application calls
navigator.credentials.create()
ornavigator.credentials.get()
(if it is a website), or the platform’s equivalent API methods, if it is a native application. -
The platform establishes a connection with a nominally appropriate available authenticator, having used criteria passed in by the Relying Party application and possibly other information it has to select the authenticator.
-
The platform gets information about the authenticator using the authenticatorGetInfo command, which helps it determine the authenticator’s capabilities.
-
Depending upon the operation the Relying Party application invoked (in step 1), the options it supplied, and the authenticator’s capabilities, the platform will invoke one or more further Authenticator API commands.
5. Authenticator API
Each operation in the authenticator API can be performed independently of the others, and all operations are asynchronous. The authenticator may enforce a limit on outstanding operations to limit resource usage - in this case, the authenticator is expected to return a busy status and the host is expected to retry the operation later. Additionally, this protocol does not enforce in-order or reliable delivery of requests and responses; if these properties are desired, they must be provided by the underlying transport protocol or implemented at a higher layer by applications.
Note that this API level is conceptual and does not represent actual APIs. The actual APIs will be provided by each implementing platform.
The authenticator API has the following methods and data structures.
5.1. authenticatorMakeCredential (0x01)
This method is invoked by the host to request generation of a new credential in the authenticator. It takes the following input parameters, which explicitly correspond to those defined in The authenticatorMakeCredential operation section of the Web Authentication specification:
Parameter name | Data type | Required? | Definition |
---|---|---|---|
clientDataHash (0x01) | Byte Array | Required | Hash of the ClientData contextual binding specified by host. See [WebAuthn]. |
rp (0x02) | PublicKeyCredentialRpEntity | Required | This PublicKeyCredentialRpEntity data structure describes a Relying Party with which the new public key credential will be associated. It contains the Relying party identifier of type text string, (optionally) a human-friendly RP name of type text string, and (optionally) a URL of type text string, referencing a RP icon image. The RP name is to be used by the authenticator when displaying the credential to the user for selection and usage authorization. The RP name and URL are optional so that the RP can be more privacy friendly if it chooses to. For example, for authenticators with a display, RP may not want to display name/icon for single-factor scenarios. |
user (0x03) | PublicKeyCredentialUserEntity | Required | This PublicKeyCredentialUserEntity data structure describes the user account to which the new public key credential will be associated at the RP. It contains an RP-specific user account identifier of type byte array, (optionally) a user name of type text string, (optionally) a user display name of type text string, and (optionally) a URL of type text string, referencing a user icon image (of a user avatar, for example). The authenticator associates the created public key credential with the account identifier, and MAY also associate any or all of the user name, user display name, and image data (pointed to by the URL, if any). The user name, display name, and URL are optional for privacy reasons for single-factor scenarios where only user presence is required. For example, in certain closed physical environments like factory floors, user presence only authenticators can satisfy RP’s productivity and security needs. In these environments, omitting user name, display name and URL makes the credential more privacy friendly. Although this information is not available without user verification, devices which support user verification but do not have it configured, can be tricked into releasing this information by configuring the user verification. |
pubKeyCredParams (0x04) | CBOR Array | Required | A sequence of CBOR maps consisting of pairs of PublicKeyCredentialType (a string) and cryptographic algorithm (a positive or negative integer), where algorithm identifiers are values that SHOULD be registered in the IANA COSE Algorithms registry [IANA-COSE-ALGS-REG]. This sequence is ordered from most preferred (by the RP) to least preferred. |
excludeList (0x05) | Sequence of PublicKeyCredentialDescriptors | Optional | A sequence of PublicKeyCredentialDescriptor structures, as specified in [WebAuthn]. The authenticator returns an error if the authenticator already contains one of the credentials enumerated in this sequence. This allows RPs to limit the creation of multiple credentials for the same account on a single authenticator. |
extensions (0x06) | CBOR map of extension identifier → authenticator extension input values | Optional | Parameters to influence authenticator operation, as specified in [WebAuthn]. These parameters might be authenticator specific. |
options (0x07) | Map of authenticator options | Optional | Parameters to influence authenticator operation, as specified in in the table below. |
| Byte Array | Optional | First 16 bytes of HMAC-SHA-256 of clientDataHash using pinUvAuthToken which platform got from the authenticator: HMAC-SHA-256(pinUvAuthToken, clientDataHash) .
|
pinUvAuthProtocol (0x09) | Unsigned Integer | Optional | PIN/UV protocol version chosen by the client |
The following values are defined for use in the options parameter. All options are booleans.
Key | Default value | Definition |
---|---|---|
rk | false | resident key: Instructs the authenticator to store the key material on the device. |
uv | false | user verification: Instructs the authenticator to require a gesture that verifies the user to complete the request. Examples of such gestures are fingerprint scan or a PIN. |
Note that the Authenticator may perform user verification even if not requested to enhance its security offering.
Note that the [WebAuthn] specification defines an abstract authenticatorMakeCredential
operation, which corresponds to the operation described in this section. The parameters in the
abstract [WebAuthn] authenticatorMakeCredential
operation map to the above parameters
as follows:
[WebAuthn] authenticatorMakeCredential operation
| CTAP authenticatorMakeCredential operation
|
---|---|
hash | clientDataHash |
rpEntity | rp |
userEntity | user |
requireResidentKey | options.rk |
requireUserPresence | Not present in the current version of CTAP. Authenticators are assumed to always check user presence. |
requireUserVerification | options.uv or pinUvAuthParam/pinUvAuthProtocol |
credTypesAndPubKeyAlgs | pubKeyCredParams |
excludeCredentialDescriptorList | excludeList |
extensions | extensions |
Note that icon values used with authenticators can employ [RFC2397] "data" URLs so that the image data is passed by value, rather than by reference. This can enable authenticators with a display but no Internet connection to display icons.
Note that a text string is a UTF-8 encoded string (CBOR major type 3).
When an authenticatorMakeCredential
request is received, the authenticator performs the
following procedure:
-
If authenticator supports clientPin and platform sends a zero length pinUvAuthParam, wait for user touch and then return either CTAP2_ERR_PIN_NOT_SET if pin is not set or CTAP2_ERR_PIN_INVALID if pin has been set.
-
This is done for the case where multiple authenticators are attached to the platform and the platform wants to enforce clientPin semantics, but the user has to select which authenticator to send the pinUvAuthToken to.
-
-
If authenticator supports clientPin and pinUvAuthParam parameter is present and the pinUvAuthProtocol is not supported, return CTAP2_ERR_PIN_AUTH_INVALID error.
-
If the pubKeyCredParams parameter does not contain a valid COSEAlgorithmIdentifier value that is supported by the authenticator, terminate this procedure and return error code CTAP2_ERR_UNSUPPORTED_ALGORITHM.
-
If the options parameter is present, process all the options. If the option is known but not supported, terminate this procedure and return CTAP2_ERR_UNSUPPORTED_OPTION. If the option is known but not valid for this command, terminate this procedure and return CTAP2_ERR_INVALID_OPTION. Ignore any options that are not understood. Note that because this specification defines normative behaviors for them, all authenticators MUST understand the "rk", "up", and "uv" options.
-
Optionally, if the extensions parameter is present, process any extensions that this authenticator supports. Authenticator extension outputs generated by the authenticator extension processing are returned in the authenticator data.
-
If the excludeList parameter is present and contains a credential ID that is present on this authenticator and bound to the specified rpId:
-
If the credential does not have credProtect value userVerificationRequired, wait for user presence, then terminate this procedure and return error code CTAP2_ERR_CREDENTIAL_EXCLUDED. User presence check is required for CTAP2 authenticators before the RP gets told that the token is already registered to behave similarly to CTAP1/U2F authenticators.
-
If the credential does have credProtect value userVerificationRequired:
-
If userVerification was performed as part of this request, wait for user presence and return CTAP2_ERR_CREDENTIAL_EXCLUDED.
-
If userVerification was not performed as part of this request, remove the credential from the exclude list and continue.
-
-
-
If authenticator is not protected by some form of user verification and platform has set "uv" or pinUvAuthParam to get the user verification, return CTAP2_ERR_INVALID_OPTION.
-
If both "rk" and "uv" parameter values are set to false or omitted go to Step 10.
-
If authenticator is protected by some form of user verification:
-
In authenticatorGetInfo, this being reflected by either "clientPin" is present and set to true or "uv" is present and set to true or both.
-
If the request is passed with "uv" option, use built-in user verification method and verify the user.
-
If the verification succeeds, set the "uv" bit to 1 in the response.
-
If the verification fails, return CTAP2_ERR_PIN_AUTH_INVALID error.
-
-
If pinUvAuthParam parameter is present and pinUvAuthProtocol is 1, verify it by matching it against first 16 bytes of HMAC-SHA-256 of clientDataHash parameter using pinUvAuthToken:
HMAC-SHA-256(pinUvAuthToken, clientDataHash)
.-
If the verification succeeds, set the "uv" bit to 1 in the response.
-
If the verification fails, return CTAP2_ERR_PIN_AUTH_INVALID error.
-
-
If user is not verified via above steps return CTAP2_ERR_PIN_REQUIRED.
-
-
Perform authenticator processing steps for the credProtect extension.
Note: This extension is called out here because such steps may involve action even if no credProtect extension is present in the request.
-
If the authenticator has a display, show the items contained within the user and rp parameter structures to the user. Alternatively, request user interaction in an authenticator-specific way (e.g., flash the LED light). Request permission to create a credential. If the user declines permission, return the CTAP2_ERR_OPERATION_DENIED error.
-
Generate a new credential key pair for the algorithm specified.
-
If "rk" in options parameter is set to true:
-
If a credential for the same RP ID and account ID already exists on the authenticator, overwrite that credential.
-
Store the user parameter along the newly-created key pair.
-
If authenticator does not have enough internal storage to persist the new credential, return CTAP2_ERR_KEY_STORE_FULL.
-
-
Generate an attestation statement for the newly-created key using clientDataHash.
On success, the authenticator returns an attestation object in its response as defined in [WebAuthn]:
Member name | Data type | Required? | Definition |
---|---|---|---|
fmt (0x01) | String | Required | The attestation statement format identifier. |
authData (0x02) | Byte Array | Required | The authenticator data object. |
attStmt (0x03) | CBOR Map, the structure of which depends on the attestation statement format identifier | Required | The attestation statement, as specified in [WebAuthn]. |
5.2. authenticatorGetAssertion (0x02)
This method is used by a host to request cryptographic proof of user authentication as well as user consent to a given transaction, using a previously generated credential that is bound to the authenticator and relying party identifier. It takes the following input parameters, which explicitly correspond to those defined in The authenticatorGetAssertion operation section of the Web Authentication specification:
Parameter name | Data type | Required? | Definition |
---|---|---|---|
rpId (0x01) | String | Required | Relying party identifier. See [WebAuthn]. |
clientDataHash (0x02) | Byte Array | Required | Hash of the serialized client data collected by the host. See [WebAuthn]. |
allowList (0x03) | Sequence of PublicKeyCredentialDescriptors | Optional | A sequence of PublicKeyCredentialDescriptor structures, each denoting a credential, as specified in [WebAuthn]. A platform MUST NOT send an empty allowList—if it would be empty it MUST be omitted. If this parameter is present the authenticator MUST only generate an assertion using one of the denoted credentials. |
extensions (0x04) | CBOR map of extension identifier → authenticator extension input values | Optional | Parameters to influence authenticator operation. These parameters might be authenticator specific. |
options (0x05) | Map of authenticator options | Optional | Parameters to influence authenticator operation, as specified in the table below. |
| Byte Array | Optional | First 16 bytes of HMAC-SHA-256 of clientDataHash using pinUvAuthToken which platform got from the authenticator: HMAC-SHA-256(pinUvAuthToken, clientDataHash) .
|
pinUvAuthProtocol (0x07) | Unsigned Integer | Optional | PIN/UV protocol version selected by client. |
The following values are defined for use in the options parameter. All options are booleans.
Key | Default value | Definition |
---|---|---|
up | true | user presence: Instructs the authenticator to require user consent to complete the operation. |
uv | false | user verification: Instructs the authenticator to require a gesture that verifies the user to complete the request. Examples of such gestures are fingerprint scan or a PIN. |
Note that the Authenticator may perform user verification even if not requested to enhance its security offering.
Note that the [WebAuthn] specification defines an abstract authenticatorGetAssertion
operation, which corresponds to the operation described in this section. The parameters in the
abstract [WebAuthn] authenticatorGetAssertion
operation map to the above parameters
as follows:
[WebAuthn] authenticatorGetAssertion operation
| CTAP authenticatorGetAssertion operation
|
---|---|
hash | clientDataHash |
rpId | rpId |
allowCredentialDescriptorList | allowList |
requireUserPresence | options.up |
requireUserVerification | options.uv or pinUvAuthParam/pinUvAuthProtocol |
extensions | extensions |
When an authenticatorGetAssertion
request is received, the authenticator performs the following procedure:
-
If authenticator supports clientPin and platform sends a zero length pinUvAuthParam, wait for user touch and then return either CTAP2_ERR_PIN_NOT_SET if pin is not set or CTAP2_ERR_PIN_INVALID if pin has been set.
-
This is done for the case where multiple authenticators are attached to the platform and the platform wants to enforce clientPin semantics, but the user has to select which authenticator to send the pinUvAuthToken to.
-
-
If authenticator supports clientPin and pinUvAuthParam parameter is present and the pinUvAuthProtocol is not supported, return CTAP2_ERR_PIN_AUTH_INVALID error.
-
If the options parameter is present, process all the options. If the option is known but not supported, terminate this procedure and return CTAP2_ERR_UNSUPPORTED_OPTION. If the option is known but not valid for this command, terminate this procedure and return CTAP2_ERR_INVALID_OPTION. Ignore any options that are not understood. Note that because this specification defines normative behaviors for them, all authenticators MUST understand the "rk", "up", and "uv" options.
-
Optionally, if the extensions parameter is present, process any extensions that this authenticator supports. Authenticator extension outputs generated by the authenticator extension processing are returned in the authenticator data.
-
If authenticator is not protected by some form of user verification and platform has set "uv" or pinUvAuthParam to get the user verification, return CTAP2_ERR_UNSUPPORTED_OPTION.
-
If authenticator is protected by some form of user verification:
-
In authenticatorGetInfo, this being reflected by either "clientPin" is present and set to true or "uv" is present and set to true or both.
-
If the request is passed with "uv" option, use built-in user verification method and verify the user.
-
If the verification succeeds, set the "uv" bit to 1 in the response.
-
If the verification fails, return CTAP2_ERR_OPERATION_DENIED error.
-
-
If pinUvAuthParam parameter is present and pinUvAuthProtocol is 1, verify it by matching it against first 16 bytes of HMAC-SHA-256 of clientDataHash parameter using pinUvAuthToken:
HMAC-SHA-256(pinUvAuthToken, clientDataHash)
.-
If the verification succeeds, set the "uv" bit to 1 in the response.
-
If the verification fails, return CTAP2_ERR_PIN_AUTH_INVALID error.
-
-
-
Locate all credentials that are eligible for retrieval under the specified criteria:
-
If an allowList is present and is non-empty, locate all denoted credentials present on this authenticator and bound to the specified rpId.
-
If an allowList is not present, locate all credentials that are present on this authenticator and bound to the specified rpId.
-
Iterate through the applicable credentials, and if credential protection for a credential is marked as
userVerificationRequired
, and user verification is not done with above steps, remove that credential from the applicable credentials list. -
Iterate through the applicable credentials, and if credential protection for a credential is marked as
userVerificationOptionalWithCredentialIDList
and there is no allowlist passed by the client or there has not been any user verification happened in above steps, remove that credential from the applicable credentials list. -
If no applicable credentials were found, return CTAP2_ERR_NO_CREDENTIALS
-
Let
numberOfCredentials
be the number of applicable credentials found.
-
-
Collect user presence if required:
-
If the "up" option is specified and user is already verified by built in user verification method, proceed to next step. Else, wait for user presence.
-
When timeout occurs without user presence, return CTAP2_ERR_OPERATION_DENIED error.
-
-
-
If allowList is present:
-
Select any applicable credential
-
Sign the clientDataHash along with authData with the selected credential, using the structure specified in [WebAuthn].
-
-
If allowlist is not present:
-
If
numberOfCredentials
is one:-
Select that credential.
-
-
If
numberOfCredentials
is more than one:-
Order the credentials by the time when they were created in reverse order. (I.e. the first credential is the most recently created.)
-
If authenticator does not have a display or the authenticator does have a display but the UV and UP options are false:
-
Remember the authenticatorGetAssertion parameters.
-
Create a credential counter (
credentialCounter
) and set it to 1. This counter signifies the next credential to be returned by the authenticator, assuming zero-based indexing. -
Start a timer. This is used during authenticatorGetNextAssertion command. This step is optional if transport is done over NFC.
-
Select the first credential.
-
-
If authenticator has a display and at least one of the UV and UP options is true:
-
Display all these credentials to the user, using their friendly name along with other stored account information.
-
Also, display the rpId of the requester (specified in the request) and ask the user to select a credential.
-
If the user declines to select a credential or takes too long (as determined by the authenticator), terminate this procedure and return the CTAP2_ERR_OPERATION_DENIED error.
-
Update the response to set the
userSelected
member totrue
and to delete thenumberOfCredentials
member. -
Select the credential indicated by the user.
-
-
-
Update the response to include the selected credential’s publicKeyCredentialUserEntity information. User identifiable information (name, DisplayName, icon) inside the publicKeyCredentialUserEntity MUST NOT be returned if user verification is not done by the authenticator.
-
Sign the clientDataHash along with authData with the selected credential, using the structure specified in [WebAuthn].
-
On success, the authenticator returns the following structure in its response:
Member name | Data type | Required? | Definition |
---|---|---|---|
credential (0x01) | PublicKeyCredentialDescriptor | Optional | PublicKeyCredentialDescriptor structure containing the credential identifier whose private key was used to generate the assertion. May be omitted if the allowList has exactly one Credential. |
authData (0x02) | Byte Array | Required | The signed-over contextual bindings made by the authenticator, as specified in [WebAuthn]. |
signature (0x03) | Byte Array | Required | The assertion signature produced by the authenticator, as specified in [WebAuthn]. |
user (0x04) | PublicKeyCredentialUserEntity | Optional |
PublicKeyCredentialUserEntity structure containing the user account information.
User identifiable information (name, DisplayName, icon) MUST not be returned if user verification
is not done by the authenticator.
U2F Devices: For U2F devices, this parameter is not returned as this user information is not present for U2F credentials. FIDO Devices - server resident credentials: For server resident credentials on FIDO devices, this parameter is optional as server resident credentials behave same as U2F credentials where they are discovered given the user information on the RP. Authenticators optionally MAY store user information inside the credential ID. FIDO devices - device resident credentials: For device resident keys on FIDO devices, at least user "id" is mandatory. For single account per RP case, authenticator returns "id" field to the platform which will be returned to the [WebAuthn] layer. For multiple accounts per RP case, where the authenticator does not have a display, authenticator returns "id" as well as other fields to the platform. Platform will use this information to show the account selection UX to the user and for the user selected account, it will ONLY return "id" back to the [WebAuthn] layer and discard other user details. |
numberOfCredentials (0x05) | Integer | Optional | Total number of account credentials for the RP. Optional; defaults to one. This member is required when more than one credential is found for an RP, and the authenticator does not have a display or the UV & UP flags are false. Omitted when returned for the authenticatorGetNextAssertion method. |
userSelected (0x06) | Boolean | Optional | Indicates that a credential was selected by the user via interaction directly with the authenticator,
and thus the platform does not need to confirm the credential. Optional; defaults to false .
MUST NOT be present in response to a request where an allowList was given,
where numberOfCredentials is greater than one,
nor in response to an authenticatorGetNextAssertion request.
|
Within the "flags" bits of the authenticator data structure returned, the authenticator will report what was actually done within the authenticator boundary. The meanings of the combinations of the User Present (UP) and User Verified (UV) flags are as follows:
Flags | Meaning |
---|---|
"up"=0 "uv"=0 | Silent authentication |
"up"=1 "uv"=0 | Physical user presence verified, but no user verification |
"up"=0 "uv"=1 | User verification performed, but physical user presence not verified (a typical "smartcard scenario") |
"up"=1 "uv"=1 | User verification performed and physical user presence verified |
5.3. authenticatorGetNextAssertion (0x08)
The client calls this method when the authenticatorGetAssertion response contains the numberOfCredentials member and the number of credentials exceeds 1. This method is used to obtain the next per-credential signature for a given authenticatorGetAssertion request.
This method takes no arguments as it is always follows a call to authenticatorGetAssertion or authenticatorGetNextAssertion.
When such a request is received, the authenticator performs the following procedure:
-
If authenticator does not remember any authenticatorGetAssertion parameters, return CTAP2_ERR_NOT_ALLOWED.
-
If the
credentialCounter
is equal to or greater thannumberOfCredentials
, return CTAP2_ERR_NOT_ALLOWED. -
If timer since the last call to authenticatorGetAssertion/authenticatorGetNextAssertion is greater than 30 seconds, discard the current authenticatorGetAssertion state and return CTAP2_ERR_NOT_ALLOWED. This step is optional if transport is done over NFC.
-
Select the credential indexed by
credentialCounter
. (I.e. credentials[n] assuming a zero-based array.) -
Update the response to include the selected credential’s publicKeyCredentialUserEntity information. User identifiable information (name, DisplayName, icon) inside the publicKeyCredentialUserEntity MUST not be returned if user verification was not done by the authenticator in the original authenticatorGetAssertion call.
-
Sign the clientDataHash along with authData with the selected credential, using the structure specified in [WebAuthn].
-
Reset the timer. This step is optional if transport is done over NFC.
-
Increment
credentialCounter
.
On success, the authenticator returns the same structure as returned by the authenticatorGetAssertion method. The numberOfCredentials member is omitted.
5.3.1. Client Logic
If client receives numberOfCredentials member value exceeding 1 in response to the authenticatorGetAssertion call:
-
Call authenticatorGetNextAssertion numberOfCredentials minus 1 times.
-
Make sure ‘rp’ member matches the current request.
-
Remember the ‘response’ member.
-
Add credential user information to the ‘credentialInfo’ list.
-
-
Draw a UX that displays credentialInfo list.
-
Let user select which credential to use.
-
Return the value of the ‘response’ member associated with the user choice.
-
Discard all other responses.
5.4. authenticatorGetInfo (0x04)
Using this method, the host can request that the authenticator report a list of all supported protocol versions, supported extensions, AAGUID of the device, and its capabilities. This method takes no inputs.
On success, the authenticator returns:
Member name | Data type | Required? | Definition |
---|---|---|---|
versions (0x01) | Sequence of strings | Required | List of supported versions. Supported versions are: "FIDO_2_0" for CTAP2 / FIDO2 / Web Authentication authenticators and "U2F_V2" for CTAP1/U2F authenticators. |
extensions (0x02) | Sequence of strings | Optional | List of supported extensions. |
aaguid (0x03) | Byte String | Required | The claimed AAGUID. 16 bytes in length and encoded the same as MakeCredential AuthenticatorData, as specified in [WebAuthn]. |
options (0x04) | Map | Optional | List of supported options. |
maxMsgSize (0x05) | Unsigned Integer | Optional | Maximum message size supported by the authenticator. |
pinUvAuthProtocols (0x06) | Array of Unsigned Integers | Optional | List of supported PIN/UV protocol versions. |
maxCredentialCountInList (0x07) | Unsigned Integer | Optional | Maximum number of credentials supported in credentialID list at a time by the authenticator. |
maxCredentialIdLength (0x08) | Unsigned Integer | Optional | Maximum Credential ID Length supported by the authenticator. |
transports (0x09) | Sequence of strings | Optional | List of supported transports. Values are taken from the AuthenticatorTransport enum in [WebAuthn]. The list MUST NOT include duplicate values. Platforms MUST tolerate unknown values. |
algorithms (0x0A) | Sequence of PublicKeyCredentialParameters | Optional | List of supported algorithms for credential generation. The sequence is ordered from most preferred to least preferred and MUST NOT include duplicate entries. |
maxAuthenticatorConfigLength (0x0B) | Unsigned Integer | Optional | The maximum size, in bytes, of the serialized config map array that this authenticator can store. If the authenticatorConfig command is not supported, this should be omitted rather than specified as zero. If the authenticatorConfig command is supported, this value defaults to 1024 if omitted. If specified, the value must be ≥ 1024. |
defaultCredProtect (0x0C) | Unsigned Integer | Optional | The default credProtect level used by this authenticator when a level is not explicitly requested by the platform.
MUST NOT be present unless credProtect is included in the supported extensions list.
If present, MUST have the value 2 or 3.
(This is purely for informational purposes and is not expected to control any platform behavior.)
|
All options are in the form key-value pairs with string IDs and boolean values. When an option is not present, the default is applied per table below. The following is a list of supported options:
Option ID | Definition | Default |
---|---|---|
plat | platform device: Indicates that the device is attached to the client and therefore can’t be removed and used on another client. | false |
rk | resident key: Indicates that the device is capable of storing keys on the device itself and therefore can satisfy the authenticatorGetAssertion request with the allowList parameter omitted. | false |
|
Client PIN:
If present and set to true, it indicates that the device is capable of accepting a PIN from the client and PIN has been set. If present and set to false, it indicates that the device is capable of accepting a PIN from the client and PIN has not been set yet. If absent, it indicates that the device is not capable of accepting a PIN from the client. Client PIN is one of the ways to do user verification. | Not supported |
up | user presence: Indicates that the device is capable of testing user presence. | true |
uv |
user verification:
Indicates that the device is capable of verifying the user within itself.
For example, devices with UI, biometrics fall into this category.
If present and set to true, it indicates that the device is capable of user verification within itself and has been configured. If present and set to false, it indicates that the device is capable of user verification within itself and has not been yet configured. For example, a biometric device that has not yet been configured will return this parameter set to false. If absent, it indicates that the device is not capable of user verification within itself. A device that can only do Client PIN will not return the "uv" parameter. If a device is capable of verifying the user within itself as well as able to do Client PIN, it will return both "uv" and the Client PIN option. | Not Supported |
uvToken | user verification token: Indicates that the device is capable of performing built in user verification based token feature. | false |
config | configuration support: Indicates that the device supports the authenticatorConfig command. | false |
5.5. authenticatorClientPIN (0x06)
One of the design goals of this command is to have minimum burden on the authenticator and to not send actual encrypted PIN to the authenticator in normal authenticator usage scenarios to have more security. Hence, below design only sends PIN in encrypted format while setting or changing a PIN. On normal PIN usage scenarios, design uses randomized pinUvAuthToken which gets generated every power cycle.
This command is used by the platform to establish key agreement with authenticator and getting sharedSecret, setting a new PIN on the authenticator, changing existing PIN on the authenticator and getting "pinUvAuthToken" from the authenticator which can be used in subsequent authenticatorMakeCredential and authenticatorGetAssertion operations.
It takes the following input parameters:
Parameter name | Data type | Required? | Definition |
---|---|---|---|
pinUvAuthProtocol (0x01) | Unsigned Integer | Required | PIN/UV protocol version chosen by the client. For this version of the spec, this SHALL be the number 1. |
subCommand (0x02) | Unsigned Integer | Required | The authenticator Client PIN sub command currently being requested |
keyAgreement (0x03) | COSE_Key | Optional | Public key of platformKeyAgreementKey. The COSE_Key-encoded public key MUST contain the optional "alg" parameter and MUST NOT contain any other optional parameters. The "alg" parameter MUST contain a COSEAlgorithmIdentifier value. |
pinUvAuthParam (0x04) | Byte Array | Optional | First 16 bytes of HMAC-SHA-256 of encrypted contents using sharedSecret. See Setting a new PIN, Changing existing PIN and Getting pinUvAuthToken from the authenticator for more details. |
newPinEnc (0x05) | Byte Array | Optional | Encrypted new PIN using sharedSecret. Encryption is done over UTF-8 representation of new PIN. |
pinHashEnc (0x06) | Byte Array | Optional | Encrypted first 16 bytes of SHA-256 of PIN using sharedSecret. |
The list of sub commands for PIN/UV protocol version 1 is:
subCommand Name | subCommand Number |
---|---|
getPINRetries | 0x01 |
getKeyAgreement | 0x02 |
setPIN | 0x03 |
changePIN | 0x04 |
getPinUvAuthTokenUsingPin | 0x05 |
getPinUvAuthTokenUsingUv | 0x06 |
getUVRetries | 0x07 |
On success, authenticator returns the following structure in its response:
Parameter name | Data type | Required? | Definition |
---|---|---|---|
KeyAgreement (0x01) | COSE_Key | Optional |
Authenticator key agreement public key in COSE_Key format. This will be used to establish a sharedSecret between platform and the authenticator.
The COSE_Key-encoded public key MUST contain the optional "alg" parameter
and MUST NOT contain any other optional parameters.
The "alg" parameter MUST contain a COSEAlgorithmIdentifier value.
Note: The COSEAlgorithmIdentifier used is -25 (ECDH-ES + HKDF-256) although this is NOT the algorithm actually used. Setting this to a different value may result in compatibility issues. |
pinUvAuthToken (0x02) | Byte Array | Optional | Encrypted pinUvAuthToken using sharedSecret to be used in subsequent authenticatorMakeCredential and authenticatorGetAssertion operations. |
| Unsigned Integer | Optional | Number of PIN attempts remaining before lockout. This is optionally used to show in UI when collecting the PIN in Setting a new PIN, Changing existing PIN and Getting pinUvAuthToken from the authenticator flows. |
| Boolean | Optional |
Present and true if the authenticator requires a power cycle before any future PIN operation, false if no power cycle needed.
If the field is omitted, no information is given about whether a power cycle is needed or not.
This field is only valid in response to a getRetries request and authenticators MUST NOT use this field as an alternative to returning CTAP2_ERR_PIN_AUTH_BLOCKED when that is required by this specification: the power cycle behaviour is a security property and cannot be delegated to the platform to enforce. |
| Unsigned Integer | Optional | Number of uv attempts remaining before lockout. |
5.5.1. Client PIN/UV Requirements
-
Platform has to fulfill following PIN support requirements while gathering input from the user:
-
Minimum PIN Length: 4 Unicode characters
-
Maximum PIN Length: UTF-8 representation must not exceed 63 bytes
-
PIN must not end in a 0x00 byte
-
-
Authenticator has to fulfill following PIN support requirements:
-
Minimum PIN Length: 4 bytes
-
Note: Authenticators can implement minimum PIN lengths that are longer than 4 bytes.
-
-
Maximum PIN Length: 63 bytes
-
PIN storage on the device has to be of the same or better security assurances as of private keys on the device.
-
-
pinRetries counter:
-
pinRetries counter represents the number of attempts left before PIN is blocked.
-
Authenticators must allow no more than 8 retries but may set a lower maximum.
-
Each correct PIN entry resets the pinRetries and uvRetries back to the maximum unless the PIN is already blocked.
-
Each incorrect PIN entry decrements the pinRetries by 1.
-
Once the pinRetries counter reaches 0, both PIN as well as on-device user verification are disabled and can only be enabled if authenticator is reset.
-
-
uvRetries counter:
-
uvRetries counter represents the number of attempts left before on-device user verification is blocked.
-
Authenticators must allow no more than 5 retries but may set a lower maximum.
-
Each correct built-in user verification resets the pinRetries as well as uvRetries counter back to the maximum unless the uv is already blocked.
-
Incorrect uv decrements the uvRetries by 1.
-
For best user experience, fingerprint-based authenticators should try at least 3 times before decrementing the counter by 1 and returning the error to the platform.
-
-
Once the uvRetries counter reaches 0, built in user verification is disabled and can only be enabled if authenticator is reset or correct PIN is entered by the user.
-
5.5.2. Authenticator Configuration Operations Upon Power Up
Authenticator generates following configuration at power up. This is to have less burden on the authenticator as key agreement is an expensive operation. This also ensures randomness across power cycles.
Following are the operations authenticator performs on each powerup:
-
Generate "authenticatorKeyAgreementKey": -
Generate an ECDH P-256 key pair called "authenticatorKeyAgreementKey" denoted by
(a, aG)
where "a" denotes the private key and "aG" denotes the public key.-
See [RFC6090] Section 4.1 and [SP800-56A] for more ECDH key agreement protocol details.
-
-
-
Generate pinUvAuthToken:
-
Generate a random integer of length which is multiple of 16 bytes (AES block length).
-
"pinUvAuthToken" is used so that there is minimum burden on the authenticator and platform does not have to not send actual encrypted PIN to the authenticator in normal authenticator usage scenarios. This also provides more security as we are not sending actual PIN even in encrypted form.
-
"pinUvAuthToken" is also interchangeably called "uvToken" when retreived from the authenticator with built-in user verification methods like fingerprint or UI based ones.
-
5.5.3. Platform getting PIN retries from Authenticator
PIN retries count is the number of PIN attempts remaining before PIN is disabled on the device. When the PIN retries count nears zero, the platform can optionally warn the user to be careful while entering the PIN.
Platform performs the following operations to get pinRetries:
-
Platform sends authenticatorClientPIN command with following parameters to the authenticator:
-
pinUvAuthProtocol: 0x01
-
subCommand: getPINRetries(0x01)
-
-
Authenticator responds back with pinRetries and, optionally, powerCycleState.
5.5.4. Platform getting UV Retries from Authenticator
UV retries count is the number of built-in UV attempts remaining before built-in UV is disabled on the device. When the UV retries count nears zero, the platform can optionally warn the user to be careful while performing user verification.Platform performs the following operations to get uvRetries:
-
Platform sends authenticatorClientPIN command with following parameters to the authenticator:
-
pinUvAuthProtocol: 0x01
-
subCommand: getUVRetries(0x07)
-
-
Authenticator responds back with uvRetries and, optionally, powerCycleState.
5.5.5. Platform generating sharedSecret
Platform does the ECDH key agreement to arrive at sharedSecret to be used only during that transaction.
Authenticator does not have to keep a list of sharedSecrets for all active sessions. If there are subsequent authenticatorClientPIN transactions, a new sharedSecret is generated every time.
Platform performs the following operations to arrive at the sharedSecret:
-
Platform sends authenticatorClientPIN command with following parameters to the authenticator:
-
pinUvAuthProtocol: 0x01
-
subCommand: getKeyAgreement(0x02)
-
-
Authenticator responds back with public key of authenticatorKeyAgreementKey, "aG".
-
Platform generates "platformKeyAgreementKey": -
Platform generates ECDH P-256 key pair called "platformKeyAgreementKey" denoted by
(b, bG)
where"b"
denotes the private key and"bG"
denotes the public key.
-
-
-
Platform generates "sharedSecret" using SHA-256 over ECDH key agreement protocol using private key of platformKeyAgreementKey, "b" and public key of authenticatorKeyAgreementKey, "aG":
SHA-256((baG).x)
.-
SHA-256 is done over only "x" curve point of baG.
-
See [RFC6090] Section 4.1 and appendix (C.2) of [SP800-56A] for more ECDH key agreement protocol details and key representation.
-
-
5.5.6. Setting a New PIN
Following operations are performed to set up a new PIN:
-
Platform gets sharedSecret from the authenticator.
-
Platform collects new PIN ("newPinUnicode") from the user in Unicode format.
-
Platform checks the Unicode character length of "newPinUnicode" against the minimum 4 Unicode character requirement and returns CTAP2_ERR_PIN_POLICY_VIOLATION if the check fails.
-
Let "newPin" be the UTF-8 representation of "newPinUnicode".
-
Platform checks the byte length of "newPin" against the max UTF-8 representation limit of 63 bytes and returns CTAP2_ERR_PIN_POLICY_VIOLATION if the check fails.
-
-
-
Platform sends § 5.5 authenticatorClientPIN (0x06) command with following parameters to the authenticator:
-
pinUvAuthProtocol: 0x01.
-
subCommand: setPIN(0x03).
-
keyAgreement: public key of platformKeyAgreementKey, "bG".
-
newPinEnc: Encrypted newPin using sharedSecret:
AES256-CBC(sharedSecret, IV=0, newPin)
.-
To avoid disclosing length of newPin, it is padded prior to encryption with 0x00 bytes until it is 64 bytes long. Since the maximum length of a PIN is 63 bytes, there is always at least one byte of padding. No PKCS#7 padding is performed during encryption, therefore newPinEnc is always 64 bytes long.
-
-
pinUvAuthParam:
LEFT(HMAC-SHA-256(sharedSecret, newPinEnc), 16)
.-
The platform sends the first 16 bytes of the HMAC-SHA-256 result.
-
-
-
Authenticator performs following operations upon receiving the request:
-
If Authenticator does not receive mandatory parameters for this command, it returns CTAP2_ERR_MISSING_PARAMETER error.
-
If a PIN has already been set, authenticator returns CTAP2_ERR_PIN_AUTH_INVALID error.
-
Authenticator generates "sharedSecret":
SHA-256((abG).x)
using private key of authenticatorKeyAgreementKey, "a" and public key of platformKeyAgreementKey, "bG".-
SHA-256 is done over only
"x"
curve point of"abG"
-
See [RFC6090] Section 4.1 and appendix (C.2) of [SP800-56A] for more ECDH key agreement protocol details and key representation.
-
-
Authenticator verifies pinUvAuthParam by generating
LEFT(HMAC-SHA-256(sharedSecret, newPinEnc), 16)
and matching against input pinUvAuthParam parameter.-
If pinUvAuthParam verification fails, authenticator returns CTAP2_ERR_PIN_AUTH_INVALID error.
-
-
Authenticator decrypts newPinEnc using above "sharedSecret" producing newPin and checks newPin length against minimum PIN length of 4 bytes.
-
The decrypted padded newPin should be of at least 64 bytes length and authenticator determines actual PIN length by looking for first 0x00 byte which terminates the PIN.
-
If minimum PIN length check fails, authenticator returns CTAP2_ERR_PIN_POLICY_VIOLATION error.
-
Authenticator may have additional constraints for PIN policy. The current spec only enforces minimum length of 4 bytes.
-
-
Authenticator stores
LEFT(SHA-256(newPin), 16)
on the device, sets the pinRetries counter to maximum count, and returns CTAP2_OK.
-
5.5.7. Changing existing PIN
Following operations are performed to change an existing PIN:
-
Platform gets sharedSecret from the authenticator.
-
Platform collects current PIN ("curPinUnicode") and new PIN ("newPinUnicode") from the user.
-
Platform checks the Unicode character length of "newPinUnicode" against the minimum 4 Unicode character requirement and returns CTAP2_ERR_PIN_POLICY_VIOLATION if the check fails.
-
Let "curPin" be the UTF-8 representation of "curPinUnicode" and "newPin" be the UTF-8 representation of "newPinUnicode"
-
Platform checks the byte length of "curPin" and "newPin" against the max UTF-8 representation limit of 63 bytes and returns CTAP2_ERR_PIN_POLICY_VIOLATION if the check fails.
-
-
-
Platform sends authenticatorClientPIN command with following parameters to the authenticator:
-
pinUvAuthProtocol: 0x01.
-
subCommand: changePIN(0x04).
-
keyAgreement: public key of platformKeyAgreementKey, "bG".
-
pinHashEnc: Encrypted first 16 bytes of SHA-256 hash of curPin using sharedSecret:
AES256-CBC(sharedSecret, IV=0, LEFT(SHA-256(curPin),16))
. -
newPinEnc: Encrypted "newPin" using sharedSecret:
AES256-CBC(sharedSecret, IV=0, newPin)
.-
To avoid disclosing length of newPin, it is padded prior to encryption with 0x00 bytes until it is 64 bytes long. Since the maximum length of a PIN is 63 bytes, there is always at least one byte of padding. No PKCS#7 padding is performed during encryption, therefore newPinEnc is always 64 bytes long.
-
-
pinUvAuthParam:
LEFT(HMAC-SHA-256(sharedSecret, newPinEnc || pinHashEnc), 16)
.-
The platform sends the first 16 bytes of the HMAC-SHA-256 result.
-
-
-
Authenticator performs following operations upon receiving the request:
-
If Authenticator does not receive mandatory parameters for this command, it returns CTAP2_ERR_MISSING_PARAMETER error.
-
If the pinRetries counter is 0, return CTAP2_ERR_PIN_BLOCKED error.
-
Authenticator generates "sharedSecret": SHA-256((abG).x) using private key of authenticatorKeyAgreementKey, "a" and public key of platformKeyAgreementKey, "bG".
-
SHA-256 is done over only
"x"
curve point of"abG"
-
See [RFC6090] Section 4.1 and appendix (C.2) of [SP800-56A] for more ECDH key agreement protocol details and key representation.
-
-
Authenticator verifies pinUvAuthParam by generating
LEFT(HMAC-SHA-256(sharedSecret, newPinEnc || pinHashEnc), 16)
and matching against input pinUvAuthParam parameter.-
If pinUvAuthParam verification fails, authenticator returns CTAP2_ERR_PIN_AUTH_INVALID error.
-
-
Authenticator decrements the pinRetries counter by 1.
-
Authenticator decrypts pinHashEnc and verifies against its internal stored
LEFT(SHA-256(curPin), 16)
.-
If a mismatch is detected, the authenticator performs the following operations:
-
Authenticator generates a new "authenticatorKeyAgreementKey".
-
Generate a new ECDH P-256 key pair called "authenticatorKeyAgreementKey" denoted by
(a, aG)
, where"a"
denotes the private key and"aG"
denotes the public key.-
See [RFC6090] Section 4.1 and [SP800-56A] for more ECDH key agreement protocol details.
-
-
-
Authenticator returns errors according to following conditions:
-
If the pinRetries counter is 0, return CTAP2_ERR_PIN_BLOCKED error.
-
If the authenticator sees 3 consecutive mismatches, it returns CTAP2_ERR_PIN_AUTH_BLOCKED, indicating that power cycling is needed for further operations. This is done so that malware running on the platform should not be able to block the device without user interaction.
-
Else return CTAP2_ERR_PIN_INVALID error.
-
-
-
-
Authenticator sets the pinRetries counter to maximum value.
-
Authenticator decrypts newPinEnc using above "sharedSecret" producing newPin and checks newPin length against minimum PIN length of 4 bytes.
-
The decrypted padded newPin should be of at least 64 bytes length and authenticator determines actual PIN length by looking for first 0x00 byte which terminates the PIN.
-
If minimum PIN length check fails, authenticator returns CTAP2_ERR_PIN_POLICY_VIOLATION error.
-
Authenticator may have additional constraints for PIN policy. The current spec only enforces minimum length of 4 bytes.
-
-
Authenticator stores
LEFT(SHA-256(newPin), 16)
on the device. -
Authenticator generates a new pinToken.
-
Authenticator returns CTAP2_OK.
-
5.5.8. Getting pinUvAuthToken from the Authenticator
This step only has to be performed once for the lifetime of the authenticator/platform handle. Getting pinUvAuthToken once allows high security without any additional roundtrips every time (except for the first key-agreement phase) and its overhead is minimal.
Following operations are performed to get pinUvAuthToken:
-
Getting pinUvAuthToken using ClientPin:
-
Platform gets sharedSecret from the authenticator.
-
Platform collects PIN from the user.
-
Platform sends authenticatorClientPIN command with following parameters to the authenticator:
-
pinUvAuthProtocol: 0x01.
-
subCommand: getPinUvAuthTokenUsingPin(0x05).
-
keyAgreement: public key of platformKeyAgreementKey, "bG".
-
pinHashEnc:
AES256-CBC(sharedSecret, IV=0, LEFT(SHA-256(PIN),16))
.
-
-
Authenticator performs following operations upon receiving the request:
-
If Authenticator does not receive mandatory parameters for this command, it returns CTAP2_ERR_MISSING_PARAMETER error.
-
If the pinRetries counter is 0, return CTAP2_ERR_PIN_BLOCKED error.
-
Authenticator generates "sharedSecret":
SHA-256((abG).x)
using private key of authenticatorKeyAgreementKey, "a" and public key of platformKeyAgreementKey, "bG".-
SHA-256 is done over only
"x"
curve point of"abG"
-
See [RFC6090] Section 4.1 and appendix (C.2) of [SP800-56A] for more ECDH key agreement protocol details and key representation.
-
-
-
Authenticator decrements the pinRetries counter by 1.
-
Authenticator decrypts pinHashEnc and verifies against its internal stored
LEFT(SHA-256(curPin), 16)
.-
If a mismatch is detected, the authenticator performs the following operations:
-
Authenticator generates a new "authenticatorKeyAgreementKey".
-
Generate a new ECDH P-256 key pair called "authenticatorKeyAgreementKey" denoted by
(a, aG)
, where"a"
denotes the private key and"aG"
denotes the public key.-
See [RFC6090] Section 4.1 and [SP800-56A] for more ECDH key agreement protocol details.
-
-
-
Authenticator returns errors according to following conditions:
-
If the pinRetries counter is 0, return CTAP2_ERR_PIN_BLOCKED error.
-
If the authenticator sees 3 consecutive mismatches, it returns CTAP2_ERR_PIN_AUTH_BLOCKED, indicating that power cycling is needed for further operations. This is done so that malware running on the platform should not be able to block the device without user interaction.
-
Else return CTAP2_ERR_PIN_INVALID error.
-
-
-
-
Authenticator sets the pinRetries counter to maximum value.
-
Authenticator returns encrypted pinUvAuthToken using "sharedSecret":
AES256-CBC(sharedSecret, IV=0, pinUvAuthToken)
.-
pinUvAuthToken should be a multiple of 16 bytes (AES block length) without any padding or IV. There is no PKCS #7 padding used in this scheme.
-
-
-
-
Getting pinUvAuthToken using built-in user verification methods: This method is only applicable when authenticator supports built-in on-device user verification method like fingerprint or has a UI having its own protections. Specifically, authenticator MUST return "uv" and "uvToken" option set to true in authenticatorGetInfo. "uvToken" in authenticatorGetInfo signifies that authenticator support uvToken feature.
-
Platform gets sharedSecret from the authenticator.
-
Platform sends authenticatorClientPIN command with following parameters to the authenticator:
-
pinUvAuthProtocol: 0x01.
-
subCommand: getUvToken(0x06).
-
keyAgreement: public key of platformKeyAgreementKey, "bG".
-
-
Authenticator performs following operations upon receiving the request:
-
If Authenticator does not receive mandatory parameters for this command, it returns CTAP2_ERR_MISSING_PARAMETER error.
-
If User Verification is supported but not configured, the authenticator returns CTAP2_ERR_NOT_ALLOWED.
-
If the uvRetries counter is 0, return CTAP2_ERR_UV_BLOCKED error.
-
Authenticator generates "sharedSecret":
SHA-256((abG).x)
using private key of authenticatorKeyAgreementKey, "a" and public key of platformKeyAgreementKey, "bG". -
Authenticator decrements the uvRetries counter by 1.
-
Authenticator performs built in user verification.
-
If user verification fails, authenticator returns CTAP2_ERR_PIN_INVALID.
-
-
Authenticator sets the uvRetries counter to maximum value.
-
Authenticator returns encrypted authToken using "sharedSecret":
AES256-CBC(sharedSecret, IV=0, authToken)
.
-
-
5.5.9. Using pinUvAuthToken
Platform has the flexibility to manage the lifetime of pinUvAuthToken based on the scenario however it should get rid of the pinUvAuthToken as soon as possible when not required. Authenticator also can expire pinUvAuthToken based on certain conditions like changing a PIN, timeout happening on authenticator, machine waking up from a suspend state etc. If pinUvAuthToken has expired, authenticator will return CTAP2_ERR_PIN_TOKEN_EXPIRED and platform can act on the error accordingly.
5.5.9.1. Using pinUvAuthToken in authenticatorMakeCredential
Following operations are performed to use pinUvAuthToken in authenticatorMakeCredential API:
-
Platform gets pinUvAuthToken from the authenticator.
-
Platform sends authenticatorMakeCredential command with following additional optional parameter:
-
pinUvAuthProtocol: 0x01.
-
pinUvAuthParam:
LEFT(HMAC-SHA-256(pinUvAuthToken, clientDataHash), 16)
.-
The platform sends the first 16 bytes of the HMAC-SHA-256 result.
-
-
-
Authenticator verifies pinUvAuthParam by generating
LEFT(HMAC-SHA-256(pinUvAuthToken, clientDataHash), 16)
and matching against input pinUvAuthParam parameter.-
If pinUvAuthParam verification fails, authenticator returns CTAP2_ERR_PIN_AUTH_INVALID error.
-
If authenticator sees 3 consecutive mismatches, it returns CTAP2_ERR_PIN_AUTH_BLOCKED indicating that power recycle is needed for further operations. This is done so that malware running on the platform should not be able to block the device without user interaction.
-
-
Authenticator returns authenticatorMakeCredential response with "uv" bit set to 1.
If platform sends zero length pinUvAuthParam, authenticator needs to wait for user touch and then returns either CTAP2_ERR_PIN_NOT_SET if pin is not set or CTAP2_ERR_PIN_INVALID if pin has been set. This is done for the case where multiple authenticators are attached to the platform and the platform wants to enforce clientPin semantics, but the user has to select which authenticator to send the pinUvAuthToken to.
5.5.9.2. Using pinUvAuthToken in authenticatorGetAssertion
Following operations are performed to use pinUvAuthToken in authenticatorGetAssertion API:
-
Platform gets pinUvAuthToken from the authenticator.
-
Platform sends authenticatorGetAssertion command with following additional optional parameter:
-
pinUvAuthProtocol: 0x01.
-
pinUvAuthParam:
LEFT(HMAC-SHA-256(pinUvAuthToken, clientDataHash), 16)
.-
The platform sends the first 16 bytes of the HMAC-SHA-256 result.
-
-
-
Authenticator verifies pinUvAuthParam by generating
LEFT(HMAC-SHA-256(pinUvAuthToken, clientDataHash), 16)
and matching against input pinUvAuthParam parameter.-
If pinUvAuthParam verification fails, authenticator returns CTAP2_ERR_PIN_AUTH_INVALID error.
-
If authenticator sees 3 consecutive mismatches, it returns CTAP2_ERR_PIN_AUTH_BLOCKED indicating that power recycle is needed for further operations. This is done so that malware running on the platform should not be able to block the device without user interaction.
-
-
Authenticator returns authenticatorGetAssertion response with "uv" bit set to 1.
If platform sends zero length pinUvAuthParam, authenticator needs to wait for user touch and then returns either CTAP2_ERR_PIN_NOT_SET if pin is not set or CTAP2_ERR_PIN_INVALID if pin has been set. This is done for the case where multiple authenticators are attached to the platform and the platform wants to enforce clientPin semantics, but the user has to select which authenticator to send the pinUvAuthToken to.
5.5.9.3. Without pinUvAuthToken in authenticatorGetAssertion
Following operations are performed without using pinUvAuthToken in authenticatorGetAssertion API:
-
Platform sends authenticatorGetAssertion command without pinUvAuthParam optional parameter.
-
Authenticator returns authenticatorGetAssertion response with "uv" bit set to 0.
5.6. authenticatorReset (0x07)
This method is used by the client to reset an authenticator back to a factory default state, invalidating all generated credentials and any configuration maps. In order to prevent accidental trigger of this mechanism, user presence is required. In case of authenticators with no display, request MUST have come to the authenticator within 10 seconds of powering up of the authenticator
If all conditions are met, authenticator returns CTAP2_OK. If user presence is explicitly denied, authenticator returns CTAP2_ERR_OPERATION_DENIED. If timeout happens, authenticator returns CTAP2_ERR_USER_ACTION_TIMEOUT. If request comes after 10 seconds of powering up, authenticator returns CTAP2_ERR_NOT_ALLOWED.
A platform SHOULD perform the following actions to invoke this command. (It may choose not to based on explicit user intent, i.e. if it’s an administrative tool that wishes to also erase all configuration.)
-
If the authenticator does not list “config” in the
options
field of the response to an authenticatorGetInfo command:-
Issue the
authenticatorReset
command. -
This process is complete.
-
-
Use the authenticatorConfig command, and the
get
field of its input, to fetch the current authenticator and platform config maps. -
If the platform config map is empty, or is ill-formed, or does not contain the key
resetPreserve
:-
Issue the
authenticatorReset
command. -
This process is complete.
-
-
Construct a new authenticator config map by making a copy of the current authenticator config map and then erasing all keys not listed in the value of resetPreserve.
-
Construct a new platform config map by making a copy of the current platform config map and then erasing all keys not listed in the value of resetPreserve.
-
Issue the
authenticatorReset
command. -
If the reset command was successful:
-
Use the authenticatorConfig command, and the
set
field of its input, to write the updated authenticator and platform config maps.
-
Note: Resetting the device clears any configured user verification and thus the authenticatorConfig command will complete without additional user interaction.
5.7. authenticatorBioEnrollment (0x09)
This command is used by the platform to provision/enumerate/delete bio enrollments in the authenticator.
It takes the following input parameters:
Parameter name | Data type | Required? | Definition |
---|---|---|---|
modality (0x01) | Unsigned Integer | Optional | The user verification modality being requested |
subCommand (0x02) | Unsigned Integer | Optional | The authenticator user verification sub command currently being requested |
subCommandParams (0x03) | CBOR Map | Optional | Map of subCommands parameters. This parameter is optional and may be omitted when the subCommand does not take any arguments. |
pinUvAuthProtocol (0x04) | Unsigned Integer | Optional | PIN/UV protocol version chosen by the client. For this version of the spec, this SHALL be the number 1. |
pinUvAuthParam (0x05) | Byte Array | Optional | First 16 bytes of HMAC-SHA-256 of contents using pinUvAuthToken. |
getModality (0x06) | Boolean | Optional | Get the user verification type modality. This MUST be set to true. |
The type of modalities supported are as under:
modality Name | modality Number |
---|---|
fingerprint | 0x01 |
The list of sub commands for fingerprint(0x01) modality is:
subCommand Name | subCommand Number |
---|---|
enrollBegin | 0x01 |
enrollCaptureNextSample | 0x02 |
cancelCurrentEnrollment | 0x03 |
enumerateEnrollments | 0x04 |
setFriendlyName | 0x05 |
removeEnrollment | 0x06 |
getFingerprintSensorInfo | 0x07 |
subCommandParams Fields:
Field name | Data type | Required? | Definition |
---|---|---|---|
templateId (0x01) | Byte Array | Optional | Template Identifier. |
templateFriendlyName (0x02) | String | Optional | Template Friendly Name. |
timeoutMilliseconds (0x03) | Unsigned Integer | Optional | Timeout in milliSeconds. |
On success, authenticator returns the following structure in its response:
Parameter name | Data type | Required? | Definition |
---|---|---|---|
modality (0x01) | Unsigned Integer | Optional | The user verification modality. |
fingerprintKind (0x02) | Unsigned Integer | Optional | Indicates the type of fingerprint sensor. For touch type sensor, its value is 1. For swipe type sensor its value is 2. |
maxCaptureSamplesRequiredForEnroll (0x03) | Unsigned Integer | Optional | Indicates the maximum good samples required for enrollment. |
templateId (0x04) | Byte Array | Optional | Template Identifier. |
lastEnrollSampleStatus (0x05) | Unsigned Integer | Optional | Last enrollment sample status. |
remainingSamples (0x06) | Unsigned Integer | Optional | Number of more sample required for enrollment to complete |
templateInfos (0x07) | CBOR ARRAY | Optional | Sequence of templateInfo’s |
TemplateInfo definition:
Field name | Data type | Required? | Definition |
---|---|---|---|
templateId (0x01) | Byte Array | Required | Template Identifier. |
templateFriendlyName (0x02) | String | Optional | Template Friendly Name. |
lastEnrollSampleStatus types:
lastEnrollSampleStatus Name | lastEnrollSampleStatus Value | Definition |
---|---|---|
CTAP2_ENROLL_FEEDBACK_FP_GOOD | 0x00 | Good fingerprint capture. |
CTAP2_ENROLL_FEEDBACK_FP_TOO_HIGH | 0x01 | Fingerprint was too high. |
CTAP2_ENROLL_FEEDBACK_FP_TOO_LOW | 0x02 | Fingerprint was too low. |
CTAP2_ENROLL_FEEDBACK_FP_TOO_LEFT | 0x03 | Fingerprint was too left. |
CTAP2_ENROLL_FEEDBACK_FP_TOO_RIGHT | 0x04 | Fingerprint was too right. |
CTAP2_ENROLL_FEEDBACK_FP_TOO_FAST | 0x05 | Fingerprint was too fast. |
CTAP2_ENROLL_FEEDBACK_FP_TOO_SLOW | 0x06 | Fingerprint was too slow. |
CTAP2_ENROLL_FEEDBACK_FP_POOR_QUALITY | 0x07 | Fingerprint was of poor quality. |
CTAP2_ENROLL_FEEDBACK_FP_TOO_SKEWED | 0x08 | Fingerprint was too skewed. |
CTAP2_ENROLL_FEEDBACK_FP_TOO_SHORT | 0x09 | Fingerprint was too short. |
CTAP2_ENROLL_FEEDBACK_FP_MERGE_FAILURE | 0x0A | Merge failure of the capture. |
CTAP2_ENROLL_FEEDBACK_FP_EXISTS | 0x0B | Fingerprint already exists. |
CTAP2_ENROLL_FEEDBACK_FP_DATABASE_FULL | 0x0C | Fingerprint database storage is full. |
CTAP2_ENROLL_FEEDBACK_NO_USER_ACTIVITY | 0x0D | User did not touch/swipe the authenticator. |
CTAP2_ENROLL_FEEDBACK_NO_USER_PRESENCE_TRANSITION | 0x0E | User did not lift the finger off the sensor. |
5.7.1. Feature detection
To detect whether authenticator supports this preview feature, following conditions MUST be met:
-
Authenticator MUST return "FIDO_2_1_PRE" in authenticatorGetInfo as one of version it supports.
Note: "FIDO_2_1_PRE" is a placeholder till we decide what the final spec version string in authenticatorGetInfo will look like in next version of the spec.
-
Authenticator MUST return "bioEnroll" in options fields of authenticatorGetInfo.
-
Presence of this key indicates that the authenticator supports authenticatorBioEnrollment commands.
-
True value indicates that authenticator has atleast one bio enrollment already provisioned.
-
False value indicates that authenticator has not been provisioned with any bio enrollment yet.
-
-
For this feature, authenticatorBioEnrollment command MUST be 0x09.
5.7.2. Get bio modality
Following operations are performed to get bio modality supported by the authenticator:
-
Platform sends authenticatorBioEnrollment command with following parameters:
-
getModality (0x06): true.
-
-
Authenticator returns authenticatorBioEnrollment response with following parameters:
-
modality (0x01): It represents the type of modality authenticator supports. For fingerprint, its value is 1.
-
5.7.3. Get fingerprint sensor info
Following operations are performed to get fingerprint sensor information:
-
Platform sends authenticatorBioEnrollment command with following parameters:
-
modality (0x01): fingerprint (0x01).
-
subCommand (0x02): getFingerprintSensorInfo (0x07)
-
-
Authenticator returns authenticatorBioEnrollment response with following parameters:
-
fingerprintKind (0x02):
-
For touch type fingerprints, its value is 1.
-
For swipe type fingerprints, its value is 2.
-
-
maxCaptureSamplesRequiredForEnroll (0x03): Indicates the maximum good samples required for enrollment.
-
5.7.4. Enrolling fingerprint
Following operations are performed to enroll a fingerprint:
-
Platform gets pinUvAuthToken from the authenticator.
-
Platform sends authenticatorBioEnrollment command with following parameters to begin the enrollment:
-
modality (0x01): fingerprint (0x01).
-
subCommand (0x02): enrollBegin (0x01).
-
subCommandParams (0x03): Map containing following parameters
-
timeoutMilliseconds (0x03) (optional): timeout in milliseconds
-
-
pinUvAuthProtocol (0x04): Pin Protocol used. Currently this is 0x01.
-
pinUvAuthParam (0x05):
LEFT(HMAC-SHA-256(pinUvAuthToken, fingerprint (0x01) || enrollBegin (0x01) || subCommandParams), 16)
.
-
-
Authenticator on receiving such request performs following procedures.
-
Authenticator verifies pinUvAuthParam by generating
LEFT(HMAC-SHA-256(pinUvAuthToken, fingerprint (0x01) || enrollBegin (0x01) || subCommandParams), 16)
and matching against input pinUvAuthParam parameter.-
Authenticator does same semantics checks for pinUvAuthParam protection as done in authenticatorClientPin command.
-
If there is no space available, authenticator returns CTAP2_ERR_KEY_STORE_FULL.
-
-
Authenticator cancels any unfinished ongoing enrollment.
-
Authenticator generates templateId for new enrollment.
-
Authenticator sends the command to the sensor to capture the sample.
-
Authenticator returns authenticatorBioEnrollment response with following parameters:
-
templateId (0x04): template identifier of the new template being enrolled.
-
lastEnrollSampleStatus (0x05) : Status of enrollment of last sample.
-
remainingSamples (0x06) : Number of sample remaining to complete the enrollment.
-
-
-
Platform sends authenticatorBioEnrollment command with following parameters to continue enrollment in a loop till remainingSamples is zero or authenticator errors out with unrecoverable error or platform wants to cancel current enrollment:
-
Platform sends authenticatorBioEnrollment command with following parameters
-
modality (0x01): fingerprint (0x01).
-
subCommand (0x02): enrollCaptureNextSample (0x02).
-
subCommandParams (0x03): Map containing following parameters
-
templateId (0x01) : template identifer platform received from enrollBegin subCommand.
-
timeoutMilliseconds (0x03) (optional): timeout in milliseconds
-
-
pinUvAuthProtocol (0x04): Pin Protocol used. Currently this is 0x01.
-
pinUvAuthParam (0x05):
LEFT(HMAC-SHA-256(pinUvAuthToken, fingerprint (0x01) || enrollCaptureNextSample (0x02) || subCommandParams), 16)
.
-
-
Authenticator on receiving such request performs following procedures.
-
Authenticator verifies pinUvAuthParam by generating
LEFT(HMAC-SHA-256(pinUvAuthToken, fingerprint (0x01) || enrollBegin (0x01) || subCommandParams), 16)
and matching against input pinUvAuthParam parameter.-
Authenticator does same semantics checks for pinUvAuthParam protection as done in authenticatorClientPin command.
-
If there is no space available, authenticator returns CTAP2_ERR_KEY_STORE_FULL.
-
-
If fingerprint is already present on the sensor, authenticator waits for user to lift finger from the sensor.
-
Authenticator sends the command to the sensor to capture the sample.
-
Authenticator returns authenticatorBioEnrollment response with following parameters:
-
lastEnrollSampleStatus (0x05) : Status of enrollment of last sample.
-
remainingSamples (0x06) : Number of sample remaining to complete the enrollment.
-
-
-
5.7.5. Cancel current enrollment
Following operations are performed to cancel current enrollment:
-
Platform sends authenticatorBioEnrollment command with following parameters:
-
modality (0x01): fingerprint (0x01).
-
subCommand (0x02): cancelCurrentEnrollment (0x03).
-
-
Authenticator on receiving such command, cancels currnet ongoing enrollment, if any, and returns CTAP2_OK.
5.7.6. Enumerate enrollments
Following operations are performed to enumerate enrollments:
-
Platform gets pinUvAuthToken from the authenticator.
-
Platform sends authenticatorBioEnrollment command with following parameters:
-
modality (0x01): fingerprint (0x01).
-
subCommand (0x02): enumerateEnrollments (0x04).
-
pinUvAuthProtocol (0x04): Pin Protocol used. Currently this is 0x01.
-
pinUvAuthParam (0x05):
LEFT(HMAC-SHA-256(pinUvAuthToken, fingerprint (0x01) || enumerateEnrollments (0x04)), 16)
.
-
-
Authenticator verifies pinUvAuthParam by generating
LEFT(HMAC-SHA-256(pinUvAuthToken, enumerateEnrollments (0x04)), 16)
and matching against input pinUvAuthParam parameter.-
Authenticator does same semantics checks for pinUvAuthParam protection as done in authenticatorClientPin command.
-
If there are no enrollments existing on authenticator, it returns CTAP2_ERR_INVALID_OPTION.
-
-
Authenticator returns authenticatorBioEnrollment response following parameters:
-
templateInfos (0x07) : Sequence of templateInfo’s for all the enrollments available on the authenticator.
-
5.7.7. Rename/Set FriendlyName
Following operations are performed to rename a fingerprint:
-
Platform gets pinUvAuthToken from the authenticator.
-
Platform sends authenticatorBioEnrollment command with following parameters:
-
modality (0x01): fingerprint (0x01).
-
subCommand (0x02): setFriendlyName (0x05).
-
subCommandParams (0x03): Map containing following parameters
-
templateId (0x01) : template identifer.
-
templateFriendlyName (0x02): Friendly name of the template
-
-
pinUvAuthProtocol (0x04): Pin Protocol used. Currently this is 0x01.
-
pinUvAuthParam (0x05):
LEFT(HMAC-SHA-256(pinUvAuthToken, fingerprint (0x01) || setFriendlyName (0x05) || subCommandParams), 16)
.
-
-
Authenticator verifies pinUvAuthParam by generating
LEFT(HMAC-SHA-256(pinUvAuthToken, fingerprint (0x01) || setFriendlyName (0x05) || subCommandParams), 16)
and matching against input pinUvAuthParam parameter.-
Authenticator does same semantics checks for pinUvAuthParam protection as done in authenticatorClientPin command.
-
If there are no enrollments existing on authenticator for the passed templateId, it returns CTAP2_ERR_INVALID_OPTION.
-
If there is an existing enrollment with that identifier, rename its friendly name and return CTAP2_OK.
-
5.7.8. Remove enrollment
Following operations are performed to remove a fingerprint:
-
Platform gets pinUvAuthToken from the authenticator.
-
Platform sends authenticatorBioEnrollment command with following parameters:
-
modality (0x01): fingerprint (0x01).
-
subCommand (0x02): removeEnrollment (0x06).
-
subCommandParams (0x03): Map containing following parameters
-
templateId (0x01) : template identifer.
-
-
pinUvAuthProtocol (0x04): Pin Protocol used. Currently this is 0x01.
-
pinUvAuthParam (0x05):
LEFT(HMAC-SHA-256(pinUvAuthToken, fingerprint (0x01) || removeEnrollment (0x05) || subCommandParams), 16)
.
-
-
Authenticator verifies pinUvAuthParam by generating
LEFT(HMAC-SHA-256(pinUvAuthToken, fingerprint (0x01) || removeEnrollment (0x05) || subCommandParams), 16)
and matching against input pinUvAuthParam parameter.-
Authenticator does same semantics checks for pinUvAuthParam protection as done in authenticatorClientPin command.
-
If there are no enrollments existing on authenticator for passed templateId, it returns CTAP2_ERR_INVALID_OPTION.
-
If there is an exiting enrollment with passed in templateInfo, delete that enrollment and return CTAP2_OK.
-
5.8. authenticatorCredentialManagement (0x0A)
This command is used by the platform to manage resident credentials on the authenticator.
It takes the following input parameters:
Parameter name | Data type | Definition |
---|---|---|
subCommand (0x01) | Unsigned Integer | subCommand currently being requested |
subCommandParams (0x02) | CBOR Map | Map of subCommands parameters. |
pinUvAuthProtocol (0x03) | Unsigned Integer | PIN/UV protocol version chosen by the client. |
pinUvAuthParam (0x04) | Byte Array | First 16 bytes of HMAC-SHA-256 of contents using pinUvAuthToken. |
The list of sub commands for credential management is:
subCommand Name | subCommand Number |
---|---|
getCredsMetadata | 0x01 |
enumerateRPsBegin | 0x02 |
enumerateRPsGetNextRP | 0x03 |
enumerateCredentialsBegin | 0x04 |
enumerateCredentialsGetNextCredential | 0x05 |
deleteCredential | 0x06 |
subCommandParams Fields:
Field name | Data type | Definition |
---|---|---|
rpIDHash (0x01) | Byte Array | RPID SHA-256 hash |
credentialID (0x02) | PublicKeyCredentialDescriptor | Credential Identifier |
On success, authenticator returns the following structure in its response:
Parameter name | Data type | Definition |
---|---|---|
existingResidentCredentialsCount (0x01) | Unsigned Integer | Number of existing resident credentials present on the authenticator. |
maxPossibleRemainingResidentCredentialsCount (0x02) | Unsigned Integer | Number of maximum possible remaining resident credentials which can be created on the authenticator. |
rp (0x03) | PublicKeyCredentialRpEntity | RP Information |
rpIDHash (0x04) | Byte Array | RPID SHA-256 hash |
totalRPs (0x05) | Unsigned Integer | total number of RPs present on the authenticator |
user (0x06) | PublicKeyCredentialUserEntity | User Information |
credentialID (0x07) | PublicKeyCredentialDescriptor | PublicKeyCredentialDescriptor |
publicKey (0x08) | COSE_Key | Public key of the credential. |
totalCredentials (0x09) | Unsigned Integer | Total number of credentials present on the authenticator for the RP in question |
credProtect (0x0A) | Unsigned Integer | Credential protection policy. |
5.8.1. Feature detection
To detect whether authenticator supports this preview feature, following conditions MUST be met:
-
Authenticator MUST return "FIDO_2_1_PRE" in authenticatorGetInfo as one of the version it supports in addition to "FIDO_2_0".
Note: "FIDO_2_1_PRE" is a placeholder till we decide what the final spec version string in authenticatorGetInfo will look like in next version of the spec.
-
Authenticator MUST return "credMgmt" in options fields of authenticatorGetInfo and it MUST be set to true.
-
For this feature, authenticatorCredentialManagement command MUST be 0x0A.
5.8.2. Getting Credentials Metadata
Following operations are performed to get credentials metadata information :
-
Platform gets pinUvAuthToken from the authenticator.
-
Platform sends authenticatorCredentialManagement command with following parameters:
-
subCommand (0x01): getCredsMetadata (0x01).
-
pinUvAuthProtocol (0x03): Pin Protocol used. Currently this is 0x01.
-
pinUvAuthParam (0x04):
LEFT(HMAC-SHA-256(pinUvAuthToken, getCredsMetadata (0x01)), 16)
.
-
-
Authenticator verifies pinUvAuthParam by generating
LEFT(HMAC-SHA-256(pinUvAuthToken, getCredsMetadata (0x01)), 16)
and matching against input pinUvAuthParam parameter.-
If pinUvAuthParam verification fails, authenticator returns CTAP2_ERR_PIN_AUTH_INVALID error.
-
If authenticator sees 3 consecutive mismatches, it returns CTAP2_ERR_PIN_AUTH_BLOCKED indicating that power recycle is needed for further operations. This is done so that malware running on the platform should not be able to block the device without user interaction.
-
-
Authenticator returns authenticatorCredentialManagement response with following parameters:
-
existingResidentCredentialsCount (0x01) : total number of resident credentials existing on the authenticator.
-
maxPossibleRemainingResidentCredentialsCount (0x02) : maximum number of possible remaining credentials that can be created on the authetenticator. Note that this number is an estimate as actual space consumed to create a credential depends on various conditions such as which algorithm is picked, user entity information etc.
-
5.8.3. Enumerating RPs
Following operations are performed to enumerate RPs present on the authenticator:
-
Platform gets pinUvAuthToken from the authenticator.
-
Platform sends authenticatorCredentialManagement command with following parameters:
-
subCommand (0x01): enumerateRPsBegin (0x02).
-
pinUvAuthProtocol (0x03): Pin Protocol used. Currently this is 0x01.
-
pinUvAuthParam (0x04):
LEFT(HMAC-SHA-256(pinUvAuthToken, enumerateRPsBegin (0x02)), 16)
.
-
-
Authenticator verifies pinUvAuthParam by generating
LEFT(HMAC-SHA-256(pinUvAuthToken, enumerateRPsBegin (0x02)), 16)
and matching against input pinUvAuthParam parameter.-
If pinUvAuthParam verification fails, authenticator returns CTAP2_ERR_PIN_AUTH_INVALID error.
-
If authenticator sees 3 consecutive mismatches, it returns CTAP2_ERR_PIN_AUTH_BLOCKED indicating that power recycle is needed for further operations. This is done so that malware running on the platform should not be able to block the device without user interaction.
-
-
Authenticator returns authenticatorCredentialManagement response with following parameters:
-
rp (0x03): PublicKeyCredentialRpEntity
-
rpIDHash (0x04) : RP ID SHA-256 hash.
-
totalRPs (0x05) : Total number of RPs present on the authenticator.
-
-
Platform on receiving more than 1 totalRPs, performs following procedure for (totalRPs - 1 ) number of times:
-
Platform sends authenticatorCredentialManagement command with following parameters:
-
subCommand (0x01): enumerateRPsGetNextRP (0x03).
-
-
Authenticator on receiving such enumerateCredentialsGetNext subCommand returns authenticatorCredentialManagement response with following parameters:
-
rp (0x03): PublicKeyCredentialRpEntity
-
rpIDHash (0x04) : RP ID SHA-256 hash.
-
-
5.8.4. Enumerating Credentials for an RP
Following operations are performed to enumerate credentials for an RP:
-
Platform gets pinUvAuthToken from the authenticator.
-
Platform sends authenticatorCredentialManagement command with following parameters:
-
subCommand (0x01): enumerateCredentialsBegin (0x04).
-
subCommandParams (0x03): Map containing following parameters
-
rpIDHash (0x01): RPID SHA-256 hash.
-
-
pinUvAuthProtocol (0x03): Pin Protocol used. Currently this is 0x01.
-
pinUvAuthParam (0x04):
LEFT(HMAC-SHA-256(pinUvAuthToken, enumerateCredentialsBegin (0x04) || subCommandParams), 16)
.
-
-
Authenticator verifies pinUvAuthParam by generating
LEFT(HMAC-SHA-256(pinUvAuthToken, enumerateCredentialsBegin (0x04) || subCommandParams), 16)
and matching against input pinUvAuthParam parameter.-
If pinUvAuthParam verification fails, authenticator returns CTAP2_ERR_PIN_AUTH_INVALID error.
-
If authenticator sees 3 consecutive mismatches, it returns CTAP2_ERR_PIN_AUTH_BLOCKED indicating that power recycle is needed for further operations. This is done so that malware running on the platform should not be able to block the device without user interaction.
-
If no credentials were found for this RPID hash, authenticator returns CTAP2_ERR_NO_CREDENTIALS.
-
-
Authenticator returns authenticatorCredentialManagement response with following parameters:
-
user (0x06): PublicKeyCredentialUserEntity
-
credentialID (0x07): PublicKeyCredentialDescriptor
-
publicKey (0x08): public key of the credential in COSE_Key format
-
totalCredentials (0x09): total number of credentials for this RP
-
credProtect (0x0A): credential protection policy
-
-
Platform on receiving more than 1 totalCredentials, performs following procedure for (totalCredentials - 1 ) number of times:
-
Platform sends authenticatorCredentialManagement command with following parameters:
-
subCommand (0x01): enumerateCredentialsGetNextCredential (0x05).
-
-
Authenticator on receiving such enumerateCredentialsGetNext subCommand returns with following parameters:
-
user (0x06): PublicKeyCredentialUserEntity
-
credentialID (0x07): PublicKeyCredentialDescriptor
-
publicKey (0x08): public key of the credential in COSE_Key format
-
credProtect (0x0A): credential protection policy
-
-
5.8.5. DeleteCredential
Following operations are performed to delete a credential:
-
Platform gets pinUvAuthToken from the authenticator.
-
Platform sends authenticatorCredentialManagement command with following parameters:
-
subCommand (0x01): deleteCredential (0x06).
-
subCommandParams (0x02): Map containing following parameters
-
credentialsId (0x02): PublicKeyCredentialDescriptor of the credential to be deleted.
-
-
pinUvAuthProtocol (0x03): Pin Protocol used. Currently this is 0x01.
-
pinUvAuthParam (0x04):
LEFT(HMAC-SHA-256(pinUvAuthToken, deleteCredential (0x06) || subCommandParams), 16)
.
-
-
Authenticator verifies pinUvAuthParam by generating
LEFT(HMAC-SHA-256(pinUvAuthToken, deleteCredential (0x03) || subCommandParams), 16)
and matching against input pinUvAuthParam parameter.-
If pinUvAuthParam verification fails, authenticator returns CTAP2_ERR_PIN_AUTH_INVALID error.
-
If authenticator sees 3 consecutive mismatches, it returns CTAP2_ERR_PIN_AUTH_BLOCKED indicating that power recycle is needed for further operations. This is done so that malware running on the platform should not be able to block the device without user interaction.
-
If there are not credential existing matching credentialDescriptor, return CTAP2_ERR_NO_CREDENTIALS.
-
Delete the credential and return CTAP2_OK.
-
5.9. authenticatorSelection (0x0B)
This command allows the platform to let a user select a certain authenticator by asking for user presence.
The command has no input parameters.
When the authenticatorSelection command is received, the authenticator will ask for user presence:
-
If User Presence is received, the authenticator will return CTAP2_OK.
-
If User Presence is explicitly denied by the user, the authenticator will return CTAP2_ERR_OPERATION_DENIED. The platform SHOULD NOT repeat the command for this authenticator.
-
If a timeout occurs, the authenticator will return CTAP2_ERR_USER_ACTION_TIMEOUT. The platform MAY repeat the command for this authenticator.
If an authenticator is selected, the platform SHOULD send a cancel to all other authenticators.
5.10. authenticatorConfig (0x0C)
This command allows at least 1024 bytes of configuration information to be stored on CTAP2 authenticators. The configuration is split into two maps: the authenticator config map and the platform config map. Both have string keys and arbitrary value types. They differ in that the platform config map is opaque to the authenticator, which simply acts as storage for it, while the authenticator config map is parsed and understood by the authenticator. Platforms are able to get and set both maps and accommodation is made to guide platforms in preserving some keys across authenticator resets.
For the purposes of this command, the two maps are serialized together as a two-element CBOR array, the first element being the authenticator config map and the second being the platform config map. This conjuction is referred to as the serialized config map array. (Authenticators need not use this format for storage internally, however.)
Platforms MUST NOT invoke this command unless the authenticator lists “config” in the options
field, and “FIDO_2_1_PRE” in the versions
field, of the response to an authenticatorGetInfo command.
Note: “FIDO_2_1_PRE” is a placeholder till we decide what the final spec version string in authenticatorGetInfo will look like in next version of the spec.
The command takes the following input parameters:
Parameter name | Data type | Required? | Notes |
---|---|---|---|
get (0x01) | Boolean | Optional | MUST be omitted unless the value is true . MUST NOT be present if set is present.
|
set (0x02) | Byte String | Optional | MUST NOT be present if get is present.
|
pinUvAuthParam (0x03) | Byte String | Optional | LEFT(HMAC-SHA-256(pinUvAuthToken, 32×0xff ⧺ h’0c00' ⧺ contents of set byte string, i.e. not including an outer CBOR tag with major type two), 16)
|
pinUvAuthProtocol (0x04) | Unsigned integer | Optional | PIN/UV protocol version chosen by the client. For this version of the spec, this SHALL be the number 1. |
An authenticator performs the following actions upon receipt of this command:
-
If neither
get
norset
are present in the input map, return CTAP1_ERR_INVALID_PARAMETER. -
If both
get
andset
are present in the input map, return CTAP1_ERR_INVALID_PARAMETER. -
If
get
is present in the input map:-
If the value of
get
isfalse
, return CTAP1_ERR_INVALID_PARAMETER. -
Return a CBOR map, as defined below, where the value of
config
is the serialized config map array set on the device, or the byte string82a0a0
if no such value has been set.
-
-
Else (implying that
set
is present in the input map):-
If the length of the value of
set
is greater than 1024 bytes and exceeds the capacity of the device, return CTAP2_ERR_KEY_STORE_FULL. (Authenticators MUST be capable of storing at least 1024 bytes.) -
If the authenticator is protected by some form of user verification:
-
If either of
pinUvAuthParam
orpinUvAuthProtocol
are missing from the input map, return CTAP2_ERR_OPERATION_DENIED. -
If
pinUvAuthProtocol
is not 1, return CTAP2_ERR_PIN_AUTH_INVALID. -
Perform the same validation as specified for getting an assertion, but where the byte string 32×0xff ⧺ h’0c00', followed by the value of
set
, is the input to HMAC. Return error codes on failure as specified.
-
-
Parse the value of
set
as a two-element CBOR array where the elements are the authenticator and platform config maps, respectively. Parse the authenticator config map and verify that every key/value pair contained is valid and understood by the authenticator. If parsing fails, return CTAP1_ERR_INVALID_PARAMETER. If an unknown key is present in the authenticator config map, return CTAP2_ERR_UNSUPPORTED_OPTION. -
Store the value of
set
as the serialized config map array for this authenticator. -
Return CTAP2_OK and an empty response.
-
Note: user verification is only checked above if user verification is configured on a device. This implies that the config can be written without user verification or user presence if user verification is not configured. Firstly, this allows the resetPreserve
command, below, to function because no user verification will be configured after a reset. Secondly, it allows organisations to write configurations suitable for their environment to authenticators before distributing them to users.
The response to a get
request, referenced above, takes the following form:
Parameter name | Data type | Required? | Notes |
---|---|---|---|
config (0x01) | Byte String | Required | Contains the serialized config map array. |
An authenticator MUST NOT act on the contents of the platform configuration map: it is purely for platforms to adjust their behavior in response to.
Authenticators MUST set the serialized config map array to the byte string 82a0a0
when reset. (These bytes are the CBOR serialisation of a two-element array containing two empty maps.)
Note: The platform may effectively preserve parts of the config maps across resets. See § 5.6 authenticatorReset (0x07) for details.
Platforms MUST ensure that the value of any set
field is a two-element CBOR array where each element is a map where all keys are strings, all encoded using the canonical rules. Platforms SHOULD take care to preserve existing entries in config maps. For example, platforms should read and insert values into the existing maps as opposed to blindly writing a fresh map.
Platforms MUST NOT set keys in the authenticator config map unless they have reason to believe that the authenticator will understand them. The definition of each key may define ways (such as indications in the response to an authenticatorGetInfo command) for an authenticator to signal this.
The semantics of particular keys in a specific map are defined in the following sections:
5.10.1. resetPreserve
The value of any platform config map entry with the key resetPreserve
MUST be an array of strings. The array MUST NOT have duplicate values and MUST be ordered lexicographically by UTF-8 encoding (prior to CBOR encoding).
The elements of the array are keys in the authenticator and platform config maps that should be preserved by the platform across resets. Details are specified in the description of the authenticatorReset command.
6. Message Encoding
Many transports (e.g., Bluetooth Smart) are bandwidth-constrained, and serialization formats such as JSON are too heavy-weight for such environments. For this reason, all encoding is done using the concise binary encoding CBOR [RFC7049].
To reduce the complexity of the messages and the resources required to parse and validate them, all messages MUST use the CTAP2 canonical CBOR encoding form as specified below, which differs from the canonicalization suggested in Section 3.9 of [RFC7049]. All encoders MUST serialize CBOR in the CTAP2 canonical CBOR encoding form without duplicate map keys. All decoders SHOULD reject CBOR that is not validly encoded in the CTAP2 canonical CBOR encoding form and SHOULD reject messages with duplicate map keys.
The CTAP2 canonical CBOR encoding form uses the following rules:
-
Integers must be encoded as small as possible.
-
0 to 23 and -1 to -24 must be expressed in the same byte as the major type;
-
24 to 255 and -25 to -256 must be expressed only with an additional uint8_t;
-
256 to 65535 and -257 to -65536 must be expressed only with an additional uint16_t;
-
65536 to 4294967295 and -65537 to -4294967296 must be expressed only with an additional uint32_t.
-
-
The representations of any floating-point values are not changed.
-
The expression of lengths in major types 2 through 5 must be as short as possible. The rules for these lengths follow the above rule for integers.
-
Indefinite-length items must be made into definite-length items.
-
The keys in every map must be sorted lowest value to highest. The sorting rules are:
-
If the major types are different, the one with the lower value in numerical order sorts earlier.
-
If two keys have different lengths, the shorter one sorts earlier;
-
If two keys have the same length, the one with the lower value in (byte-wise) lexical order sorts earlier.
Note: These rules are equivalent to a lexicographical comparison of the canonical encoding of keys for major types 0-3 and 7 (integers, strings, and simple values). They differ for major types 4-6 (arrays, maps, and tags), which CTAP2 does not use as keys in maps. These rules should be revisited if CTAP2 does start using the complex major types as keys.
-
-
Tags as defined in Section 2.4 in [RFC7049] MUST NOT be present.
Because some authenticators are memory constrained, the depth of nested CBOR structures used by all message encodings is limited to at most four (4) levels of any combination of CBOR maps and/or CBOR arrays. Authenticators MUST support at least 4 levels of CBOR nesting. Clients, platforms, and servers MUST NOT use more than 4 levels of CBOR nesting.
Likewise, because some authenticators are memory constrained, the maximum message size supported by an authenticator MAY be limited. By default, authenticators MUST support messages of at least 1024 bytes. Authenticators MAY declare a different maximum message size supported using the maxMsgSize authenticatorGetInfo result parameter. Clients, platforms, and servers MUST NOT send messages larger than 1024 bytes unless the authenticator’s maxMsgSize indicates support for the larger message size. Authenticators MAY return the CTAP2_ERR_REQUEST_TOO_LARGE error if size or memory constraints are exceeded.
If map keys are present that an implementation does not understand, they MUST be ignored. Note that this enables additional fields to be used as new features are added without breaking existing implementations.
Messages from the host to authenticator are called "commands" and messages from authenticator to host are called "replies". All values are big endian encoded.
Authenticators SHOULD return the CTAP2_ERR_INVALID_CBOR error if received CBOR does not conform to the requirements above.
6.1. Commands
All commands are structured as:
Name | Length | Required? | Definition |
---|---|---|---|
Command Value | 1 byte | Required | The value of the command to execute |
Command Parameters | variable | Optional | CBOR [RFC7049] encoded set of parameters. Some commands have parameters, while others do not (see below) |
The assigned values for commands and their descriptions are:
Command Name | Command Value | Has parameters? |
---|---|---|
authenticatorMakeCredential | 0x01 | yes |
authenticatorGetAssertion | 0x02 | yes |
authenticatorGetInfo | 0x04 | no |
authenticatorClientPIN | 0x06 | yes |
authenticatorReset | 0x07 | no |
authenticatorGetNextAssertion | 0x08 | no |
authenticatorBioEnrollment | 0x09 | yes |
authenticatorCredentialManagement | 0x0A | yes |
authenticatorPlatformConfig | 0x0c | yes |
authenticatorVendorFirst | 0x40 | NA |
Vendor - Bio Enrollment Prototype | 0x40 | yes |
Vendor - Credential Management Prototype | 0x41 | yes |
authenticatorVendorLast | 0xBF | NA |
Command codes in the range between authenticatorVendorFirst and authenticatorVendorLast may be used for vendor-specific implementations. For example, the vendor may choose to put in some testing commands. Note that the FIDO client will never generate these commands. All other command codes are reserved for future use and may not be used.
Command parameters are encoded using a CBOR map (CBOR major type 5). The CBOR map must be encoded using the definite length variant.
Some commands have optional parameters. Therefore, the length of the parameter map for these commands may vary. For example, authenticatorMakeCredential may have 4, 5, 6, or 7 parameters, while authenticatorGetAssertion may have 2, 3, 4, or 5 parameters.
All command parameters are CBOR encoded following the JSON to CBOR conversion procedures as per the CBOR specification [RFC7049]. Specifically, parameters that are represented as DOM objects in the Authenticator API layers (formally defined in the Web API [WebAuthn]) are converted first to JSON and subsequently to CBOR.
For each command that contains parameters, the parameter map keys and value types are specified below:
Command | Parameter Name | Key | Value type |
---|---|---|---|
authenticatorMakeCredential | clientDataHash | 0x01 | byte string (CBOR major type 2). |
rp | 0x02 | CBOR definite length map (CBOR major type 5). | |
user | 0x03 | CBOR definite length map (CBOR major type 5). | |
pubKeyCredParams | 0x04 | CBOR definite length array (CBOR major type 4) of CBOR definite length maps (CBOR major type 5). | |
excludeList | 0x05 | CBOR definite length array (CBOR major type 4) of CBOR definite length maps (CBOR major type 5). | |
extensions | 0x06 | CBOR definite length map (CBOR major type 5). | |
options | 0x07 | CBOR definite length map (CBOR major type 5). | |
pinUvAuthParam | 0x08 | byte string (CBOR major type 2). | |
pinUvAuthProtocol | 0x09 | PIN/UV protocol version chosen by the client. For this version of the spec, this SHALL be the number 1. | |
authenticatorGetAssertion | rpId | 0x01 | UTF-8 encoded text string (CBOR major type 3). |
clientDataHash | 0x02 | byte string (CBOR major type 2). | |
allowList | 0x03 | CBOR definite length array (CBOR major type 4) of CBOR definite length maps (CBOR major type 5). | |
extensions | 0x04 | CBOR definite length map (CBOR major type 5). | |
options | 0x05 | CBOR definite length map (CBOR major type 5). | |
pinUvAuthParam | 0x06 | byte string (CBOR major type 2). | |
pinUvAuthProtocol | 0x07 | PIN/UV protocol version chosen by the client. For this version of the spec, this SHALL be the number 1. | |
authenticatorClientPIN | pinUvAuthProtocol | 0x01 | Unsigned Integer. (CBOR major type 0) |
subCommand | 0x02 | Unsigned Integer. (CBOR major type 0) | |
keyAgreement | 0x03 | COSE_Key | |
pinUvAuthParam | 0x04 | byte string (CBOR major type 2). | |
newPinEnc | 0x05 | byte string (CBOR major type 2). It is UTF-8 representation of encrypted input PIN value. | |
pinHashEnc | 0x06 | byte string (CBOR major type 2). | |
authenticatorBioEnrollment | modality | 0x01 | Unsigned Integer. (CBOR major type 0) |
0x02 | Unsigned Integer. (CBOR major type 0) | ||
subCommandParams | 0x03 | CBOR definite length map (CBOR major type 5). | |
pinUvAuthProtocol | 0x04 | Unsigned Integer. (CBOR major type 0). | |
pinUvAuthParam | 0x05 | byte string (CBOR major type 2). | |
getModality | 0x06 | Boolean | |
authenticatorCredentialManagement | subCommand | 0x01 | Unsigned Integer. (CBOR major type 0) |
subCommandParams | 0x02 | CBOR definite length map (CBOR major type 5) | |
pinUvAuthProtocol | 0x03 | Unsigned Integer. (CBOR major type 0) | |
pinUvAuthParam | 0x04 | byte string (CBOR major type 2). |
6.2. Responses
All responses are structured as:
Name | Length | Required? | Definition |
---|---|---|---|
Status | 1 byte | Required | The status of the response. 0x00 means success; all other values are errors. See the table in the next section for valid values. |
Response Data | variable | Optional | CBOR encoded set of values. |
Response data is encoded using a CBOR map (CBOR major type 5). The CBOR map must be encoded using the definite length variant.
For each response message, the map keys and value types are specified below:
Response Message | Member Name | Key | Value type |
---|---|---|---|
authenticatorMakeCredential_Response | fmt | 0x01 | text string (CBOR major type 3). |
authData | 0x02 | byte string (CBOR major type 2). | |
attStmt | 0x03 | definite length map (CBOR major type 5). | |
authenticatorGetAssertion_Response | credential | 0x01 | definite length map (CBOR major type 5). |
authData | 0x02 | byte string (CBOR major type 2). | |
signature | 0x03 | byte string (CBOR major type 2). | |
publicKeyCredentialUserEntity | 0x04 | definite length map (CBOR major type 5). | |
numberOfCredentials | 0x05 | unsigned integer(CBOR major type 0). | |
userSelected | 0x06 | boolean (CBOR simple value 21). | |
authenticatorGetNextAssertion_Response | credential | 0x01 | definite length map (CBOR major type 5). |
authData | 0x02 | byte string (CBOR major type 2). | |
signature | 0x03 | byte string (CBOR major type 2). | |
publicKeyCredentialUserEntity | 0x04 | definite length map (CBOR major type 5). | |
authenticatorGetInfo_Response | versions | 0x01 | definite length array (CBOR major type 4) of UTF-8 encoded strings (CBOR major type 3). |
extensions | 0x02 | definite length array (CBOR major type 4) of UTF-8 encoded strings (CBOR major type 3). | |
aaguid | 0x03 | byte string (CBOR major type 2). 16 bytes in length and encoded the same as MakeCredential AuthenticatorData, as specified in [WebAuthn]. | |
options | 0x04 | Definite length map (CBOR major type 5) of key-value pairs where keys are UTF8 strings (CBOR major type 3) and values are booleans (CBOR simple value 21). | |
maxMsgSize | 0x05 | unsigned integer(CBOR major type 0). This is the maximum message size supported by the authenticator. | |
pinUvAuthProtocols | 0x06 | array of unsigned integers (CBOR major type). This is the list of pinUvAuthProtocols supported by the authenticator. | |
maxCredentialCountInList | 0x07 | unsigned integer(CBOR major type 0). | |
maxCredentialIdLength | 0x08 | unsigned integer(CBOR major type 0). | |
transports | 0x09 | definite length array (CBOR major type 4) of UTF-8 encoded strings (CBOR major type 3). This is the list of transports supported by the authenticator. | |
algorithms | 0x0A | definite length array (CBOR major type 4) of PublicKeyCredentialParameters. | |
maxAuthenticatorConfigLength | 0x0B | unsigned integer(CBOR major type 0). | |
defaultCredProtect | 0x0C | unsigned integer (CBOR major type 0). | |
authenticatorClientPIN_Response | keyAgreement | 0x01 | Authenticator public key in COSE_Key format. The COSE_Key-encoded public key MUST contain the optional "alg" parameter and MUST NOT contain any other optional parameters. The "alg" parameter MUST contain a COSEAlgorithmIdentifier value. |
pinUvAuthToken | 0x02 | byte string (CBOR major type 2). | |
pinRetries | 0x03 | Unsigned integer (CBOR major type 0). This is number of pinRetries left before lockout. | |
uvRetries | 0x04 | Unsigned integer (CBOR major type 0). This is number of uv retries left before lockout. | |
authenticatorBioEnrollment_Response | modality | 0x01 | Unsigned integer (CBOR major type 0). |
fingerprintKind | 0x02 | Unsigned integer (CBOR major type 0). | |
maxCaptureSamplesRequiredForEnroll | 0x03 | Unsigned integer (CBOR major type 0). | |
templateId | 0x04 | byte string (CBOR major type 2). | |
lastEnrollSampleStatus | 0x05 | Unsigned integer (CBOR major type 0). | |
remainingSamples | 0x06 | Unsigned integer (CBOR major type 0). | |
templateInfos | 0x07 | CBOR definite length map (CBOR major type 5). | |
authenticatorCredentialManagement_Response | existingResidentCredentialsCount | 0x01 | Unsigned integer (CBOR major type 0). |
maxPossibleRemainingResidentCredentialsCount | 0x02 | Unsigned integer (CBOR major type 0). | |
rp | 0x03 | CBOR definite length map (CBOR major type 5). | |
rpIDHash | 0x04 | byte string (CBOR major type 2). | |
totalRPs | 0x05 | Unsigned integer (CBOR major type 0). | |
user | 0x06 | CBOR definite length map (CBOR major type 5). | |
credentialID | 0x07 | CBOR definite length map (CBOR major type 5). | |
publickKey | 0x08 | CBOR definite length map (CBOR major type 5). COSE_Key. | |
totalCredentials | 0x09 | Unsigned integer (CBOR major type 0). | |
credProtect | 0x09 | Unsigned integer (CBOR major type 0). | |
6.3. Status codes
The error response values range from 0x01 - 0xff. This range is split based on error type.
Error response values in the range between CTAP2_OK and CTAP2_ERR_SPEC_LAST are reserved for spec purposes.
Error response values in the range between CTAP2_ERR_VENDOR_FIRST and CTAP2_ERR_VENDOR_LAST may be used for vendor-specific implementations. All other response values are reserved for future use and may not be used. These vendor specific error codes are not interoperable and the platform should treat these errors as any other unknown error codes.
Error response values in the range between CTAP2_ERR_EXTENSION_FIRST and CTAP2_ERR_EXTENSION_LAST may be used for extension-specific implementations. These errors need to be interoperable for vendors who decide to implement such optional extension.
Code | Name | Description |
---|---|---|
0x00 | CTAP1_ERR_SUCCESS, CTAP2_OK | Indicates successful response. |
0x01 | CTAP1_ERR_INVALID_COMMAND | The command is not a valid CTAP command. |
0x02 | CTAP1_ERR_INVALID_PARAMETER | The command included an invalid parameter. |
0x03 | CTAP1_ERR_INVALID_LENGTH | Invalid message or item length. |
0x04 | CTAP1_ERR_INVALID_SEQ | Invalid message sequencing. |
0x05 | CTAP1_ERR_TIMEOUT | Message timed out. |
0x06 | CTAP1_ERR_CHANNEL_BUSY | Channel busy. Client SHOULD retry the request after a short delay. Note that the client may abort the transaction if the command is no longer relevant. |
0x0A | CTAP1_ERR_LOCK_REQUIRED | Command requires channel lock. |
0x0B | CTAP1_ERR_INVALID_CHANNEL | Command not allowed on this cid. |
0x11 | CTAP2_ERR_CBOR_UNEXPECTED_TYPE | Invalid/unexpected CBOR error. |
0x12 | CTAP2_ERR_INVALID_CBOR | Error when parsing CBOR. |
0x14 | CTAP2_ERR_MISSING_PARAMETER | Missing non-optional parameter. |
0x15 | CTAP2_ERR_LIMIT_EXCEEDED | Limit for number of items exceeded. |
0x16 | CTAP2_ERR_UNSUPPORTED_EXTENSION | Unsupported extension. |
0x19 | CTAP2_ERR_CREDENTIAL_EXCLUDED | Valid credential found in the exclude list. |
0x21 | CTAP2_ERR_PROCESSING | Processing (Lengthy operation is in progress). |
0x22 | CTAP2_ERR_INVALID_CREDENTIAL | Credential not valid for the authenticator. |
0x23 | CTAP2_ERR_USER_ACTION_PENDING | Authentication is waiting for user interaction. |
0x24 | CTAP2_ERR_OPERATION_PENDING | Processing, lengthy operation is in progress. |
0x25 | CTAP2_ERR_NO_OPERATIONS | No request is pending. |
0x26 | CTAP2_ERR_UNSUPPORTED_ALGORITHM | Authenticator does not support requested algorithm. |
0x27 | CTAP2_ERR_OPERATION_DENIED | Not authorized for requested operation. |
0x28 | CTAP2_ERR_KEY_STORE_FULL | Internal key storage is full. |
0x2A | CTAP2_ERR_NO_OPERATION_PENDING | No outstanding operations. |
0x2B | CTAP2_ERR_UNSUPPORTED_OPTION | Unsupported option. |
0x2C | CTAP2_ERR_INVALID_OPTION | Not a valid option for current operation. |
0x2D | CTAP2_ERR_KEEPALIVE_CANCEL | Pending keep alive was cancelled. |
0x2E | CTAP2_ERR_NO_CREDENTIALS | No valid credentials provided. |
0x2F | CTAP2_ERR_USER_ACTION_TIMEOUT | Timeout waiting for user interaction. |
0x30 | CTAP2_ERR_NOT_ALLOWED | Continuation command, such as, authenticatorGetNextAssertion not allowed. |
0x31 | CTAP2_ERR_PIN_INVALID | PIN Invalid. |
0x32 | CTAP2_ERR_PIN_BLOCKED | PIN Blocked. |
0x33 | CTAP2_ERR_PIN_AUTH_INVALID | PIN authentication,pinUvAuthParam, verification failed. |
0x34 | CTAP2_ERR_PIN_AUTH_BLOCKED | PIN authentication,pinUvAuthParam, blocked. Requires power recycle to reset. |
0x35 | CTAP2_ERR_PIN_NOT_SET | No PIN has been set. |
0x36 | CTAP2_ERR_PIN_REQUIRED | PIN is required for the selected operation. |
0x37 | CTAP2_ERR_PIN_POLICY_VIOLATION | PIN policy violation. Currently only enforces minimum length. |
0x38 | CTAP2_ERR_PIN_TOKEN_EXPIRED | pinUvAuthToken expired on authenticator. |
0x39 | CTAP2_ERR_REQUEST_TOO_LARGE | Authenticator cannot handle this request due to memory constraints. |
0x3A | CTAP2_ERR_ACTION_TIMEOUT | The current operation has timed out. |
0x3B | CTAP2_ERR_UP_REQUIRED | User presence is required for the requested operation. |
0x3C | CTAP2_ERR_UV_BLOCKED | Built in UV is blocked. |
0x7F | CTAP1_ERR_OTHER | Other unspecified error. |
0xDF | CTAP2_ERR_SPEC_LAST | CTAP 2 spec last error. |
0xE0 | CTAP2_ERR_EXTENSION_FIRST | Extension specific error. |
0xEF | CTAP2_ERR_EXTENSION_LAST | Extension specific error. |
0xF0 | CTAP2_ERR_VENDOR_FIRST | Vendor specific error. |
0xFF | CTAP2_ERR_VENDOR_LAST | Vendor specific error. |
7. Interoperating with CTAP1/U2F authenticators
This section defines how a platform maps CTAP2 requests to CTAP1/U2F requests and CTAP1/U2F responses to CTAP2 responses in order to support CTAP1/U2F authenticators via CTAP2. CTAP2 requests can be mapped to CTAP1/U2F requests provided the CTAP2 request does not have parameters that only CTAP2 authenticators can fulfill. The processes for RPs to use to verify CTAP1/U2F based authenticatorMakeCredential and authenticatorGetAssertion responses are also defined below. Platform may choose to skip this feature and work only with CTAP devices.
7.1. Framing of U2F commands
The U2F protocol is based on a request-response mechanism, where a requester sends a request message to a U2F device, which always results in a response message being sent back from the U2F device to the requester.
The request message has to be "framed" to send to the lower layer. Taking the signature request as an example, the "framing" is a way for the FIDO client to tell the lower transport layer that it is sending a signature request and then send the raw message contents. The framing also specifies how the transport will carry back the response raw message and any meta-information such as an error code if the command failed.
In this current version of U2F, the framing is defined based on the ISO7816-4:2005 extended APDU format. This is very appropriate for the USB transport since devices are typically built around secure elements which understand this format already. This same argument may apply for futures such as Bluetooth based devices. For other futures based on other transports, such as a built-in u2f token on a mobile device TEE, this framing may not be appropriate, and a different framing may need to be defined.
7.1.1. U2F Request Message Framing
The raw request message is framed as a command APDU:
CLA | INS | P1 | P2 | LC1 | LC2 | LC3 |
Where:
CLA: Reserved to be used by the underlying transport protocol (if applicable). The host application shall set this byte to zero.
INS: U2F command code, defined in the following sections.
P1, P2: Parameter 1 and 2, defined by each command.
LC1-LC3: Length of the request data, big-endian coded, i.e. LC1 being MSB and LC3 LSB
7.1.2. U2F Response Message Framing
The raw response data is framed as a response APDU:
SW1 | SW2 |
Where:
SW1, SW2: Status word bytes 1 and 2, forming a 16-bit status word, defined below. SW1 is MSB and SW2 LSB. Status Codes
The following ISO7816-4 defined status words have a special meaning in U2F:
SW_NO_ERROR: The command completed successfully without error.
SW_CONDITIONS_NOT_SATISFIED: The request was rejected due to test-of-user-presence being required.
SW_WRONG_DATA: The request was rejected due to an invalid key handle.
Each implementation may define any other vendor-specific status codes, providing additional information about an error condition. Only the error codes listed above will be handled by U2F FIDO clients, whereas others will be seen as general errors and logging of these is optional.
7.2. Using the CTAP2 authenticatorMakeCredential Command with CTAP1/U2F authenticators
Platform follows the following procedure (Fig: Mapping: WebAuthn authenticatorMakeCredential to and from CTAP1/U2F Registration Messages):
-
Platform tries to get information about the authenticator by sending authenticatorGetInfo command as specified in CTAP2 protocol overview.
-
CTAP1/U2F authenticator returns a command error or improperly formatted CBOR response. For any failure, platform may fall back to CTAP1/U2F protocol.
-
-
Map CTAP2 authenticatorMakeCredential request to U2F_REGISTER request.
-
Platform verifies that CTAP2 request does not have any parameters that CTAP1/U2F authenticators cannot fulfill.
-
All of the below conditions must be true for the platform to proceed to next step. If any of the below conditions is not true, platform errors out with CTAP2_ERR_UNSUPPORTED_OPTION.
-
pubKeyCredParams must use the ES256 algorithm (-7).
-
Options must not include "rk" set to true.
-
Options must not include "uv" set to true.
-
-
If excludeList is not empty:
-
If the excludeList is not empty, the platform must send signing request with check-only control byte to the CTAP1/U2F authenticator using each of the credential ids (key handles) in the excludeList. If any of them does not result in an error, that means that this is a known device. Afterwards, the platform must still send a dummy registration request (with a dummy appid and invalid challenge) to CTAP1/U2F authenticators that it believes are excluded. This makes it so the user still needs to touch the CTAP1/U2F authenticator before the RP gets told that the token is already registered.
-
-
-
Use clientDataHash parameter of CTAP2 request as CTAP1/U2F challenge parameter (32 bytes).
-
Let
rpIdHash
be a byte array of size 32 initialized with SHA-256 hash ofrp.id
parameter as CTAP1/U2F application parameter (32 bytes).
-
-
Send the U2F_REGISTER request to the authenticator as specified in [U2FRawMsgs] spec.
-
Map the U2F registration response message (see: FIDO U2F Raw Message Formats v1.2 §registration-response-message-success) to a CTAP2 authenticatorMakeCredential response message:
-
Generate
authenticatorData
from the U2F registration response message (FIDO U2F Raw Message Formats v1.2 §registration-response-message-success) received from the authenticator:-
Initialize
attestedCredData
:-
Let
credentialIdLength
be a 2-byte unsigned big-endian integer representing length of the Credential ID initialized with CTAP1/U2F response key handle length. -
Let
credentialId
be acredentialIdLength
byte array initialized with CTAP1/U2F response key handle bytes. -
Let
x9encodedUserPublicKey
be theuser public key
returned in the U2F registration response message [U2FRawMsgs]. LetcoseEncodedCredentialPublicKey
be the result of convertingx9encodedUserPublicKey
’s value from ANS X9.62 / Sec-1 v2 uncompressed curve point representation [SEC1V2] to COSE_Key representation ([RFC8152] Section 7). -
Let
attestedCredData
be a byte array with following structure:Length (in bytes) Description Value 16 The AAGUID of the authenticator. Initialized with all zeros. 2 Byte length L of Credential ID Initialized with credentialIdLength
bytes.credentialIdLength
Credential ID. Initialized with credentialId
bytes.77 The credential public key. Initialized with coseEncodedCredentialPublicKey
bytes. -
Initialize
authenticatorData
:-
Let
flags
be a byte whose zeroth bit (bit 0, UP) is set, and whose sixth bit (bit 6, AT) is set, and all other bits are zero (bit zero is the least significant bit). See also Authenticator Data section of [WebAuthn]. -
Let
signCount
be a 4-byte unsigned integer initialized to zero. -
Let
authenticatorData
be a byte array with the following structure:Length (in bytes) Description Value 32 SHA-256 hash of the rp.id
.Initialized with rpIdHash
bytes.1 Flags Initialized with flags
' value.4 Signature counter (signCount). Initialized with signCount
bytes.Variable Length Attested credential data. Initialized with attestedCredData
’s value.
-
-
-
-
Let
attestationStatement
be a CBOR map (see "attStmtTemplate" in Generating an Attestation Object [WebAuthn]) with the following keys, whose values are as follows:-
Set "x5c" as an array of the one attestation cert extracted from CTAP1/U2F response.
-
Set "sig" to be the "signature" bytes from the U2F registration response message [U2FRawMsgs].
-
-
Let
attestationObject
be a CBOR map (see "attObj" in Attestation object [WebAuthn]) with the following keys, whose values are as follows:-
Set "authData" to
authenticatorData
. -
Set "fmt" to "fido-u2f".
-
Set "attStmt" to
attestationStatement
.
-
-
-
Return
attestationObject
to the caller.
7.3. Using the CTAP2 authenticatorGetAssertion Command with CTAP1/U2F authenticators
Platform follows the following procedure (Fig: Mapping: WebAuthn authenticatorGetAssertion to and from CTAP1/U2F Authentication Messages):
-
Platform tries to get information about the authenticator by sending authenticatorGetInfo command as specified in CTAP2 protocol overview.
-
CTAP1/U2F authenticator returns a command error or improperly formatted CBOR response. For any failure, platform may fall back to CTAP1/U2F protocol.
-
-
Map CTAP2 authenticatorGetAssertion request to U2F_AUTHENTICATE request:
-
Platform verifies that CTAP2 request does not have any parameters that CTAP1/U2F authenticators cannot fulfill:
-
All of the below conditions must be true for the platform to proceed to next step. If any of the below conditions is not true, platform errors out with CTAP2_ERR_UNSUPPORTED_OPTION.
-
Options must not include "uv" set to true.
-
allowList must have at least one credential.
-
-
-
If allowList has more than one credential, platform has to loop over the list and send individual different U2F_AUTHENTICATE commands to the authenticator. For each credential in credential list, map CTAP2 authenticatorGetAssertion request to U2F_AUTHENTICATE as below:
-
Let
controlByte
be a byte initialized as follows:-
If "up" is set to false, set it to 0x08 (dont-enforce-user-presence-and-sign).
-
For USB, set it to 0x07 (check-only). This should prevent call getting blocked on waiting for user input. If response returns success, then call again setting the enforce-user-presence-and-sign.
-
For NFC, set it to 0x03 (enforce-user-presence-and-sign). The tap has already provided the presence and won’t block.
-
-
Use clientDataHash parameter of CTAP2 request as CTAP1/U2F challenge parameter (32 bytes).
-
Let
rpIdHash
be a byte array of size 32 initialized with SHA-256 hash ofrp.id
parameter as CTAP1/U2F application parameter (32 bytes). -
Let
credentialId
is the byte array initialized with the id for this PublicKeyCredentialDescriptor. -
Let
keyHandleLength
be a byte initialized with length ofcredentialId
byte array. -
Let
u2fAuthenticateRequest
be a byte array with the following structure:Length (in bytes) Description Value 32 Challenge parameter Initialized with clientDataHash parameter bytes. 32 Application parameter Initialized with rpIdHash
bytes.1 Key handle length Initialized with keyHandleLength
’s value.keyHandleLength
Key handle Initialized with credentialId
bytes.and let
Control Byte
be P1 of the framing.
-
-
-
Send
u2fAuthenticateRequest
to the authenticator. -
Map the U2F authentication response message (see the "Authentication Response Message: Success" section of [U2FRawMsgs]) to a CTAP2 authenticatorGetAssertion response message:
-
Generate
authenticatorData
from the U2F authentication response message received from the authenticator:-
Copy bits 0 (the UP bit) and bit 1 from the CTAP2/U2F response user presence byte to bits 0 and 1 of the CTAP2 flags, respectively. Set all other bits of flags to zero. Note: bit zero is the least significant bit. See also Authenticator Data section of [WebAuthn].
-
Let
signCount
be a 4-byte unsigned integer initialized with CTAP1/U2F response counter field. -
Let
authenticatorData
is a byte array of following structure:Length (in bytes) Description Value 32 SHA-256 hash of the rp.id
.Initialized with rpIdHash
bytes.1 Flags Initialized with flags
' value.4 Signature counter (signCount) Initialized with signCount
bytes.
-
-
Let
authenticatorGetAssertionResponse
be a CBOR map with the following keys whose values are as follows:-
Set 0x01 with the credential from allowList that whose response succeeded.
-
Set 0x02 with
authenticatorData
bytes. -
Set 0x03 with signature field from CTAP1/U2F authentication response message.
-
-
8. Transport-specific Bindings
8.1. Secure protocol implementation
In order to ensure that the interaction between the platform and any authenticators is secure, authenticators SHALL:
-
Ensure that all state (e.g. resident credentials, signature counters, PINs, etc) that is observable or alterable over FIDO interfaces is not observable or alterable over any other interfaces on transports that FIDO has defined.
-
Ensure that all non-resident credentials that are created over FIDO interfaces are not valid over any other interfaces on transports that FIDO has defined. (For example, if non-resident credentials store state in the credential ID, protected by an authenticator-global secret, then that secret must only be used for requests received over FIDO interfaces.)
Note: Above recommendations are also valid for future transports.
FIDO interfaces are defined as:
-
USB, when using USB HID and the FIDO_USAGE_PAGE/FIDO_USAGE_CTAPHID combination.
-
NFC, when the applet is selected as specified.
-
Authenticator SHALL NOT allow FIDO applet to be implicitly selected or enabled.
-
Recommended: Authenticator SHALL NOT have default applet selected on power cycle. All CTAP commands SHALL be preceded by an explicit applet selection command as described in Applet selection section.
-
Alternative: If authenticator has a FIDO applet selected for some reason at power cycle, it SHALL be in disabled mode and SHALL ONLY be enabled once it receives explicit applet selection command as described in Applet selection section.
-
-
Authenticator SHALL disable FIDO interface when it receives applet deselect command.
-
-
BLE, when using the FIDO GATT service.
8.2. USB Human Interface Device (USB HID)
See also § 8.1 Secure protocol implementation.8.2.1. Design rationale
CTAP messages are framed for USB transport using the HID (Human Interface Device) protocol. We henceforth refer to the protocol as CTAPHID. The CTAPHID protocol is designed with the following design objectives in mind
-
Driver-less installation on all major host platforms
-
Multi-application support with concurrent application access without the need for serialization and centralized dispatching.
-
Fixed latency response and low protocol overhead
-
Scalable method for CTAPHID device discovery
Since HID data is sent as interrupt packets and multiple applications may access the HID stack at once, a non-trivial level of complexity has to be added to handle this.
8.2.2. Protocol structure and data framing
The CTAP protocol is designed to be concurrent and state-less in such a way that each performed function is not dependent on previous actions. However, there has to be some form of "atomicity" that varies between the characteristics of the underlying transport protocol, which for the CTAPHID protocol introduces the following terminology:
-
Transaction
-
Message
-
Packet
A transaction is the highest level of aggregated functionality, which in turn consists of a request, followed by a response message. Once a request has been initiated, the transaction has to be entirely completed or aborted before a second transaction can take place and a response is never sent without a previous request. Transactions exist only at the highest CTAP protocol layer.
Request and response messages are in turn divided into individual fragments, known as packets. The packet is the smallest form of protocol data unit, which in the case of CTAPHID are mapped into HID reports.
8.2.3. Concurrency and channels
Additional logic and overhead is required to allow a CTAPHID device to deal with multiple "clients", i.e. multiple applications accessing the single resource through the HID stack. Each client communicates with a CTAPHID device through a logical channel, where each application uses a unique 32-bit channel identifier for routing and arbitration purposes.
A channel identifier is allocated by the FIDO authenticator to ensure its system-wide uniqueness. The actual algorithm for generation of channel identifiers is vendor specific and not defined by this specification.
Channel ID 0 is reserved and 0xffffffff
is reserved for
broadcast commands, i.e. at the time of channel allocation.
8.2.4. Message and packet structure
Packets are one of two types, initialization packets and continuation packets. As the name suggests, the first packet sent in a message is an initialization packet, which also becomes the start of a transaction. If the entire message does not fit into one packet (including the CTAPHID protocol overhead), one or more continuation packets have to be sent in strict ascending order to complete the message transfer.
A message sent from a host to a device is known as a request and a message sent from a device back to the host is known as a response. A request always triggers a response and response messages are never sent ad-hoc, i.e. without a prior request message. However, a keep-alive message can be sent between a request and a response message.
The request and response messages have an identical structure. A transaction is started with the initialization packet of the request message and ends with the last packet of the response message. The client starting a transaction may also abort it.
Packets are always fixed size (defined by the endpoint and HID report descriptors) and although all bytes may not be needed in a particular packet, the full size always has to be sent. Unused bytes SHOULD be set to zero.
An initialization packet is defined as
Offset | Length | Mnemonic | Description |
---|---|---|---|
0 | 4 | CID | Channel identifier |
4 | 1 | CMD | Command identifier (bit 7 always set) |
5 | 1 | BCNTH | High part of payload length |
6 | 1 | BCNTL | Low part of payload length |
7 | (s - 7) | DATA | Payload data (s is equal to the fixed packet size) |
The command byte has always the highest bit set to distinguish it from a continuation packet, which is described below.
A continuation packet is defined as
Offset | Length | Mnemonic | Description |
---|---|---|---|
0 | 4 | CID | Channel identifier |
4 | 1 | SEQ | Packet sequence 0x00..0x7f (bit 7 always cleared) |
5 | (s - 5) | DATA | Payload data (s is equal to the fixed packet size) |
With this approach, a message with a payload less or equal to (s - 7) may be sent as one packet. A larger message is then divided into one or more continuation packets, starting with sequence number 0, which then increments by one to a maximum of 127.
With a packet size of 64 bytes (max for full-speed devices), this means that the maximum message payload length is 64 - 7 + 128 * (64 - 5) = 7609 bytes.
8.2.5. Arbitration
In order to handle multiple channels and clients concurrency, the CTAPHID protocol has to maintain certain internal states, block conflicting requests and maintain protocol integrity. The protocol relies on each client application (channel) behaves politely, i.e. does not actively act to destroy for other channels. With this said, a malign or malfunctioning application can cause issues for other channels. Expected errors and potentially stalling applications should however, be handled properly.
8.2.5.1. Transaction atomicity, idle and busy states.
A transaction always consists of three stages:
-
A message is sent from the host to the device
-
The device processes the message
-
A response is sent back from the device to the host
The protocol is built on the assumption that a plurality of concurrent applications may try ad-hoc to perform transactions at any time, with each transaction being atomic, i.e. it cannot be interrupted by another application once started.
The application channel that manages to get through the first initialization packet when the device is in idle state will keep the device locked for other channels until the last packet of the response message has been received or the transaction is aborted. The device then returns to idle state, ready to perform another transaction for the same or a different channel. Between two transactions, no state is maintained in the device and a host application must assume that any other process may execute other transactions at any time.
If an application tries to access the device from a different channel while the device is busy with a transaction, that request will immediately fail with a busy-error message sent to the requesting channel.
8.2.5.2. Transaction timeout
A transaction has to be completed within a specified period of time to prevent a stalling application to cause the device to be completely locked out for access by other applications. If for example an application sends an initialization packet that signals that continuation packets will follow and that application crashes, the device will back out that pending channel request and return to an idle state.
8.2.5.3. Transaction abort and re-synchronization
If an application for any reason "gets lost", gets an unexpected response or error, it may at any time issue an abort-and-resynchronize command. If the device detects an INIT command during a transaction that has the same channel id as the active transaction, the transaction is aborted (if possible) and all buffered data flushed (if any). The device then returns to idle state to become ready for a new transaction.
If an application wishes to abort a command after the request has been fully sent, e.g. while an authenticator is waiting for user presence, the application may do this by sending a CTAPHID_CANCEL command.
8.2.5.4. Packet sequencing
The device keeps track of packets arriving in correct and ascending order and that no expected packets are missing. The device will continue to assemble a message until all parts of it has been received or that the transaction times out. Spurious continuation packets appearing without a prior initialization packet will be ignored.
8.2.6. Channel locking
In order to deal with aggregated transactions that may not be interrupted, such as tunneling of vendor-specific commands, a channel lock command may be implemented. By sending a channel lock command, the device prevents other channels from communicating with the device until the channel lock has timed out or been explicitly unlocked by the application.
This feature is optional and has not to be considered by general CTAP HID applications.
8.2.7. Protocol version and compatibility
The CTAPHID protocol is designed to be extensible yet maintain backwards compatibility, to the extent it is applicable. This means that a CTAPHID host SHALL support any version of a device with the command set available in that particular version.
8.2.8. HID device implementation
This description assumes knowledge of the USB and HID specifications and is intended to provide the basics for implementing a CTAPHID device. There are several ways to implement USB devices and reviewing these different methods is beyond the scope of this document. This specification targets the interface part, where a device is regarded as either a single or multiple interface (composite) device.
The description further assumes (but is not limited to) a full-speed USB device (12 Mbit/s). Although not excluded per se, USB low-speed devices are not practical to use given the 8-byte report size limitation together with the protocol overhead.
8.2.8.1. Interface and endpoint descriptors
The device implements two endpoints (except the control endpoint 0), one for IN and one for OUT transfers. The packet size is vendor defined, but the reference implementation assumes a full-speed device with two 64-byte endpoints.
Interface Descriptor
Mnemonic | Value | Description |
---|---|---|
bNumEndpoints | 2 | One IN and one OUT endpoint |
bInterfaceClass | 0x03 | HID |
bInterfaceSubClass | 0x00 | No interface subclass |
bInterfaceProtocol | 0x00 | No interface protocol |
Mnemonic | Value | Description |
---|---|---|
bmAttributes | 0x03 | Interrupt transfer |
bEndpointAdresss | 0x01 | 1, OUT |
bMaxPacketSize | 64 | 64-byte packet max |
bInterval | 5 | Poll every 5 millisecond |
Mnemonic | Value | Description |
---|---|---|
bmAttributes | 0x03 | Interrupt transfer |
bEndpointAdresss | 0x81 | 1, IN |
bMaxPacketSize | 64 | 64-byte packet max |
bInterval | 5 | Poll every 5 millisecond |
The actual endpoint order, intervals, endpoint numbers and endpoint packet size may be defined freely by the vendor and the host application is responsible for querying these values and handle these accordingly. For the sake of clarity, the values listed above are used in the following examples.
8.2.8.2. HID report descriptor and device discovery
A HID report descriptor is required for all HID devices, even though the reports and their interpretation (scope, range, etc.) makes very little sense from an operating system perspective. The CTAPHID just provides two "raw" reports, which basically map directly to the IN and OUT endpoints. However, the HID report descriptor has an important purpose in CTAPHID, as it is used for device discovery.
For the sake of clarity, a bit of high-level C-style abstraction is provided
// HID report descriptor const uint8_t HID_ReportDescriptor[] = { HID_UsagePage ( FIDO_USAGE_PAGE ), HID_Usage ( FIDO_USAGE_CTAPHID ), HID_Collection ( HID_Application ), HID_Usage ( FIDO_USAGE_DATA_IN ), HID_LogicalMin ( 0 ), HID_LogicalMaxS ( 0xff ), HID_ReportSize ( 8 ), HID_ReportCount ( HID_INPUT_REPORT_BYTES ), HID_Input ( HID_Data | HID_Absolute | HID_Variable ), HID_Usage ( FIDO_USAGE_DATA_OUT ), HID_LogicalMin ( 0 ), HID_LogicalMaxS ( 0xff ), HID_ReportSize ( 8 ), HID_ReportCount ( HID_OUTPUT_REPORT_BYTES ), HID_Output ( HID_Data | HID_Absolute | HID_Variable ), HID_EndCollection };
A unique Usage Page is defined (0xF1D0) for the FIDO alliance and under this realm, a CTAPHID Usage is defined as well (0x01). During CTAPHID device discovery, all HID devices present in the system are examined and devices that match this usage pages and usage are then considered to be CTAPHID devices.
The length values specified by the HID_INPUT_REPORT_BYTES
and
the HID_OUTPUT_REPORT_BYTES
should typically match the
respective endpoint sizes defined in the endpoint descriptors.
8.2.9. CTAPHID commands
The CTAPHID protocol implements the following commands.
8.2.9.1. Mandatory commands
The following list describes the minimum set of commands required by a CTAPHID device. Optional and vendor-specific commands may be implemented as described in respective sections of this document.
8.2.9.1.1. CTAPHID_MSG (0x03)
This command sends an encapsulated CTAP1/U2F message to the device. The semantics of the data message is defined in the U2F Raw Message Format encoding specification.
Request
CMD | CTAPHID_MSG |
BCNT | 1..(n + 1) |
DATA | U2F command byte |
DATA + 1 | n bytes of data |
Response at success
CMD | CTAPHID_MSG |
BCNT | 1..(n + 1) |
DATA | U2F status code |
DATA + 1 | n bytes of data |
8.2.9.1.2. CTAPHID_CBOR (0x10)
This command sends an encapsulated CTAP CBOR encoded message. The semantics of the data message is defined in the CTAP Message encoding specification. Please note that keep-alive messages MAY be sent from the device to the client before the response message is returned.
Request
CMD | CTAPHID_CBOR |
BCNT | 1..(n + 1) |
DATA | CTAP command byte |
DATA + 1 | n bytes of CBOR encoded data |
Response at success
CMD | CTAPHID_CBOR |
BCNT | 1..(n + 1) |
DATA | CTAP status code |
DATA + 1 | n bytes of CBOR encoded data |
8.2.9.1.3. CTAPHID_INIT (0x06)
This command has two functions.
If sent on an allocated CID, it synchronizes a channel, discarding the current transaction, buffers and state as quickly as possible. It will then be ready for a new transaction. The device then responds with the CID of the channel it received the INIT on, using that channel.
If sent on the broadcast CID, it requests the device to allocate a unique 32-bit channel identifier (CID) that can be used by the requesting application during its lifetime. The requesting application generates a nonce that is used to match the response. When the response is received, the application compares the sent nonce with the received one. After a positive match, the application stores the received channel id and uses that for subsequent transactions.
To allocate a new channel, the requesting application SHALL use the broadcast channel CTAPHID_BROADCAST_CID (0xFFFFFFFF). The device then responds with the newly allocated channel in the response, using the broadcast channel.
Request
CMD | CTAPHID_INIT |
BCNT | 8 |
DATA | 8-byte nonce |
Response at success
CMD | CTAPHID_INIT |
BCNT | 17 (see note below) |
DATA | 8-byte nonce |
DATA+8 | 4-byte channel ID |
DATA+12 | CTAPHID protocol version identifier |
DATA+13 | Major device version number |
DATA+14 | Minor device version number |
DATA+15 | Build device version number |
DATA+16 | Capabilities flags |
The protocol version identifies the protocol version implemented by the device. This version of the CTAPHID protocol is 2.
A CTAPHID host SHALL accept a response size that is longer than the anticipated size to allow for future extensions of the protocol, yet maintaining backwards compatibility. Future versions will maintain the response structure of the current version, but additional fields may be added.
The meaning and interpretation of the device version number is vendor defined.
The capability flags value is a bitfield where the following bits values are defined. Unused values are reserved for future use and must be set to zero by device vendors.
Name | Value | Description |
---|---|---|
CAPABILITY_WINK | 0x01 | If set to 1, authenticator implements CTAPHID_WINK function |
CAPABILITY_CBOR | 0x04 | If set to 1, authenticator implements CTAPHID_CBOR function |
CAPABILITY_NMSG | 0x08 | If set to 1, authenticator DOES NOT implement CTAPHID_MSG function |
8.2.9.1.4. CTAPHID_PING (0x01)
Sends a transaction to the device, which immediately echoes the same data back. This command is defined to be a uniform function for debugging, latency and performance measurements.
Request
CMD | CTAPHID_PING |
BCNT | 0..n |
DATA | n bytes |
Response at success
CMD | CTAPHID_PING |
BCNT | n |
DATA | N bytes |
8.2.9.1.5. CTAPHID_CANCEL (0x11)
Cancel any outstanding requests on this CID. If there is an outstanding request that can be cancelled, the authenticator MUST cancel it and that cancelled request will reply with the error CTAP2_ERR_KEEPALIVE_CANCEL.
As the CTAPHID_CANCEL command is sent during an ongoing transaction, transaction semantics do not apply. Whether a request was cancelled or not, the authenticator MUST NOT reply to the CTAPHID_CANCEL message itself. The CTAPHID_CANCEL command MAY be sent by the client during ongoing processing of a CTAPHID_CBOR request. The CTAP2_ERR_KEEPALIVE_CANCEL response MUST be the response to that request, not an error response in the HID transport.
A CTAPHID_CANCEL received while no CTAPHID_CBOR request is being processed, or on a non-active CID SHALL be ignored by the authenticator.
CMD | CTAPHID_CANCEL |
BCNT | 0 |
8.2.9.1.6. CTAPHID_ERROR (0x3F)
This command code is used in response messages only.
CMD | CTAPHID_ERROR |
BCNT | 1 |
DATA | Error code |
The following error codes are defined
ERR_INVALID_CMD | 0x01 | The command in the request is invalid |
ERR_INVALID_PAR | 0x02 | The parameter(s) in the request is invalid |
ERR_INVALID_LEN | 0x03 | The length field (BCNT) is invalid for the request |
ERR_INVALID_SEQ | 0x04 | The sequence does not match expected value |
ERR_MSG_TIMEOUT | 0x05 | The message has timed out |
ERR_CHANNEL_BUSY | 0x06 | The device is busy for the requesting channel. The client SHOULD retry the request after a short delay. Note that the client may abort the transaction if the command is no longer relevant. |
ERR_LOCK_REQUIRED | 0x0A | Command requires channel lock |
ERR_INVALID_CHANNEL | 0x0B | CID is not valid. |
ERR_OTHER | 0x7F | Unspecified error |
8.2.9.1.7. CTAPHID_KEEPALIVE (0x3B)
This command code is sent while processing a CTAPHID_MSG. It should be sent at least every 100ms and whenever the status changes. A KEEPALIVE sent by an authenticator does not constitute a response and does therefore not end an ongoing transaction.
CMD | CTAPHID_KEEPALIVE |
BCNT | 1 |
DATA | Status code |
The following status codes are defined
STATUS_PROCESSING | 1 | The authenticator is still processing the current request. |
STATUS_UPNEEDED | 2 | The authenticator is waiting for user presence. |
8.2.9.2. Optional commands
The following commands are defined by this specification but are optional and does not have to be implemented.
8.2.9.2.1. CTAPHID_WINK (0x08)
The wink command performs a vendor-defined action that provides some visual or audible identification a particular authenticator. A typical implementation will do a short burst of flashes with a LED or something similar. This is useful when more than one device is attached to a computer and there is confusion which device is paired with which connection.
Request
CMD | CTAPHID_WINK |
BCNT | 0 |
DATA | N/A |
Response at success
CMD | CTAPHID_WINK |
BCNT | 0 |
DATA | N/A |
8.2.9.2.2. CTAPHID_LOCK (0x04)
The lock command places an exclusive lock for one channel to communicate with the device. As long as the lock is active, any other channel trying to send a message will fail. In order to prevent a stalling or crashing application to lock the device indefinitely, a lock time up to 10 seconds may be set. An application requiring a longer lock has to send repeating lock commands to maintain the lock.
Request
CMD | CTAPHID_LOCK |
BCNT | 1 |
DATA | Lock time in seconds 0..10. A value of 0 immediately releases the lock |
Response at success
CMD | CTAPHID_LOCK |
BCNT | 0 |
DATA | N/A |
8.2.9.3. Vendor specific commands
A CTAPHID may implement additional vendor specific commands that are not defined in this specification, while being CTAPHID compliant. Such commands, if implemented, must use a command in the range between CTAPHID_VENDOR_FIRST (0x40) and CTAPHID_VENDOR_LAST (0x7F).
8.3. ISO7816, ISO14443 and Near Field Communication (NFC)
See also § 8.1 Secure protocol implementation.8.3.1. Conformance
Please refer to [ISO7816-4] for APDU definition.
8.3.2. Protocol
The general protocol between a FIDO2 client and an authenticator over ISO7816/ISO14443 is as follows:
-
Client sends an applet selection command
-
Authenticator replies with success if the applet is present
-
Client sends a command for an operation
-
Authenticator replies with response data or error
-
Return to 3.
Because of timeouts that may otherwise occur on some platforms, it is RECOMMENDED that the Authenticators reply to APDU commands within 800 milliseconds.
8.3.3. Applet selection
Note: See also § 8.1 Secure protocol implementation
A successful Select allows the client to know that the applet is present and active. A client SHALL send a Select to the authenticator before any other command.
The FIDO2 AID consists of the following fields:
Field | Value |
---|---|
RID
| 0xA000000647 |
PIX
| 0x2F0001 |
The command to select the FIDO applet is:
CLA | INS | P1 | P2 | Data In | Le |
---|---|---|---|---|---|
0x00 | 0xA4 | 0x04 | 0x00 | AID | Variable |
In response to the applet selection command, the FIDO authenticator replies with its version information string in the successful response.
Clients and authenticators MAY support additional selection mechanisms. Clients MUST fall back to the previously defined selection process if the additional selection mechanisms fail to select the applet. Authenticators MUST at least support the previously defined selection process.
Given legacy support for CTAP1/U2F, the client must determine the capabilities of the device at the selection stage.
-
If the authenticator implements CTAP1/U2F, the version information SHALL be the string "U2F_V2", or 0x5532465f5632, to maintain backwards-compatibility with CTAP1/U2F-only clients.
-
If the authenticator ONLY implements CTAP2, the device SHALL respond with "FIDO_2_0", or 0x4649444f5f325f30.
-
If the authenticator implements both CTAP1/U2F and CTAP2, the version information SHALL be the string "U2F_V2", or 0x5532465f5632, to maintain backwards-compatibility with CTAP1/U2F-only clients. CTAP2-aware clients may then issue a CTAP authenticatorGetInfo command to determine if the device supports CTAP2 or not.
8.3.4. Applet deselection
Note: See also § 8.1 Secure protocol implementation
-
Authenticator SHALL deselect or disable FIDO applet upon receiving below
NFCCTAP_CONTROL END CTAP_MSG
command.-
Authenticators SHALL ignore subsequent FIDO CTAP commands until it receives the next explicit FIDO Applet selection command.
-
NFCCTAP_CONTROL END CTAP_MSG
command is as follows:CLA INS P1 P2 0x80 0x12 (NFCCTAP_CONTROL) 0x01 (End CTAP_MSG Control Byte) 0x00
-
8.3.5. Framing
Conceptually, framing defines an encapsulation of FIDO2 commands. This encapsulation is done in an APDU following [ISO7816-4]. Authenticators MUST support short and extended length encoding for this APDU. Fragmentation, if needed, is discussed in the following paragraph.
8.3.5.1. Commands
Commands SHALL have the following format:
CLA | INS | P1 | P2 | Data In | Le |
---|---|---|---|---|---|
0x80 | 0x10 | 0x00 | 0x00 | CTAP Command Byte || CBOR Encoded Data | Variable |
8.3.5.2. Response
Response SHALL have the following format in case of success:
Case | Data | Status word |
---|---|---|
Success | CTAP Status code || Response data | "9000" - Success |
Status update | Status data | "9100" - OK When receiving this, the ISO transport layer will immediately issue an NFCCTAP_GETREPONSE command unless a cancel was issued. The ISO transport layer will provide the status data to the higher layers. |
Errors | See [ISO7816-4] |
8.3.6. Fragmentation
APDU command may hold up to 255 or 65535 bytes of data using short or extended length encoding respectively. APDU response may hold up to 256 or 65536 bytes of data using short or extended length encoding respectively.
Some requests may not fit into a short APDU command, or the expected response may not fit in a short APDU response. For this reason, FIDO2 client MAY encode APDU command in the following way:
-
The request may be encoded using extended length APDU encoding.
-
The request may be encoded using short APDU encoding. If the request does not fit a short APDU command, the client MUST use ISO 7816-4 APDU chaining.
Short APDU Chaining commands SHALL have the following format:
CLA | INS | P1 | P2 | Data In |
---|---|---|---|---|
0x90 | 0x10 | 0x00 | 0x00 | CTAP Payload |
Some responses may not fit into a short APDU response. For this reason, FIDO2 authenticators MUST respond in the following way:
-
If the request was encoded using extended length APDU encoding, the authenticator MUST respond using the extended length APDU response format.
-
If the request was encoded using short APDU encoding, the authenticator MUST respond using ISO 7816-4 APDU chaining.
8.3.7. Commands
8.3.7.1. NFCCTAP_MSG (0x10)
The NFCCTAP_MSG command send a CTAP message to the authenticator. This command SHALL return as soon as processing is done. If the operation was not completed, it MAY return a 0x9100 result to trigger NFCCTAP_GETRESPONSE functionality if the client indicated support by setting the relevant bit in P1.
The values for P1 for the NFCCTAP_MSG command are:
P1 Bits | Meaning |
---|---|
0x80 | The client supports NFCCTAP_GETRESPONSE |
0x7F | RFU, must be (0x00) |
Values for P2 are all RFU and MUST be set to 0.
8.3.7.2. NFCCTAP_GETRESPONSE (0x11)
The NFCCTAP_GETRESPONSE command is issued up to receiving 0x9100 unless a cancel was issued. This command SHALL return a 0x9100 result with a status indication if it has a status update, the reply to the request with a 0x9000 result code to indicate success or an error value.
All values for P1 and P2 are RFU and MUST be set to 0x00.
8.4. Bluetooth Smart / Bluetooth Low Energy Technology
See also § 8.1 Secure protocol implementation.8.4.1. Conformance
Authenticator and client devices using Bluetooth Low Energy Technology SHALL conform to Bluetooth Core Specification 4.0 or later [BTCORE]. Bluetooth SIG specified UUID values SHALL be found on the Assigned Numbers website [BTASSNUM].
8.4.2. Pairing
Bluetooth Low Energy Technology is a long-range wireless protocol and thus has several implications for privacy, security, and overall user-experience. Because it is wireless, Bluetooth Low Energy Technology may be subject to monitoring, injection, and other network-level attacks.
For these reasons, clients and authenticators MUST create and use a long-term link key (LTK) and SHALL encrypt all communications. Authenticator MUST never use short term keys.
Because Bluetooth Low Energy Technology has poor ranging (i.e., there is no good indication of proximity), it may not be clear to a FIDO client with which Bluetooth Low Energy Technology authenticator it should communicate. Pairing is the only mechanism defined in this protocol to ensure that FIDO clients are interacting with the expected Bluetooth Low Energy Technology authenticator. As a result, authenticator manufacturers SHOULD instruct users to avoid performing Bluetooth pairing in a public space such as a cafe, shop or train station.
One disadvantage of using standard Bluetooth pairing is that the pairing is "system-wide" on most operating systems. That is, if an authenticator is paired to a FIDO client which resides on an operating system where Bluetooth pairing is "system-wide", then any application on that device might be able to interact with an authenticator. This issue is discussed further in Implementation Considerations.
8.4.3. Link Security
For Bluetooth Low Energy Technology connections, the authenticator
SHALL enforce Security Mode 1, Level 2
(unauthenticated
pairing with encryption) or Security Mode 1, Level 3
(authenticated pairing with encryption) before any FIDO messages
are exchanged.
8.4.4. Framing
Conceptually, framing defines an encapsulation of FIDO raw messages responsible for correct transmission of a single request and its response by the transport layer.
All requests and their responses are conceptually written as a single frame. The format of the requests and responses is given first as complete frames. Fragmentation is discussed next for each type of transport layer.
8.4.4.1. Request from Client to Authenticator
Request frames must have the following format
Offset | Length | Mnemonic | Description |
---|---|---|---|
0 | 1 | CMD
| Command identifier |
1 | 1 | HLEN
| High part of data length |
2 | 1 | LLEN
| Low part of data length |
3 | s | DATA
| Data (s is equal to the length) |
Supported commands are PING
, MSG
and CANCEL
.
The constant values for them are described below.
The CANCEL
command cancels any outstanding MSG
commands.
The data format for the MSG
command is defined in § 6 Message Encoding.
8.4.4.2. Response from Authenticator to Client
Response frames must have the following format, which share a similar format to the request frames:
Offset | Length | Mnemonic | Description |
---|---|---|---|
0 | 1 | STAT
| Response status |
1 | 1 | HLEN
| High part of data length |
2 | 1 | LLEN
| Low part of data length |
3 | s | DATA
| Data (s is equal to the length) |
When the status byte in the response is the same as the command
byte in the request, the response is a successful response. The
value ERROR
indicates an error, and the response data
contains an error code as a variable-length, big-endian integer. The
constant value for ERROR
is described below.
Note that the errors sent in this response are errors at the
encapsulation layer, e.g., indicating an incorrectly
formatted request, or possibly an error communicating with the
authenticator’s FIDO message processing layer. Errors reported by the
FIDO message processing layer itself are considered a success from
the encapsulation layer’s point of view and are reported as a
complete MSG
response.
Data format is defined in § 6 Message Encoding.
8.4.4.3. Command, Status, and Error constants
The COMMAND constants and values are:
Constant | Value |
---|---|
PING
| 0x81 |
KEEPALIVE
| 0x82 |
MSG
| 0x83 |
CANCEL
| 0xbe |
ERROR
| 0xbf |
The KEEPALIVE command contains a single byte with the following possible values:
Status Constant | Value |
---|---|
PROCESSING
| 0x01 |
UP_NEEDED
| 0x02 |
RFU
| 0x00, 0x03-0xFF |
The ERROR constants and values are:
Error Constant | Value | Meaning |
---|---|---|
ERR_INVALID_CMD
| 0x01 | The command in the request is unknown/invalid |
ERR_INVALID_PAR
| 0x02 | The parameter(s) of the command is/are invalid or missing |
ERR_INVALID_LEN
| 0x03 | The length of the request is invalid |
ERR_INVALID_SEQ
| 0x04 | The sequence number is invalid |
ERR_REQ_TIMEOUT
| 0x05 | The request timed out |
ERR_BUSY
| 0x06 | The device is busy and can’t accept commands at this time. The client SHOULD retry the request after a short delay. Note that the client may abort the transaction if the command is no longer relevant. |
NA
| 0x0a | Value reserved (HID) |
NA
| 0x0b | Value reserved (HID) |
ERR_OTHER
| 0x7f | Other, unspecified error |
8.4.5. GATT Service Description
This profile defines two roles: FIDO Authenticator and FIDO Client.
-
The FIDO Client SHALL be a GATT Client.
-
The FIDO Authenticator SHALL be a GATT Server.
The following figure illustrates the mandatory services and characteristics that SHALL be offered by a FIDO Authenticator as part of its GATT server:
The table below summarizes additional GATT sub-procedure requirements for a FIDO Authenticator (GATT Server) beyond those required by all GATT Servers.
GATT Sub-Procedure | Requirements |
---|---|
Write Characteristic Value | Mandatory
|
Notifications | Mandatory
|
Read Characteristic Descriptors | Mandatory
|
Write Characteristic Descriptors | Mandatory
|
The table below summarizes additional GATT sub-procedure requirements for a FIDO Client (GATT Client) beyond those required by all GATT Clients.
GATT Sub-Procedure | Requirements |
---|---|
Discover All Primary Services | (*)
|
Discover Primary Services by Service UUID | (*)
|
Discover All Characteristics of a Service | (**)
|
Discover Characteristics by UUID | (**)
|
Discover All Characteristic Descriptors | Mandatory
|
Read Characteristic Value | Mandatory
|
Write Characteristic Value | Mandatory
|
Notification | Mandatory
|
Read Characteristic Descriptors | Mandatory
|
Write Characteristic Descriptors | Mandatory
|
(*): Mandatory to support at least one of these sub-procedures. (**): Mandatory to support at least one of these sub-procedures. Other GATT sub-procedures may be used if supported by both client and server.
Specifics of each service are explained below. In the following descriptions: all values are big-endian coded, all strings are in UTF-8 encoding, and any characteristics not mentioned explicitly are optional.
8.4.5.1. FIDO Service
An authenticator SHALL implement the FIDO Service described below.
The UUID for the FIDO GATT service is 0xFFFD
; it SHALL be declared as a Primary Service.
The service contains the following characteristics:
Characteristic Name | Mnemonic | Property | Length | UUID |
---|---|---|---|---|
FIDO Control Point | fidoControlPoint
| Write | Defined by Vendor (20-512 bytes) | F1D0FFF1-DEAA-ECEE-B42F-C9BA7ED623BB |
FIDO Status | fidoStatus
| Notify | N/A | F1D0FFF2-DEAA-ECEE-B42F-C9BA7ED623BB |
FIDO Control Point Length | fidoControlPointLength
| Read | 2 bytes | F1D0FFF3-DEAA-ECEE-B42F-C9BA7ED623BB |
FIDO Service Revision Bitfield | fidoServiceRevisionBitfield
| Read/Write | Defined by Vendor (1+ bytes) | F1D0FFF4-DEAA-ECEE-B42F-C9BA7ED623BB |
FIDO Service Revision | fidoServiceRevision
| Read | Defined by Vendor (20-512 bytes) | 0x2A28 |
fidoControlPoint
is a write-only command buffer.
fidoStatus
is a notify-only response attribute.
The authenticator will send a series of notifications on this attribute
with a maximum length of (ATT_MTU-3) using the response frames defined
above. This mechanism is used because this results in a faster transfer
speed compared to a notify-read combination.
fidoControlPointLength
defines the maximum size in
bytes of a single write request to fidoControlPoint
.
This value SHALL be between 20 and 512.
fidoServiceRevision
is a deprecated field that is only relevant to
U2F 1.0 support. It defines the revision of the U2F Service.
The value is a UTF-8 string. For version 1.0 of the specification,
the value fidoServiceRevision
SHALL be 1.0
or in
raw bytes: 0x312e30
. This field SHALL be omitted if protocol
version 1.0 is not supported.
The fidoServiceRevision
Characteristic MAY include
a Characteristic Presentation Format descriptor with format value
0x19, UTF-8 String
.
fidoServiceRevisionBitfield
defines the revision of the FIDO Service.
The value is a bit field which each bit representing a version. For each
version bit the value is 1 if the version is supported, 0 if it is not.
The length of the bitfield is 1 or more bytes. All bytes that are 0 are
omitted if all the following bytes are 0 too. The byte order is big endian.
The client SHALL write a value to this characteristic with exactly 1 bit
set before sending any FIDO commands unless u2fServiceRevision is present
and U2F 1.0 compatibility is desired. If only U2F version 1.0 is supported,
this characteristic SHALL be omitted.
Byte (left to right) | Bit | Version |
---|---|---|
0 | 7 | U2F 1.1 |
0 | 6 | U2F 1.2 |
0 | 5 | FIDO2 |
0 | 4-0 | Reserved |
For example, a device that only supports FIDO2 Rev 1 will only have a fidoServiceRevisionBitfield characteristic of length 1 with value 0x20.
8.4.5.2. Device Information Service
An authenticator SHALL implement the Device Information Service [BTDIS] with the following characteristics:
-
Manufacturer Name String
-
Model Number String
-
Firmware Revision String
All values for the Device Information Service are left to the vendors. However, vendors should not create uniquely identifiable values so that authenticators do not become a method of tracking users.
8.4.5.3. Generic Access Profile Service
Every authenticator SHALL implement the Generic Access Profile Service [BTGAS] with the following characteristics:
-
Device Name
-
Appearance
8.4.6. Protocol Overview
The general overview of the communication protocol follows:
-
Authenticator advertises the FIDO Service.
-
Client scans for authenticator advertising the FIDO Service.
-
Client performs characteristic discovery on the authenticator.
-
If not already paired, the client and authenticator SHALL perform BLE pairing and create a LTK. Authenticator SHALL only allow connections from previously bonded clients without user intervention.
-
Client checks if the
fidoServiceRevisionBitfield
characteristic is present. If so, the client selects a supported version by writing a value with a single bit set. -
Client reads the
fidoControlPointLength
characteristic. -
Client registers for notifications on the
fidoStatus
characteristic. -
Client writes a request (e.g., an enroll request) into the
fidoControlPoint
characteristic. -
Optionally, the client writes a CANCEL command to the
fidoControlPoint
characteristic to cancel the pending request. -
Authenticator evaluates the request and responds by sending notifications over
fidoStatus
characteristic. -
The protocol completes when either:
-
The client unregisters for notifications on the
fidoStatus
characteristic, or: -
The connection times out and is closed by the authenticator.
-
8.4.7. Authenticator Advertising Format
When advertising, the authenticator SHALL advertise the FIDO service UUID.
When advertising, the authenticator MAY include the TxPower value in the advertisement (see [BTXPLAD]).
When advertising in pairing mode, the authenticator SHALL either: (1) set the LE Limited Mode bit to zero and the LE General Discoverable bit to one OR (2) set the LE Limited Mode bit to one and the LE General Discoverable bit to zero. When advertising in non-pairing mode, the authenticator SHALL set both the LE Limited Mode bit and the LE General Discoverable Mode bit to zero in the Advertising Data Flags.
The advertisement MAY also carry a device name which is distinctive and user-identifiable. For example, "ACME Key" would be an appropriate name, while "XJS4" would not be.
The authenticator SHALL also implement the Generic Access Profile [BTGAP] and Device Information Service [BTDIS], both of which also provide a user-friendly name for the device that could be used by the client.
It is not specified when or how often an authenticator should advertise, instead that flexibility is left to manufacturers.
8.4.8. Requests
Clients SHOULD make requests by connecting to the authenticator
and performing a write into the fidoControlPoint
characteristic.
Upon receiving a CANCEL request, if there is an outstanding request that can be cancelled, the authenticator MUST cancel it and that cancelled request will reply with the error CTAP2_ERR_KEEPALIVE_CANCEL. Whether a request was cancelled or not, the authenticator MUST NOT reply to the cancel message itself.
8.4.9. Responses
Authenticators SHOULD respond to clients by sending notifications
on the fidoStatus
characteristic.
Some authenticators might alert users or prompt them to complete the
test of user presence (e.g., via sound, light, vibration)
Upon receiving any request, the authenticators SHALL send
KEEPALIVE commands every kKeepAliveMillis
milliseconds until completing processing the commands. While the
authenticator is processing the request the KEEPALIVE command will
contain status PROCESSING
. If the authenticator is
waiting to complete the Test of User Presence, the KEEPALIVE command
will contains status UP_NEEDED
. While waiting to
complete the Test of User Presence, the authenticator MAY alert the
user (e.g., by flashing) in order to prompt the user to complete the
test of user presence.
As soon the authenticator has completed processing and confirmed
user presence, it SHALL stop sending KEEPALIVE commands, and send the
reply.
Upon receiving a KEEPALIVE command, the client SHALL assume the
authenticator is still processing the command; the client SHALL not
resend the command. The authenticator SHALL continue sending
KEEPALIVE messages at least every kKeepAliveMillis
to indicate that it is still handling the request. Until a
client-defined timeout occurs, the client SHALL NOT move on to other
devices when it receives a KEEPALIVE with UP_NEEDED
status, as it knows this is a device that can satisfy its request.
8.4.10. Framing fragmentation
A single request/response sent over Bluetooth Low Energy Technology MAY be split over multiple writes and notifications, due to the inherent limitations of Bluetooth Low Energy Technology which is not currently meant for large messages. Frames are fragmented in the following way:
A frame is divided into an initialization fragment and zero or more continuation fragments.
An initialization fragment is defined as:
Offset | Length | Mnemonic | Description |
---|---|---|---|
0 | 1 | CMD
| Command identifier |
1 | 1 | HLEN
| High part of data length |
2 | 1 | LLEN
| Low part of data length |
3 | 0 to (maxLen - 3) | DATA
| Data |
where maxLen
is the maximum packet size supported by
the characteristic or notification.
In other words, the start of an initialization fragment is
indicated by setting the high bit in the first byte. The subsequent
two bytes indicate the total length of the frame, in big-endian
order. The first maxLen
- 3 bytes of data follow.
Continuation fragments are defined as:
Offset | Length | Mnemonic | Description |
---|---|---|---|
0 | 1 | SEQ
| Packet sequence 0x00..0x7f (high bit always cleared) |
1 | 0 to (maxLen - 1) | DATA
| Data |
where maxLen
is the maximum packet size supported
by the characteristic or notification.
In other words, continuation fragments begin with a sequence number, beginning at 0, implicitly with the high bit cleared. The sequence number must wraparound to 0 after reaching the maximum sequence number of 0x7f.
Example for sending a PING
command with 40 bytes of
data with a maxLen
of 20 bytes:
Frame | Bytes |
---|---|
0 | [810028] [17 bytes of data]
|
1 | [00] [19 bytes of data]
|
2 | [01] [4 bytes of data]
|
Example for sending a ping command with 400 bytes of data with a maxLen
of 512 bytes:
Frame | Bytes |
---|---|
0 | [810190] [400 bytes of data]
|
8.4.11. Notifications
A client needs to register for notifications before it can receive them. Bluetooth Core Specification 4.0 or later [BTCORE] forces a device to remember the notification registration status over different connections [BTCCC]. Unless a client explicitly unregisters for notifications, the registration will be automatically restored when reconnecting. A client MAY therefor check the notification status upon connection and only register if notifications aren’t already registered. Please note that some clients MAY disable notifications from a power management point of view (see below) and the notification registration is remembered per bond, not per client. A client MUST NOT remember the notification status in its own data storage.
8.4.12. Request Collisions
Because there is no concept of a session between the authenticator and a client (only between the host and the client), a BLE Authenticator cannot distinguish between different clients. If two clients on the same host register for notifications from an authenticator at the same time, some existing host platforms will allow this by reusing the same underlying BLE connection. However, when the authenticator generates a notification, the host platform has insufficient information to route it to a particular client. Depending on the host platform implementation, the notification may be delivered to either or both clients. The result is undefined behavior which will likely result in both requests failing.
8.4.13. Implementation Considerations
8.4.13.1. Bluetooth pairing: Client considerations
As noted in § 8.4.2 Pairing, a disadvantage of using standard Bluetooth pairing is that the pairing is "system-wide" on most operating systems. That is, if an authenticator is paired to a FIDO client that resides on an operating system where Bluetooth pairing is "system-wide", then any application on that device might be able to interact with an authenticator. This poses both security and privacy risks to users.
While client operating system security is partly out of FIDO’s scope, further revisions of this specification MAY propose mitigations for this issue.
8.4.13.2. Bluetooth pairing: Authenticator considerations
The method to put the authenticator into Pairing Mode should be such that it is not easy for the user to do accidentally especially if the pairing method is Just Works. For example, the action could be pressing a physically recessed button or pressing multiple buttons. A visible or audible cue that the authenticator is in Pairing Mode should be considered. As a counter example, a silent, long press of a single non-recessed button is not advised as some users naturally hold buttons down during regular operation.
Note that at times, authenticators may legitimately receive communication from an unpaired device. For example, a user attempts to use an authenticator for the first time with a new client; he turns it on, but forgets to put the authenticator into pairing mode. In this situation, after connecting to the authenticator, the client will notify the user that he needs to pair his authenticator. The authenticator should make it easy for the user to do so, e.g., by not requiring the user to wait for a timeout before being able to enable pairing mode.
Some client platforms (most notably iOS) do not expose the AD Flag LE Limited and General Discoverable Mode bits to applications. For this reason, authenticators are also strongly recommended to include the Service Data field [BTSD] in the Scan Response. The Service Data field is 3 or more octets long. This allows the Flags field to be extended while using the minimum number of octets within the data packet. All octets that are 0x00 are not transmitted as long as all other octets after that octet are also 0x00 and it is not the first octet after the service UUID. The first 2 bytes contain the FIDO Service UUID, the following bytes are flag bytes.
To help clients show the correct UX, authenticators can use the Service Data field to specify whether or not authenticators will require a Passkey (PIN) during pairing.
Service Data Bit | Meaning (if set) |
---|---|
7 | Device is in pairing mode. |
6 | Device requires Passkey Entry [BTPESTK]. |
8.4.14. Handling command completion
It is important for low-power devices to be able to conserve power by shutting down or switching to a lower-power state when they have satisfied a client’s requests. However, the FIDO protocol makes this hard as it typically includes more than one command/response. This is especially true if a user has more than one key handle associated with an account or identity, multiple key handles may need to be tried before getting a successful outcome. Furthermore, clients that fail to send follow up commands in a timely fashion may cause the authenticator to drain its battery by staying powered up anticipating more commands.
A further consideration is to ensure that a user is not confused about which command she is confirming by completing the test of user presence. That is, if a user performs the test of user presence, that action should perform exactly one operation.
We combine these considerations into the following series of recommendations:
-
Upon initial connection to an authenticator, and upon receipt of a response from an authenticator, if a client has more commands to issue, the client MUST transmit the next command or fragment within
kMaxCommandTransmitDelayMillis
milliseconds. -
Upon final response from an authenticator, if the client decides it has no more commands to send it should indicate this by disabling notifications on the
fidoStatus
characteristic. When the notifications are disabled the authenticator may enter a low power state or disconnect and shut down. -
Any time the client wishes to send a FIDO message, it must have first enabled notifications on the
fidoStatus
characteristic and wait for the ATT acknowledgement to be sure the authenticator is ready to process messages. -
Upon successful completion of a command which required a test of user presence, e.g. upon a successful authentication or registration command, the authenticator can assume the client is satisfied, and MAY reset its state or power down.
-
Upon sending a command response that did not consume a test of user presence, the authenticator MUST assume that the client may wish to initiate another command and leave the connection open until the client closes it or until a timeout of at least
kErrorWaitMillis
elapses. Examples of command responses that do not consume user presence include failed authenticate or register commands, as well as get version responses, whether successful or not. AfterkErrorWaitMillis
milliseconds have elapsed without further commands from a client, an authenticator MAY reset its state or power down.
Constant | Value |
---|---|
kMaxCommandTransmitDelayMillis
| 1500 milliseconds |
kErrorWaitMillis
| 2000 milliseconds |
kKeepAliveMillis
| 500 milliseconds |
8.4.15. Data throughput
Bluetooth Low Energy Technology does not have particularly high throughput, this can cause noticeable latency to the user if request/responses are large. Some ways that implementers can reduce latency are:
-
Support the maximum MTU size allowable by hardware (up to the 512-byte max from the Bluetooth specifications).
-
Make the attestation certificate as small as possible; do not include unnecessary extensions.
8.4.16. Advertising
Though the standard does not appear to mandate it (in any way that we’ve found thus far), advertising and device discovery seems to work better when the authenticators advertise on all 3 advertising channels and not just one.
8.4.17. Authenticator Address Type
In order to enhance the user’s privacy and specifically to guard against tracking, it is recommended that authenticators use Resolvable Private Addresses (RPAs) instead of static addresses.
The transports that FIDO has defined are thus USB, NFC, and BLE.
9. Defined Extensions
This section defines authenticator extensions and any neccessary corresponding client extension processing for them.
Note: extensions may be defined such that an unsolicited extension response is generated. I.e. extension processing and output may occur without any extension input.
9.1. Credential Protection (credProtect)
9.1.1. Feature detection
To detect whether authenticator supports this feature, following conditions MUST be met:
-
Authenticator MUST return "credProtect" in extensions field in authenticatorGetInfo in addition to other extensions it may support.
-
Authenticator MUST return global maxCredentialCountInList (0x08) in authenticatorGetInfo.
-
Its value maximum number of credentials it can support in one call in a credentialId list.
-
-
Authenticator MUST return global maxCredentialIdLength (0x09) in authenticatorGetInfo.
-
Its value represents maximum credential ID length it supports.
-
This extension is only valid for an authenticator if it is protected by a user verification method.
- Extension identifier
-
credProtect
This extension indicates that the authenticator supports enhanced protection mode for the credentials created on the authenticator.
- Client extension input
-
create()
: A single USVString specifying a protection level of the credential to be created.partial dictionary AuthenticationExtensionsClientInputs {USVString
;credentialProtectionPolicy boolean
=enforceCredentialProtectionPolicy false ; }; - Client extension processing
-
If present, verify that the credentialProtectionPolicy value is one of following values:
-
userVerificationOptional:
-
This reflects "FIDO_2_0" semantics. In this configuration, user verification is optional with or without credentialID list. This is the default state of the credential if the extension is not specified and the authenticator does not report a
defaultCredProtect
value in the authenticatorGetInfo response.
-
-
userVerificationOptionalWithCredentialIDList:
-
In this configuration, credential is discovered only when its credentialID is provided by the platform or when user verification is performed.
-
-
userVerificationRequired:
-
This reflects that discovery and usage of the credential MUST be preceeded by user verification.
-
enforceCredentialProtectionPolicy controls whether it is better to fail to create a credential rather than ignore the protection policy. When enforceCredentialProtectionPolicy is true, and credentialProtectionPolicy is either userVerificationOptionalWithCredentialIDList or userVerificationRequired, the platform SHOULD NOT create the credential in a way that does not implement the requested protection policy. (For example, by creating it on an authenticator that doesn’t support this extension.)
-
- Client extension output
-
None.
- Authenticator extension input
-
Map credentialProtectionPolicy value to credProtect and send it to the authenticator.
-
authenticatorMakeCredential additional behaviors
The list of possible values for credProtect is:
credentialProtectionPolicy | credProtect Value |
---|---|
userVerificationOptional | 0x01 |
userVerificationOptionalWithCredentialIDList | 0x02 |
userVerificationRequired | 0x03 |
The platform sends the authenticatorMakeCredential request with the following CBOR map entry in the "extensions" field to the authenticator:
-
"credProtect":
- Authenticator extension processing
-
credProtect value is persisted with the Credential. If no credProtect extension was included in the request and a
defaultCredProtect
value was included in the authenticatorGetInfo response, then the authenticator MUST use that value and MUST return an unsolicited credProtect extension output. - Authenticator extension output
-
-
The authenticator responds with the following CBOR map entry in the "extensions" fields to the client:
-
"credProtect":
-
-
9.2. HMAC Secret Extension (hmac-secret)
- Extension identifier
-
hmac-secret
This extension is used by the platform to retrieve a symmetric secret from the authenticator when it needs to encrypt or decrypt data using that symmetric secret. This symmetric secret is scoped to a credential. The authenticator and the platform each only have the part of the complete secret to prevent offline attacks. This extension can be used to maintain different secrets on different machines.
- Client extension input
-
create()
: A boolean value to indicate that this extension is requested by the Relying Party.partial dictionary AuthenticationExtensionsClientInputs {boolean
; };hmacCreateSecret get()
: A JavaScript object defined as follows:dictionary
{HMACGetSecretInput required ArrayBuffer
; // 32-byte random datasalt1 ArrayBuffer
; // Optional additional 32-byte random data };salt2 partial dictionary AuthenticationExtensionsClientInputs {HMACGetSecretInput
; };hmacGetSecret The salt2 input is optional. It can be used when the platform wants to roll over the symmetric secret in one operation.
- Client extension processing
-
-
If present in a
create()
:-
If set to true, pass a CBOR true value as the authenticator extension input.
-
If set to false, do not process this extension.
-
-
If present in a
get()
:-
Verify that salt1 is a 32-byte ArrayBuffer.
-
If salt2 is present, verify that it is a 32-byte ArrayBuffer.
-
Pass salt1 and, if present, salt2 as the authenticator extension input.
-
-
- Client extension output
-
create()
: Boolean true value indicating that the authenticator has processed the extension.partial dictionary AuthenticationExtensionsClientOutputs {boolean
; };hmacCreateSecret get()
: A dictionary with the following data:dictionary
{HMACGetSecretOutput required ArrayBuffer
;output1 ArrayBuffer
; };output2 partial dictionary AuthenticationExtensionsClientOutputs {HMACGetSecretOutput
; };hmacGetSecret - Authenticator extension input
-
Same as the client extension input, except represented in CBOR.
- Authenticator extension processing
-
authenticatorGetInfo additional behaviors
The authenticator indicates to the platform that it supports the "hmac-secret" extension via the "extensions" parameter in the authenticatorGetInfo response.
-
authenticatorMakeCredential additional behaviors
The platform sends the authenticatorMakeCredential request with the following CBOR map entry in the "extensions" field to the authenticator:
-
"hmac-secret": true
-
The authenticator generates two random 32-byte values (called
CredRandomWithUV
andCredRandomWithoutUV
) and associates it with the credential. -
The authenticator responds with the following CBOR map entry in the "extensions" fields to the authenticator:
-
"hmac-secret": true
-
-
-
authenticatorGetAssertion additional behaviors
-
The platform gets sharedSecret from the authenticator.
-
The platform sends the authenticatorGetAssertion request with the following CBOR map entry in the "extensions" field to the authenticator:
-
"hmac-secret":
-
keyAgreement(0x01): public key of platformKeyAgreementKey, "bG".
-
saltEnc(0x02): Encrypt one or two salts (Called salt1 (32 bytes) and salt2 (32 bytes)) using sharedSecret as follows:
-
One salt case:
AES256-CBC(sharedSecret, IV=0, salt1 (32 bytes))
. -
Two salt case:
AES256-CBC(sharedSecret, IV=0, salt1 (32 bytes) || salt2 (32 bytes))
.
-
-
saltAuth(0x03):
LEFT(HMAC-SHA-256(sharedSecret, saltEnc), 16)
.-
The platform sends the first 16 bytes of the HMAC-SHA-256 result.
-
-
-
-
The authenticator performs the following operations when processing this extension:
-
If "up" is set to false, authenticator returns CTAP2_ERR_UNSUPPORTED_OPTION.
-
The authenticator waits for user consent.
-
If request asks for user verification, authenticator waits for user verification.
-
If user verification is requested via Client PIN mechanism, verify the user by verifying the Client PIN parameters in the request as mentioned in the authenticatorGetAssertion steps.
-
If user verification is requested via built in "uv" method, verify the user by built-in user verification method as mentioned in the authenticatorGetAssertion steps.
-
-
The authenticator generates "sharedSecret":
SHA-256((abG).x)
using the private key of authenticatorKeyAgreementKey, "a" and the public key of platformKeyAgreementKey, "bG".-
SHA-256 is done over only the
"x"
curve point of"abG"
. -
See [RFC6090] Section 4.1 and Appendix (C.2) of [SP800-56A] for more ECDH key agreement protocol details and key representation information.
-
-
The authenticator verifies saltEnc by generating
LEFT(HMAC-SHA-256(sharedSecret, saltEnc), 16)
and matching against the input saltAuth parameter. -
The authenticator chooses which
CredRandom
to use for next step based on whether user verification was done or not in above steps.-
If uv bit is set to 1 in the response, let
CredRandom
beCredRandomWithUV
. -
If uv bit is set to 0 in the response, let
CredRandom
beCredRandomWithoutUV
.
-
-
The authenticator generates one or two HMAC-SHA-256 values, depending upon whether it received one salt (32 bytes) or two salts (64 bytes):
-
output1:
HMAC-SHA-256(CredRandom, salt1)
-
output2:
HMAC-SHA-256(CredRandom, salt2)
-
-
The authenticator returns output1 and, when there were two salts, output2 encrypted to the platform using sharedSecret as part of "extensions" parameter:
-
One salt case:
"hmac-secret": AES256-CBC(sharedSecret, IV=0, output1 (32 bytes))
-
Two salt case:
"hmac-secret": AES256-CBC(sharedSecret, IV=0, output1 (32 bytes) || output2 (32 bytes))
-
-
-
- Authenticator extension output
-
Same as the client extension output, except represented in CBOR.
10. IANA Considerations
10.1. WebAuthn Extension Identifier Registrations
This section registers the extension identifier values defined in Section § 9 Defined Extensions in the IANA "WebAuthn Extension Identifier" registry.
-
WebAuthn Extension Identifier: credProtect
-
This registration extension allows relying parties to specify a credential protection policy when creating a credential. Additionally, authenticators may choose to establish a default credential protection policy greater than
userVerificationOptional
(the lowest level) and unilateraly enforce such policy. -
Specification Document: Section § 9.1 Credential Protection (credProtect) of this specification
-
WebAuthn Extension Identifier: hmac-secret
-
Description: This registration extension and authentication extension enables the platform to retrieve a symmetric secret scoped to the credential from the authenticator.
-
Specification Document: Section § 9.2 HMAC Secret Extension (hmac-secret) of this specification
11. Security Considerations
See FIDO Security Reference document [FIDOSecRef].