mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
675 lines
22 KiB
C
675 lines
22 KiB
C
/*
|
|
* Copyright (C) 2021 Freie Universität Berlin
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
|
|
/**
|
|
* @defgroup fido2_ctap_ctap FIDO2 CTAP
|
|
* @ingroup fido2_ctap
|
|
* @brief FIDO2 CTAP
|
|
*
|
|
* The Client-to-Authenticator Protocol (CTAP) is an application layer protocol
|
|
* for the communication between an authenticator and a host.
|
|
*
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief Internal FIDO2 CTAP defines, structures and function declarations
|
|
*
|
|
* @author Nils Ollrogge <nils.ollrogge@fu-berlin.de>
|
|
*/
|
|
|
|
#ifndef FIDO2_CTAP_CTAP_H
|
|
#define FIDO2_CTAP_CTAP_H
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "mutex.h"
|
|
#include "cbor.h"
|
|
#include "assert.h"
|
|
#include "crypto/modes/ccm.h"
|
|
#include "timex.h"
|
|
#include "board.h"
|
|
|
|
#include "fido2/ctap.h"
|
|
#include "fido2/ctap/ctap_crypto.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @brief Size of pin auth
|
|
*
|
|
* First 16 bytes of a HMAC-256.
|
|
*
|
|
* CTAP specification (version 20190130) section 5.5.8.2.
|
|
*/
|
|
#define CTAP_PIN_AUTH_SZ 16
|
|
|
|
/**
|
|
* @name CTAP methods
|
|
*
|
|
* @{
|
|
*/
|
|
#define CTAP_MAKE_CREDENTIAL 0x01 /**< authenticatorMakeCredential method */
|
|
#define CTAP_GET_ASSERTION 0x02 /**< authenticatorGetAssertion method */
|
|
#define CTAP_GET_INFO 0x04 /**< authenticatorGetInfo method */
|
|
#define CTAP_CLIENT_PIN 0x06 /**< authenticatorClientPIN method */
|
|
#define CTAP_RESET 0x07 /**< authenticatorReset method */
|
|
#define CTAP_GET_NEXT_ASSERTION 0x08 /**< authenticatorGetNextAssertion method */
|
|
/** @} */
|
|
|
|
/**
|
|
* @name CTAP authenticator data option flags
|
|
*
|
|
* @{
|
|
*/
|
|
#define CTAP_AUTH_DATA_FLAG_UP (1 << 0) /**< user present */
|
|
#define CTAP_AUTH_DATA_FLAG_UV (1 << 2) /**< user verified */
|
|
#define CTAP_AUTH_DATA_FLAG_AT (1 << 6) /**< attested credential data included */
|
|
#define CTAP_AUTH_DATA_FLAG_ED (1 << 7) /**< extension data included */
|
|
/** @} */
|
|
|
|
/**
|
|
* @name CTAP version flags
|
|
*
|
|
* @{
|
|
*/
|
|
#define CTAP_VERSION_FLAG_FIDO_PRE 0x01 /**< FIDO 2.1 flag */
|
|
#define CTAP_VERSION_FLAG_FIDO 0x02 /**< FIDO 2 flag */
|
|
#define CTAP_VERSION_FLAG_U2F_V2 0x04 /**< U2F V2 flag */
|
|
/** @} */
|
|
|
|
/**
|
|
* @name CTAP get info response options map CBOR key values
|
|
*
|
|
* All options are in the form key-value pairs with string IDs and
|
|
* boolean values
|
|
* @{
|
|
*/
|
|
#define CTAP_GET_INFO_RESP_OPTIONS_ID_PLAT "plat" /**< platform device string */
|
|
#define CTAP_GET_INFO_RESP_OPTIONS_ID_RK "rk" /**< resident key string */
|
|
#define CTAP_GET_INFO_RESP_OPTIONS_ID_CLIENT_PIN "clientPin" /**< client PIN string */
|
|
#define CTAP_GET_INFO_RESP_OPTIONS_ID_UP "up" /**< user presence string */
|
|
#define CTAP_GET_INFO_RESP_OPTIONS_ID_UV "uv" /**< user verification string */
|
|
/** @} */
|
|
|
|
/**
|
|
* @name CTAP get info options flags
|
|
*
|
|
* @{
|
|
*/
|
|
#define CTAP_INFO_OPTIONS_FLAG_PLAT (1 << 0) /**< platform device flag */
|
|
#define CTAP_INFO_OPTIONS_FLAG_RK (1 << 1) /**< resident key flag */
|
|
#define CTAP_INFO_OPTIONS_FLAG_CLIENT_PIN (1 << 2) /**< clientPIN flag */
|
|
#define CTAP_INFO_OPTIONS_FLAG_UP (1 << 3) /**< user presence flag */
|
|
#define CTAP_INFO_OPTIONS_FLAG_UV (1 << 4) /**< user verification flag */
|
|
/** @} */
|
|
|
|
/**
|
|
* @name CTAP Client PIN request subCommand CBOR key values
|
|
*
|
|
* @{
|
|
*/
|
|
#define CTAP_CP_REQ_SUB_COMMAND_GET_RETRIES 0x01 /**< getRetries subCommand */
|
|
#define CTAP_CP_REQ_SUB_COMMAND_GET_KEY_AGREEMENT 0x02 /**< getKeyAgreement subCommand */
|
|
#define CTAP_CP_REQ_SUB_COMMAND_SET_PIN 0x03 /**< setPIN subCommand */
|
|
#define CTAP_CP_REQ_SUB_COMMAND_CHANGE_PIN 0x04 /**< changePIN subCommand */
|
|
#define CTAP_CP_REQ_SUB_COMMAND_GET_PIN_TOKEN 0x05 /**< getPinToken subCommand */
|
|
/** @} */
|
|
|
|
/**
|
|
* @brief CTAP thread stack size
|
|
*/
|
|
#ifdef CONFIG_FIDO2_CTAP_STACK_SIZE
|
|
#define CTAP_STACKSIZE CONFIG_FIDO2_CTAP_STACK_SIZE
|
|
#else
|
|
#define CTAP_STACKSIZE 15000
|
|
#endif
|
|
|
|
#if !IS_ACTIVE(CONFIG_FIDO2_CTAP_DISABLE_UP)
|
|
/**
|
|
* @brief CTAP user presence button
|
|
*/
|
|
#if defined(CONFIG_FIDO2_CTAP_UP_BUTTON_PORT) && defined(CONFIG_FIDO2_CTAP_UP_BUTTON_PIN) && \
|
|
(CONFIG_FIDO2_CTAP_UP_BUTTON_PORT >= 0) && (CONFIG_FIDO2_CTAP_UP_BUTTON_PIN >= 0)
|
|
#define CTAP_UP_BUTTON GPIO_PIN(CONFIG_FIDO2_CTAP_UP_BUTTON_PORT, CONFIG_FIDO2_CTAP_UP_BUTTON_PIN)
|
|
#else
|
|
/* set default button if no button is configured */
|
|
#ifdef BTN0_PIN
|
|
#define CTAP_UP_BUTTON BTN0_PIN
|
|
/* if no button available disable UP test */
|
|
#else
|
|
#define CONFIG_FIDO2_CTAP_DISABLE_UP 1
|
|
#endif
|
|
#endif
|
|
|
|
/**
|
|
* @brief CTAP user presence button mode
|
|
*/
|
|
#if IS_ACTIVE(CONFIG_FIDO2_CTAP_UP_BUTTON_MODE_IN_PU)
|
|
#define CTAP_UP_BUTTON_MODE GPIO_IN_PU
|
|
#elif IS_ACTIVE(CONFIG_FIDO2_CTAP_UP_BUTTON_MODE_IN_PD)
|
|
#define CTAP_UP_BUTTON_MODE GPIO_IN_PD
|
|
#elif IS_ACTIVE(CONFIG_FIDO2_CTAP_UP_BUTTON_MODE_IN)
|
|
#define CTAP_UP_BUTTON_MODE GPIO_IN
|
|
#else
|
|
#define CTAP_UP_BUTTON_MODE GPIO_IN_PU
|
|
#endif
|
|
|
|
/**
|
|
* @brief CTAP user presence button flank
|
|
*/
|
|
#if IS_ACTIVE(CONFIG_FIDO2_CTAP_UP_BUTTON_FLANK_FALLING)
|
|
#define CTAP_UP_BUTTON_FLANK GPIO_FALLING
|
|
#elif IS_ACTIVE(CONFIG_FIDO2_CTAP_UP_BUTTON_FLANK_RISING)
|
|
#define CTAP_UP_BUTTON_FLANK GPIO_RISING
|
|
#elif IS_ACTIVE(CONFIG_FIDO2_CTAP_UP_BUTTON_FLANK_BOTH)
|
|
#define CTAP_UP_BUTTON_FLANK GPIO_BOTH
|
|
#else
|
|
#define CTAP_UP_BUTTON_FLANK GPIO_FALLING
|
|
#endif
|
|
|
|
#endif /* !IS_ACTIVE(CONFIG_FIDO2_CTAP_DISABLE_UP) */
|
|
|
|
/**
|
|
* @brief Max size of relying party name
|
|
*/
|
|
#define CTAP_RP_MAX_NAME_SIZE 32
|
|
|
|
/**
|
|
* @brief Max size of username including null character
|
|
*/
|
|
#define CTAP_USER_MAX_NAME_SIZE 64 + 1
|
|
|
|
/**
|
|
* @brief Max size of user id
|
|
*/
|
|
#define CTAP_USER_ID_MAX_SIZE 64
|
|
|
|
/**
|
|
* @brief Max size of a domain name including null character
|
|
*/
|
|
#define CTAP_DOMAIN_NAME_MAX_SIZE 253 + 1
|
|
|
|
/**
|
|
* @brief Max size of icon including null character
|
|
*/
|
|
#define CTAP_ICON_MAX_SIZE 128 + 1
|
|
|
|
/**
|
|
* @brief PIN min size
|
|
*/
|
|
#define CTAP_PIN_MIN_SIZE 4
|
|
|
|
/**
|
|
* @brief Encrypted newPin min size
|
|
*
|
|
* Encrypted PIN is padded with trailing 0x00 bytes to a minimum length
|
|
* of 64 in order to prevent leak of PIN length.
|
|
*/
|
|
#define CTAP_PIN_ENC_MIN_SIZE 64
|
|
|
|
/**
|
|
* @brief Encrypted newPin max size
|
|
*
|
|
*/
|
|
#define CTAP_PIN_ENC_MAX_SIZE 256
|
|
|
|
/**
|
|
* @brief PIN max size
|
|
*/
|
|
#define CTAP_PIN_MAX_SIZE 64
|
|
|
|
/**
|
|
* @brief Max total consecutive incorrect PIN attempts
|
|
*/
|
|
#define CTAP_PIN_MAX_ATTS 8
|
|
|
|
/**
|
|
* @brief Max consecutive incorrect PIN attempts for 1 boot cycle
|
|
*/
|
|
#define CTAP_PIN_MAX_ATTS_BOOT 3
|
|
|
|
/**
|
|
* @brief PIN protocol version
|
|
*/
|
|
#define CTAP_PIN_PROT_VER 1
|
|
|
|
/**
|
|
* @brief Total number of supported PIN protocol versions
|
|
*/
|
|
#define CTAP_AMT_SUP_PIN_VER 1
|
|
|
|
/**
|
|
* @brief Size of pin token
|
|
*
|
|
* Needs to be a multiple of 16 bytes (AES block length).
|
|
*/
|
|
#define CTAP_PIN_TOKEN_SZ 16
|
|
|
|
/**
|
|
* @brief Size of key used to encrypt credential
|
|
*
|
|
* Needed if authenticator is unable to store resident keys.
|
|
* See webauthn specification (version 20190304) section 4 (Credential ID)
|
|
* for details.
|
|
*/
|
|
#define CTAP_CRED_KEY_LEN 16
|
|
|
|
/**
|
|
* @brief AES_CCM_L parameter
|
|
*
|
|
* L has to be between 2 and 8. Value of 2 means that message has to be
|
|
* in the range 0 <= l(m) < 2^(16) = 65536.
|
|
* This should always be sufficient to send an encrypted resident key.
|
|
*/
|
|
#define CTAP_AES_CCM_L 2
|
|
|
|
/**
|
|
* @brief AES CCM nonce size
|
|
*/
|
|
#define CTAP_AES_CCM_NONCE_SIZE (15 - CTAP_AES_CCM_L)
|
|
|
|
/**
|
|
* @brief Total size of AES CCM credential id
|
|
*
|
|
* Size of encrypted resident key = resident key - cred id - has_nonce
|
|
*/
|
|
#define CTAP_CREDENTIAL_ID_ENC_SIZE (sizeof(struct ctap_resident_key) - \
|
|
sizeof(((struct ctap_resident_key *)0)-> \
|
|
cred_desc.cred_id) - \
|
|
sizeof(((struct ctap_resident_key *)0)-> \
|
|
cred_desc.has_nonce))
|
|
|
|
/**
|
|
* @brief Timeout for user presence test
|
|
*/
|
|
#ifdef CONFIG_FIDO2_CTAP_UP_TIMEOUT
|
|
#define CTAP_UP_TIMEOUT (CONFIG_FIDO2_CTAP_UP_TIMEOUT * MS_PER_SEC)
|
|
#else
|
|
#define CTAP_UP_TIMEOUT (15 * MS_PER_SEC)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Max time between call to get_assertion or get_next_assertion until
|
|
* error is returned
|
|
*/
|
|
#define CTAP_GET_NEXT_ASSERTION_TIMEOUT (30 * MS_PER_SEC)
|
|
|
|
/**
|
|
* 128 bit identifier of authenticator
|
|
*/
|
|
#ifdef CONFIG_FIDO2_CTAP_DEVICE_AAGUID
|
|
#define CTAP_AAGUID CONFIG_FIDO2_CTAP_DEVICE_AAGUID
|
|
#else
|
|
/* randomly generated fallback value */
|
|
#define CTAP_AAGUID "9c295865fa2c36b705a42320af9c8f16"
|
|
#endif
|
|
|
|
/**
|
|
* @name CTAP credential types
|
|
*
|
|
* @{
|
|
*/
|
|
#define CTAP_PUB_KEY_CRED_PUB_KEY 0x01 /**< public key credential type */
|
|
#define CTAP_PUB_KEY_CRED_UNKNOWN 0x02 /**< unknown credential type */
|
|
/** @} */
|
|
|
|
/**
|
|
* @name CTAP COSE key CBOR map key values
|
|
*
|
|
* @{
|
|
*/
|
|
#define CTAP_COSE_KEY_LABEL_KTY 1 /**< key type identifier */
|
|
#define CTAP_COSE_KEY_LABEL_ALG 3 /**< algorithm identifier */
|
|
#define CTAP_COSE_KEY_LABEL_CRV -1 /**< elliptic curve identifier */
|
|
#define CTAP_COSE_KEY_LABEL_X -2 /**< x coordinate */
|
|
#define CTAP_COSE_KEY_LABEL_Y -3 /**< y coordinate */
|
|
#define CTAP_COSE_KEY_KTY_EC2 2 /**< 2 coordinate elliptic curve key identifier */
|
|
#define CTAP_COSE_KEY_CRV_P256 1 /**< secp256r1 elliptic curve key identifier */
|
|
/** @} */
|
|
|
|
/**
|
|
* @brief CTAP size of authenticator AAGUID in bytes
|
|
*/
|
|
#define CTAP_AAGUID_SIZE 16
|
|
|
|
/**
|
|
* @brief CTAP COSE Algorithms registry identifier for ES256
|
|
*/
|
|
#define CTAP_COSE_ALG_ES256 -7
|
|
|
|
/**
|
|
* @brief CTAP COSE Algorithms registry identifier for ECDH ES HKDF 256
|
|
*/
|
|
#define CTAP_COSE_ALG_ECDH_ES_HKDF_256 -25
|
|
|
|
/**
|
|
* @brief CTAP size of credential id
|
|
*
|
|
*/
|
|
#define CTAP_CREDENTIAL_ID_SIZE 16U
|
|
|
|
/**
|
|
* @brief CTAP state initialized marker
|
|
*
|
|
* Used to check if authenticator state has already been initialized when
|
|
* reading data from flash.
|
|
*/
|
|
#define CTAP_INITIALIZED_MARKER 0x4e
|
|
|
|
/**
|
|
* @brief Max size of allow list
|
|
*/
|
|
#define CTAP_MAX_EXCLUDE_LIST_SIZE 0x10
|
|
|
|
/**
|
|
* @brief CTAP cred struct forward declaration
|
|
*/
|
|
typedef struct ctap_cred_desc ctap_cred_desc_t;
|
|
|
|
/**
|
|
* @brief Alternative CTAP cred struct forward declaration
|
|
*/
|
|
typedef struct ctap_cred_desc_alt ctap_cred_desc_alt_t;
|
|
|
|
/**
|
|
* @brief CTAP resident key credential forward declaration
|
|
*/
|
|
typedef struct ctap_resident_key ctap_resident_key_t;
|
|
|
|
/**
|
|
* @brief CTAP authenticator config struct
|
|
*/
|
|
typedef struct {
|
|
uint8_t aaguid[CTAP_AAGUID_SIZE]; /**< AAGUID of device */
|
|
uint8_t options; /**< options */
|
|
} ctap_config_t;
|
|
|
|
/**
|
|
* @brief CTAP state struct
|
|
*
|
|
* state of authenticator. Stored in flash memory
|
|
*/
|
|
typedef struct {
|
|
ctap_config_t config; /**< configuration of authenticator */
|
|
ctap_crypto_key_agreement_key_t ag_key; /**< Platform key agreement key */
|
|
int rem_pin_att; /**< remaining PIN tries */
|
|
uint16_t rk_amount_stored; /**< total number of resident keys stored on device */
|
|
uint8_t initialized_marker; /**< CTAP initialized marker */
|
|
uint8_t pin_hash[SHA256_DIGEST_LENGTH / 2]; /**< LEFT(SHA-256(pin), 16) */
|
|
uint8_t cred_key[CTAP_CRED_KEY_LEN]; /**< AES CCM encryption key for cred */
|
|
bool cred_key_is_initialized; /**< AES CCM key initialized flag */
|
|
bool pin_is_set; /**< PIN is set or not */
|
|
} ctap_state_t;
|
|
|
|
/**
|
|
* @brief CTAP options struct
|
|
*/
|
|
typedef struct {
|
|
int rk; /**< resident key */
|
|
int uv; /**< user verification */
|
|
int up; /**< user presence */
|
|
} ctap_options_t;
|
|
|
|
/**
|
|
* @brief CTAP user entity struct
|
|
*/
|
|
typedef struct {
|
|
uint8_t id[CTAP_USER_ID_MAX_SIZE]; /**< RP-specific user account id */
|
|
uint8_t id_len; /**< actual length of user id */
|
|
uint8_t name[CTAP_USER_MAX_NAME_SIZE]; /**< user name */
|
|
uint8_t display_name[CTAP_USER_MAX_NAME_SIZE]; /**< user display name */
|
|
uint8_t icon[CTAP_DOMAIN_NAME_MAX_SIZE]; /**< URL referencing user icon image */
|
|
} ctap_user_ent_t;
|
|
|
|
/**
|
|
* @brief CTAP relying party entity struct
|
|
*
|
|
*/
|
|
typedef struct {
|
|
uint8_t id[CTAP_DOMAIN_NAME_MAX_SIZE + 1]; /**< relying party identifier */
|
|
uint8_t id_len; /**< actual length of
|
|
relying party identifier */
|
|
uint8_t name[CTAP_RP_MAX_NAME_SIZE + 1]; /**< human friendly relying
|
|
party name */
|
|
uint8_t icon[CTAP_DOMAIN_NAME_MAX_SIZE + 1]; /**< URL referencing relying
|
|
party icon image */
|
|
} ctap_rp_ent_t;
|
|
|
|
/**
|
|
* @brief CTAP cose key struct
|
|
*
|
|
* https://www.iana.org/assignments/cose/cose.xhtml
|
|
*/
|
|
typedef struct {
|
|
ctap_crypto_pub_key_t pubkey; /**< public key */
|
|
int kty; /**< identification of key type */
|
|
int crv; /**< EC identifier */
|
|
int32_t alg_type; /**< COSEAlgorithmIdentifier */
|
|
uint8_t cred_type; /**< type of credential */
|
|
} ctap_public_key_cose_t;
|
|
|
|
/**
|
|
* @brief CTAP credential description struct
|
|
*
|
|
* Webauthn specification (version 20190304) section 5.8.3
|
|
*
|
|
* @warning reordering this struct will break the AES CCM encryption of
|
|
* resident keys.
|
|
*/
|
|
struct ctap_cred_desc {
|
|
uint8_t cred_type; /**< type of credential */
|
|
union {
|
|
uint8_t cred_id[CTAP_CREDENTIAL_ID_SIZE]; /**< credential identifier */
|
|
uint8_t nonce[CTAP_AES_CCM_NONCE_SIZE]; /**< CTAP AES CCM nonce */
|
|
};
|
|
bool has_nonce; /**< Indicate if nonce or
|
|
cred_id */
|
|
};
|
|
|
|
/**
|
|
* @brief CTAP resident key struct
|
|
*
|
|
* A resident key is a fido2 credential that is being stored on the
|
|
* authenticator.
|
|
*/
|
|
struct __attribute__((packed)) ctap_resident_key {
|
|
uint8_t rp_id_hash[SHA256_DIGEST_LENGTH]; /**< hash of rp domain string */
|
|
uint8_t user_id[CTAP_USER_ID_MAX_SIZE]; /**< id of user */
|
|
uint8_t user_id_len; /**< length of the user id */
|
|
uint8_t priv_key[CTAP_CRYPTO_KEY_SIZE]; /**< private key */
|
|
uint32_t sign_count; /**< signature counter.
|
|
See webauthn specification
|
|
(version 20190304) section 6.1.1
|
|
for details. */
|
|
uint32_t creation_time; /**< timestamp for when credential
|
|
was created */
|
|
ctap_cred_desc_t cred_desc; /**< credential descriptor */
|
|
};
|
|
|
|
/**
|
|
* @brief CTAP credential ID
|
|
*
|
|
* Credential ID can either be 16 random bytes or the encrypted resident
|
|
* key. (AES CCM cipher + mac + nonce used)
|
|
*/
|
|
typedef struct __attribute__((packed)) {
|
|
uint8_t id[CTAP_CREDENTIAL_ID_ENC_SIZE]; /**< id */
|
|
uint8_t mac[CCM_MAC_MAX_LEN]; /**< AES CCM MAC */
|
|
uint8_t nonce[CTAP_AES_CCM_NONCE_SIZE]; /**< AES CCM nonce */
|
|
} ctap_cred_id_t;
|
|
|
|
/**
|
|
* @brief CTAP credential description alternative struct
|
|
*
|
|
* This struct is used when parsing an allow or exclude list.
|
|
*/
|
|
struct ctap_cred_desc_alt {
|
|
uint8_t cred_type; /**< type of credential */
|
|
ctap_cred_id_t cred_id; /**< credential id */
|
|
};
|
|
|
|
/**
|
|
* @brief CTAP make credential request struct
|
|
*/
|
|
typedef struct {
|
|
ctap_cred_desc_alt_t exclude_list[CTAP_MAX_EXCLUDE_LIST_SIZE]; /**< exclude list */
|
|
size_t exclude_list_len; /**< length of CBOR exclude list array */
|
|
ctap_rp_ent_t rp; /**< relying party */
|
|
ctap_user_ent_t user; /**< user */
|
|
ctap_options_t options; /**< parameters to influence authenticator operation */
|
|
uint8_t client_data_hash[SHA256_DIGEST_LENGTH]; /**< SHA-256 hash of JSON serialized client data */
|
|
uint8_t pin_auth[CTAP_PIN_AUTH_SZ]; /**< pin_auth if PIN is set */
|
|
size_t pin_auth_len; /**< pin_auth len */
|
|
int32_t alg_type; /**< cryptographic algorithm identifier */
|
|
bool pin_auth_present; /**< pin_auth present */
|
|
uint8_t pin_protocol; /**< PIN protocol version */
|
|
uint8_t cred_type; /**< type of credential */
|
|
} ctap_make_credential_req_t;
|
|
|
|
/**
|
|
* @brief CTAP get assertion request struct
|
|
*/
|
|
typedef struct {
|
|
ctap_options_t options; /**< parameters to influence authenticator operation */
|
|
ctap_cred_desc_alt_t allow_list[CTAP_MAX_EXCLUDE_LIST_SIZE]; /**< allow list */
|
|
uint8_t client_data_hash[SHA256_DIGEST_LENGTH]; /**< SHA-256 hash of JSON serialized client data */
|
|
uint8_t rp_id[CTAP_DOMAIN_NAME_MAX_SIZE + 1]; /**< Relying Party Identifier */
|
|
uint8_t rp_id_len; /**< Actual Length of Relying Party Identifier */
|
|
uint8_t allow_list_len; /**< length of CBOR allow list array */
|
|
uint8_t pin_auth[CTAP_PIN_AUTH_SZ]; /**< pin_auth if PIN is set */
|
|
size_t pin_auth_len; /**< pin_auth length */
|
|
uint8_t pin_protocol; /**< PIN protocol version */
|
|
bool pin_auth_present; /**< indicate if pin_auth present */
|
|
} ctap_get_assertion_req_t;
|
|
|
|
/**
|
|
* @brief CTAP client pin request struct
|
|
*/
|
|
typedef struct {
|
|
ctap_public_key_cose_t key_agreement; /**< public key of platform_key_agreement_key*/
|
|
uint16_t new_pin_enc_size; /**< size of encrypted new pin */
|
|
uint8_t pin_auth[CTAP_PIN_AUTH_SZ]; /**< first 16 bytes of HMAC-SHA-256 of encrypted contents */
|
|
uint8_t new_pin_enc[CTAP_PIN_ENC_MAX_SIZE]; /**< Encrypted new PIN using sharedSecret. */
|
|
uint8_t pin_hash_enc[SHA256_DIGEST_LENGTH / 2]; /**< Encrypted first 16 bytes of SHA-256 of PIN using sharedSecret. */
|
|
uint8_t sub_command; /**< authenticator Client PIN sub command */
|
|
uint8_t pin_protocol; /**< PIN protocol version chosen by the client */
|
|
bool pin_hash_enc_present; /**< indicate pin_hash_enc is present */
|
|
bool pin_auth_present; /**< indicate if pin_auth present */
|
|
bool key_agreement_present; /**< indicate if key_agreement present */
|
|
} ctap_client_pin_req_t;
|
|
|
|
/**
|
|
* @brief CTAP attested credential data header struct
|
|
*
|
|
* Defined for easier serialization
|
|
*/
|
|
typedef struct __attribute__((packed)){
|
|
uint8_t aaguid[CTAP_AAGUID_SIZE]; /**< authenticator aaguid */
|
|
uint8_t cred_len_h; /**< higher byte of credential length */
|
|
uint8_t cred_len_l; /**< lower byte of credential length */
|
|
ctap_cred_id_t cred_id; /**< credential id */
|
|
} ctap_attested_cred_data_header_t;
|
|
|
|
/**
|
|
* @brief CTAP attested credential data struct
|
|
*/
|
|
typedef struct {
|
|
ctap_attested_cred_data_header_t header; /**< attested credential data header */
|
|
ctap_public_key_cose_t key; /**< cose key */
|
|
} ctap_attested_cred_data_t;
|
|
|
|
/**
|
|
* @brief CTAP authenticator data header struct
|
|
*
|
|
* Defined for easier serialization
|
|
*/
|
|
typedef struct __attribute__((packed)){
|
|
uint8_t rp_id_hash[SHA256_DIGEST_LENGTH]; /**< hash of relying party id */
|
|
uint8_t flags; /**< flags indicating result of user verification */
|
|
uint32_t sign_count; /**< sign count of credential */
|
|
} ctap_auth_data_header_t;
|
|
|
|
/**
|
|
* @brief CTAP authenticator data struct
|
|
*/
|
|
typedef struct {
|
|
ctap_auth_data_header_t header; /**< auth data header */
|
|
ctap_attested_cred_data_t attested_cred_data; /**< attested credential data */
|
|
} ctap_auth_data_t;
|
|
|
|
/**
|
|
* @brief CTAP info struct
|
|
*/
|
|
typedef struct {
|
|
uint16_t max_msg_size; /**< max message size */
|
|
uint8_t aaguid[CTAP_AAGUID_SIZE]; /**< AAGUID */
|
|
uint8_t versions; /**< supported versions of FIDO */
|
|
uint8_t options; /**< supported options */
|
|
uint8_t pin_protocol; /**< supported PIN protocol versions */
|
|
bool pin_is_set; /**< PIN is set or not */
|
|
} ctap_info_t;
|
|
|
|
/**
|
|
* @brief Create signature from authenticator data
|
|
*
|
|
* Used for attestation and assertion statement.
|
|
*
|
|
* @param[in] auth_data authenticator data
|
|
* @param[in] auth_data_len length of @p auth_data
|
|
* @param[in] client_data_hash hash of client data sent by relying party in request
|
|
* @param[in] rk resident key used to sign the data
|
|
* @param[in] sig signature buffer
|
|
* @param[in] sig_len length of @p sig
|
|
*
|
|
* @return @ref ctap_status_codes_t
|
|
*/
|
|
int fido2_ctap_get_sig(const uint8_t *auth_data, size_t auth_data_len,
|
|
const uint8_t *client_data_hash,
|
|
const ctap_resident_key_t *rk,
|
|
uint8_t *sig, size_t *sig_len);
|
|
|
|
/**
|
|
* @brief Check if requested algorithm is supported
|
|
*
|
|
* @param[in] cred_type type of credential
|
|
* @param[in] alg_type cryptographic algorithm identifier
|
|
*
|
|
* @return true if algorithm is supported
|
|
* @return false otherwise
|
|
*/
|
|
bool fido2_ctap_cred_params_supported(uint8_t cred_type, int32_t alg_type);
|
|
|
|
/**
|
|
* @brief Encrypt resident key with AES CCM
|
|
*
|
|
* @param[in] rk type of credential
|
|
* @param[in] nonce CCM nonce
|
|
* @param[in] nonce_len length of @p nonce
|
|
* @param[in] id credential id struct storing encrypted resident key
|
|
*
|
|
* @return @ref ctap_status_codes_t
|
|
*/
|
|
int fido2_ctap_encrypt_rk(ctap_resident_key_t *rk, uint8_t *nonce,
|
|
size_t nonce_len, ctap_cred_id_t *id);
|
|
|
|
/**
|
|
* @brief Check if PIN has been set on authenticator
|
|
*
|
|
* @return true if PIN has been set
|
|
* @return false otherwise
|
|
*/
|
|
bool fido2_ctap_pin_is_set(void);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#endif /* FIDO2_CTAP_CTAP_H */
|
|
/** @} */
|