CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
u2f.cpp File Reference

Legacy U2F/CTAP1 protocol implementation for compatibility clients. More...

#include "mod_fido2/u2f.h"
#include "mod_fido2/fido2.h"
#include "mod_fido2/fido2_storage.h"
#include "mod_fido2/fido2_common.h"
#include "cdc_hal/ISecureElement.h"
#include "cdc_core/Bytes.h"
#include "cdc_log.h"
#include <mbedtls/sha256.h>
#include <esp_attr.h>
#include <string.h>
#include <stdio.h>

Go to the source code of this file.

Macros

#define U2F_ATTEST_SLOT   0
 Attestation certificate constants and cached buffers.

Functions

static uint8_t * encode_der_integer (uint8_t *p, const uint8_t *mpi, size_t len)
 Encodes a single big-endian unsigned integer as a DER INTEGER element.
static bool u2f_attest_sign (const uint8_t *data, size_t data_len, uint8_t *signature, uint8_t *sig_len)
 Signs payload hash with attestation key and encodes signature as DER.
bool u2f_init_attestation (void)
 Initializes attestation key material and builds self-signed attestation certificate.
bool u2f_get_attestation_cert (const uint8_t **cert, uint16_t *cert_len)
 Returns attestation certificate pointer and length, initializing attestation on demand if the boot-time init did not complete.
bool u2f_attestation_sign (const uint8_t *data, size_t data_len, uint8_t *signature, uint8_t *sig_len)
 Signs payload using the attestation key, initializing attestation on demand if the boot-time init did not complete.
static uint16_t u2f_response_sw (uint8_t *response, uint16_t sw)
 Writes a U2F status word to response buffer.
static uint16_t u2f_response_error (uint8_t *response, uint16_t sw)
 Writes a U2F error status word to response buffer.
static uint16_t u2f_version (uint8_t *response, uint16_t response_max)
 Handles U2F VERSION instruction (INS=0x03).
static bool is_dummy_application (const uint8_t *application)
 U2F register/authenticate command helpers.
static uint16_t u2f_register (const uint8_t *challenge, const uint8_t *application, uint8_t *response, uint16_t response_max)
 Handles U2F REGISTER instruction (INS=0x01).
static uint16_t u2f_authenticate (uint8_t p1, const uint8_t *challenge, const uint8_t *application, const uint8_t *key_handle, uint8_t key_handle_len, uint8_t *response, uint16_t response_max)
 Handles U2F AUTHENTICATE instruction (INS=0x02).
uint16_t u2f_process_apdu (const uint8_t *apdu, uint16_t apdu_len, uint8_t *response, uint16_t response_max)
 Parses U2F APDU and dispatches to instruction handlers.
void sha256 (const uint8_t *data, size_t len, uint8_t out[32])

Variables

static const char * TAG = "U2F"
static constexpr uint8_t DER_SEQUENCE_TAG = 0x30
 DER encoding helper constants for X.509/signature generation.
static constexpr uint8_t DER_INTEGER_TAG = 0x02
static constexpr uint8_t DER_BIT_STRING_TAG = 0x03
static constexpr uint8_t DER_EXPLICIT_TAG_0 = 0xA0
static constexpr uint8_t DER_EXPLICIT_TAG_3 = 0xA3
static constexpr uint8_t DER_LENGTH_TWO_BYTES = 0x82
static constexpr uint8_t EC_POINT_UNCOMPRESSED = 0x04
 ECDSA and EC-point encoding constants.
static constexpr uint8_t DER_INTEGER_NEGATIVE_MASK = 0x80
static constexpr uint8_t DER_ENSURE_POSITIVE_MASK = 0x7F
static constexpr int RAW_SIGNATURE_COMPONENT_SIZE = 32
static uint8_t g_attest_cert [U2F_MAX_ATT_CERT_SIZE]
 Cached DER attestation certificate and associated state.
static uint16_t g_attest_cert_len = 0
static uint8_t g_attest_pubkey [65]
static bool g_attest_initialized = false

Detailed Description

Legacy U2F/CTAP1 protocol implementation for compatibility clients.

Definition in file u2f.cpp.

Macro Definition Documentation

◆ U2F_ATTEST_SLOT

#define U2F_ATTEST_SLOT   0

Attestation certificate constants and cached buffers.

Definition at line 38 of file u2f.cpp.

Referenced by u2f_attest_sign(), and u2f_init_attestation().

Function Documentation

◆ encode_der_integer()

uint8_t * encode_der_integer ( uint8_t * p,
const uint8_t * mpi,
size_t len )
static

Encodes a single big-endian unsigned integer as a DER INTEGER element.

Parameters
pOutput cursor (advances past written bytes).
mpiBig-endian magnitude buffer.
lenMagnitude length in bytes.
Returns
Updated output cursor positioned after the encoded INTEGER.

Strips leading zero bytes (keeping at least one) and prepends a 0x00 padding byte when the MSB is set, ensuring the integer remains non-negative in DER.

Definition at line 56 of file u2f.cpp.

References DER_INTEGER_NEGATIVE_MASK, and DER_INTEGER_TAG.

Referenced by u2f_attest_sign().

◆ is_dummy_application()

bool is_dummy_application ( const uint8_t * application)
static

U2F register/authenticate command helpers.

Detects Chrome-style dummy application hashes used for blink/device selection.

Parameters
applicationPointer to the 32-byte U2F application hash.
Returns
true if the hash matches the repetitive dummy pattern, otherwise false.

Definition at line 417 of file u2f.cpp.

References LOG_I, and TAG.

Referenced by u2f_register().

◆ sha256()

void cdc::mod_fido2::sha256 ( const uint8_t * data,
size_t len,
uint8_t out[32] )
inline

Definition at line 29 of file fido2_common.h.

◆ u2f_attest_sign()

bool u2f_attest_sign ( const uint8_t * data,
size_t data_len,
uint8_t * signature,
uint8_t * sig_len )
static

Signs payload hash with attestation key and encodes signature as DER.

Parameters
dataData to hash and sign.
data_lenLength of data.
signatureDestination buffer for DER signature.
sig_lenOutput DER signature length.
Returns
true on success, otherwise false.

Definition at line 84 of file u2f.cpp.

References DER_SEQUENCE_TAG, encode_der_integer(), cdc::hal::getSecureElementInstance(), LOG_E, cdc::hal::OK, RAW_SIGNATURE_COMPONENT_SIZE, TAG, and U2F_ATTEST_SLOT.

Referenced by u2f_attestation_sign(), u2f_init_attestation(), and u2f_register().

◆ u2f_attestation_sign()

bool u2f_attestation_sign ( const uint8_t * data,
size_t data_len,
uint8_t * signature,
uint8_t * sig_len )

Signs payload using the attestation key, initializing attestation on demand if the boot-time init did not complete.

Parameters
dataData to sign.
data_lenLength of data.
signatureDestination signature buffer.
sig_lenOutput signature length.
Returns
true on success, otherwise false.

Definition at line 359 of file u2f.cpp.

References u2f_attest_sign(), and u2f_init_attestation().

Referenced by cdc::mod_fido2::create_credential_and_respond().

◆ u2f_authenticate()

uint16_t u2f_authenticate ( uint8_t p1,
const uint8_t * challenge,
const uint8_t * application,
const uint8_t * key_handle,
uint8_t key_handle_len,
uint8_t * response,
uint16_t response_max )
static

Handles U2F AUTHENTICATE instruction (INS=0x02).

Parameters
p1U2F authenticate control byte.
challenge32-byte challenge parameter.
application32-byte application hash parameter.
key_handleKey-handle bytes.
key_handle_lenLength of key_handle.
responseDestination response buffer.
response_maxCapacity of response.
Returns
Number of response bytes written.

Definition at line 633 of file u2f.cpp.

References FIDO2_ACTION_AUTHENTICATE, fido2_increment_auth_counter(), fido2_request_user_presence(), fido2_storage_find_slot_by_cred_id(), fido2_storage_get_credential(), fido2_storage_increment_sign_count(), fido2_storage_sign_raw(), FIDO2_UP_APPROVED, LOG_E, LOG_I, LOG_W, TAG, U2F_AUTH_CHECK_ONLY, U2F_AUTH_ENFORCE, U2F_KEY_HANDLE_SIZE, U2F_MAX_EC_SIG_SIZE, u2f_response_error(), U2F_SW_CONDITIONS_NOT_SATISFIED, U2F_SW_WRONG_DATA, and cdc::core::writeBe32().

Referenced by u2f_process_apdu().

◆ u2f_get_attestation_cert()

bool u2f_get_attestation_cert ( const uint8_t ** cert,
uint16_t * cert_len )

Returns attestation certificate pointer and length, initializing attestation on demand if the boot-time init did not complete.

Parameters
certOutput pointer to DER certificate.
cert_lenOutput certificate length.
Returns
true on success, otherwise false.

Definition at line 338 of file u2f.cpp.

References g_attest_cert, g_attest_cert_len, and u2f_init_attestation().

Referenced by cdc::mod_fido2::create_credential_and_respond().

◆ u2f_init_attestation()

bool u2f_init_attestation ( void )

◆ u2f_process_apdu()

uint16_t u2f_process_apdu ( const uint8_t * apdu,
uint16_t apdu_len,
uint8_t * response,
uint16_t response_max )

Parses U2F APDU and dispatches to instruction handlers.

Parameters
apduInput APDU bytes.
apdu_lenLength of apdu.
responseDestination response buffer.
response_maxCapacity of response.
Returns
Number of response bytes written.

Definition at line 738 of file u2f.cpp.

References LOG_I, LOG_W, TAG, U2F_APPLICATION_SIZE, u2f_authenticate(), U2F_CHALLENGE_SIZE, U2F_INS_AUTHENTICATE, U2F_INS_REGISTER, U2F_INS_VERSION, u2f_register(), u2f_response_error(), U2F_SW_CLA_NOT_SUPPORTED, U2F_SW_INS_NOT_SUPPORTED, U2F_SW_WRONG_LENGTH, and u2f_version().

Referenced by process_complete_message().

◆ u2f_register()

uint16_t u2f_register ( const uint8_t * challenge,
const uint8_t * application,
uint8_t * response,
uint16_t response_max )
static

Handles U2F REGISTER instruction (INS=0x01).

Parameters
challenge32-byte challenge parameter.
application32-byte application hash parameter.
responseDestination response buffer.
response_maxCapacity of response.
Returns
Number of response bytes written.

Definition at line 437 of file u2f.cpp.

References CDC_CURVE_P256, EC_POINT_UNCOMPRESSED, FIDO2_ACTION_REGISTER, FIDO2_ACTION_SELECT, fido2_request_user_presence(), fido2_storage_create_credential(), fido2_storage_delete_credential(), FIDO2_UP_APPROVED, g_attest_cert, g_attest_cert_len, cdc::hal::getSecureElementInstance(), is_dummy_application(), LOG_D, LOG_E, LOG_I, rp_id, TAG, u2f_attest_sign(), u2f_init_attestation(), U2F_KEY_HANDLE_SIZE, U2F_MAX_EC_SIG_SIZE, U2F_REGISTER_ID, u2f_response_error(), U2F_SW_CONDITIONS_NOT_SATISFIED, U2F_SW_WRONG_DATA, U2F_SW_WRONG_LENGTH, U2F_SW_WTF, and user_id.

Referenced by u2f_process_apdu().

◆ u2f_response_error()

uint16_t u2f_response_error ( uint8_t * response,
uint16_t sw )
static

Writes a U2F error status word to response buffer.

Parameters
responseDestination response buffer.
swStatus word.
Returns
Number of response bytes written.

Definition at line 385 of file u2f.cpp.

References u2f_response_sw().

Referenced by u2f_authenticate(), u2f_process_apdu(), u2f_register(), and u2f_version().

◆ u2f_response_sw()

uint16_t u2f_response_sw ( uint8_t * response,
uint16_t sw )
static

Writes a U2F status word to response buffer.

Parameters
responseDestination response buffer.
swStatus word.
Returns
Number of response bytes written.

Definition at line 373 of file u2f.cpp.

Referenced by u2f_response_error().

◆ u2f_version()

uint16_t u2f_version ( uint8_t * response,
uint16_t response_max )
static

Handles U2F VERSION instruction (INS=0x03).

Parameters
responseDestination response buffer.
response_maxCapacity of response.
Returns
Number of response bytes written.

Definition at line 395 of file u2f.cpp.

References LOG_I, TAG, u2f_response_error(), U2F_SW_WRONG_LENGTH, and version.

Referenced by u2f_process_apdu().

Variable Documentation

◆ DER_BIT_STRING_TAG

uint8_t DER_BIT_STRING_TAG = 0x03
staticconstexpr

Definition at line 25 of file u2f.cpp.

Referenced by u2f_init_attestation().

◆ DER_ENSURE_POSITIVE_MASK

uint8_t DER_ENSURE_POSITIVE_MASK = 0x7F
staticconstexpr

Definition at line 33 of file u2f.cpp.

Referenced by u2f_init_attestation().

◆ DER_EXPLICIT_TAG_0

uint8_t DER_EXPLICIT_TAG_0 = 0xA0
staticconstexpr

Definition at line 26 of file u2f.cpp.

Referenced by u2f_init_attestation().

◆ DER_EXPLICIT_TAG_3

uint8_t DER_EXPLICIT_TAG_3 = 0xA3
staticconstexpr

Definition at line 27 of file u2f.cpp.

◆ DER_INTEGER_NEGATIVE_MASK

uint8_t DER_INTEGER_NEGATIVE_MASK = 0x80
staticconstexpr

Definition at line 32 of file u2f.cpp.

Referenced by encode_der_integer().

◆ DER_INTEGER_TAG

uint8_t DER_INTEGER_TAG = 0x02
staticconstexpr

Definition at line 24 of file u2f.cpp.

Referenced by encode_der_integer(), and u2f_init_attestation().

◆ DER_LENGTH_TWO_BYTES

uint8_t DER_LENGTH_TWO_BYTES = 0x82
staticconstexpr

Definition at line 28 of file u2f.cpp.

Referenced by u2f_init_attestation().

◆ DER_SEQUENCE_TAG

uint8_t DER_SEQUENCE_TAG = 0x30
staticconstexpr

DER encoding helper constants for X.509/signature generation.

Definition at line 23 of file u2f.cpp.

Referenced by u2f_attest_sign(), and u2f_init_attestation().

◆ EC_POINT_UNCOMPRESSED

uint8_t EC_POINT_UNCOMPRESSED = 0x04
staticconstexpr

ECDSA and EC-point encoding constants.

Definition at line 31 of file u2f.cpp.

Referenced by u2f_init_attestation(), and u2f_register().

◆ g_attest_cert

uint8_t g_attest_cert[U2F_MAX_ATT_CERT_SIZE]
static

Cached DER attestation certificate and associated state.

Definition at line 41 of file u2f.cpp.

Referenced by u2f_get_attestation_cert(), u2f_init_attestation(), and u2f_register().

◆ g_attest_cert_len

uint16_t g_attest_cert_len = 0
static

Definition at line 42 of file u2f.cpp.

Referenced by u2f_get_attestation_cert(), u2f_init_attestation(), and u2f_register().

◆ g_attest_initialized

bool g_attest_initialized = false
static

Definition at line 44 of file u2f.cpp.

Referenced by u2f_init_attestation().

◆ g_attest_pubkey

uint8_t g_attest_pubkey[65]
static

Definition at line 43 of file u2f.cpp.

Referenced by u2f_init_attestation().

◆ RAW_SIGNATURE_COMPONENT_SIZE

int RAW_SIGNATURE_COMPONENT_SIZE = 32
staticconstexpr

Definition at line 34 of file u2f.cpp.

Referenced by u2f_attest_sign().

◆ TAG

const char* TAG = "U2F"
static

Definition at line 20 of file u2f.cpp.