CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
openpgp.h
Go to the documentation of this file.
1/*
2 * OpenPGP SmartCard Application for CDC Badge
3 *
4 * Based on pico-openpgp (https://github.com/polhenarejos/pico-openpgp)
5 * Original: Copyright (c) 2022 Pol Henarejos, AGPLv3
6 * Adapted for CDC Badge with TROPIC01 Secure Element
7 *
8 * This implementation follows OpenPGP 3.4.1 specification:
9 * https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.4.pdf
10 */
11
12#pragma once
13#include <stdint.h>
14#include <stdbool.h>
15#include <stddef.h>
16
17#ifdef __cplusplus
18extern "C" {
19#endif
20
21// OpenPGP Application ID (AID) - initialized dynamically in openpgp_init()
22extern const uint8_t* OPENPGP_AID;
23extern const uint8_t OPENPGP_AID_LEN;
24
25// NOTE: ATR is defined in ccid.cpp and accessed via ccid_get_atr()
26// Do not use OPENPGP_ATR - use ccid_get_atr() instead!
27
28// Algorithm identifiers
29#define ALGO_RSA 0x01
30#define ALGO_ECDH 0x12
31#define ALGO_ECDSA 0x13
32#define ALGO_EDDSA 0x16 // Ed25519
33
34// Key slots
35#define KEY_SIG 0xB6 // Signature key
36#define KEY_DEC 0xB8 // Decryption key
37#define KEY_AUT 0xA4 // Authentication key
38
39// PIN constraints (keep in sync with PinManager)
40#define OPENPGP_PW1_MIN_LEN 6
41#define OPENPGP_PW3_MIN_LEN 8
42#define OPENPGP_PIN_MAX_LEN 32
43
44// Data Object tags (selected)
45#define DO_AID 0x004F // Application Identifier
46#define DO_HIST_BYTES 0x5F52 // Historical bytes
47#define DO_CARDHOLDER 0x0065 // Cardholder Related Data
48#define DO_APP_RELATED 0x006E // Application Related Data
49#define DO_DISCRET_DO 0x0073 // Discretionary Data Objects
50#define DO_EXT_CAP 0x00C0 // Extended Capabilities
51#define DO_ALGO_SIG 0x00C1 // Algorithm Attributes: Signature
52#define DO_ALGO_DEC 0x00C2 // Algorithm Attributes: Decryption
53#define DO_ALGO_AUT 0x00C3 // Algorithm Attributes: Authentication
54#define DO_PW_STATUS 0x00C4 // PW Status Bytes
55#define DO_RC 0x00D3 // Resetting Code (optional, see OpenPGP 3.4.1 §4.4.3.12)
56#define DO_FP_SIG 0x00C7 // Fingerprint Signature key
57#define DO_FP_DEC 0x00C8 // Fingerprint Decryption key
58#define DO_FP_AUT 0x00C9 // Fingerprint Authentication key
59#define DO_CA_FP_1 0x00CA // CA Fingerprint 1
60#define DO_CA_FP_2 0x00CB // CA Fingerprint 2
61#define DO_CA_FP_3 0x00CC // CA Fingerprint 3
62// Per OpenPGP Smart Card 3.4.1 §4.4.3.10:
63// CD = concatenation of the three generation dates (read-only)
64// CE = date of generation of SIG key (writable, 4-byte big-endian)
65// CF = date of generation of DEC key
66// D0 = date of generation of AUT key
67// Earlier versions of this code used CD/CE/CF which is the per-key time table
68// from older OpenPGP revisions; gpg-card 2.5+ follows the 3.4.1 layout and
69// rejects every key-generation handshake when the tags are off by one.
70#define DO_GEN_TIME_ALL 0x00CD // Concatenated SIG||DEC||AUT (12 bytes, read-only)
71#define DO_GEN_TIME_SIG 0x00CE // Generation time: Signature
72#define DO_GEN_TIME_DEC 0x00CF // Generation time: Decryption
73#define DO_GEN_TIME_AUT 0x00D0 // Generation time: Authentication
74#define DO_SIG_COUNT 0x0093 // Digital Signature Counter
75#define DO_URL 0x5F50 // URL for public key retrieval
76#define DO_LOGIN 0x005E // Login data
77#define DO_NAME 0x005B // Name (Cardholder)
78#define DO_LANG_PREF 0x5F2D // Language preference
79#define DO_SEX 0x5F35 // Sex
80#define DO_UIF_SIG 0x00D6 // User Interaction Flag: Signature
81#define DO_UIF_DEC 0x00D7 // User Interaction Flag: Decryption
82#define DO_UIF_AUT 0x00D8 // User Interaction Flag: Authentication
83#define DO_KEY_INFO 0x00DE // Key Information
84#define DO_SEC_TPL 0x007A // Security Support Template
85#define DO_KDF 0x00F9 // KDF (Key Derivation Function)
86#define DO_AES_KEY 0x00D5 // AES symmetric key (PSO:DECIPHER 0x02)
87#define DO_CARDHOLDER_CERT 0x7F21 // Cardholder Certificate
88
89// Status Words (SW1-SW2)
90#define SW_OK 0x9000
91#define SW_FILE_TERMINATED 0x6285
92#define SW_WRONG_LENGTH 0x6700
93#define SW_SECURITY_NOT_SATISFIED 0x6982
94#define SW_AUTH_METHOD_BLOCKED 0x6983
95#define SW_CONDITIONS_NOT_SATISFIED 0x6985
96#define SW_WRONG_DATA 0x6A80
97#define SW_FILE_NOT_FOUND 0x6A82
98#define SW_INCORRECT_P1P2 0x6A86
99#define SW_REFERENCED_DATA_NOT_FOUND 0x6A88
100#define SW_WRONG_P1P2 0x6B00
101#define SW_INS_NOT_SUPPORTED 0x6D00
102#define SW_CLA_NOT_SUPPORTED 0x6E00
103#define SW_UNKNOWN 0x6F00
104
105// Initialize OpenPGP application
106bool openpgp_init(void);
107
108// Process incoming APDU command
109// Returns response length (including SW1-SW2)
110int openpgp_process_apdu(const uint8_t *cmd, size_t cmd_len,
111 uint8_t *resp, size_t resp_max);
112
113// Check if OpenPGP application is selected
114bool openpgp_is_selected(void);
115
116// Get current signature count
117uint32_t openpgp_get_sig_count(void);
118
119// Update fingerprint for a key type (call after key generation via serial cmd)
120// key_type: KEY_SIG (0xB6), KEY_DEC (0xB8), KEY_AUT (0xA4)
121// fingerprint: 20-byte SHA-1 fingerprint (V4 format)
122// gen_time: Unix timestamp of key generation (big-endian)
123bool openpgp_set_key_fingerprint(uint8_t key_type, const uint8_t *fingerprint,
124 uint32_t gen_time);
125
126// Wipe all persistent OpenPGP state: fingerprints, generation times,
127// cardholder data, signature counter, RC, selected curves, PINs. Used by
128// ACTIVATE FILE (APDU 0x44) and the GPG_RESET serial command.
129void openpgp_factory_reset(void);
130
137bool openpgp_get_fingerprint(uint8_t key_type, uint8_t *fp_out);
138
143bool openpgp_has_any_key(void);
144
150size_t openpgp_get_cardholder_name(char *out, size_t out_size);
151
156uint32_t openpgp_get_gen_time(uint8_t key_type);
157
162bool openpgp_set_cardholder_name(const char *name);
163
164#ifdef __cplusplus
165}
166#endif
167
char name[cdc::hal::ISecureElement::RMEM_NAME_LEN]
const uint8_t * OPENPGP_AID
Definition openpgp.cpp:156
bool openpgp_get_fingerprint(uint8_t key_type, uint8_t *fp_out)
Reads the stored OpenPGP v4 fingerprint for a key role.
Definition openpgp.cpp:890
uint32_t openpgp_get_gen_time(uint8_t key_type)
Returns the stored Unix timestamp of key generation, or 0 when unset.
Definition openpgp.cpp:922
int openpgp_process_apdu(const uint8_t *cmd, size_t cmd_len, uint8_t *resp, size_t resp_max)
Definition openpgp.cpp:2683
bool openpgp_set_key_fingerprint(uint8_t key_type, const uint8_t *fingerprint, uint32_t gen_time)
Definition openpgp.cpp:949
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<<Firstn...
Definition openpgp.cpp:913
bool openpgp_set_cardholder_name(const char *name)
Sets the cardholder name (OpenPGP DO 0x5B) and persists state.
Definition openpgp.cpp:936
bool openpgp_init(void)
Definition openpgp.cpp:863
uint32_t openpgp_get_sig_count(void)
Definition openpgp.cpp:886
bool openpgp_has_any_key(void)
Reports whether any of the SIG / DEC / AUT roles has a non-zero fingerprint configured....
Definition openpgp.cpp:907
bool openpgp_is_selected(void)
Definition openpgp.cpp:882
const uint8_t OPENPGP_AID_LEN
Definition openpgp.cpp:157
void openpgp_factory_reset(void)
Definition openpgp.cpp:2218