15static const char *
TAG =
"CCID";
26 0x02, 0x00, 0x00, 0x00,
27 0xA0, 0x0F, 0x00, 0x00,
28 0xA0, 0x0F, 0x00, 0x00,
30 0xB0, 0x04, 0x00, 0x00,
31 0xB0, 0x04, 0x00, 0x00,
33 0xFE, 0x00, 0x00, 0x00,
34 0x00, 0x00, 0x00, 0x00,
35 0x00, 0x00, 0x00, 0x00,
41 0x42, 0x08, 0x04, 0x00,
42 0x00, 0x08, 0x00, 0x00,
57static const uint8_t
ATR[] = {
69 0x00, 0x31, 0xF5, 0x73, 0xC0, 0x01, 0x60, 0x00, 0x90, 0x00,
87 LOG_E(
TAG,
"Failed to initialize OpenPGP");
127 uint8_t slot, uint8_t seq, uint8_t status, uint8_t error) {
129 resp[1] = data_len & 0xFF;
130 resp[2] = (data_len >> 8) & 0xFF;
131 resp[3] = (data_len >> 16) & 0xFF;
132 resp[4] = (data_len >> 24) & 0xFF;
149 uint8_t *resp,
size_t resp_max) {
151 LOG_E(
TAG,
"Invalid parameters: msg_len=%zu resp_max=%zu", msg_len, resp_max);
163 switch (hdr->bMessageType) {
190 uint32_t apdu_len = hdr->dwLength;
197 LOG_E(
TAG,
"XFR length invalid (apdu=%u msg=%zu rmax=%zu)",
198 apdu_len, msg_len, resp_max);
212 resp_data, resp_data_max);
227 uint16_t sw = (resp_len >= 2)
228 ? ((uint16_t)resp_data[resp_len - 2] << 8) | resp_data[resp_len - 1]
230 LOG_I(
TAG,
"XFR seq=%u INS=0x%02X in=%uB out=%dB sw=%04X",
231 hdr->bSeq, apdu_len >= 2 ? apdu_data[1] : 0,
232 apdu_len, resp_len, sw);
256 0x01, 0x00, 0x00, 0xFE, 0x00, 0xFE, 0x00
267 LOG_W(
TAG,
"Unknown CCID type 0x%02X seq=%u", hdr->bMessageType, hdr->bSeq);
static const uint8_t ATR[]
ATR (Answer To Reset) for CDC Badge OpenPGP card.
int ccid_process_message(const uint8_t *msg, size_t msg_len, uint8_t *resp, size_t resp_max)
Processes one incoming CCID message and writes corresponding response.
static uint8_t current_slot
static uint8_t current_seq
bool ccid_card_present(void)
Returns whether virtual CCID card is available.
void ccid_driver_link_anchor(void)
Initializes CCID transport and backing OpenPGP applet.
const uint8_t * ccid_get_atr(size_t *len)
Returns pointer and length of ATR bytes.
static void ccid_build_header(uint8_t *resp, uint8_t msg_type, uint32_t data_len, uint8_t slot, uint8_t seq, uint8_t status, uint8_t error)
Builds a CCID response header in transport byte format.
#define CCID_PC_TO_RDR_GET_PARAMETERS
#define CCID_ERROR_HW_ERROR
#define CCID_PC_TO_RDR_XFR_BLOCK
#define CCID_PC_TO_RDR_ICC_POWER_ON
#define CCID_ERROR_CMD_NOT_SUPPORTED
const uint8_t CCID_DESCRIPTOR[]
CCID functional descriptor (54 bytes) per OpenPGP 3.4.1 profile.
#define CCID_PC_TO_RDR_ICC_POWER_OFF
#define CCID_PC_TO_RDR_GET_SLOT_STATUS
#define CCID_RDR_TO_PC_PARAMETERS
#define CCID_CMD_STATUS_FAILED
#define CCID_PC_TO_RDR_RESET_PARAMETERS
const size_t CCID_DESCRIPTOR_LEN
#define CCID_ICC_PRESENT_INACTIVE
#define CCID_RDR_TO_PC_SLOT_STATUS
#define CCID_RDR_TO_PC_DATA_BLOCK
#define CCID_ICC_PRESENT_ACTIVE
#define CCID_ERROR_XFR_OVERRUN
CDC Log: logging over TinyUSB CDC and UART.
#define LOG_W(tag, fmt,...)
#define LOG_I(tag, fmt,...)
#define LOG_E(tag, fmt,...)
int openpgp_process_apdu(const uint8_t *cmd, size_t cmd_len, uint8_t *resp, size_t resp_max)