|
CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
|
#include "mod_gpg/openpgp/openpgp.h"#include "mod_gpg/openpgp/apdu.h"#include "mod_gpg/openpgp/algo_attr.h"#include "mod_gpg/openpgp/constants.h"#include "cdc_log.h"#include "mod_gpg/gpg.h"#include "mod_gpg/GpgStorage.h"#include "ecdh.h"#include "rsa.h"#include "mod_gpg/openpgp/kdf.h"#include "cdc_core/pin_storage_c.h"#include "cdc_core/PinManager.h"#include "cdc_hal/ISecureElement.h"#include <mbedtls/platform_util.h>#include <mbedtls/sha256.h>#include <mbedtls/aes.h>#include <mbedtls/ecp.h>#include <mbedtls/ecdsa.h>#include <mbedtls/bignum.h>#include <esp_attr.h>#include <string.h>#include <time.h>#include <esp_mac.h>#include <nvs_flash.h>#include <nvs.h>#include <esp_random.h>Go to the source code of this file.
Classes | |
| struct | put_data_desc_t |
| Descriptor entry for table-driven PUT DATA processing. More... | |
Macros | |
| #define | OPENPGP_RC_MIN_LEN 8 |
| Resetting Code (RC) — optional per OpenPGP 3.4.1 §4.3.2. When set, the host can unblock PW1 with the RC instead of PW3 (RESET RETRY COUNTER with P1=0x00). We persist the configured RC bytes plus a separate retry counter in NVS. | |
| #define | NVS_NAMESPACE "openpgp" |
| NVS namespace used for OpenPGP persistent data. | |
| #define | NVS_STATE_KEY "state" |
| #define | NVS_CERT_KEY "cardcert" |
| NVS key holding the (public) cardholder certificate (DO 0x7F21). | |
| #define | APP_VERSION "0.0.0" |
Typedefs | |
| typedef bool(* | pin_change_fn_t) (const char *pin) |
| Type alias for PIN change callbacks. | |
Enumerations | |
| enum | key_type_t { KEY_TYPE_SIG = 0 , KEY_TYPE_DEC = 1 , KEY_TYPE_AUT = 2 } |
| Builders for OpenPGP application-related data objects. More... | |
| enum | put_data_kind_t { PUT_KIND_BLOB_FIXED = 0 , PUT_KIND_STRING_BOUNDED = 1 } |
| Storage kind for PUT DATA descriptor entries. More... | |
| enum | pin_slot_t { PIN_SLOT_PW1 = 0 , PIN_SLOT_PW3 = 1 } |
| PIN slot identifier used by PIN helper routines. More... | |
Functions | |
| static cdc::hal::ISecureElement * | get_se () |
| Returns secure-element instance used by OpenPGP backend. | |
| static bool | se_ecc_key_read (uint8_t slot, uint8_t *pubkey, size_t max_len, uint8_t *curve_out) |
| Reads ECC public key from secure element and exposes curve metadata. | |
| static bool | se_ecc_key_generate (uint8_t slot, uint8_t curve) |
| Generates ECC key material in secure element slot. | |
| static bool | se_ecdsa_sign (uint8_t slot, const uint8_t *hash, size_t hash_len, uint8_t *sig) |
| Signs a hash using secure-element ECDSA key. | |
| static bool | se_eddsa_sign (uint8_t slot, const uint8_t *msg, size_t msg_len, uint8_t *sig) |
| Signs a message using secure-element EdDSA key. | |
| static void | se_random_fill (uint8_t *buf, size_t len) |
| Fills buffer with secure random bytes, with ESP fallback. | |
| static bool | compute_rc_hash (const uint8_t *rc, size_t rc_len, const uint8_t *salt, uint8_t *hash_out) |
| Iterated-salted SHA-256 over salt||rc for resetting-code storage. Same construction as PinManager::computeKdfHash (OpenPGP S2K). | |
| static void | chain_reset (void) |
| struct | __attribute__ ((packed)) OpenpgpNvsState |
| Single-blob persistent OpenPGP runtime state. | |
| static size_t | tlv_write_tag (uint8_t *buf, uint16_t tag) |
| TLV builder helper functions. | |
| static size_t | tlv_write_len (uint8_t *buf, size_t len) |
| Writes a TLV length field using DER length encoding. | |
| static size_t | tlv_build (uint8_t *buf, size_t buf_max, uint16_t tag, const uint8_t *value, size_t value_len) |
| Builds complete TLV object and returns total encoded length. | |
| static const uint8_t * | get_algo_attr (key_type_t key_type, size_t *len) |
| Returns algorithm attributes for a key role based on stored key type. | |
| static int | build_do_app_related (uint8_t *buf, size_t buf_max) |
| Builds OpenPGP DO 0x6E (Application Related Data). | |
| static int | build_do_cardholder (uint8_t *buf, size_t buf_max) |
| Builds OpenPGP DO 0x65 (Cardholder Related Data). | |
| static bool | verify_state_signature (cdc::hal::ISecureElement *se, const uint8_t *payload, size_t payload_len, const uint8_t *sig, size_t sig_len) |
| Verifies the P-256 ECDSA attestation signature over an OpenPGP state payload. Same construction as PinManager. | |
| static void | load_state_from_nvs (void) |
| Loads persistent OpenPGP runtime state from NVS. | |
| static void | save_state_to_nvs (void) |
| Persists OpenPGP runtime state to NVS. | |
| static bool | save_cardholder_cert (const uint8_t *data, size_t len) |
| Persists the cardholder certificate as a standalone NVS blob. len == 0 erases it. Stored unsigned: a certificate is public data. | |
| static size_t | load_cardholder_cert (uint8_t *out, size_t cap) |
| Loads the cardholder certificate into out. | |
| static uint8_t | kdf_hash_len (kdf_hash_t hash) |
| Returns the on-device byte length of an SHA-256/512 KDF pre-hash. | |
| static uint16_t | apply_kdf_do (const uint8_t *data, size_t len) |
| Applies a KDF-DO payload written via PUT DATA 0xF9. | |
| static int | role_index_for_key_ref (uint8_t key_ref) |
| Maps an OpenPGP key reference (B6/B8/A4) to a 0-based role index. | |
| static void | init_aid_from_mac (void) |
| Initializes the OpenPGP AID serial section from the ESP32 MAC address. | |
| bool | openpgp_init (void) |
| bool | openpgp_is_selected (void) |
| uint32_t | openpgp_get_sig_count (void) |
| bool | openpgp_get_fingerprint (uint8_t key_type, uint8_t *fp_out) |
| Reads the stored OpenPGP v4 fingerprint for a key role. | |
| static bool | fp_is_set (const uint8_t fp[OPENPGP_FINGERPRINT_SIZE]) |
| bool | openpgp_has_any_key (void) |
| Reports whether any of the SIG / DEC / AUT roles has a non-zero fingerprint configured. Acts as the canonical "card has keys" check. | |
| size_t | openpgp_get_cardholder_name (char *out, size_t out_size) |
| Copies the cardholder name (OpenPGP DO 0x5B) into the caller buffer. Format is gpg's "Surname<<Firstname" or empty when unset. | |
| uint32_t | openpgp_get_gen_time (uint8_t key_type) |
| Returns the stored Unix timestamp of key generation, or 0 when unset. | |
| bool | openpgp_set_cardholder_name (const char *name) |
| Sets the cardholder name (OpenPGP DO 0x5B) and persists state. | |
| bool | openpgp_set_key_fingerprint (uint8_t key_type, const uint8_t *fingerprint, uint32_t gen_time) |
| static int | cmd_select (const apdu_t *apdu, uint8_t *resp, size_t resp_max) |
| Handles APDU SELECT command processing. | |
| static int | respond_chunked (const uint8_t *payload, size_t payload_len, uint32_t le, uint8_t *resp, size_t resp_max) |
| Returns a payload larger than the response window using response chaining, priming the GET RESPONSE buffer directly. | |
| static int | cmd_get_data (const apdu_t *apdu, uint8_t *resp, size_t resp_max) |
| Handles APDU GET DATA command processing. | |
| static const put_data_desc_t * | find_put_data_desc (uint16_t tag) |
| Returns descriptor for an OpenPGP PUT DATA tag. | |
| static int | apply_put_data_desc (const put_data_desc_t *desc, const apdu_t *apdu, uint8_t *resp) |
| Applies a PUT DATA descriptor to the request payload. | |
| static void | wipe_role_key (int r) |
| Handles APDU PUT DATA command processing. | |
| static int | put_data_algo_attr (uint16_t tag, const apdu_t *apdu, uint8_t *resp) |
| static int | cmd_put_data (const apdu_t *apdu, uint8_t *resp, size_t resp_max) |
| static void | update_generation_timestamp (uint8_t key_ref) |
| Updates and persists the generation timestamp for a key role. | |
| static bool | ehl_parse_one (const uint8_t *buf, size_t buf_len, size_t *pos, uint16_t *tag_out, const uint8_t **value_out, size_t *value_len_out) |
Parse one BER-TLV field at pos. | |
| static bool | parse_rsa_import (const uint8_t *tmpl, size_t tmpl_len, const uint8_t *concat, size_t concat_len, const uint8_t **e, size_t *e_len, const uint8_t **p, size_t *p_len, const uint8_t **q, size_t *q_len) |
| Splits the RSA key material (5F48) into e / p / q using the lengths declared in the Cardholder Private Key Template (7F48). | |
| static int | cmd_put_data_odd (const apdu_t *apdu, uint8_t *resp, size_t resp_max) |
| Handles APDU PUT DATA (odd INS, 0xDB) for keypair import. | |
| static int | cmd_verify (const apdu_t *apdu, uint8_t *resp, size_t resp_max) |
| Handles APDU VERIFY command for PIN verification. | |
| static bool | compute_kdf_hash (const char *pin, const uint8_t *salt, uint32_t iterations, uint8_t hash_out[32]) |
| Computes the iterated-salted S2K hash (OpenPGP KDF) for a PIN candidate. | |
| static bool | const_time_equal (const uint8_t *a, const uint8_t *b, size_t n) |
| Constant-time comparison of two equal-length byte buffers. | |
| static bool | peek_verify_pin (pin_slot_t slot, const char *pin) |
| Compares a candidate PIN against the stored hash without touching retry counters. | |
| static bool | try_change_pin (const uint8_t *data, size_t len, size_t min_len, pin_slot_t slot, pin_change_fn_t change_fn) |
| Searches the split point for CHANGE REFERENCE DATA without consuming retries. | |
| static int | cmd_change_reference_data (const apdu_t *apdu, uint8_t *resp, size_t resp_max) |
| Handles APDU CHANGE REFERENCE DATA command for PIN updates. | |
| static int | cmd_pso_cds (const apdu_t *apdu, uint8_t *resp, size_t resp_max) |
| Handles APDU PSO: COMPUTE DIGITAL SIGNATURE. | |
| static int | cmd_pso_decipher_aes (const apdu_t *apdu, uint8_t *resp, size_t resp_max) |
| Handles APDU PSO: DECIPHER for ECDH key agreement. | |
| static int | cmd_pso_decipher (const apdu_t *apdu, uint8_t *resp, size_t resp_max) |
| static int | cmd_manage_security_env (const apdu_t *apdu, uint8_t *resp, size_t resp_max) |
| Handles APDU MANAGE SECURITY ENVIRONMENT (INS 0x22). | |
| static int | cmd_internal_authenticate (const apdu_t *apdu, uint8_t *resp, size_t resp_max) |
| Handles APDU INTERNAL AUTHENTICATE (INS 0x88). | |
| static int | cmd_terminate_df (const apdu_t *apdu, uint8_t *resp, size_t resp_max) |
| Handles APDU TERMINATE DF (INS 0xE6). | |
| static int | cmd_activate_file (const apdu_t *apdu, uint8_t *resp, size_t resp_max) |
| Handles APDU ACTIVATE FILE (INS 0x44). | |
| void | openpgp_factory_reset (void) |
| static int | cmd_reset_retry_counter (const apdu_t *apdu, uint8_t *resp, size_t resp_max) |
| Handles APDU RESET RETRY COUNTER (INS 0x2C). | |
| static uint8_t | get_ecc_slot_for_key_ref (uint8_t key_ref) |
| Returns ECC slot mapping for an OpenPGP key reference. | |
| static key_type_t | get_key_type_for_ref (uint8_t key_ref) |
| Maps an OpenPGP key reference to an internal key type. | |
| static uint16_t | generate_dec_key (uint8_t *pubkey_out) |
| Generates a software ECDH P-256 key pair for the DEC slot. | |
| static uint16_t | generate_hardware_key (uint8_t ecc_slot, uint8_t curve) |
| Generates a hardware ECC key pair in the TROPIC01 secure element. | |
| static bool | read_public_key (key_type_t key_type, uint8_t ecc_slot, uint8_t *pubkey, uint8_t *curve_out) |
| Reads the public key for a given key role. | |
| static void | encode_pubkey_with_prefix (const uint8_t *pubkey, uint8_t curve, uint8_t *out, size_t *out_len) |
| Encodes the public key with the OpenPGP/SEC1 uncompressed prefix. | |
| static int | build_rsa_pubkey_from_storage (int r, uint8_t *resp, size_t resp_max) |
| Builds the 7F49 { 81 <modulus> 82 <exponent> } public-key response for an RSA role from its stored private-key blob. | |
| static int | cmd_generate_keypair (const apdu_t *apdu, uint8_t *resp, size_t resp_max) |
| Handles APDU GENERATE ASYMMETRIC KEY PAIR. | |
| static int | apply_response_chaining (uint32_t le, uint8_t *resp, size_t resp_max, int result_len) |
| Trim an APDU response to the host-requested Le window. | |
| static int | cmd_get_response (const apdu_t *apdu, uint8_t *resp, size_t resp_max) |
| Handles INS GET RESPONSE (0xC0) — drains the chained response buffer. | |
| int | openpgp_process_apdu (const uint8_t *cmd, size_t cmd_len, uint8_t *resp, size_t resp_max) |
Variables | |
| static const char * | TAG = "OpenPGP" |
| OpenPGP smart-card application implementation for CDC Badge. | |
| static uint8_t | s_openpgp_aid [16] |
| OpenPGP Application ID (RID + PIX), initialized dynamically. | |
| const uint8_t * | OPENPGP_AID = s_openpgp_aid |
| const uint8_t | OPENPGP_AID_LEN = sizeof(s_openpgp_aid) |
| static bool | app_selected = false |
| ATR is defined in ccid.cpp and accessed via ccid_get_atr(). | |
| static bool | pw1_verified = false |
| static bool | pw3_verified = false |
| static uint32_t | sig_count = 0 |
| static constexpr size_t | RC_SALT_SIZE = 16 |
| static constexpr size_t | RC_HASH_SIZE = 32 |
| static constexpr size_t | RC_KDF_TOTAL_BYTES = 100000 |
| static uint8_t | s_rc_salt [RC_SALT_SIZE] = {0} |
| static uint8_t | s_rc_hash [RC_HASH_SIZE] = {0} |
| static uint8_t | s_rc_len = 0 |
| static uint8_t | s_rc_retries = 3 |
| static uint8_t | selected_curve_sig = CDC_CURVE_ED25519 |
| Host-selected ECC curve per key role. DEC is fixed to P-256 because the TROPIC01 cannot perform ECDH natively and the firmware only carries a software P-256 ECDH path in ecdh.cpp. SIG and AUT default to Ed25519 (the project's preferred curve for signing) and can be flipped to P-256 via PUT DATA C1 / C3 per OpenPGP 3.4.1 §4.4.3.7-9. | |
| static uint8_t | selected_curve_aut = CDC_CURVE_ED25519 |
| static bool | role_is_rsa [3] = {false, false, false} |
| Per-role algorithm selection beyond the ECC curve. When role_is_rsa[r] is set the role is an RSA software key (blob in the mod_gpg_rsa R-Memory pool) and the rsa_* parameters carry its algorithm attributes; otherwise the role is ECC and selected_curve_* (SIG/AUT) or the fixed DEC P-256 ECDH apply. Index order matches key_type_t: SIG=0, DEC=1, AUT=2. | |
| static uint16_t | role_rsa_n_bits [3] = {0, 0, 0} |
| static uint16_t | role_rsa_e_bits [3] = {0, 0, 0} |
| static uint8_t | role_rsa_fmt [3] = {0, 0, 0} |
| static bool | kdf_active = false |
| KDF-DO (tag 0xF9) state. When kdf_active the host pre-hashes the PINs (PBKDF2) before VERIFY / CHANGE REFERENCE DATA / RESET RETRY COUNTER; PW1/PW3 are then compared through the binary PinManager path. The raw DO bytes are echoed back on GET DATA 0xF9. | |
| static uint8_t | kdf_pin_len = 0 |
| static uint8_t | kdf_do_bytes [124] = {} |
| static uint8_t | kdf_do_len = 0 |
| static bool | card_terminated = false |
| Card lifecycle state per OpenPGP 3.4.1 §7.2.18. | |
| static uint8_t | g_resp_buffer [4096] |
| Buffered remainder of an APDU response that did not fit into the caller-supplied Le window. Drained one chunk at a time via GET RESPONSE (INS 0xC0) per ISO 7816-4 §5.3.4. Lifetime is bound to the next APDU on the same logical channel: the buffer is invalidated when any non-GET RESPONSE command arrives. | |
| static size_t | g_resp_remaining = 0 |
| static size_t | g_resp_pos = 0 |
| static uint8_t | g_chain_buffer [4096] |
| Command-chaining accumulator (ISO 7816-4 §5.1.1). | |
| static size_t | g_chain_len = 0 |
| static bool | g_chain_active = false |
| static uint8_t | g_chain_ins = 0 |
| static uint8_t | g_chain_p1 = 0 |
| static uint8_t | g_chain_p2 = 0 |
| static char | s_session_pin [OPENPGP_PIN_MAX_LEN+1] = {} |
| Session PIN cache for DEC key decryption (temporary after VERIFY for PSO:DECIPHER). | |
| static constexpr uint8_t | OPENPGP_NVS_SCHEMA_V3 = 3 |
| static uint8_t | fingerprint_sig [OPENPGP_FINGERPRINT_SIZE] = {0} |
| Data object storage buffers (fingerprints and related metadata). | |
| static uint8_t | fingerprint_dec [OPENPGP_FINGERPRINT_SIZE] = {0} |
| static uint8_t | fingerprint_aut [OPENPGP_FINGERPRINT_SIZE] = {0} |
| static uint8_t | gen_time_sig [4] = {0} |
| Key-generation timestamps (4-byte big-endian Unix time each). | |
| static uint8_t | gen_time_dec [4] = {0} |
| static uint8_t | gen_time_aut [4] = {0} |
| static uint8_t | ca_fp_1 [OPENPGP_FINGERPRINT_SIZE] = {0} |
| Optional CA fingerprints for trust-chain metadata. | |
| static uint8_t | ca_fp_2 [OPENPGP_FINGERPRINT_SIZE] = {0} |
| static uint8_t | ca_fp_3 [OPENPGP_FINGERPRINT_SIZE] = {0} |
| static char | cardholder_name [40] = {0} |
| Cardholder profile data stored in NVS. | |
| static char | cardholder_lang [8] = "en" |
| static uint8_t | cardholder_sex = 0x39 |
| static char | cardholder_url [64] = {0} |
| static char | cardholder_login [32] = {0} |
| static const uint8_t | HIST_BYTES [] |
| Historical bytes used in OpenPGP ATR-related data objects. | |
| static const uint8_t | ALGO_ATTR_ED25519 [] |
| Algorithm attributes for Ed25519 (EdDSA with curve25519). | |
| static const uint8_t | ALGO_ATTR_P256_ECDSA [] |
| Algorithm attributes for P-256 ECDSA (signature/authentication roles). | |
| static const uint8_t | ALGO_ATTR_P256_ECDH [] |
| Algorithm attributes for P-256 ECDH (decryption role). | |
| static const uint8_t | EXT_CAPABILITIES [] |
| Extended capabilities object per OpenPGP 3.4.1 section 4.2.1. | |
| static constexpr uint8_t | ATTESTATION_ECC_SLOT = 0 |
| static constexpr size_t | OPENPGP_STATE_SIG_SIZE = 64 |
| static constexpr size_t | CARDHOLDER_CERT_MAX = 2048 |
| #define APP_VERSION "0.0.0" |
| #define NVS_CERT_KEY "cardcert" |
NVS key holding the (public) cardholder certificate (DO 0x7F21).
Definition at line 901 of file openpgp.cpp.
Referenced by load_cardholder_cert(), and save_cardholder_cert().
| #define NVS_NAMESPACE "openpgp" |
NVS namespace used for OpenPGP persistent data.
Definition at line 322 of file openpgp.cpp.
| #define NVS_STATE_KEY "state" |
Definition at line 323 of file openpgp.cpp.
Referenced by load_state_from_nvs(), and save_state_to_nvs().
| #define OPENPGP_RC_MIN_LEN 8 |
Resetting Code (RC) — optional per OpenPGP 3.4.1 §4.3.2. When set, the host can unblock PW1 with the RC instead of PW3 (RESET RETRY COUNTER with P1=0x00). We persist the configured RC bytes plus a separate retry counter in NVS.
Storage rationale: the existing PW1/PW3 path stores hashes inside the TROPIC01 R-Memory; allocating extra slots there for RC is deferred until the next slot-map revision. Plain NVS bytes are equivalent to plaintext Yubikey behaviour and unlock the same workflow.
Definition at line 184 of file openpgp.cpp.
Referenced by cmd_put_data().
| typedef bool(* pin_change_fn_t) (const char *pin) |
Type alias for PIN change callbacks.
Definition at line 2119 of file openpgp.cpp.
| enum key_type_t |
Builders for OpenPGP application-related data objects.
Key role discriminator used for algorithm-attribute selection.
| Enumerator | |
|---|---|
| KEY_TYPE_SIG | |
| KEY_TYPE_DEC | |
| KEY_TYPE_AUT | |
Definition at line 523 of file openpgp.cpp.
| enum pin_slot_t |
PIN slot identifier used by PIN helper routines.
| Enumerator | |
|---|---|
| PIN_SLOT_PW1 | |
| PIN_SLOT_PW3 | |
Definition at line 2024 of file openpgp.cpp.
| enum put_data_kind_t |
Storage kind for PUT DATA descriptor entries.
BLOB_FIXED requires apdu->lc == max_size; STRING_BOUNDED requires apdu->lc < max_size and writes a trailing NUL terminator.
| Enumerator | |
|---|---|
| PUT_KIND_BLOB_FIXED | |
| PUT_KIND_STRING_BOUNDED | |
Definition at line 1424 of file openpgp.cpp.
| struct __attribute__ | ( | (packed) | ) |
Single-blob persistent OpenPGP runtime state.
One nvs_set_blob per save keeps NVS page fragmentation bounded: the default 20 KB NVS partition is shared with every other module and the old per-field layout (~21 entries) silently filled up under load.
Definition at line 317 of file openpgp.cpp.
References OPENPGP_PIN_MAX_LEN, and s_session_pin.
|
static |
Applies a KDF-DO payload written via PUT DATA 0xF9.
On enable, PW1/PW3 references are initialised from the host-supplied initial hashes (tags 0x87 / 0x88). On disable, the PINs are reset to the cleartext defaults so the regular VERIFY path keeps working.
Definition at line 951 of file openpgp.cpp.
References kdf_do_t::algo, cdc::core::PinManager::DEFAULT_PW1, cdc::core::PinManager::DEFAULT_PW3, kdf_do_t::has_pw1_initial, kdf_do_t::has_pw3_initial, kdf_do_t::hash, kdf_active, KDF_ALGO_NONE, kdf_do_bytes, kdf_do_len, kdf_do_parse(), kdf_hash_len(), KDF_HASH_SHA256, KDF_HASH_SHA512, KDF_OK, kdf_pin_len, LOG_I, pin_storage_openpgp_change_pw1(), pin_storage_openpgp_change_pw3(), pin_storage_openpgp_set_pw1_raw(), pin_storage_openpgp_set_pw3_raw(), kdf_do_t::pw1_initial, kdf_do_t::pw1_initial_len, kdf_do_t::pw3_initial, kdf_do_t::pw3_initial_len, save_state_to_nvs(), SW_OK, SW_WRONG_DATA, SW_WRONG_LENGTH, and TAG.
Referenced by cmd_put_data().
|
static |
Applies a PUT DATA descriptor to the request payload.
| desc | Descriptor from find_put_data_desc. |
| apdu | Parsed APDU containing the new value. |
| resp | Response buffer. |
Definition at line 1486 of file openpgp.cpp.
References apdu_sw(), put_data_desc_t::buffer, put_data_desc_t::kind, LOG_I, put_data_desc_t::log_label, put_data_desc_t::max_size, PUT_KIND_STRING_BOUNDED, save_state_to_nvs(), SW_OK, SW_WRONG_LENGTH, and TAG.
Referenced by cmd_put_data().
|
static |
Trim an APDU response to the host-requested Le window.
If the dispatcher produced more payload than the host asked for, we keep the head (Le bytes) in resp and stash the rest in g_resp_buffer so the host can retrieve it via GET RESPONSE (INS 0xC0). The status word becomes 61xx where xx = remaining payload size (capped at 0xFF, 0x00 means "more
than 255 still pending"). Responses that already fit pass through.
Definition at line 3221 of file openpgp.cpp.
References g_resp_buffer, g_resp_pos, g_resp_remaining, LOG_W, SW_OK, and TAG.
Referenced by openpgp_process_apdu().
|
static |
Builds OpenPGP DO 0x6E (Application Related Data).
| buf | Output buffer for the encoded TLV object. |
| buf_max | Maximum size of buf. |
Definition at line 572 of file openpgp.cpp.
References ca_fp_1, ca_fp_2, ca_fp_3, DO_AID, DO_ALGO_AUT, DO_ALGO_DEC, DO_ALGO_SIG, DO_EXT_CAP, DO_HIST_BYTES, DO_PW_STATUS, EXT_CAPABILITIES, fingerprint_aut, fingerprint_dec, fingerprint_sig, gen_time_aut, gen_time_dec, gen_time_sig, get_algo_attr(), HIST_BYTES, KEY_TYPE_AUT, KEY_TYPE_DEC, KEY_TYPE_SIG, OPENPGP_AID, OPENPGP_AID_LEN, OPENPGP_FINGERPRINT_SIZE, OPENPGP_PIN_MAX_LEN, pin_storage_openpgp_pw1_retries(), pin_storage_openpgp_pw3_retries(), s_rc_len, s_rc_retries, tlv_build(), tlv_write_len(), and tlv_write_tag().
Referenced by cmd_get_data().
|
static |
Builds OpenPGP DO 0x65 (Cardholder Related Data).
| buf | Output buffer for the encoded TLV object. |
| buf_max | Maximum size of buf. |
Definition at line 666 of file openpgp.cpp.
References cardholder_lang, cardholder_name, cardholder_sex, DO_CARDHOLDER, DO_LANG_PREF, DO_NAME, DO_SEX, tlv_build(), tlv_write_len(), and tlv_write_tag().
Referenced by cmd_get_data().
|
static |
Builds the 7F49 { 81 <modulus> 82 <exponent> } public-key response for an RSA role from its stored private-key blob.
| r | Role index (0 = SIG, 1 = DEC, 2 = AUT). |
Definition at line 3043 of file openpgp.cpp.
References apdu_build_response(), apdu_sw(), GPG_RSA_BLOB_MAX, gpg_rsa_blob_public(), GPG_RSA_MAX_MODULUS_BYTES, gpg_storage_load_rsa_key(), SW_OK, SW_REFERENCED_DATA_NOT_FOUND, SW_UNKNOWN, tlv_build(), tlv_write_len(), and tlv_write_tag().
Referenced by cmd_generate_keypair().
|
static |
Definition at line 306 of file openpgp.cpp.
References g_chain_active, g_chain_ins, g_chain_len, g_chain_p1, and g_chain_p2.
Referenced by openpgp_process_apdu().
|
static |
Handles APDU ACTIVATE FILE (INS 0x44).
Per OpenPGP 3.4.1 §7.2.18: in operational state ACTIVATE FILE is a no-op (SW_OK). In terminated state it wipes every persistent OpenPGP artefact (keys, fingerprints, generation times, cardholder data, PINs) and returns the card to operational state.
Definition at line 2716 of file openpgp.cpp.
References apdu_sw(), card_terminated, LOG_W, openpgp_factory_reset(), SW_INCORRECT_P1P2, SW_OK, and TAG.
Referenced by openpgp_process_apdu().
|
static |
Handles APDU CHANGE REFERENCE DATA command for PIN updates.
| apdu | Parsed APDU request. |
| resp | Output response buffer. |
| resp_max | Maximum size of resp. |
Definition at line 2171 of file openpgp.cpp.
References apdu_sw(), kdf_active, kdf_pin_len, LOG_I, OPENPGP_PIN_MAX_LEN, OPENPGP_PW1_MIN_LEN, OPENPGP_PW3_MIN_LEN, PIN_SLOT_PW1, PIN_SLOT_PW3, pin_storage_openpgp_change_pw1(), pin_storage_openpgp_change_pw3(), pin_storage_openpgp_pw1_retries(), pin_storage_openpgp_pw3_retries(), pin_storage_openpgp_set_pw1_raw(), pin_storage_openpgp_set_pw3_raw(), pin_storage_openpgp_verify_pw1(), pin_storage_openpgp_verify_pw1_raw(), pin_storage_openpgp_verify_pw3(), pin_storage_openpgp_verify_pw3_raw(), PW1_CODE_1, PW3_CODE, SW_AUTH_METHOD_BLOCKED, SW_INCORRECT_P1P2, SW_OK, SW_WRONG_DATA, SW_WRONG_LENGTH, TAG, and try_change_pin().
Referenced by openpgp_process_apdu().
|
static |
Handles APDU GENERATE ASYMMETRIC KEY PAIR.
| apdu | Parsed APDU request. |
| resp | Output response buffer. |
| resp_max | Maximum size of resp. |
Definition at line 3080 of file openpgp.cpp.
References apdu_build_response(), apdu_sw(), build_rsa_pubkey_from_storage(), CDC_CURVE_P256, curve, encode_pubkey_with_prefix(), generate_dec_key(), generate_hardware_key(), get_ecc_slot_for_key_ref(), get_key_type_for_ref(), GPG_RSA_BLOB_MAX, gpg_rsa_generate(), gpg_storage_save_rsa_key(), KEY_SIG, KEY_TYPE_AUT, KEY_TYPE_DEC, KEY_TYPE_SIG, LOG_I, LOG_W, P256_PUBKEY_SIZE, pw3_verified, read_public_key(), role_index_for_key_ref(), role_is_rsa, role_rsa_n_bits, selected_curve_aut, selected_curve_sig, SW_OK, SW_REFERENCED_DATA_NOT_FOUND, SW_SECURITY_NOT_SATISFIED, SW_UNKNOWN, TAG, tlv_build(), tlv_write_len(), and update_generation_timestamp().
Referenced by openpgp_process_apdu().
|
static |
Handles APDU GET DATA command processing.
| apdu | Parsed APDU request. |
| resp | Output response buffer. |
| resp_max | Maximum size of resp. |
Definition at line 1221 of file openpgp.cpp.
References apdu_build_response(), apdu_sw(), build_do_app_related(), build_do_cardholder(), ca_fp_1, ca_fp_2, ca_fp_3, CARDHOLDER_CERT_MAX, cardholder_lang, cardholder_login, cardholder_name, cardholder_sex, cardholder_url, curve, DO_AID, DO_ALGO_AUT, DO_ALGO_DEC, DO_ALGO_SIG, DO_APP_RELATED, DO_CA_FP_1, DO_CA_FP_2, DO_CA_FP_3, DO_CARDHOLDER, DO_CARDHOLDER_CERT, DO_EXT_CAP, DO_FP_AUT, DO_FP_DEC, DO_FP_SIG, DO_GEN_TIME_AUT, DO_GEN_TIME_DEC, DO_GEN_TIME_SIG, DO_HIST_BYTES, DO_KDF, DO_KEY_INFO, DO_LANG_PREF, DO_LOGIN, DO_NAME, DO_PW_STATUS, DO_SEC_TPL, DO_SEX, DO_SIG_COUNT, DO_UIF_AUT, DO_UIF_DEC, DO_UIF_SIG, DO_URL, EXT_CAPABILITIES, fingerprint_aut, fingerprint_dec, fingerprint_sig, gen_time_aut, gen_time_dec, gen_time_sig, get_algo_attr(), gpg_storage_aut_slot(), gpg_storage_has_dec_privkey(), gpg_storage_has_rsa_key(), gpg_storage_sig_slot(), HIST_BYTES, kdf_do_build_disabled(), kdf_do_bytes, kdf_do_len, KEY_TYPE_AUT, KEY_TYPE_DEC, KEY_TYPE_SIG, load_cardholder_cert(), LOG_W, OPENPGP_AID, OPENPGP_AID_LEN, OPENPGP_FINGERPRINT_SIZE, OPENPGP_PIN_MAX_LEN, P256_PUBKEY_SIZE, pin_storage_openpgp_pw1_retries(), pin_storage_openpgp_pw3_retries(), respond_chunked(), role_is_rsa, s_rc_len, s_rc_retries, se_ecc_key_read(), sig_count, SW_OK, SW_REFERENCED_DATA_NOT_FOUND, SW_UNKNOWN, and TAG.
Referenced by openpgp_process_apdu().
|
static |
Handles INS GET RESPONSE (0xC0) — drains the chained response buffer.
Definition at line 3251 of file openpgp.cpp.
References apdu_sw(), g_resp_buffer, g_resp_pos, g_resp_remaining, SW_CONDITIONS_NOT_SATISFIED, SW_INCORRECT_P1P2, and SW_OK.
Referenced by openpgp_process_apdu().
|
static |
Handles APDU INTERNAL AUTHENTICATE (INS 0x88).
Signs the supplied authentication challenge with the AUT key (ECC slot 3). Used by gpg-agent / ssh for client authentication.
Per OpenPGP 3.4.1 §7.2.13: P1=0x00 P2=0x00, Lc = challenge length, Le = signature length. PW1 (reference 0x82) must be verified; we reuse the PW1 session flag.
Signature format matches PSO:CDS: raw R||S for ECDSA, 64-byte EdDSA sig.
Definition at line 2631 of file openpgp.cpp.
References apdu_build_response(), apdu_sw(), CDC_CURVE_P256, curve, GPG_RSA_BLOB_MAX, GPG_RSA_MAX_MODULUS_BYTES, gpg_rsa_sign(), gpg_storage_aut_slot(), gpg_storage_load_rsa_key(), LOG_E, P256_PUBKEY_SIZE, pw1_verified, role_is_rsa, se_ecc_key_read(), se_ecdsa_sign(), se_eddsa_sign(), SW_CONDITIONS_NOT_SATISFIED, SW_INCORRECT_P1P2, SW_OK, SW_SECURITY_NOT_SATISFIED, SW_UNKNOWN, SW_WRONG_LENGTH, and TAG.
Referenced by openpgp_process_apdu().
|
static |
Handles APDU MANAGE SECURITY ENVIRONMENT (INS 0x22).
Per OpenPGP 3.4.1 §7.2.10: gpg / scd issue MSE before PSO to point the key reference into a different slot. Two combinations matter in practice: P1=0x41 P2=0xB6 + tag 83 01 01 → use SIG key for DSI (signature) P1=0x41 P2=0xA4 + tag 83 01 03 → use AUT key for INTERNAL AUTHENTICATE
Our key-slot mapping is fixed by role (SIG=B6, DEC=B8, AUT=A4) so MSE is effectively a no-op as long as the requested reference matches the role encoded in P2. We accept the documented combinations and return SW_OK, which is enough for gpg-card / ssh workflows that issue MSE defensively.
Definition at line 2591 of file openpgp.cpp.
References apdu_sw(), KEY_AUT, KEY_DEC, KEY_SIG, SW_CONDITIONS_NOT_SATISFIED, SW_INCORRECT_P1P2, SW_OK, SW_WRONG_DATA, and SW_WRONG_LENGTH.
Referenced by openpgp_process_apdu().
|
static |
Handles APDU PSO: COMPUTE DIGITAL SIGNATURE.
| apdu | Parsed APDU request. |
| resp | Output response buffer. |
| resp_max | Maximum size of resp. |
Definition at line 2298 of file openpgp.cpp.
References apdu_build_response(), apdu_sw(), CDC_CURVE_P256, curve, GPG_RSA_BLOB_MAX, GPG_RSA_MAX_MODULUS_BYTES, gpg_rsa_sign(), gpg_storage_load_rsa_key(), gpg_storage_sig_slot(), LOG_E, LOG_I, P256_PUBKEY_SIZE, pw1_verified, role_is_rsa, save_state_to_nvs(), se_ecc_key_read(), se_ecdsa_sign(), se_eddsa_sign(), SHA256_DIGEST_SIZE, sig_count, SW_CONDITIONS_NOT_SATISFIED, SW_OK, SW_SECURITY_NOT_SATISFIED, SW_UNKNOWN, SW_WRONG_DATA, and TAG.
Referenced by openpgp_process_apdu().
|
static |
Definition at line 2450 of file openpgp.cpp.
References apdu_build_response(), apdu_sw(), cmd_pso_decipher_aes(), ecdh_p256_compute_shared_secret(), GPG_RSA_BLOB_MAX, gpg_rsa_decrypt(), GPG_RSA_MAX_MODULUS_BYTES, gpg_storage_has_dec_privkey(), gpg_storage_load_dec_privkey(), gpg_storage_load_rsa_key(), P256_ECDH_SECRET_SIZE, P256_PRIVKEY_SIZE, P256_PUBKEY_SIZE, pw1_verified, role_is_rsa, SW_CONDITIONS_NOT_SATISFIED, SW_OK, SW_SECURITY_NOT_SATISFIED, SW_UNKNOWN, and SW_WRONG_DATA.
Referenced by openpgp_process_apdu().
|
static |
Handles APDU PSO: DECIPHER for ECDH key agreement.
| apdu | Parsed APDU request. |
| resp | Output response buffer. |
| resp_max | Maximum size of resp. |
PSO:DECIPHER - ECDH Decryption.
SECURITY NOTE: The TROPIC01 secure element does NOT support native ECDH operations. Therefore, the DEC private key is stored encrypted in R-Memory and temporarily decrypted in RAM for the ECDH computation.
This is a necessary trade-off for GPG compatibility. See docs/GPG_ECDH_SECURITY.md for details.
Mitigations:
OpenPGP 3.4.1, Section 7.2.11: Command: 00 2A 80 86 <Lc> <data> <Le> Data format for ECDH: 7F49 <len> – Cipher DO A6 <len> – External Public Key template 86 <len> – External Public Key point (04||X||Y for P-256) <65 bytes ephemeral pubkey> Response: Shared Secret (32 bytes for P-256)
Decrypts an AES-CFB128 payload using the stored symmetric key (DO 0xD5).
| apdu | Parsed APDU request, payload[0] = 0x02 padding indicator. |
| resp | Output response buffer. |
| resp_max | Maximum size of resp. |
Payload format: 0x02 || IV(16) || ciphertext.
Definition at line 2398 of file openpgp.cpp.
References apdu_build_response(), apdu_sw(), gpg_storage_has_aes_key(), gpg_storage_load_aes_key(), s_session_pin, SW_CONDITIONS_NOT_SATISFIED, SW_OK, SW_SECURITY_NOT_SATISFIED, SW_UNKNOWN, SW_WRONG_DATA, and SW_WRONG_LENGTH.
Referenced by cmd_pso_decipher().
|
static |
Definition at line 1624 of file openpgp.cpp.
References apdu_sw(), apply_kdf_do(), apply_put_data_desc(), CARDHOLDER_CERT_MAX, cardholder_sex, compute_rc_hash(), DO_AES_KEY, DO_ALGO_AUT, DO_ALGO_DEC, DO_ALGO_SIG, DO_CARDHOLDER_CERT, DO_KDF, DO_RC, DO_SEX, find_put_data_desc(), gpg_storage_save_aes_key(), LOG_I, LOG_W, OPENPGP_PIN_MAX_LEN, OPENPGP_RC_MIN_LEN, put_data_algo_attr(), pw3_verified, RC_HASH_SIZE, RC_SALT_SIZE, s_rc_hash, s_rc_len, s_rc_retries, s_rc_salt, s_session_pin, save_cardholder_cert(), save_state_to_nvs(), se_random_fill(), SW_FILE_NOT_FOUND, SW_OK, SW_SECURITY_NOT_SATISFIED, SW_UNKNOWN, SW_WRONG_LENGTH, and TAG.
Referenced by openpgp_process_apdu().
|
static |
Handles APDU PUT DATA (odd INS, 0xDB) for keypair import.
Used by gpg --card-edit → keytocard / off-card backup import: GnuPG ships a key as an OpenPGP 3.4.1 §7.2.8 Extended Header List
4D LL <CRT> // B6 00 (SIG) / B8 00 (DEC) / A4 00 (AUT) 7F48 LL // Cardholder Private Key Template (tag list) 5F48 LL // Concatenation of values
ECC roles: the 32-byte private scalar is imported into the TROPIC01 ECC slot (SIG / AUT) or the software ECDH store (DEC). RSA roles: e / p / q are parsed per the template and stored as an encrypted blob in the RSA R-Memory pool.
Definition at line 1819 of file openpgp.cpp.
References apdu_sw(), CDC_CURVE_ED25519, curve, cdc::hal::ED25519, ehl_parse_one(), get_se(), gpg_rsa_blob_build(), GPG_RSA_BLOB_MAX, gpg_storage_aut_slot(), gpg_storage_save_dec_privkey(), gpg_storage_save_rsa_key(), gpg_storage_sig_slot(), LOG_I, cdc::hal::OK, cdc::hal::P256, P256_PRIVKEY_SIZE, parse_rsa_import(), pw3_verified, role_index_for_key_ref(), role_is_rsa, role_rsa_n_bits, selected_curve_aut, selected_curve_sig, SW_INCORRECT_P1P2, SW_OK, SW_SECURITY_NOT_SATISFIED, SW_UNKNOWN, SW_WRONG_DATA, SW_WRONG_LENGTH, TAG, and update_generation_timestamp().
Referenced by openpgp_process_apdu().
|
static |
Handles APDU RESET RETRY COUNTER (INS 0x2C).
Per OpenPGP 3.4.1 §7.2.7: P1=0x02, P2=0x81: reset PW1 with admin authorisation. Lc = new PW1 length. Requires PW3 verified. P1=0x00, P2=0x81: reset PW1 using the Resetting Code. Lc = RC || new PW1. Not yet implemented — returns SW_INS_NOT_SUPPORTED until the RC store lands (planned in Phase D.3, full path).
Definition at line 2790 of file openpgp.cpp.
References apdu_sw(), compute_rc_hash(), kdf_active, LOG_I, OPENPGP_PIN_MAX_LEN, OPENPGP_PW1_MIN_LEN, pin_storage_openpgp_change_pw1(), pin_storage_openpgp_reset_pw1_retries(), pin_storage_openpgp_set_pw1_raw(), PW1_CODE_1, pw1_verified, pw3_verified, RC_HASH_SIZE, s_rc_hash, s_rc_len, s_rc_retries, s_rc_salt, save_state_to_nvs(), SW_AUTH_METHOD_BLOCKED, SW_CONDITIONS_NOT_SATISFIED, SW_INCORRECT_P1P2, SW_OK, SW_SECURITY_NOT_SATISFIED, SW_UNKNOWN, SW_WRONG_LENGTH, and TAG.
Referenced by openpgp_process_apdu().
|
static |
Handles APDU SELECT command processing.
| apdu | Parsed APDU request. |
| resp | Output response buffer. |
| resp_max | Maximum size of resp. |
Definition at line 1165 of file openpgp.cpp.
References apdu_sw(), app_selected, gpg_storage_clear_session(), LOG_I, OPENPGP_AID, pw1_verified, pw3_verified, s_session_pin, SW_FILE_NOT_FOUND, SW_OK, and TAG.
Referenced by openpgp_process_apdu().
|
static |
Handles APDU TERMINATE DF (INS 0xE6).
Per OpenPGP 3.4.1 §7.2.18: takes the card into the terminated lifecycle state. Allowed under PW3 verification, or unconditionally when both PW1 and PW3 retry counters have reached zero (last-resort recovery).
After TERMINATE only SELECT and ACTIVATE FILE are accepted; every other command returns SW_FILE_TERMINATED (0x6285).
Definition at line 2690 of file openpgp.cpp.
References apdu_sw(), card_terminated, LOG_W, pin_storage_openpgp_pw1_blocked(), pin_storage_openpgp_pw3_blocked(), pw1_verified, pw3_verified, save_state_to_nvs(), SW_INCORRECT_P1P2, SW_OK, SW_SECURITY_NOT_SATISFIED, and TAG.
Referenced by openpgp_process_apdu().
|
static |
Handles APDU VERIFY command for PIN verification.
| apdu | Parsed APDU request. |
| resp | Output response buffer. |
| resp_max | Maximum size of resp. |
Definition at line 1928 of file openpgp.cpp.
References apdu_sw(), gpg_storage_clear_session(), gpg_storage_set_session_pin(), kdf_active, LOG_I, LOG_W, OPENPGP_PIN_MAX_LEN, pin_storage_openpgp_pw1_blocked(), pin_storage_openpgp_pw1_retries(), pin_storage_openpgp_pw3_blocked(), pin_storage_openpgp_pw3_retries(), pin_storage_openpgp_verify_pw1(), pin_storage_openpgp_verify_pw1_raw(), pin_storage_openpgp_verify_pw3(), pin_storage_openpgp_verify_pw3_raw(), PW1_CODE_1, PW1_CODE_2, pw1_verified, PW3_CODE, pw3_verified, s_session_pin, SW_AUTH_METHOD_BLOCKED, SW_INCORRECT_P1P2, SW_OK, SW_WRONG_LENGTH, and TAG.
Referenced by openpgp_process_apdu().
|
static |
Computes the iterated-salted S2K hash (OpenPGP KDF) for a PIN candidate.
| pin | PIN string. |
| salt | 8-byte salt. |
| iterations | Iteration count from PinManager. |
| hash_out | 32-byte output buffer. |
Definition at line 2037 of file openpgp.cpp.
References OPENPGP_PIN_MAX_LEN.
Referenced by peek_verify_pin().
|
static |
Iterated-salted SHA-256 over salt||rc for resetting-code storage. Same construction as PinManager::computeKdfHash (OpenPGP S2K).
Definition at line 197 of file openpgp.cpp.
References OPENPGP_PIN_MAX_LEN, RC_KDF_TOTAL_BYTES, and RC_SALT_SIZE.
Referenced by cmd_put_data(), and cmd_reset_retry_counter().
|
static |
Constant-time comparison of two equal-length byte buffers.
| a | First buffer. |
| b | Second buffer. |
| n | Number of bytes to compare. |
Definition at line 2080 of file openpgp.cpp.
Referenced by peek_verify_pin().
|
static |
Parse one BER-TLV field at pos.
Supports 1- or 2-byte tags and short-form / 0x81 / 0x82 length encodings, which covers everything the OpenPGP 3.4.1 PUT DATA odd payload uses.
pos is advanced past the parsed value. Definition at line 1721 of file openpgp.cpp.
Referenced by cmd_put_data_odd().
|
static |
Encodes the public key with the OpenPGP/SEC1 uncompressed prefix.
P-256 keys are normalized to 0x04 || X || Y. Ed25519 keys are returned as their raw 32-byte encoding without prefix.
| pubkey | Source public key buffer. |
| curve | Curve identifier (CDC_CURVE_*). |
| out | Destination buffer (must hold at least P256_PUBKEY_SIZE bytes). |
| out_len | Receives the encoded length. |
Definition at line 3020 of file openpgp.cpp.
References CDC_CURVE_P256, curve, ED25519_PUBKEY_SIZE, and P256_PUBKEY_SIZE.
Referenced by cmd_generate_keypair().
|
static |
Returns descriptor for an OpenPGP PUT DATA tag.
| tag | OpenPGP DO tag. |
Definition at line 1448 of file openpgp.cpp.
References ca_fp_1, ca_fp_2, ca_fp_3, cardholder_lang, cardholder_login, cardholder_name, cardholder_url, DO_CA_FP_1, DO_CA_FP_2, DO_CA_FP_3, DO_FP_AUT, DO_FP_DEC, DO_FP_SIG, DO_GEN_TIME_AUT, DO_GEN_TIME_DEC, DO_GEN_TIME_SIG, DO_LANG_PREF, DO_LOGIN, DO_NAME, DO_URL, fingerprint_aut, fingerprint_dec, fingerprint_sig, gen_time_aut, gen_time_dec, gen_time_sig, OPENPGP_FINGERPRINT_SIZE, PUT_KIND_BLOB_FIXED, and PUT_KIND_STRING_BOUNDED.
Referenced by cmd_put_data().
|
static |
Definition at line 1074 of file openpgp.cpp.
References OPENPGP_FINGERPRINT_SIZE.
Referenced by openpgp_has_any_key().
|
static |
Generates a software ECDH P-256 key pair for the DEC slot.
The TROPIC01 secure element does not support ECDH, so the DEC private key is generated and persisted by gpg_storage (encrypted by device key). Memory holding the raw key is zeroized before returning.
Definition at line 2919 of file openpgp.cpp.
References ecdh_p256_generate_keypair(), gpg_storage_save_dec_privkey(), P256_PRIVKEY_SIZE, SW_OK, and SW_UNKNOWN.
Referenced by cmd_generate_keypair().
|
static |
Generates a hardware ECC key pair in the TROPIC01 secure element.
| ecc_slot | ECC slot index targeted by the key generation. |
| curve | Curve identifier (CDC_CURVE_*). |
Definition at line 2938 of file openpgp.cpp.
References curve, LOG_E, LOG_I, se_ecc_key_generate(), SW_OK, SW_UNKNOWN, and TAG.
Referenced by cmd_generate_keypair().
|
static |
Returns algorithm attributes for a key role based on stored key type.
| key_type | Key role (signature, decryption, authentication). |
| len | Output pointer receiving the attribute length. |
Definition at line 535 of file openpgp.cpp.
References ALGO_ATTR_ED25519, ALGO_ATTR_P256_ECDH, ALGO_ATTR_P256_ECDSA, ALGO_RSA, CDC_CURVE_P256, curve, KEY_TYPE_AUT, KEY_TYPE_DEC, role_is_rsa, role_rsa_e_bits, role_rsa_fmt, role_rsa_n_bits, selected_curve_aut, and selected_curve_sig.
Referenced by build_do_app_related(), and cmd_get_data().
|
static |
Returns ECC slot mapping for an OpenPGP key reference.
| key_ref | OpenPGP key reference value. |
Definition at line 2883 of file openpgp.cpp.
References gpg_storage_aut_slot(), gpg_storage_dec_slot(), gpg_storage_sig_slot(), KEY_AUT, KEY_DEC, and KEY_SIG.
Referenced by cmd_generate_keypair().
|
static |
Maps an OpenPGP key reference to an internal key type.
| key_ref | OpenPGP key reference value. |
Definition at line 2901 of file openpgp.cpp.
References KEY_AUT, KEY_DEC, KEY_SIG, KEY_TYPE_AUT, KEY_TYPE_DEC, and KEY_TYPE_SIG.
Referenced by cmd_generate_keypair().
|
static |
Returns secure-element instance used by OpenPGP backend.
Definition at line 43 of file openpgp.cpp.
References cdc::hal::getSecureElementInstance().
Referenced by cmd_put_data_odd(), load_state_from_nvs(), openpgp_factory_reset(), save_state_to_nvs(), se_ecc_key_generate(), se_ecc_key_read(), se_ecdsa_sign(), se_eddsa_sign(), se_random_fill(), and wipe_role_key().
|
static |
Initializes the OpenPGP AID serial section from the ESP32 MAC address.
Definition at line 1007 of file openpgp.cpp.
References LOG_I, LOG_W, s_openpgp_aid, and TAG.
Referenced by openpgp_init().
|
static |
Returns the on-device byte length of an SHA-256/512 KDF pre-hash.
Definition at line 939 of file openpgp.cpp.
References KDF_HASH_SHA512.
Referenced by apply_kdf_do().
|
static |
Loads the cardholder certificate into out.
Definition at line 927 of file openpgp.cpp.
References NVS_CERT_KEY, and NVS_NAMESPACE.
Referenced by cmd_get_data().
|
static |
Loads persistent OpenPGP runtime state from NVS.
Definition at line 746 of file openpgp.cpp.
References ca_fp_1, ca_fp_2, ca_fp_3, card_terminated, cardholder_lang, cardholder_login, cardholder_name, cardholder_sex, cardholder_url, CDC_CURVE_ED25519, CDC_CURVE_P256, fingerprint_aut, fingerprint_dec, fingerprint_sig, gen_time_aut, gen_time_dec, gen_time_sig, get_se(), kdf_active, kdf_do_bytes, kdf_do_len, kdf_pin_len, LOG_W, NVS_NAMESPACE, NVS_STATE_KEY, OPENPGP_FINGERPRINT_SIZE, OPENPGP_NVS_SCHEMA_V3, OPENPGP_PIN_MAX_LEN, OPENPGP_STATE_SIG_SIZE, RC_HASH_SIZE, RC_SALT_SIZE, role_is_rsa, role_rsa_e_bits, role_rsa_fmt, role_rsa_n_bits, s_rc_hash, s_rc_len, s_rc_retries, s_rc_salt, selected_curve_aut, selected_curve_sig, sig_count, TAG, and verify_state_signature().
Referenced by openpgp_init().
| void openpgp_factory_reset | ( | void | ) |
Definition at line 2729 of file openpgp.cpp.
References ca_fp_1, ca_fp_2, ca_fp_3, card_terminated, cardholder_lang, cardholder_login, cardholder_name, cardholder_sex, cardholder_url, CDC_CURVE_ED25519, fingerprint_aut, fingerprint_dec, fingerprint_sig, gen_time_aut, gen_time_dec, gen_time_sig, get_se(), gpg_storage_aut_slot(), gpg_storage_clear_session(), gpg_storage_delete_dec_privkey(), gpg_storage_delete_rsa_key(), gpg_storage_sig_slot(), kdf_active, kdf_do_bytes, kdf_do_len, kdf_pin_len, pin_storage_openpgp_reset(), pw1_verified, pw3_verified, role_is_rsa, role_rsa_e_bits, role_rsa_fmt, role_rsa_n_bits, s_rc_hash, s_rc_len, s_rc_retries, s_rc_salt, save_cardholder_cert(), save_state_to_nvs(), selected_curve_aut, selected_curve_sig, and sig_count.
Referenced by cmd_activate_file(), and gpg_reset().
| size_t openpgp_get_cardholder_name | ( | char * | out, |
| size_t | out_size ) |
Copies the cardholder name (OpenPGP DO 0x5B) into the caller buffer. Format is gpg's "Surname<<Firstname" or empty when unset.
Definition at line 1087 of file openpgp.cpp.
References cardholder_name.
Referenced by gpg_get_status().
| bool openpgp_get_fingerprint | ( | uint8_t | key_type, |
| uint8_t * | fp_out ) |
Reads the stored OpenPGP v4 fingerprint for a key role.
| key_type | One of KEY_SIG, KEY_DEC, KEY_AUT. |
| fp_out | 20-byte output buffer. |
Definition at line 1064 of file openpgp.cpp.
References fingerprint_aut, fingerprint_dec, fingerprint_sig, KEY_AUT, KEY_DEC, KEY_SIG, and OPENPGP_FINGERPRINT_SIZE.
Referenced by gpg_get_status().
| uint32_t openpgp_get_gen_time | ( | uint8_t | key_type | ) |
Returns the stored Unix timestamp of key generation, or 0 when unset.
| key_type | One of KEY_SIG, KEY_DEC, KEY_AUT. |
Definition at line 1096 of file openpgp.cpp.
References gen_time_aut, gen_time_dec, gen_time_sig, KEY_AUT, KEY_DEC, and KEY_SIG.
Referenced by gpg_get_status(), cdc::mod_gpg::gpgBuildOwnSignedKeyArmored(), and cdc::mod_gpg::gpgBuildOwnSubkeyMaterial().
| uint32_t openpgp_get_sig_count | ( | void | ) |
| bool openpgp_has_any_key | ( | void | ) |
Reports whether any of the SIG / DEC / AUT roles has a non-zero fingerprint configured. Acts as the canonical "card has keys" check.
Definition at line 1081 of file openpgp.cpp.
References fingerprint_aut, fingerprint_dec, fingerprint_sig, and fp_is_set().
Referenced by gpg_export_pubkey_pem(), gpg_generate_key(), gpg_get_status(), gpg_is_initialized(), and cdc::mod_gpg::rebuildMenu().
| bool openpgp_init | ( | void | ) |
Definition at line 1037 of file openpgp.cpp.
References gpg_init(), init_aid_from_mac(), load_state_from_nvs(), LOG_E, LOG_I, pin_storage_openpgp_init(), sig_count, and TAG.
Referenced by ccid_init().
| bool openpgp_is_selected | ( | void | ) |
Definition at line 1056 of file openpgp.cpp.
References app_selected.
| int openpgp_process_apdu | ( | const uint8_t * | cmd, |
| size_t | cmd_len, | ||
| uint8_t * | resp, | ||
| size_t | resp_max ) |
Definition at line 3283 of file openpgp.cpp.
References apdu_build_response(), apdu_parse(), apdu_sw(), app_selected, APP_VERSION, apply_response_chaining(), card_terminated, chain_reset(), cmd_activate_file(), cmd_change_reference_data(), cmd_generate_keypair(), cmd_get_data(), cmd_get_response(), cmd_internal_authenticate(), cmd_manage_security_env(), cmd_pso_cds(), cmd_pso_decipher(), cmd_put_data(), cmd_put_data_odd(), cmd_reset_retry_counter(), cmd_select(), cmd_terminate_df(), cmd_verify(), g_chain_active, g_chain_buffer, g_chain_ins, g_chain_len, g_chain_p1, g_chain_p2, g_resp_pos, g_resp_remaining, INS_ACTIVATE, INS_CHANGE_PIN, INS_GENERATE_KEYPAIR, INS_GET_CHALLENGE, INS_GET_DATA, INS_GET_RESPONSE, INS_GET_VERSION, INS_INTERNAL_AUTH, INS_MSE, INS_PSO, INS_PUT_DATA, INS_PUT_DATA_ODD, INS_RESET_RETRY, INS_SELECT, INS_TERMINATE, INS_VERIFY, LOG_D, LOG_E, LOG_W, se_random_fill(), SW_CLA_NOT_SUPPORTED, SW_CONDITIONS_NOT_SATISFIED, SW_FILE_TERMINATED, SW_INCORRECT_P1P2, SW_INS_NOT_SUPPORTED, SW_OK, SW_WRONG_DATA, SW_WRONG_LENGTH, and TAG.
Referenced by ccid_process_message().
| bool openpgp_set_cardholder_name | ( | const char * | name | ) |
Sets the cardholder name (OpenPGP DO 0x5B) and persists state.
| name | UTF-8 string; truncated to fit the storage buffer. |
Definition at line 1110 of file openpgp.cpp.
References cardholder_name, name, and save_state_to_nvs().
Referenced by gpg_generate_key().
| bool openpgp_set_key_fingerprint | ( | uint8_t | key_type, |
| const uint8_t * | fingerprint, | ||
| uint32_t | gen_time ) |
Definition at line 1123 of file openpgp.cpp.
References fingerprint_aut, fingerprint_dec, fingerprint_sig, gen_time_aut, gen_time_dec, gen_time_sig, KEY_AUT, KEY_DEC, KEY_SIG, LOG_E, LOG_I, OPENPGP_FINGERPRINT_SIZE, save_state_to_nvs(), and TAG.
Referenced by gpg_generate_key().
|
static |
Splits the RSA key material (5F48) into e / p / q using the lengths declared in the Cardholder Private Key Template (7F48).
The template is a sequence of <tag><length> pairs with no inline value; the 5F48 concatenation carries the values in the same order. RSA tags: 0x91 = e, 0x92 = p, 0x93 = q (0x94-0x97 are recomputed by mbedTLS).
Definition at line 1766 of file openpgp.cpp.
Referenced by cmd_put_data_odd().
|
static |
Compares a candidate PIN against the stored hash without touching retry counters.
| slot | PIN slot to query. |
| pin | Candidate PIN string. |
Definition at line 2092 of file openpgp.cpp.
References compute_kdf_hash(), const_time_equal(), cdc::core::PinManager::instance(), and PIN_SLOT_PW1.
Referenced by try_change_pin().
|
static |
Definition at line 1559 of file openpgp.cpp.
References ALGO_ATTR_CURVE_ED25519, ALGO_ATTR_CURVE_P256, ALGO_ATTR_ID_ECDH, ALGO_ATTR_OK, algo_attr_parse(), ALGO_ATTR_ROLE_AUT, ALGO_ATTR_ROLE_DEC, ALGO_ATTR_ROLE_SIG, algo_attr_validate_capability(), algo_attr_validate_role(), algo_attr_t::algo_id, apdu_sw(), CDC_CURVE_ED25519, CDC_CURVE_P256, algo_attr_t::curve, DO_ALGO_AUT, DO_ALGO_DEC, DO_ALGO_SIG, algo_attr_t::is_rsa, LOG_I, role_is_rsa, role_rsa_e_bits, role_rsa_fmt, role_rsa_n_bits, algo_attr_t::rsa_e_bits, algo_attr_t::rsa_import_fmt, algo_attr_t::rsa_n_bits, save_state_to_nvs(), selected_curve_aut, selected_curve_sig, SW_FILE_NOT_FOUND, SW_OK, SW_WRONG_DATA, TAG, and wipe_role_key().
Referenced by cmd_put_data().
|
static |
Reads the public key for a given key role.
For SIG/AUT keys this reads from the TROPIC01 ECC slot. For DEC keys, the public key is derived from the encrypted software-stored private key; the temporary private-key buffer is zeroized after use.
| key_type | Logical key role. |
| ecc_slot | ECC slot index for hardware-backed keys. |
| pubkey | Output buffer (must be at least P256_PUBKEY_SIZE bytes). |
| curve_out | Curve detected for the loaded public key. |
Definition at line 2982 of file openpgp.cpp.
References CDC_CURVE_P256, ecdh_p256_derive_pubkey(), gpg_storage_has_dec_privkey(), gpg_storage_load_dec_privkey(), KEY_TYPE_DEC, LOG_I, LOG_W, P256_PRIVKEY_SIZE, P256_PUBKEY_SIZE, se_ecc_key_read(), and TAG.
Referenced by cmd_generate_keypair().
|
static |
Returns a payload larger than the response window using response chaining, priming the GET RESPONSE buffer directly.
Unlike apply_response_chaining (which trims a fully-built response) this handles payloads that exceed resp_max by emitting the first chunk plus a 61xx status word and stashing the remainder. The dispatcher's trailing apply_response_chaining is a no-op afterwards (61xx is not SW_OK).
Definition at line 1192 of file openpgp.cpp.
References apdu_sw(), g_resp_buffer, g_resp_pos, g_resp_remaining, and SW_WRONG_LENGTH.
Referenced by cmd_get_data().
|
static |
Maps an OpenPGP key reference (B6/B8/A4) to a 0-based role index.
Definition at line 994 of file openpgp.cpp.
References KEY_AUT, KEY_DEC, and KEY_SIG.
Referenced by cmd_generate_keypair(), and cmd_put_data_odd().
|
static |
Persists the cardholder certificate as a standalone NVS blob. len == 0 erases it. Stored unsigned: a certificate is public data.
Definition at line 908 of file openpgp.cpp.
References NVS_CERT_KEY, and NVS_NAMESPACE.
Referenced by cmd_put_data(), and openpgp_factory_reset().
|
static |
Persists OpenPGP runtime state to NVS.
Definition at line 824 of file openpgp.cpp.
References ATTESTATION_ECC_SLOT, ca_fp_1, ca_fp_2, ca_fp_3, card_terminated, cardholder_lang, cardholder_login, cardholder_name, cardholder_sex, cardholder_url, fingerprint_aut, fingerprint_dec, fingerprint_sig, gen_time_aut, gen_time_dec, gen_time_sig, get_se(), kdf_active, kdf_do_bytes, kdf_do_len, kdf_pin_len, LOG_E, NVS_NAMESPACE, NVS_STATE_KEY, cdc::hal::OK, OPENPGP_FINGERPRINT_SIZE, OPENPGP_NVS_SCHEMA_V3, OPENPGP_STATE_SIG_SIZE, RC_HASH_SIZE, RC_SALT_SIZE, role_is_rsa, role_rsa_e_bits, role_rsa_fmt, role_rsa_n_bits, s_rc_hash, s_rc_len, s_rc_retries, s_rc_salt, selected_curve_aut, selected_curve_sig, sig_count, and TAG.
Referenced by apply_kdf_do(), apply_put_data_desc(), cmd_pso_cds(), cmd_put_data(), cmd_reset_retry_counter(), cmd_terminate_df(), openpgp_factory_reset(), openpgp_set_cardholder_name(), openpgp_set_key_fingerprint(), put_data_algo_attr(), and update_generation_timestamp().
|
static |
Generates ECC key material in secure element slot.
| slot | ECC slot index. |
| curve | Curve identifier (CDC_CURVE_*). |
Definition at line 76 of file openpgp.cpp.
References CDC_CURVE_ED25519, curve, cdc::hal::ED25519, get_se(), LOG_E, LOG_W, cdc::hal::OK, cdc::hal::P256, and TAG.
Referenced by generate_hardware_key().
|
static |
Reads ECC public key from secure element and exposes curve metadata.
| slot | ECC slot index. |
| pubkey | Output public key buffer. |
| max_len | Capacity of pubkey. |
| curve_out | Optional output curve identifier. |
Definition at line 55 of file openpgp.cpp.
References CDC_CURVE_ED25519, CDC_CURVE_P256, curve, cdc::hal::ED25519, ED25519_PUBKEY_SIZE, get_se(), cdc::hal::OK, cdc::hal::P256, and P256_PUBKEY_SIZE.
Referenced by cmd_get_data(), cmd_internal_authenticate(), cmd_pso_cds(), and read_public_key().
|
static |
Signs a hash using secure-element ECDSA key.
| slot | ECC slot index. |
| hash | Hash bytes to sign. |
| hash_len | Hash length. |
| sig | Output 64-byte signature buffer. |
Definition at line 111 of file openpgp.cpp.
References get_se(), and cdc::hal::OK.
Referenced by cmd_internal_authenticate(), and cmd_pso_cds().
|
static |
Signs a message using secure-element EdDSA key.
| slot | ECC slot index. |
| Message transfer (badge-to-badge) | Message bytes. |
| msg_len | Message length. |
| sig | Output signature buffer. |
Definition at line 126 of file openpgp.cpp.
References get_se(), and cdc::hal::OK.
Referenced by cmd_internal_authenticate(), and cmd_pso_cds().
|
static |
Fills buffer with secure random bytes, with ESP fallback.
| buf | Output buffer. |
| len | Number of bytes to generate. |
Definition at line 137 of file openpgp.cpp.
References get_se().
Referenced by cmd_put_data(), and openpgp_process_apdu().
|
static |
Builds complete TLV object and returns total encoded length.
| buf | Output buffer. |
| buf_max | Maximum size of buf. |
| tag | TLV tag. |
| value | Optional value bytes. |
| value_len | Value length. |
Definition at line 504 of file openpgp.cpp.
References tlv_write_len(), and tlv_write_tag().
Referenced by build_do_app_related(), build_do_cardholder(), build_rsa_pubkey_from_storage(), and cmd_generate_keypair().
|
static |
Writes a TLV length field using DER length encoding.
| buf | Output buffer receiving the encoded length. |
| len | Length value to encode. |
Definition at line 479 of file openpgp.cpp.
Referenced by build_do_app_related(), build_do_cardholder(), build_rsa_pubkey_from_storage(), cmd_generate_keypair(), and tlv_build().
|
static |
TLV builder helper functions.
Writes a TLV tag using one or two bytes.
| buf | Output buffer receiving the tag bytes. |
| tag | TLV tag value. |
Definition at line 463 of file openpgp.cpp.
Referenced by build_do_app_related(), build_do_cardholder(), build_rsa_pubkey_from_storage(), and tlv_build().
|
static |
Searches the split point for CHANGE REFERENCE DATA without consuming retries.
Iterates over candidate old-PIN lengths and uses a non-decrementing hash comparison. Only the matched split is applied through change_fn; the underlying retry counter is left untouched until the caller consumes one retry on overall failure.
| data | Concatenated old||new PIN bytes. |
| len | Total length of data. |
| min_len | Minimum PIN length for the target slot. |
| slot | PIN slot identifier. |
| change_fn | Callback that applies the new PIN. |
Definition at line 2136 of file openpgp.cpp.
References OPENPGP_PIN_MAX_LEN, and peek_verify_pin().
Referenced by cmd_change_reference_data().
|
static |
Updates and persists the generation timestamp for a key role.
Definition at line 2951 of file openpgp.cpp.
References gen_time_aut, gen_time_dec, gen_time_sig, KEY_AUT, KEY_DEC, KEY_SIG, and save_state_to_nvs().
Referenced by cmd_generate_keypair(), and cmd_put_data_odd().
|
static |
Verifies the P-256 ECDSA attestation signature over an OpenPGP state payload. Same construction as PinManager.
Definition at line 701 of file openpgp.cpp.
References ATTESTATION_ECC_SLOT, curve, cdc::hal::ISecureElement::eccGetPublicKey(), cdc::hal::OK, OPENPGP_STATE_SIG_SIZE, and cdc::hal::P256.
Referenced by load_state_from_nvs().
|
static |
Handles APDU PUT DATA command processing.
| apdu | Parsed APDU request. |
| resp | Output response buffer. |
| resp_max | Maximum size of resp. |
Parses and applies a PUT DATA payload addressed to one of the algorithm-attribute Data Objects (C1, C2, C3).
For SIG (C1) and AUT (C3) the selected curve is updated and the existing key in the corresponding slot is wiped to force the host to regenerate it. DEC (C2) is constrained to P-256 ECDH (software path), so we accept the documented attribute and reject everything else.
Invalidates all stored key material for a role (ECC slot, RSA blob, software DEC key, fingerprint and generation time). Used when the algorithm attributes change so the next GENERATE / import is clean.
| r | Role index: 0 = SIG, 1 = DEC, 2 = AUT. |
Definition at line 1535 of file openpgp.cpp.
References fingerprint_aut, fingerprint_dec, fingerprint_sig, gen_time_aut, gen_time_dec, gen_time_sig, get_se(), gpg_storage_aut_slot(), gpg_storage_delete_dec_privkey(), gpg_storage_delete_rsa_key(), and gpg_storage_sig_slot().
Referenced by put_data_algo_attr().
|
static |
Algorithm attributes for Ed25519 (EdDSA with curve25519).
Format: Algorithm ID (1) + OID bytes (no length prefix per OpenPGP 3.4.1).
Definition at line 415 of file openpgp.cpp.
Referenced by get_algo_attr().
|
static |
Algorithm attributes for P-256 ECDH (decryption role).
Format: Algorithm ID (1) + OID bytes (no length prefix per OpenPGP 3.4.1).
Definition at line 435 of file openpgp.cpp.
Referenced by get_algo_attr().
|
static |
Algorithm attributes for P-256 ECDSA (signature/authentication roles).
Format: Algorithm ID (1) + OID bytes (no length prefix per OpenPGP 3.4.1).
Definition at line 425 of file openpgp.cpp.
Referenced by get_algo_attr().
|
static |
ATR is defined in ccid.cpp and accessed via ccid_get_atr().
Application session/authentication state.
Definition at line 168 of file openpgp.cpp.
Referenced by cmd_select(), openpgp_is_selected(), and openpgp_process_apdu().
|
staticconstexpr |
Definition at line 694 of file openpgp.cpp.
Referenced by save_state_to_nvs(), and verify_state_signature().
|
static |
Optional CA fingerprints for trust-chain metadata.
Definition at line 385 of file openpgp.cpp.
Referenced by build_do_app_related(), cmd_get_data(), find_put_data_desc(), load_state_from_nvs(), openpgp_factory_reset(), and save_state_to_nvs().
|
static |
Definition at line 386 of file openpgp.cpp.
Referenced by build_do_app_related(), cmd_get_data(), find_put_data_desc(), load_state_from_nvs(), openpgp_factory_reset(), and save_state_to_nvs().
|
static |
Definition at line 387 of file openpgp.cpp.
Referenced by build_do_app_related(), cmd_get_data(), find_put_data_desc(), load_state_from_nvs(), openpgp_factory_reset(), and save_state_to_nvs().
|
static |
Card lifecycle state per OpenPGP 3.4.1 §7.2.18.
false = operational, true = terminated. While terminated the dispatcher accepts only SELECT and ACTIVATE FILE; everything else returns SW_FILE_TERMINATED (0x6285). ACTIVATE FILE wipes keys, DOs and PINs back to factory defaults.
Definition at line 274 of file openpgp.cpp.
Referenced by cmd_activate_file(), cmd_terminate_df(), load_state_from_nvs(), openpgp_factory_reset(), openpgp_process_apdu(), and save_state_to_nvs().
|
staticconstexpr |
Definition at line 902 of file openpgp.cpp.
Referenced by cmd_get_data(), and cmd_put_data().
|
static |
Definition at line 393 of file openpgp.cpp.
Referenced by build_do_cardholder(), cmd_get_data(), find_put_data_desc(), load_state_from_nvs(), openpgp_factory_reset(), and save_state_to_nvs().
|
static |
Definition at line 396 of file openpgp.cpp.
Referenced by cmd_get_data(), find_put_data_desc(), load_state_from_nvs(), openpgp_factory_reset(), and save_state_to_nvs().
|
static |
Cardholder profile data stored in NVS.
Definition at line 392 of file openpgp.cpp.
Referenced by build_do_cardholder(), cmd_get_data(), find_put_data_desc(), load_state_from_nvs(), openpgp_factory_reset(), openpgp_get_cardholder_name(), openpgp_set_cardholder_name(), and save_state_to_nvs().
|
static |
Definition at line 394 of file openpgp.cpp.
Referenced by build_do_cardholder(), cmd_get_data(), cmd_put_data(), load_state_from_nvs(), openpgp_factory_reset(), and save_state_to_nvs().
|
static |
Definition at line 395 of file openpgp.cpp.
Referenced by cmd_get_data(), find_put_data_desc(), load_state_from_nvs(), openpgp_factory_reset(), and save_state_to_nvs().
|
static |
Extended capabilities object per OpenPGP 3.4.1 section 4.2.1.
Definition at line 443 of file openpgp.cpp.
Referenced by build_do_app_related(), and cmd_get_data().
|
static |
Definition at line 373 of file openpgp.cpp.
Referenced by build_do_app_related(), cmd_get_data(), find_put_data_desc(), load_state_from_nvs(), openpgp_factory_reset(), openpgp_get_fingerprint(), openpgp_has_any_key(), openpgp_set_key_fingerprint(), save_state_to_nvs(), and wipe_role_key().
|
static |
Definition at line 372 of file openpgp.cpp.
Referenced by build_do_app_related(), cmd_get_data(), find_put_data_desc(), load_state_from_nvs(), openpgp_factory_reset(), openpgp_get_fingerprint(), openpgp_has_any_key(), openpgp_set_key_fingerprint(), save_state_to_nvs(), and wipe_role_key().
|
static |
Data object storage buffers (fingerprints and related metadata).
Definition at line 371 of file openpgp.cpp.
Referenced by build_do_app_related(), cmd_get_data(), find_put_data_desc(), load_state_from_nvs(), openpgp_factory_reset(), openpgp_get_fingerprint(), openpgp_has_any_key(), openpgp_set_key_fingerprint(), save_state_to_nvs(), and wipe_role_key().
|
static |
Definition at line 301 of file openpgp.cpp.
Referenced by chain_reset(), and openpgp_process_apdu().
|
static |
Command-chaining accumulator (ISO 7816-4 §5.1.1).
The host sets the CLA chaining bit (0x10) on every intermediate APDU and clears it on the last one. We accumulate the command data here until the final chunk arrives, then dispatch a single synthetic APDU. Triggered by gpg key import (RSA / large ECC), large PUT DATA (e.g. cardholder cert), and PSO:DECIPHER with extended Cipher DOs.
Definition at line 299 of file openpgp.cpp.
Referenced by openpgp_process_apdu().
|
static |
Definition at line 302 of file openpgp.cpp.
Referenced by chain_reset(), and openpgp_process_apdu().
|
static |
Definition at line 300 of file openpgp.cpp.
Referenced by chain_reset(), and openpgp_process_apdu().
|
static |
Definition at line 303 of file openpgp.cpp.
Referenced by chain_reset(), and openpgp_process_apdu().
|
static |
Definition at line 304 of file openpgp.cpp.
Referenced by chain_reset(), and openpgp_process_apdu().
|
static |
Buffered remainder of an APDU response that did not fit into the caller-supplied Le window. Drained one chunk at a time via GET RESPONSE (INS 0xC0) per ISO 7816-4 §5.3.4. Lifetime is bound to the next APDU on the same logical channel: the buffer is invalidated when any non-GET RESPONSE command arrives.
4 kB cap covers the largest OpenPGP DOs (Cardholder Certificate, Application Related Data with full key info) without claiming PSRAM.
Definition at line 286 of file openpgp.cpp.
Referenced by apply_response_chaining(), cmd_get_response(), and respond_chunked().
|
static |
Definition at line 288 of file openpgp.cpp.
Referenced by apply_response_chaining(), cmd_get_response(), openpgp_process_apdu(), and respond_chunked().
|
static |
Definition at line 287 of file openpgp.cpp.
Referenced by apply_response_chaining(), cmd_get_response(), openpgp_process_apdu(), and respond_chunked().
|
static |
Definition at line 380 of file openpgp.cpp.
Referenced by build_do_app_related(), cmd_get_data(), find_put_data_desc(), load_state_from_nvs(), openpgp_factory_reset(), openpgp_get_gen_time(), openpgp_set_key_fingerprint(), save_state_to_nvs(), update_generation_timestamp(), and wipe_role_key().
|
static |
Definition at line 379 of file openpgp.cpp.
Referenced by build_do_app_related(), cmd_get_data(), find_put_data_desc(), load_state_from_nvs(), openpgp_factory_reset(), openpgp_get_gen_time(), openpgp_set_key_fingerprint(), save_state_to_nvs(), update_generation_timestamp(), and wipe_role_key().
|
static |
Key-generation timestamps (4-byte big-endian Unix time each).
Definition at line 378 of file openpgp.cpp.
Referenced by build_do_app_related(), cmd_get_data(), find_put_data_desc(), load_state_from_nvs(), openpgp_factory_reset(), openpgp_get_gen_time(), openpgp_set_key_fingerprint(), save_state_to_nvs(), update_generation_timestamp(), and wipe_role_key().
|
static |
Historical bytes used in OpenPGP ATR-related data objects.
Definition at line 401 of file openpgp.cpp.
Referenced by build_do_app_related(), and cmd_get_data().
|
static |
KDF-DO (tag 0xF9) state. When kdf_active the host pre-hashes the PINs (PBKDF2) before VERIFY / CHANGE REFERENCE DATA / RESET RETRY COUNTER; PW1/PW3 are then compared through the binary PinManager path. The raw DO bytes are echoed back on GET DATA 0xF9.
Definition at line 261 of file openpgp.cpp.
Referenced by apply_kdf_do(), cmd_change_reference_data(), cmd_reset_retry_counter(), cmd_verify(), load_state_from_nvs(), openpgp_factory_reset(), and save_state_to_nvs().
|
static |
Definition at line 263 of file openpgp.cpp.
Referenced by apply_kdf_do(), cmd_get_data(), load_state_from_nvs(), openpgp_factory_reset(), and save_state_to_nvs().
|
static |
Definition at line 264 of file openpgp.cpp.
Referenced by apply_kdf_do(), cmd_get_data(), load_state_from_nvs(), openpgp_factory_reset(), and save_state_to_nvs().
|
static |
Definition at line 262 of file openpgp.cpp.
Referenced by apply_kdf_do(), cmd_change_reference_data(), load_state_from_nvs(), openpgp_factory_reset(), and save_state_to_nvs().
| const uint8_t* OPENPGP_AID = s_openpgp_aid |
Definition at line 158 of file openpgp.cpp.
Referenced by build_do_app_related(), cmd_get_data(), and cmd_select().
| const uint8_t OPENPGP_AID_LEN = sizeof(s_openpgp_aid) |
Definition at line 159 of file openpgp.cpp.
Referenced by build_do_app_related(), and cmd_get_data().
|
staticconstexpr |
Definition at line 366 of file openpgp.cpp.
Referenced by load_state_from_nvs(), and save_state_to_nvs().
|
staticconstexpr |
Definition at line 695 of file openpgp.cpp.
Referenced by load_state_from_nvs(), save_state_to_nvs(), and verify_state_signature().
|
static |
Definition at line 169 of file openpgp.cpp.
Referenced by cmd_internal_authenticate(), cmd_pso_cds(), cmd_pso_decipher(), cmd_reset_retry_counter(), cmd_select(), cmd_terminate_df(), cmd_verify(), and openpgp_factory_reset().
|
static |
Definition at line 170 of file openpgp.cpp.
Referenced by cmd_generate_keypair(), cmd_put_data(), cmd_put_data_odd(), cmd_reset_retry_counter(), cmd_select(), cmd_terminate_df(), cmd_verify(), and openpgp_factory_reset().
|
staticconstexpr |
Definition at line 186 of file openpgp.cpp.
Referenced by cmd_put_data(), cmd_reset_retry_counter(), load_state_from_nvs(), and save_state_to_nvs().
|
staticconstexpr |
Definition at line 187 of file openpgp.cpp.
Referenced by compute_rc_hash().
|
staticconstexpr |
Definition at line 185 of file openpgp.cpp.
Referenced by cmd_put_data(), compute_rc_hash(), load_state_from_nvs(), and save_state_to_nvs().
|
static |
Per-role algorithm selection beyond the ECC curve. When role_is_rsa[r] is set the role is an RSA software key (blob in the mod_gpg_rsa R-Memory pool) and the rsa_* parameters carry its algorithm attributes; otherwise the role is ECC and selected_curve_* (SIG/AUT) or the fixed DEC P-256 ECDH apply. Index order matches key_type_t: SIG=0, DEC=1, AUT=2.
Definition at line 250 of file openpgp.cpp.
Referenced by cmd_generate_keypair(), cmd_get_data(), cmd_internal_authenticate(), cmd_pso_cds(), cmd_pso_decipher(), cmd_put_data_odd(), get_algo_attr(), load_state_from_nvs(), openpgp_factory_reset(), put_data_algo_attr(), and save_state_to_nvs().
|
static |
Definition at line 252 of file openpgp.cpp.
Referenced by get_algo_attr(), load_state_from_nvs(), openpgp_factory_reset(), put_data_algo_attr(), and save_state_to_nvs().
|
static |
Definition at line 253 of file openpgp.cpp.
Referenced by get_algo_attr(), load_state_from_nvs(), openpgp_factory_reset(), put_data_algo_attr(), and save_state_to_nvs().
|
static |
Definition at line 251 of file openpgp.cpp.
Referenced by cmd_generate_keypair(), cmd_put_data_odd(), get_algo_attr(), load_state_from_nvs(), openpgp_factory_reset(), put_data_algo_attr(), and save_state_to_nvs().
|
static |
OpenPGP Application ID (RID + PIX), initialized dynamically.
D2 76 00 01 24 01 = OpenPGP RID. Structure: RID(6) + Version(2) + Manufacturer(2) + Serial(4) + RFU(2) = 16 bytes.
Definition at line 151 of file openpgp.cpp.
Referenced by init_aid_from_mac().
|
static |
Definition at line 189 of file openpgp.cpp.
Referenced by cmd_put_data(), cmd_reset_retry_counter(), load_state_from_nvs(), openpgp_factory_reset(), and save_state_to_nvs().
|
static |
Definition at line 190 of file openpgp.cpp.
Referenced by build_do_app_related(), cmd_get_data(), cmd_put_data(), cmd_reset_retry_counter(), load_state_from_nvs(), openpgp_factory_reset(), and save_state_to_nvs().
|
static |
Definition at line 191 of file openpgp.cpp.
Referenced by build_do_app_related(), cmd_get_data(), cmd_put_data(), cmd_reset_retry_counter(), load_state_from_nvs(), openpgp_factory_reset(), and save_state_to_nvs().
|
static |
Definition at line 188 of file openpgp.cpp.
Referenced by cmd_put_data(), cmd_reset_retry_counter(), load_state_from_nvs(), openpgp_factory_reset(), and save_state_to_nvs().
|
static |
Session PIN cache for DEC key decryption (temporary after VERIFY for PSO:DECIPHER).
Definition at line 317 of file openpgp.cpp.
Referenced by __attribute__(), cmd_pso_decipher_aes(), cmd_put_data(), cmd_select(), and cmd_verify().
|
static |
Definition at line 240 of file openpgp.cpp.
Referenced by cmd_generate_keypair(), cmd_put_data_odd(), get_algo_attr(), load_state_from_nvs(), openpgp_factory_reset(), put_data_algo_attr(), and save_state_to_nvs().
|
static |
Host-selected ECC curve per key role. DEC is fixed to P-256 because the TROPIC01 cannot perform ECDH natively and the firmware only carries a software P-256 ECDH path in ecdh.cpp. SIG and AUT default to Ed25519 (the project's preferred curve for signing) and can be flipped to P-256 via PUT DATA C1 / C3 per OpenPGP 3.4.1 §4.4.3.7-9.
Definition at line 239 of file openpgp.cpp.
Referenced by cmd_generate_keypair(), cmd_put_data_odd(), get_algo_attr(), load_state_from_nvs(), openpgp_factory_reset(), put_data_algo_attr(), and save_state_to_nvs().
|
static |
Definition at line 171 of file openpgp.cpp.
Referenced by cmd_get_data(), cmd_pso_cds(), load_state_from_nvs(), openpgp_factory_reset(), openpgp_get_sig_count(), openpgp_init(), and save_state_to_nvs().
|
static |
OpenPGP smart-card application implementation for CDC Badge.
Based on pico-openpgp (https://github.com/polhenarejos/pico-openpgp), adapted for CDC Badge and TROPIC01 secure element integration. Specification target: OpenPGP Smart Card Application 3.4.1.
Definition at line 37 of file openpgp.cpp.