CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
cdc::core::PinManager Class Reference

#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

Detailed Description

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:

  • Badge/FIDO2: "123456"
  • OpenPGP PW1 (User): "123456" (min 6 digits)
  • OpenPGP PW3 (Admin): "12345678" (min 8 digits)

Definition at line 46 of file PinManager.h.

Member Function Documentation

◆ changeBadgePin()

bool cdc::core::PinManager::changeBadgePin ( const char * currentPin,
const char * newPin )

Changes badge PIN after validating current PIN.

Parameters
currentPinCurrent PIN.
newPinNew PIN.
Returns
true if change succeeded.

Definition at line 547 of file PinManager.cpp.

References setBadgePin(), and verifyBadgePin().

◆ changePW1()

bool cdc::core::PinManager::changePW1 ( const char * currentPin,
const char * newPin )

Changes PW1 after validating the current value.

Parameters
currentPinCurrent PW1 value.
newPinNew PW1 value.
Returns
true if change succeeded.

Definition at line 724 of file PinManager.cpp.

References setPW1(), and verifyPW1().

◆ changePW3()

bool cdc::core::PinManager::changePW3 ( const char * currentPin,
const char * newPin )

Changes PW3 after validating the current value.

Parameters
currentPinCurrent PW3 value.
newPinNew PW3 value.
Returns
true if change succeeded.

Definition at line 803 of file PinManager.cpp.

References setPW3(), and verifyPW3().

◆ checkAndResetExpiredLockout()

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().

◆ clearDuressPin()

bool cdc::core::PinManager::clearDuressPin ( )

Clears the duress PIN, disarming the self-destruct trigger.

Returns
true if the record was updated.

Definition at line 675 of file PinManager.cpp.

References init(), LOG_I, and TAG.

Referenced by cdc::serial::cmdPinDuressClear().

◆ getBadgePinHash()

bool cdc::core::PinManager::getBadgePinHash ( uint8_t * hashOut) const

Copies stored badge PIN hash into caller buffer.

Parameters
hashOutOutput hash buffer.
Returns
true if hash was copied.

Definition at line 607 of file PinManager.cpp.

References BADGE_HASH_SIZE.

◆ getBadgeRetries()

uint8_t cdc::core::PinManager::getBadgeRetries ( ) const
inline

Definition at line 87 of file PinManager.h.

Referenced by cdc::ui::PinChangeView::getRetriesRemaining().

◆ getHashAlgorithm()

uint8_t cdc::core::PinManager::getHashAlgorithm ( ) const
inline

Definition at line 157 of file PinManager.h.

References HASH_SHA256.

◆ getIterationCount()

uint32_t cdc::core::PinManager::getIterationCount ( ) const
inline

Definition at line 158 of file PinManager.h.

◆ getKdfAlgorithm()

uint8_t cdc::core::PinManager::getKdfAlgorithm ( ) const
inline

Definition at line 156 of file PinManager.h.

References KDF_ITERSALTED_S2K.

◆ getLockoutRemainingMs()

uint32_t cdc::core::PinManager::getLockoutRemainingMs ( ) const

Returns remaining badge lockout duration.

Returns
Remaining lockout time in milliseconds.

Definition at line 887 of file PinManager.cpp.

References LOCKOUT_DURATION_MS.

Referenced by checkAndResetExpiredLockout(), cdc::ui::PinEntryView::getLockoutRemaining(), and isLockoutActive().

◆ getPW1Hash()

bool cdc::core::PinManager::getPW1Hash ( uint8_t * hashOut) const

Copies stored PW1 hash into caller buffer.

Parameters
hashOutOutput hash buffer.
Returns
true if copied.

Definition at line 757 of file PinManager.cpp.

References KDF_HASH_SIZE.

◆ getPW1Retries()

uint8_t cdc::core::PinManager::getPW1Retries ( ) const
inline

Definition at line 111 of file PinManager.h.

Referenced by pin_storage_openpgp_pw1_retries().

◆ getPW1Salt()

bool cdc::core::PinManager::getPW1Salt ( uint8_t * saltOut) const

Copies stored PW1 salt into caller buffer.

Parameters
saltOutOutput salt buffer.
Returns
true if copied.

Definition at line 768 of file PinManager.cpp.

References SALT_SIZE.

◆ getPW3Hash()

bool cdc::core::PinManager::getPW3Hash ( uint8_t * hashOut) const

Copies stored PW3 hash into caller buffer.

Parameters
hashOutOutput hash buffer.
Returns
true if copied.

Definition at line 835 of file PinManager.cpp.

References KDF_HASH_SIZE.

◆ getPW3Retries()

uint8_t cdc::core::PinManager::getPW3Retries ( ) const
inline

Definition at line 121 of file PinManager.h.

Referenced by pin_storage_openpgp_pw3_retries().

◆ getPW3Salt()

bool cdc::core::PinManager::getPW3Salt ( uint8_t * saltOut) const

Copies stored PW3 salt into caller buffer.

Parameters
saltOutOutput salt buffer.
Returns
true if copied.

Definition at line 846 of file PinManager.cpp.

References SALT_SIZE.

◆ hasDuressPin()

bool cdc::core::PinManager::hasDuressPin ( ) const
inline

Returns whether a duress PIN is currently armed.

Definition at line 146 of file PinManager.h.

◆ init()

bool cdc::core::PinManager::init ( )

Initializes PIN state from secure storage or defaults.

Returns
true if state is ready for use.

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().

◆ instance()

◆ isBadgeBlocked()

bool cdc::core::PinManager::isBadgeBlocked ( ) const

Lockout timer handling.

Returns whether badge PIN entry is currently blocked by lockout.

Returns
true if blocked.

Definition at line 870 of file PinManager.cpp.

Referenced by cdc::ui::PinChangeView::onKey().

◆ isDuressPin()

bool cdc::core::PinManager::isDuressPin ( const char * pin) const

Constant-time check whether a candidate matches the duress PIN.

Parameters
pinCandidate PIN string.
Returns
true if a duress PIN is set and the candidate matches it.
Parameters
pinCandidate PIN string.
Returns
true if a duress PIN is armed and the candidate matches it.

Definition at line 693 of file PinManager.cpp.

References BADGE_PIN_MAX, and KDF_HASH_SIZE.

Referenced by setBadgePin().

◆ isLockoutActive()

bool cdc::core::PinManager::isLockoutActive ( ) const

Returns whether lockout is currently active without mutating state.

Returns
true if lockout is still active.

Definition at line 905 of file PinManager.cpp.

References getLockoutRemainingMs().

◆ isPinSet()

bool cdc::core::PinManager::isPinSet ( ) const
inline

Definition at line 161 of file PinManager.h.

◆ isPW1Blocked()

bool cdc::core::PinManager::isPW1Blocked ( ) const
inline

Definition at line 112 of file PinManager.h.

Referenced by pin_storage_openpgp_pw1_blocked().

◆ isPW3Blocked()

bool cdc::core::PinManager::isPW3Blocked ( ) const
inline

Definition at line 122 of file PinManager.h.

Referenced by pin_storage_openpgp_pw3_blocked().

◆ isStorageAvailable()

bool cdc::core::PinManager::isStorageAvailable ( ) const

Returns whether secure storage access is currently available.

Returns
true when secure-element session is active.

Definition at line 105 of file PinManager.cpp.

References cdc::hal::getSecureElementInstance(), and cdc::hal::ISecureElement::isSessionActive().

◆ resetBadgeRetries()

void cdc::core::PinManager::resetBadgeRetries ( )

Resets badge retry counter to maximum.

Definition at line 593 of file PinManager.cpp.

Referenced by cdc::serial::cmdPinReset().

◆ resetPW1Retries()

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().

◆ resetPW3Retries()

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().

◆ setBadgePin()

bool cdc::core::PinManager::setBadgePin ( const char * newPin)

Sets badge PIN directly with format validation.

Parameters
newPinNew PIN value.
Returns
true if update succeeded.

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().

◆ setDuressPin()

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.

Parameters
pinCandidate duress PIN (4-8 digits).
Returns
true if set; false on invalid format or if equal to the current badge PIN.

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.

Parameters
pinCandidate duress PIN.
Returns
true if set; false on invalid format or equality with the badge 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().

◆ setPW1()

bool cdc::core::PinManager::setPW1 ( const char * newPin)

Sets PW1 directly and refreshes salt/hash material.

Parameters
newPinNew PW1 value.
Returns
true if update succeeded.

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().

◆ setPW3()

bool cdc::core::PinManager::setPW3 ( const char * newPin)

Sets PW3 directly and refreshes salt/hash material.

Parameters
newPinNew PW3 value.
Returns
true if update succeeded.

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().

◆ startLockout()

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().

◆ verifyBadgePin()

bool cdc::core::PinManager::verifyBadgePin ( const char * pin)

Verifies badge PIN, updates retries, and handles lockout transitions.

Parameters
pinCandidate badge PIN.
Returns
true if PIN is valid.

Definition at line 537 of file PinManager.cpp.

Referenced by changeBadgePin(), and cdc::mod_fido2::onPinVerify().

◆ verifyBadgePinHash()

bool cdc::core::PinManager::verifyBadgePinHash ( const uint8_t * hashIn) const

Verifies provided hash against stored badge hash.

Parameters
hashInCandidate hash buffer.
Returns
true if hashes match.

Definition at line 618 of file PinManager.cpp.

References BADGE_HASH_SIZE.

◆ verifyPW1()

bool cdc::core::PinManager::verifyPW1 ( const char * pin)

OpenPGP PW1 (user PIN) workflow.

Verifies OpenPGP PW1 and updates retry counters.

Parameters
pinCandidate PW1 value.
Returns
true if PW1 is valid.

Definition at line 714 of file PinManager.cpp.

Referenced by changePW1(), and pin_storage_openpgp_verify_pw1().

◆ verifyPW3()

bool cdc::core::PinManager::verifyPW3 ( const char * pin)

OpenPGP PW3 (admin PIN) workflow.

Verifies OpenPGP PW3 and updates retry counters.

Parameters
pinCandidate PW3 value.
Returns
true if PW3 is valid.

Definition at line 793 of file PinManager.cpp.

Referenced by changePW3(), and pin_storage_openpgp_verify_pw3().

Member Data Documentation

◆ ATTESTATION_ECC_SLOT

uint8_t cdc::core::PinManager::ATTESTATION_ECC_SLOT = 0
staticconstexpr

Definition at line 61 of file PinManager.h.

Referenced by cdc::core::verify_payload_signature().

◆ BADGE_HASH_SIZE

uint8_t cdc::core::PinManager::BADGE_HASH_SIZE = 16
staticconstexpr

◆ BADGE_PIN_MAX

◆ BADGE_PIN_MIN

◆ DEFAULT_BADGE_PIN

const char* cdc::core::PinManager::DEFAULT_BADGE_PIN = "123456"
staticconstexpr

Definition at line 74 of file PinManager.h.

Referenced by setBadgePin().

◆ DEFAULT_ITERATIONS

uint32_t cdc::core::PinManager::DEFAULT_ITERATIONS = 100000
staticconstexpr

Definition at line 71 of file PinManager.h.

◆ DEFAULT_PW1

const char* cdc::core::PinManager::DEFAULT_PW1 = "123456"
staticconstexpr

Definition at line 75 of file PinManager.h.

Referenced by pin_storage_openpgp_reset().

◆ DEFAULT_PW3

const char* cdc::core::PinManager::DEFAULT_PW3 = "12345678"
staticconstexpr

Definition at line 76 of file PinManager.h.

Referenced by pin_storage_openpgp_reset().

◆ HASH_SHA256

uint8_t cdc::core::PinManager::HASH_SHA256 = 0x08
staticconstexpr

Definition at line 70 of file PinManager.h.

Referenced by getHashAlgorithm().

◆ KDF_HASH_SIZE

uint8_t cdc::core::PinManager::KDF_HASH_SIZE = 32
staticconstexpr

Definition at line 65 of file PinManager.h.

Referenced by getPW1Hash(), getPW3Hash(), and isDuressPin().

◆ KDF_ITERSALTED_S2K

uint8_t cdc::core::PinManager::KDF_ITERSALTED_S2K = 0x03
staticconstexpr

Definition at line 69 of file PinManager.h.

Referenced by getKdfAlgorithm().

◆ LOCKOUT_DURATION_MS

uint32_t cdc::core::PinManager::LOCKOUT_DURATION_MS = 60000
staticconstexpr

Definition at line 92 of file PinManager.h.

Referenced by getLockoutRemainingMs(), and startLockout().

◆ PIN_MAX

uint8_t cdc::core::PinManager::PIN_MAX = 16
staticconstexpr

Definition at line 53 of file PinManager.h.

Referenced by cdc::mod_gpg::onSettingsSelect(), setPW1(), and setPW3().

◆ PW1_MIN

uint8_t cdc::core::PinManager::PW1_MIN = 6
staticconstexpr

Definition at line 51 of file PinManager.h.

Referenced by cdc::mod_gpg::onSettingsSelect(), and setPW1().

◆ PW3_MIN

uint8_t cdc::core::PinManager::PW3_MIN = 8
staticconstexpr

Definition at line 52 of file PinManager.h.

Referenced by cdc::mod_gpg::onSettingsSelect(), and setPW3().

◆ RMEM_SLOT_PIN

uint16_t cdc::core::PinManager::RMEM_SLOT_PIN = 0
staticconstexpr

Definition at line 56 of file PinManager.h.

◆ SALT_SIZE

uint8_t cdc::core::PinManager::SALT_SIZE = 8
staticconstexpr

Definition at line 66 of file PinManager.h.

Referenced by getPW1Salt(), and getPW3Salt().


The documentation for this class was generated from the following files: