|
CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
|
#include <PinManager.h>
Public Member Functions | |
| bool | init () |
| Initializes PIN state from secure storage or defaults. | |
| bool | verifyBadgePin (const char *pin) |
| Verifies badge PIN, updates retries, and handles lockout transitions. | |
| bool | changeBadgePin (const char *currentPin, const char *newPin) |
| Changes badge PIN after validating current PIN. | |
| bool | setBadgePin (const char *newPin) |
| bool | getBadgePinHash (uint8_t *hashOut) const |
| Copies stored badge PIN hash into caller buffer. | |
| bool | verifyBadgePinHash (const uint8_t *hashIn) const |
| Verifies provided hash against stored badge hash. | |
| uint8_t | getBadgeRetries () const |
| bool | isBadgeBlocked () const |
| Lockout timer handling. | |
| void | resetBadgeRetries () |
| Resets badge retry counter to maximum. | |
| void | setMinPinLengthFloor (uint8_t minLen) |
| Sets the minimum badge-PIN length floor enforced on changes. | |
| uint8_t | minPinLengthFloor () const |
| void | startLockout () |
| Starts the badge recovery timer. | |
| uint32_t | getLockoutRemainingMs () const |
| Returns remaining badge lockout duration. | |
| bool | isLockoutActive () const |
| Returns whether lockout is currently active without mutating state. | |
| void | checkAndResetExpiredLockout () |
| Clears expired lockout state and resets retry counter. | |
| bool | verifyPW1 (const char *pin) |
| OpenPGP PW1 (user PIN) workflow. | |
| bool | changePW1 (const char *currentPin, const char *newPin) |
| Changes PW1 after validating the current value. | |
| bool | setPW1 (const char *newPin) |
| Sets PW1 directly and refreshes salt/hash material. | |
| bool | getPW1Hash (uint8_t *hashOut) const |
| Copies stored PW1 hash into caller buffer. | |
| bool | getPW1Salt (uint8_t *saltOut) const |
| Copies stored PW1 salt into caller buffer. | |
| uint8_t | getPW1Retries () const |
| bool | isPW1Blocked () const |
| void | resetPW1Retries () |
| Resets PW1 retry counter to maximum. | |
| bool | verifyPW1Raw (const uint8_t *data, size_t len) |
| bool | setPW1Raw (const uint8_t *data, size_t len) |
| bool | verifyPW3 (const char *pin) |
| OpenPGP PW3 (admin PIN) workflow. | |
| bool | changePW3 (const char *currentPin, const char *newPin) |
| Changes PW3 after validating the current value. | |
| bool | setPW3 (const char *newPin) |
| Sets PW3 directly and refreshes salt/hash material. | |
| bool | getPW3Hash (uint8_t *hashOut) const |
| Copies stored PW3 hash into caller buffer. | |
| bool | getPW3Salt (uint8_t *saltOut) const |
| Copies stored PW3 salt into caller buffer. | |
| uint8_t | getPW3Retries () const |
| bool | isPW3Blocked () const |
| void | resetPW3Retries () |
| Resets PW3 retry counter to maximum. | |
| bool | verifyPW3Raw (const uint8_t *data, size_t len) |
| OpenPGP KDF-DO path: PW3 reference is a host-supplied pre-hash. | |
| bool | setPW3Raw (const uint8_t *data, size_t len) |
| bool | setDuressPin (const char *pin) |
| Sets the duress PIN, arming the self-destruct trigger. | |
| bool | clearDuressPin () |
| Clears the duress PIN, disarming the self-destruct trigger. | |
| bool | hasDuressPin () const |
| Returns whether a duress PIN is currently armed. | |
| bool | isDuressPin (const char *pin) const |
| Constant-time check whether a candidate matches the duress PIN. | |
| uint8_t | getKdfAlgorithm () const |
| uint8_t | getHashAlgorithm () const |
| uint32_t | getIterationCount () const |
| bool | isPinSet () const |
| bool | isStorageAvailable () const |
| Returns whether secure storage access is currently available. | |
Static Public Member Functions | |
| static PinManager & | instance () |
| Returns singleton PIN manager instance. | |
Static Public Attributes | |
| static constexpr uint8_t | BADGE_PIN_MIN = 4 |
| static constexpr uint8_t | BADGE_PIN_MAX = 8 |
| static constexpr uint8_t | PW1_MIN = 6 |
| static constexpr uint8_t | PW3_MIN = 8 |
| static constexpr uint8_t | PIN_MAX = 16 |
| static constexpr uint16_t | RMEM_SLOT_PIN = 0 |
| static constexpr uint8_t | ATTESTATION_ECC_SLOT = 0 |
| static constexpr uint8_t | BADGE_HASH_SIZE = 16 |
| static constexpr uint8_t | KDF_HASH_SIZE = 32 |
| static constexpr uint8_t | SALT_SIZE = 8 |
| static constexpr uint8_t | KDF_ITERSALTED_S2K = 0x03 |
| static constexpr uint8_t | HASH_SHA256 = 0x08 |
| static constexpr uint32_t | DEFAULT_ITERATIONS = 100000 |
| static constexpr const char * | DEFAULT_BADGE_PIN = "123456" |
| static constexpr const char * | DEFAULT_PW1 = "123456" |
| static constexpr const char * | DEFAULT_PW3 = "12345678" |
| static constexpr uint32_t | LOCKOUT_DURATION_MS = 60000 |
PIN Manager - Manages all device PINs in TROPIC01 R-Memory Slot 0
Storage Format (147 bytes): [Magic 0xE0] (1) - Format identifier [Badge/FIDO2 Hash] (16) - LEFT(SHA256(PIN), 16) [Badge Locked] (1) - 0x00 unlocked, 0x01 locked (recovery on next boot) [KDF Algorithm] (1) - 0x03 = KDF_ITERSALTED_S2K [Hash Algorithm] (1) - 0x08 = SHA256 [Iteration Count] (4) - Default 100000 [PW1 Salt] (8) - Random salt for User PIN [PW3 Salt] (8) - Random salt for Admin PIN [PW1 Hash] (32) - KDF hash of User PIN [PW3 Hash] (32) - KDF hash of Admin PIN [PW1 Retries] (1) - Remaining attempts (smartcard-style, no recovery) [PW3 Retries] (1) - Remaining attempts (smartcard-style, no recovery) [Duress Set] (1) - 0x00 not set, 0x01 set (self-destruct armed) [Duress Salt] (8) - Random salt for duress PIN [Duress Hash] (32) - KDF hash of duress PIN
The whole payload, including the duress fields, is covered by the slot-0 attestation signature, so tampering with the duress state invalidates the record and forces a reset to defaults.
Badge PIN: retry counter lives in RAM only. R-Memory persists just a binary "locked" flag. Boot grants one attempt (or zero if locked) and starts the 60-second recovery timer; on expiry the counter is restored to MAX_RETRIES and the locked flag cleared. A crash mid-verify cannot brick the badge PIN.
PW1/PW3: smartcard semantics. Pre-decrement is persisted synchronously before the verify so a power-cycle cannot reset the counter, and reaching zero is terminal until an admin reset.
Defaults:
Definition at line 46 of file PinManager.h.
| bool cdc::core::PinManager::changeBadgePin | ( | const char * | currentPin, |
| const char * | newPin ) |
Changes badge PIN after validating current PIN.
| currentPin | Current PIN. |
| newPin | New PIN. |
Definition at line 562 of file PinManager.cpp.
References setBadgePin(), and verifyBadgePin().
| bool cdc::core::PinManager::changePW1 | ( | const char * | currentPin, |
| const char * | newPin ) |
Changes PW1 after validating the current value.
| currentPin | Current PW1 value. |
| newPin | New PW1 value. |
Definition at line 746 of file PinManager.cpp.
References setPW1(), and verifyPW1().
| bool cdc::core::PinManager::changePW3 | ( | const char * | currentPin, |
| const char * | newPin ) |
Changes PW3 after validating the current value.
| currentPin | Current PW3 value. |
| newPin | New PW3 value. |
Definition at line 839 of file PinManager.cpp.
References setPW3(), and verifyPW3().
| void cdc::core::PinManager::checkAndResetExpiredLockout | ( | ) |
Clears expired lockout state and resets retry counter.
Clears expired lockout state and persists updated retry counter.
Call this from non-const contexts to perform the lazy state update that isLockoutActive() only observes.
This is the non-const counterpart to isLockoutActive(). Callers in non-const contexts use this to perform the lazy state update without needing const_cast.
Definition at line 969 of file PinManager.cpp.
References getLockoutRemainingMs(), LOG_I, and TAG.
Referenced by runMainLoopIteration().
| bool cdc::core::PinManager::clearDuressPin | ( | ) |
Clears the duress PIN, disarming the self-destruct trigger.
Definition at line 697 of file PinManager.cpp.
References init(), LOG_I, and TAG.
Referenced by cdc::serial::cmdPinDuressClear().
| bool cdc::core::PinManager::getBadgePinHash | ( | uint8_t * | hashOut | ) | const |
Copies stored badge PIN hash into caller buffer.
| hashOut | Output hash buffer. |
Definition at line 629 of file PinManager.cpp.
References BADGE_HASH_SIZE.
|
inline |
Definition at line 87 of file PinManager.h.
Referenced by cdc::ui::PinChangeView::getRetriesRemaining().
|
inline |
Definition at line 175 of file PinManager.h.
References HASH_SHA256.
|
inline |
Definition at line 176 of file PinManager.h.
|
inline |
Definition at line 174 of file PinManager.h.
References KDF_ITERSALTED_S2K.
| uint32_t cdc::core::PinManager::getLockoutRemainingMs | ( | ) | const |
Returns remaining badge lockout duration.
Definition at line 937 of file PinManager.cpp.
References LOCKOUT_DURATION_MS.
Referenced by checkAndResetExpiredLockout(), cdc::ui::PinEntryView::getLockoutRemaining(), and isLockoutActive().
| bool cdc::core::PinManager::getPW1Hash | ( | uint8_t * | hashOut | ) | const |
Copies stored PW1 hash into caller buffer.
| hashOut | Output hash buffer. |
Definition at line 793 of file PinManager.cpp.
References KDF_HASH_SIZE.
|
inline |
Definition at line 119 of file PinManager.h.
Referenced by pin_storage_openpgp_pw1_retries().
| bool cdc::core::PinManager::getPW1Salt | ( | uint8_t * | saltOut | ) | const |
Copies stored PW1 salt into caller buffer.
| saltOut | Output salt buffer. |
Definition at line 804 of file PinManager.cpp.
References SALT_SIZE.
| bool cdc::core::PinManager::getPW3Hash | ( | uint8_t * | hashOut | ) | const |
Copies stored PW3 hash into caller buffer.
| hashOut | Output hash buffer. |
Definition at line 885 of file PinManager.cpp.
References KDF_HASH_SIZE.
|
inline |
Definition at line 135 of file PinManager.h.
Referenced by pin_storage_openpgp_pw3_retries().
| bool cdc::core::PinManager::getPW3Salt | ( | uint8_t * | saltOut | ) | const |
Copies stored PW3 salt into caller buffer.
| saltOut | Output salt buffer. |
Definition at line 896 of file PinManager.cpp.
References SALT_SIZE.
|
inline |
Returns whether a duress PIN is currently armed.
Definition at line 164 of file PinManager.h.
| bool cdc::core::PinManager::init | ( | ) |
Initializes PIN state from secure storage or defaults.
Definition at line 41 of file PinManager.cpp.
References LOG_I, startLockout(), and TAG.
Referenced by clearDuressPin(), pin_storage_openpgp_init(), setDuressPin(), and cdc::ui::ui_init().
|
static |
Returns singleton PIN manager instance.
Definition at line 32 of file PinManager.cpp.
References instance().
Referenced by cdc::serial::SerialCmd::authenticate(), cdc::serial::cmdPinChange(), cdc::serial::cmdPinDuress(), cdc::serial::cmdPinDuressClear(), cdc::serial::cmdPinReset(), cdc::serial::cmdPinStatus(), cdc::ui::PinEntryView::getLockoutRemaining(), cdc::ui::PinChangeView::getRetriesRemaining(), instance(), cdc::ui::onDuressPinSet(), cdc::ui::PinChangeView::onKey(), cdc::mod_fido2::onPinVerify(), cdc::ui::onPinVerify(), cdc::mod_fido2::onPromptApprove(), cdc::ui::PinEntryView::onTick(), peek_verify_pin(), pin_storage_fido2_available(), pin_storage_get_fido2_hash(), pin_storage_get_min_pin_floor(), pin_storage_is_set(), pin_storage_openpgp_change_pw1(), pin_storage_openpgp_change_pw3(), pin_storage_openpgp_init(), pin_storage_openpgp_pw1_blocked(), pin_storage_openpgp_pw1_retries(), pin_storage_openpgp_pw3_blocked(), pin_storage_openpgp_pw3_retries(), pin_storage_openpgp_reset(), pin_storage_openpgp_reset_pw1_retries(), pin_storage_openpgp_reset_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(), pin_storage_set_min_pin_floor(), pin_storage_verify_fido2_hash(), cdc::serial::CommandRegistry::processCommand(), cdc::ui::PinEntryView::render(), runMainLoopIteration(), and cdc::ui::ui_init().
| bool cdc::core::PinManager::isBadgeBlocked | ( | ) | const |
Lockout timer handling.
Returns whether badge PIN entry is currently blocked by lockout.
Definition at line 920 of file PinManager.cpp.
Referenced by cdc::ui::PinChangeView::onKey().
| bool cdc::core::PinManager::isDuressPin | ( | const char * | pin | ) | const |
Constant-time check whether a candidate matches the duress PIN.
| pin | Candidate PIN string. |
| pin | Candidate PIN string. |
Definition at line 715 of file PinManager.cpp.
References BADGE_PIN_MAX, and KDF_HASH_SIZE.
Referenced by setBadgePin().
| bool cdc::core::PinManager::isLockoutActive | ( | ) | const |
Returns whether lockout is currently active without mutating state.
Definition at line 955 of file PinManager.cpp.
References getLockoutRemainingMs().
|
inline |
Definition at line 179 of file PinManager.h.
|
inline |
Definition at line 120 of file PinManager.h.
Referenced by pin_storage_openpgp_pw1_blocked().
|
inline |
Definition at line 136 of file PinManager.h.
Referenced by pin_storage_openpgp_pw3_blocked().
| bool cdc::core::PinManager::isStorageAvailable | ( | ) | const |
Returns whether secure storage access is currently available.
Definition at line 106 of file PinManager.cpp.
References cdc::hal::getSecureElementInstance(), and cdc::hal::ISecureElement::isSessionActive().
|
inline |
Definition at line 97 of file PinManager.h.
Referenced by pin_storage_get_min_pin_floor().
| void cdc::core::PinManager::resetBadgeRetries | ( | ) |
Resets badge retry counter to maximum.
Definition at line 615 of file PinManager.cpp.
Referenced by cdc::serial::cmdPinReset().
| void cdc::core::PinManager::resetPW1Retries | ( | ) |
Resets PW1 retry counter to maximum.
Definition at line 813 of file PinManager.cpp.
Referenced by pin_storage_openpgp_reset_pw1_retries().
| void cdc::core::PinManager::resetPW3Retries | ( | ) |
Resets PW3 retry counter to maximum.
Definition at line 905 of file PinManager.cpp.
Referenced by pin_storage_openpgp_reset_pw3_retries().
| bool cdc::core::PinManager::setBadgePin | ( | const char * | newPin | ) |
Definition at line 578 of file PinManager.cpp.
References BADGE_HASH_SIZE, BADGE_PIN_MAX, BADGE_PIN_MIN, DEFAULT_BADGE_PIN, isDuressPin(), LOG_E, LOG_I, and TAG.
Referenced by changeBadgePin().
| bool cdc::core::PinManager::setDuressPin | ( | const char * | pin | ) |
Sets the duress PIN, arming the self-destruct trigger.
Duress / self-destruct PIN workflow.
The duress PIN must be distinct from the current badge PIN so the unlock path can tell them apart unambiguously. Setting it again overwrites the previous duress PIN.
| pin | Candidate duress PIN (4-8 digits). |
Sets the duress PIN, arming the self-destruct trigger.
Reuses the PW1/PW3 KDF/salt machinery. The candidate must satisfy the badge PIN format and must differ from the current badge PIN so the unlock path can distinguish a duress entry from a normal unlock.
| pin | Candidate duress PIN. |
Definition at line 659 of file PinManager.cpp.
References BADGE_HASH_SIZE, BADGE_PIN_MAX, BADGE_PIN_MIN, init(), LOG_E, LOG_I, and TAG.
Referenced by cdc::ui::onDuressPinSet().
| void cdc::core::PinManager::setMinPinLengthFloor | ( | uint8_t | minLen | ) |
Sets the minimum badge-PIN length floor enforced on changes.
Sets badge PIN directly with format validation.
| minLen | Requested floor; clamped into [BADGE_PIN_MIN, BADGE_PIN_MAX]. |
| newPin | New PIN value. |
Definition at line 572 of file PinManager.cpp.
References BADGE_PIN_MAX, and BADGE_PIN_MIN.
Referenced by pin_storage_set_min_pin_floor().
| bool cdc::core::PinManager::setPW1 | ( | const char * | newPin | ) |
Sets PW1 directly and refreshes salt/hash material.
| newPin | New PW1 value. |
Definition at line 756 of file PinManager.cpp.
References LOG_E, LOG_I, PIN_MAX, PW1_MIN, and TAG.
Referenced by changePW1(), and pin_storage_openpgp_change_pw1().
| bool cdc::core::PinManager::setPW1Raw | ( | const uint8_t * | data, |
| size_t | len ) |
Definition at line 778 of file PinManager.cpp.
Referenced by pin_storage_openpgp_set_pw1_raw().
| bool cdc::core::PinManager::setPW3 | ( | const char * | newPin | ) |
Sets PW3 directly and refreshes salt/hash material.
| newPin | New PW3 value. |
Definition at line 849 of file PinManager.cpp.
References LOG_E, LOG_I, PIN_MAX, PW3_MIN, and TAG.
Referenced by changePW3(), and pin_storage_openpgp_change_pw3().
| bool cdc::core::PinManager::setPW3Raw | ( | const uint8_t * | data, |
| size_t | len ) |
Definition at line 870 of file PinManager.cpp.
Referenced by pin_storage_openpgp_set_pw3_raw().
| void cdc::core::PinManager::startLockout | ( | ) |
Starts the badge recovery timer.
Definition at line 927 of file PinManager.cpp.
References LOCKOUT_DURATION_MS, LOG_I, and TAG.
Referenced by init().
| bool cdc::core::PinManager::verifyBadgePin | ( | const char * | pin | ) |
Verifies badge PIN, updates retries, and handles lockout transitions.
| pin | Candidate badge PIN. |
Definition at line 552 of file PinManager.cpp.
Referenced by changeBadgePin(), and cdc::mod_fido2::onPinVerify().
| bool cdc::core::PinManager::verifyBadgePinHash | ( | const uint8_t * | hashIn | ) | const |
Verifies provided hash against stored badge hash.
| hashIn | Candidate hash buffer. |
Definition at line 640 of file PinManager.cpp.
References BADGE_HASH_SIZE.
| bool cdc::core::PinManager::verifyPW1 | ( | const char * | pin | ) |
OpenPGP PW1 (user PIN) workflow.
Verifies OpenPGP PW1 and updates retry counters.
| pin | Candidate PW1 value. |
Definition at line 736 of file PinManager.cpp.
Referenced by changePW1(), and pin_storage_openpgp_verify_pw1().
| bool cdc::core::PinManager::verifyPW1Raw | ( | const uint8_t * | data, |
| size_t | len ) |
Definition at line 774 of file PinManager.cpp.
Referenced by pin_storage_openpgp_verify_pw1_raw().
| bool cdc::core::PinManager::verifyPW3 | ( | const char * | pin | ) |
OpenPGP PW3 (admin PIN) workflow.
Verifies OpenPGP PW3 and updates retry counters.
| pin | Candidate PW3 value. |
Definition at line 829 of file PinManager.cpp.
Referenced by changePW3(), and pin_storage_openpgp_verify_pw3().
| bool cdc::core::PinManager::verifyPW3Raw | ( | const uint8_t * | data, |
| size_t | len ) |
OpenPGP KDF-DO path: PW3 reference is a host-supplied pre-hash.
Definition at line 866 of file PinManager.cpp.
Referenced by pin_storage_openpgp_verify_pw3_raw().
|
staticconstexpr |
Definition at line 61 of file PinManager.h.
Referenced by cdc::core::verify_payload_signature().
|
staticconstexpr |
Definition at line 64 of file PinManager.h.
Referenced by getBadgePinHash(), pin_storage_fido2_available(), setBadgePin(), setDuressPin(), and verifyBadgePinHash().
|
staticconstexpr |
Definition at line 50 of file PinManager.h.
Referenced by cdc::serial::cmdPinChange(), cdc::serial::cmdPinDuress(), ctap2_config(), isDuressPin(), cdc::mod_fido2::onPromptApprove(), cdc::ui::onSettingsSelect(), setBadgePin(), setDuressPin(), setMinPinLengthFloor(), cdc::ui::showDuressPinSetup(), and cdc::ui::ui_init().
|
staticconstexpr |
Definition at line 49 of file PinManager.h.
Referenced by cdc::serial::cmdPinChange(), cdc::serial::cmdPinDuress(), ctap2_config(), encode_info_min_pin_length(), cdc::ui::PinEntryView::init(), cdc::mod_fido2::onPromptApprove(), cdc::ui::onSettingsSelect(), setBadgePin(), setDuressPin(), setMinPinLengthFloor(), cdc::ui::showDuressPinSetup(), and cdc::ui::ui_init().
|
staticconstexpr |
Definition at line 74 of file PinManager.h.
Referenced by setBadgePin().
|
staticconstexpr |
Definition at line 71 of file PinManager.h.
|
staticconstexpr |
Definition at line 75 of file PinManager.h.
Referenced by apply_kdf_do(), and pin_storage_openpgp_reset().
|
staticconstexpr |
Definition at line 76 of file PinManager.h.
Referenced by apply_kdf_do(), and pin_storage_openpgp_reset().
|
staticconstexpr |
Definition at line 70 of file PinManager.h.
Referenced by getHashAlgorithm().
|
staticconstexpr |
Definition at line 65 of file PinManager.h.
Referenced by getPW1Hash(), getPW3Hash(), and isDuressPin().
|
staticconstexpr |
Definition at line 69 of file PinManager.h.
Referenced by getKdfAlgorithm().
|
staticconstexpr |
Definition at line 100 of file PinManager.h.
Referenced by getLockoutRemainingMs(), and startLockout().
|
staticconstexpr |
Definition at line 53 of file PinManager.h.
Referenced by cdc::mod_gpg::onSettingsSelect(), setPW1(), and setPW3().
|
staticconstexpr |
Definition at line 51 of file PinManager.h.
Referenced by cdc::mod_gpg::onSettingsSelect(), and setPW1().
|
staticconstexpr |
Definition at line 52 of file PinManager.h.
Referenced by cdc::mod_gpg::onSettingsSelect(), and setPW3().
|
staticconstexpr |
Definition at line 56 of file PinManager.h.
|
staticconstexpr |
Definition at line 66 of file PinManager.h.
Referenced by getPW1Salt(), and getPW3Salt().