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

CTAPHID transport layer for USB HID framed CTAP2/U2F traffic. More...

#include "mod_fido2/ctaphid.h"
#include "mod_fido2/ctap2.h"
#include "mod_fido2/u2f.h"
#include "mod_fido2/Fido2Ui.h"
#include "cdc_hal/IDisplay.h"
#include "cdc_log.h"
#include "cdc_core/feature_flags.h"
#include <esp_attr.h>
#include <string.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/semphr.h>

Go to the source code of this file.

Namespaces

namespace  cdc
namespace  cdc::mod_fido2

Macros

#define CTAPHID_DEBUG_PACKETS   DEBUG_MODE
 Enable verbose packet-level debug logging when feature flags allow it.
#define CTAPHID_MSG_TIMEOUT_MS   500
#define CTAPHID_MAX_CHANNELS   8
#define CTAPHID_RESPONSE_QUEUE_SIZE   8
#define CTAPHID_RATE_LIMIT_WINDOW_MS   1000
 Runtime state and channel bookkeeping for CTAPHID transport.
#define CTAPHID_RATE_LIMIT_MAX_CMDS   200

Functions

bool cdc::mod_fido2::fido2_usb_write (const uint8_t *buffer)
 Sends one CTAPHID packet over USB HID.
static ctaphid_channel_t * find_channel (uint32_t cid)
 Returns the channel record for a given channel identifier.
static void init_channel_slot (int index, uint32_t cid)
 Allocates or reuses a channel slot for the provided channel identifier.
static ctaphid_channel_t * alloc_channel (uint32_t cid)
static uint32_t allocate_cid (void)
 Allocates the next non-broadcast CTAPHID channel identifier.
static void build_init_packet (uint8_t *packet, uint32_t cid, uint8_t cmd, uint16_t bcnt, const uint8_t *data, uint16_t data_len)
 Builds a CTAPHID initialization packet.
static void build_cont_packet (uint8_t *packet, uint32_t cid, uint8_t seq, const uint8_t *data, uint16_t data_len)
 Builds a CTAPHID continuation packet.
static void prepare_response (uint32_t cid, uint8_t cmd, const uint8_t *data, uint16_t len)
 Stores a command response so it can be packetized and read out later.
static void prepare_response_on (ctaphid_channel_t *ch, uint32_t send_cid, uint8_t cmd, const uint8_t *data, uint16_t len)
 Stores a response on the given channel slot but addressed to a different CID.
static void handle_init (uint32_t cid, const uint8_t *data, uint16_t len)
 Handles CTAPHID INIT and returns negotiated channel/capability data.
static void handle_ping (uint32_t cid, const uint8_t *data, uint16_t len)
 Handles CTAPHID PING by echoing the request payload.
static void handle_wink (uint32_t cid)
 Handles CTAPHID WINK requests.
static void handle_cancel (uint32_t cid)
 Handles CTAPHID CANCEL requests and aborts active CTAP2 work.
static void handle_cbor (uint32_t cid, const uint8_t *data, uint16_t len)
 Handles CTAPHID CBOR requests by dispatching to the CTAP2 command processor.
static void process_complete_message (ctaphid_channel_t *ch)
 Dispatches a fully assembled channel message to its command handler.
bool ctaphid_init (void)
 Initializes CTAPHID transport state and synchronization primitives.
void ctaphid_get_cmd_counts (uint32_t *cbor_count, uint32_t *msg_count)
 Returns cumulative counters for CTAPHID CBOR and MSG commands.
void ctaphid_reset_cmd_counts (void)
 Resets CTAPHID command counters.
bool ctaphid_process_packet (const uint8_t *packet)
 Processes one incoming 64-byte CTAPHID packet.
bool ctaphid_has_response (void)
 Indicates whether any channel has a response queued for host retrieval.
static ctaphid_channel_t * pick_next_response_channel (void)
 Selects the next channel with a pending response in a round-robin fashion.
bool ctaphid_get_response_packet (uint8_t *packet)
 Retrieves the next response HID packet from a per-channel response queue.
void ctaphid_send_keepalive (uint32_t cid, uint8_t status)
 Sends a CTAPHID KEEPALIVE packet immediately over USB.
void ctaphid_send_error (uint32_t cid, uint8_t error)
 Queues a CTAPHID ERROR response for the given channel.
void ctaphid_check_timeout (void)
 Expires active channels whose message assembly timeout elapsed.
uint32_t ctaphid_get_current_cid (void)
 Returns the channel identifier of the currently processed request.
bool ctaphid_is_busy (void)
 Reports whether any CTAPHID channel currently has an active transaction.
bool fido2_usb_write (const uint8_t *buffer)
 Sends one CTAPHID packet over USB HID.

Variables

static const char * TAG = "CTAPHID"
static uint8_t s_msg_buffers [8][CTAPHID_MAX_MSG_SIZE]
 Message and response buffers located in PSRAM to save internal RAM.
static uint8_t s_response_buffers [8][CTAPHID_MAX_MSG_SIZE]
struct { 
   bool   initialized 
   uint32_t   next_cid 
   ctaphid_channel_t   channels [8] 
   uint8_t   init_buffer [64] 
   SemaphoreHandle_t   mutex 
   uint32_t   current_cid 
   uint8_t   response_rr_index 
   uint32_t   rate_window_start 
   uint8_t   rate_cmd_count 
   uint32_t   cbor_cmd_count 
   uint32_t   msg_cmd_count 
g_ctaphid = {}

Detailed Description

CTAPHID transport layer for USB HID framed CTAP2/U2F traffic.

Definition in file ctaphid.cpp.

Macro Definition Documentation

◆ CTAPHID_DEBUG_PACKETS

#define CTAPHID_DEBUG_PACKETS   DEBUG_MODE

Enable verbose packet-level debug logging when feature flags allow it.

Definition at line 30 of file ctaphid.cpp.

Referenced by ctaphid_process_packet(), handle_cancel(), handle_cbor(), handle_init(), handle_ping(), handle_wink(), and process_complete_message().

◆ CTAPHID_MAX_CHANNELS

◆ CTAPHID_MSG_TIMEOUT_MS

#define CTAPHID_MSG_TIMEOUT_MS   500

Definition at line 32 of file ctaphid.cpp.

Referenced by ctaphid_check_timeout().

◆ CTAPHID_RATE_LIMIT_MAX_CMDS

#define CTAPHID_RATE_LIMIT_MAX_CMDS   200

Definition at line 40 of file ctaphid.cpp.

Referenced by ctaphid_process_packet().

◆ CTAPHID_RATE_LIMIT_WINDOW_MS

#define CTAPHID_RATE_LIMIT_WINDOW_MS   1000

Runtime state and channel bookkeeping for CTAPHID transport.

Per-window command rate limiting configuration.

Definition at line 39 of file ctaphid.cpp.

Referenced by ctaphid_process_packet().

◆ CTAPHID_RESPONSE_QUEUE_SIZE

#define CTAPHID_RESPONSE_QUEUE_SIZE   8

Definition at line 34 of file ctaphid.cpp.

Function Documentation

◆ alloc_channel()

ctaphid_channel_t * alloc_channel ( uint32_t cid)
static

Definition at line 101 of file ctaphid.cpp.

References CTAPHID_MAX_CHANNELS, find_channel(), g_ctaphid, init_channel_slot(), LOG_W, and TAG.

Referenced by ctaphid_send_error(), and handle_init().

◆ allocate_cid()

uint32_t allocate_cid ( void )
static

Allocates the next non-broadcast CTAPHID channel identifier.

Returns
Newly allocated channel identifier.

Definition at line 139 of file ctaphid.cpp.

References CTAPHID_BROADCAST_CID, and g_ctaphid.

Referenced by handle_init().

◆ build_cont_packet()

void build_cont_packet ( uint8_t * packet,
uint32_t cid,
uint8_t seq,
const uint8_t * data,
uint16_t data_len )
static

Builds a CTAPHID continuation packet.

Parameters
packetDestination buffer for the 64-byte HID packet.
cidCTAPHID channel identifier.
seqContinuation sequence number.
dataOptional payload pointer.
data_lenNumber of payload bytes available in data.

Definition at line 188 of file ctaphid.cpp.

References CTAPHID_CONT_DATA, and CTAPHID_PACKET_SIZE.

Referenced by ctaphid_get_response_packet().

◆ build_init_packet()

void build_init_packet ( uint8_t * packet,
uint32_t cid,
uint8_t cmd,
uint16_t bcnt,
const uint8_t * data,
uint16_t data_len )
static

Builds a CTAPHID initialization packet.

Parameters
packetDestination buffer for the 64-byte HID packet.
cidCTAPHID channel identifier.
Plugin command channelCTAPHID command byte without the init bit.
bcntTotal message byte count.
dataOptional payload pointer.
data_lenNumber of payload bytes available in data.

Definition at line 160 of file ctaphid.cpp.

References CTAPHID_INIT_DATA, and CTAPHID_PACKET_SIZE.

Referenced by ctaphid_get_response_packet(), and ctaphid_send_keepalive().

◆ ctaphid_check_timeout()

void ctaphid_check_timeout ( void )

Expires active channels whose message assembly timeout elapsed.

Definition at line 730 of file ctaphid.cpp.

References CTAPHID_ERR_MSG_TIMEOUT, CTAPHID_MAX_CHANNELS, CTAPHID_MSG_TIMEOUT_MS, ctaphid_send_error(), g_ctaphid, LOG_W, and TAG.

Referenced by fido2_task().

◆ ctaphid_get_cmd_counts()

void ctaphid_get_cmd_counts ( uint32_t * cbor_count,
uint32_t * msg_count )

Returns cumulative counters for CTAPHID CBOR and MSG commands.

Parameters
cbor_countOptional destination for CBOR command count.
msg_countOptional destination for MSG/U2F command count.

Definition at line 456 of file ctaphid.cpp.

References g_ctaphid.

◆ ctaphid_get_current_cid()

uint32_t ctaphid_get_current_cid ( void )

Returns the channel identifier of the currently processed request.

Returns
Active request channel identifier.

Definition at line 753 of file ctaphid.cpp.

References g_ctaphid.

Referenced by ctap2_send_keepalive(), cdc::mod_fido2::fido2_ui_user_presence_callback(), and wait_for_user_presence().

◆ ctaphid_get_response_packet()

bool ctaphid_get_response_packet ( uint8_t * packet)

Retrieves the next response HID packet from a per-channel response queue.

Parameters
packetDestination buffer for the response packet.
Returns
true when a packet was written, otherwise false.

Definition at line 634 of file ctaphid.cpp.

References build_cont_packet(), build_init_packet(), cancelled, ctap2_is_cancelled(), CTAPHID_CONT_DATA, CTAPHID_INIT_DATA, g_ctaphid, LOG_W, pick_next_response_channel(), and TAG.

Referenced by fido2_task().

◆ ctaphid_has_response()

bool ctaphid_has_response ( void )

Indicates whether any channel has a response queued for host retrieval.

Returns
true when at least one channel has a pending response, otherwise false.

Definition at line 607 of file ctaphid.cpp.

References CTAPHID_MAX_CHANNELS, and g_ctaphid.

Referenced by fido2_task().

◆ ctaphid_init()

bool ctaphid_init ( void )

Initializes CTAPHID transport state and synchronization primitives.

Returns
true on success, otherwise false.

Definition at line 434 of file ctaphid.cpp.

References g_ctaphid, LOG_E, LOG_I, and TAG.

Referenced by fido2_init().

◆ ctaphid_is_busy()

bool ctaphid_is_busy ( void )

Reports whether any CTAPHID channel currently has an active transaction.

Returns
true when at least one channel is active, otherwise false.

Definition at line 761 of file ctaphid.cpp.

References CTAPHID_MAX_CHANNELS, and g_ctaphid.

◆ ctaphid_process_packet()

bool ctaphid_process_packet ( const uint8_t * packet)

Processes one incoming 64-byte CTAPHID packet.

Parameters
packetHID packet buffer.
Returns
true when the packet is consumed, false on invalid preconditions.

Definition at line 474 of file ctaphid.cpp.

References CTAPHID_CONT_DATA, CTAPHID_DEBUG_PACKETS, CTAPHID_ERR_CHANNEL_BUSY, CTAPHID_ERR_INVALID_CHANNEL, CTAPHID_ERR_INVALID_LEN, CTAPHID_ERR_INVALID_SEQ, CTAPHID_INIT, CTAPHID_INIT_DATA, CTAPHID_MAX_MSG_SIZE, CTAPHID_RATE_LIMIT_MAX_CMDS, CTAPHID_RATE_LIMIT_WINDOW_MS, ctaphid_send_error(), find_channel(), g_ctaphid, LOG_D, LOG_W, process_complete_message(), and TAG.

Referenced by fido2_task().

◆ ctaphid_reset_cmd_counts()

void ctaphid_reset_cmd_counts ( void )

Resets CTAPHID command counters.

Definition at line 464 of file ctaphid.cpp.

References g_ctaphid.

◆ ctaphid_send_error()

void ctaphid_send_error ( uint32_t cid,
uint8_t error )

Queues a CTAPHID ERROR response for the given channel.

Parameters
cidChannel identifier.
errorCTAPHID error code.

Definition at line 703 of file ctaphid.cpp.

References alloc_channel(), CTAPHID_BROADCAST_CID, CTAPHID_ERROR, CTAPHID_MAX_CHANNELS, find_channel(), g_ctaphid, LOG_W, prepare_response_on(), and TAG.

Referenced by ctaphid_check_timeout(), ctaphid_process_packet(), handle_cbor(), handle_init(), and process_complete_message().

◆ ctaphid_send_keepalive()

void ctaphid_send_keepalive ( uint32_t cid,
uint8_t status )

Sends a CTAPHID KEEPALIVE packet immediately over USB.

Parameters
cidChannel identifier.
statusCTAPHID keepalive status byte.

Definition at line 689 of file ctaphid.cpp.

References build_init_packet(), CTAPHID_KEEPALIVE, CTAPHID_PACKET_SIZE, and fido2_usb_write().

Referenced by ctap2_send_keepalive(), cdc::mod_fido2::fido2_ui_user_presence_callback(), and wait_for_user_presence().

◆ fido2_usb_write()

bool cdc::mod_fido2::fido2_usb_write ( const uint8_t * buffer)

Sends one CTAPHID packet over USB HID.

Parameters
bufferPacket data buffer.
Returns
true if report submission succeeded.

Definition at line 293 of file Fido2Module.cpp.

Referenced by ctaphid_send_keepalive().

◆ find_channel()

ctaphid_channel_t * find_channel ( uint32_t cid)
static

Returns the channel record for a given channel identifier.

Parameters
cidCTAPHID channel identifier.
Returns
Pointer to the channel entry, or NULL when not found.

Definition at line 67 of file ctaphid.cpp.

References CTAPHID_MAX_CHANNELS, and g_ctaphid.

Referenced by alloc_channel(), ctaphid_process_packet(), ctaphid_send_error(), handle_cbor(), and prepare_response().

◆ handle_cancel()

void handle_cancel ( uint32_t cid)
static

Handles CTAPHID CANCEL requests and aborts active CTAP2 work.

Parameters
cidRequest channel identifier.

Definition at line 330 of file ctaphid.cpp.

References ctap2_cancel(), CTAPHID_DEBUG_PACKETS, cdc::mod_fido2::fido2_ui_abort_prompt(), LOG_D, and TAG.

Referenced by process_complete_message().

◆ handle_cbor()

void handle_cbor ( uint32_t cid,
const uint8_t * data,
uint16_t len )
static

Handles CTAPHID CBOR requests by dispatching to the CTAP2 command processor.

Parameters
cidRequest channel identifier.
dataCBOR command payload.
lenLength of data in bytes.

Definition at line 342 of file ctaphid.cpp.

References ctap2_process_command(), CTAPHID_CBOR, CTAPHID_DEBUG_PACKETS, CTAPHID_ERR_INVALID_CHANNEL, CTAPHID_ERR_INVALID_LEN, ctaphid_send_error(), find_channel(), g_ctaphid, LOG_D, LOG_I, and TAG.

Referenced by process_complete_message().

◆ handle_init()

void handle_init ( uint32_t cid,
const uint8_t * data,
uint16_t len )
static

Handles CTAPHID INIT and returns negotiated channel/capability data.

Parameters
cidSource channel identifier from the request.
dataINIT request payload.
lenLength of data in bytes.

Definition at line 267 of file ctaphid.cpp.

References alloc_channel(), allocate_cid(), ctap2_clear_cancel(), CTAPHID_BROADCAST_CID, CTAPHID_CAP_CBOR, CTAPHID_CAP_WINK, CTAPHID_DEBUG_PACKETS, CTAPHID_ERR_INVALID_LEN, CTAPHID_ERR_OTHER, CTAPHID_INIT, ctaphid_send_error(), LOG_D, prepare_response_on(), and TAG.

Referenced by process_complete_message().

◆ handle_ping()

void handle_ping ( uint32_t cid,
const uint8_t * data,
uint16_t len )
static

Handles CTAPHID PING by echoing the request payload.

Parameters
cidRequest channel identifier.
dataPING payload bytes.
lenLength of data in bytes.

Definition at line 310 of file ctaphid.cpp.

References CTAPHID_DEBUG_PACKETS, CTAPHID_PING, LOG_D, prepare_response(), and TAG.

Referenced by process_complete_message().

◆ handle_wink()

void handle_wink ( uint32_t cid)
static

Handles CTAPHID WINK requests.

Parameters
cidRequest channel identifier.

Definition at line 320 of file ctaphid.cpp.

References CTAPHID_DEBUG_PACKETS, CTAPHID_WINK, LOG_D, prepare_response(), TAG, and cdc::hal::winkBacklight().

Referenced by process_complete_message().

◆ init_channel_slot()

void init_channel_slot ( int index,
uint32_t cid )
static

Allocates or reuses a channel slot for the provided channel identifier.

Parameters
cidCTAPHID channel identifier to allocate.
Returns
Pointer to the allocated channel entry, or NULL when no slot is available.

Wires per-channel scratch and response buffers for a freshly assigned slot.

Parameters
indexChannel-array index.
cidCTAPHID channel identifier to assign.

Definition at line 87 of file ctaphid.cpp.

References CTAPHID_MAX_MSG_SIZE, g_ctaphid, s_msg_buffers, and s_response_buffers.

Referenced by alloc_channel().

◆ pick_next_response_channel()

ctaphid_channel_t * pick_next_response_channel ( void )
static

Selects the next channel with a pending response in a round-robin fashion.

Returns
Channel pointer, or NULL when no responses are pending.

Definition at line 618 of file ctaphid.cpp.

References CTAPHID_MAX_CHANNELS, and g_ctaphid.

Referenced by ctaphid_get_response_packet().

◆ prepare_response()

void prepare_response ( uint32_t cid,
uint8_t cmd,
const uint8_t * data,
uint16_t len )
static

Stores a command response so it can be packetized and read out later.

Parameters
cidChannel identifier for the response.
Plugin command channelCTAPHID response command.
dataOptional response payload pointer.
lenNumber of payload bytes.

Definition at line 213 of file ctaphid.cpp.

References CTAPHID_CBOR, find_channel(), LOG_E, LOG_I, LOG_W, and TAG.

Referenced by handle_ping(), handle_wink(), and process_complete_message().

◆ prepare_response_on()

void prepare_response_on ( ctaphid_channel_t * ch,
uint32_t send_cid,
uint8_t cmd,
const uint8_t * data,
uint16_t len )
static

Stores a response on the given channel slot but addressed to a different CID.

Parameters
chChannel slot that holds the response buffer.
send_cidCTAPHID identifier that should appear on outgoing packets.
Plugin command channelCTAPHID response command.
dataOptional response payload pointer.
lenNumber of payload bytes.

Definition at line 244 of file ctaphid.cpp.

References LOG_E, and TAG.

Referenced by ctaphid_send_error(), and handle_init().

◆ process_complete_message()

void process_complete_message ( ctaphid_channel_t * ch)
static

Dispatches a fully assembled channel message to its command handler.

Parameters
chChannel state containing command and assembled payload.

Definition at line 378 of file ctaphid.cpp.

References CTAPHID_CANCEL, CTAPHID_CBOR, CTAPHID_DEBUG_PACKETS, CTAPHID_ERR_INVALID_CMD, CTAPHID_INIT, CTAPHID_MSG, CTAPHID_PING, ctaphid_send_error(), CTAPHID_VENDOR_FIRST, CTAPHID_VENDOR_LAST, CTAPHID_WINK, g_ctaphid, handle_cancel(), handle_cbor(), handle_init(), handle_ping(), handle_wink(), LOG_D, prepare_response(), TAG, and u2f_process_apdu().

Referenced by ctaphid_process_packet().

Variable Documentation

◆ cbor_cmd_count

uint32_t cbor_cmd_count

Definition at line 58 of file ctaphid.cpp.

◆ channels

ctaphid_channel_t channels[8]

Definition at line 49 of file ctaphid.cpp.

◆ current_cid

uint32_t current_cid

Definition at line 52 of file ctaphid.cpp.

◆ [struct]

◆ init_buffer

uint8_t init_buffer[64]

Definition at line 50 of file ctaphid.cpp.

◆ initialized

bool initialized

Definition at line 47 of file ctaphid.cpp.

◆ msg_cmd_count

uint32_t msg_cmd_count

Definition at line 59 of file ctaphid.cpp.

◆ mutex

◆ next_cid

uint32_t next_cid

Definition at line 48 of file ctaphid.cpp.

◆ rate_cmd_count

uint8_t rate_cmd_count

Definition at line 56 of file ctaphid.cpp.

◆ rate_window_start

uint32_t rate_window_start

Definition at line 55 of file ctaphid.cpp.

◆ response_rr_index

uint8_t response_rr_index

Definition at line 53 of file ctaphid.cpp.

◆ s_msg_buffers

uint8_t s_msg_buffers[8][CTAPHID_MAX_MSG_SIZE]
static

Message and response buffers located in PSRAM to save internal RAM.

Definition at line 43 of file ctaphid.cpp.

Referenced by init_channel_slot().

◆ s_response_buffers

uint8_t s_response_buffers[8][CTAPHID_MAX_MSG_SIZE]
static

Definition at line 44 of file ctaphid.cpp.

Referenced by init_channel_slot().

◆ TAG

const char* TAG = "CTAPHID"
static

Definition at line 25 of file ctaphid.cpp.