|
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) |
| Sets badge PIN directly with format validation. | |
| 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 | 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 | 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 | 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 547 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 724 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 803 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 919 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 675 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 607 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 157 of file PinManager.h.
References HASH_SHA256.
|
inline |
Definition at line 158 of file PinManager.h.
|
inline |
Definition at line 156 of file PinManager.h.
References KDF_ITERSALTED_S2K.
| uint32_t cdc::core::PinManager::getLockoutRemainingMs | ( | ) | const |
Returns remaining badge lockout duration.
Definition at line 887 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 757 of file PinManager.cpp.
References KDF_HASH_SIZE.
|
inline |
Definition at line 111 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 768 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 835 of file PinManager.cpp.
References KDF_HASH_SIZE.
|
inline |
Definition at line 121 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 846 of file PinManager.cpp.
References SALT_SIZE.
|
inline |
Returns whether a duress PIN is currently armed.
Definition at line 146 of file PinManager.h.
| bool cdc::core::PinManager::init | ( | ) |
Initializes PIN state from secure storage or defaults.
Definition at line 40 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 31 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_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_verify_pw1(), pin_storage_openpgp_verify_pw3(), 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 870 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 693 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 905 of file PinManager.cpp.
References getLockoutRemainingMs().
|
inline |
Definition at line 161 of file PinManager.h.
|
inline |
Definition at line 112 of file PinManager.h.
Referenced by pin_storage_openpgp_pw1_blocked().
|
inline |
Definition at line 122 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 105 of file PinManager.cpp.
References cdc::hal::getSecureElementInstance(), and cdc::hal::ISecureElement::isSessionActive().
| void cdc::core::PinManager::resetBadgeRetries | ( | ) |
Resets badge retry counter to maximum.
Definition at line 593 of file PinManager.cpp.
Referenced by cdc::serial::cmdPinReset().
| void cdc::core::PinManager::resetPW1Retries | ( | ) |
Resets PW1 retry counter to maximum.
Definition at line 777 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 855 of file PinManager.cpp.
Referenced by pin_storage_openpgp_reset_pw3_retries().
| bool cdc::core::PinManager::setBadgePin | ( | const char * | newPin | ) |
Sets badge PIN directly with format validation.
| newPin | New PIN value. |
Definition at line 557 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 637 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().
| bool cdc::core::PinManager::setPW1 | ( | const char * | newPin | ) |
Sets PW1 directly and refreshes salt/hash material.
| newPin | New PW1 value. |
Definition at line 734 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::setPW3 | ( | const char * | newPin | ) |
Sets PW3 directly and refreshes salt/hash material.
| newPin | New PW3 value. |
Definition at line 813 of file PinManager.cpp.
References LOG_E, LOG_I, PIN_MAX, PW3_MIN, and TAG.
Referenced by changePW3(), and pin_storage_openpgp_change_pw3().
| void cdc::core::PinManager::startLockout | ( | ) |
Starts the badge recovery timer.
Definition at line 877 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 537 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 618 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 714 of file PinManager.cpp.
Referenced by changePW1(), and pin_storage_openpgp_verify_pw1().
| 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 793 of file PinManager.cpp.
Referenced by changePW3(), and pin_storage_openpgp_verify_pw3().
|
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(), isDuressPin(), cdc::mod_fido2::onPromptApprove(), cdc::ui::onSettingsSelect(), setBadgePin(), setDuressPin(), 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(), cdc::ui::PinEntryView::init(), cdc::mod_fido2::onPromptApprove(), cdc::ui::onSettingsSelect(), setBadgePin(), setDuressPin(), 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 pin_storage_openpgp_reset().
|
staticconstexpr |
Definition at line 76 of file PinManager.h.
Referenced by 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 92 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().