Skip to content

fix(hsm): enforce HSM_OPT_COMBINED_AUTH instead of ignoring it - #143

Open
lrascao wants to merge 1 commit into
polhenarejos:masterfrom
lrascao:fix/combined-auth-enforcement
Open

lrascao wants to merge 1 commit into
polhenarejos:masterfrom
lrascao:fix/combined-auth-enforcement

Conversation

@lrascao

@lrascao lrascao commented Sep 17, 2026

Copy link
Copy Markdown

Summary

Bug fix, security-relevant.

HSM_OPT_COMBINED_AUTH (bit 0x10) is defined in sc_hsm.h and referenced
nowhere in the firmware. cmd_initialize stores device options wholesale, so
the bit is accepted and persisted, and OpenSC reads it back and prints
Public Key Authentication and PIN verification enforced.

Nothing enforces it. A device initialised with sc-hsm-tool --require-pka-and-pin reports that PIN verification is required and then
grants full private-key access to the quorum alone, with no PIN presented at
any point.

Details / Impact

  • Hardware / board(s) tested: Pico 2 / RP2350; a second device as custodian.
  • Firmware / commit/base version: fa3fd433.
  • Security impact: the card currently advertises a control it does not
    apply. This makes bit 0x10 mean what the card already claims it means. It
    cannot loosen anything -- when the bit is clear, behaviour is unchanged.
  • Behavior changes: with the bit set, isUserAuthenticated is granted only
    once the quorum is met and a user PIN has been verified in the same
    session. Because either can complete last, EXTERNAL AUTHENTICATE and
    check_pin both re-evaluate through one helper rather than setting the flag
    directly.

Testing

Same device, same EF_DEVOPS, same registered key; only the firmware differs.
Probe is GENERATE KEY PAIR with an empty body, which tests the flag before
parsing anything and cannot create a key:

firmware user PIN verified probe access
fa3fd433 no 6700 granted
+ this patch no 6982 withheld
+ this patch yes 6700 granted

The card reported Public Key Authentication and PIN verification enforced in
all three runs.

Reproducing requires the PKA exchange, which OpenSC cannot perform
(OpenSC/OpenSC#594); I drove it directly over PC/SC. It also requires the curve
fix in my other PR, without which EXTERNAL AUTHENTICATE fails at 6985
before this code is reached. The two changes are independent in code -- only
the reproduction needs both.

Anything else?

If enforcing dual control is unwelcome for the AGPLv3 tree, the minimum
acceptable alternative is to reject the option at INITIALIZE rather than
accept, store and report a control that is not applied.

Bit 0x10 is what OpenSC sets for sc-hsm-tool --require-pka-and-pin, and
cmd_initialize stores the options wholesale in EF_DEVOPS. HSM_OPT_COMBINED_AUTH
was defined in sc_hsm.h and referenced nowhere else, so the bit was accepted,
persisted, and reported back -- sc-hsm-tool prints "Public Key Authentication
and PIN verification enforced" from it -- while key access was granted on the
quorum alone.

Either half of the pair can complete last: the quorum may be reached before the
user PIN is verified, or after it. Neither EXTERNAL AUTHENTICATE nor check_pin
can decide alone, so both now call hsm_update_user_auth(), which grants access
only when the quorum is met and, when the bit is set, a user PIN has been
verified in the same session.

Measured on Pico 2 / RP2350. Same device, same EF_DEVOPS, same registered key
across all three runs; the card reported "PIN verification enforced" throughout.
The probe is GENERATE KEY PAIR with an empty body, which checks the flag before
parsing, so 6700 (wrong length) means access was granted and 6982 means it was
withheld:

  before, no PIN     -> 6700   access granted
  after,  no PIN     -> 6982   access withheld
  after,  with PIN   -> 6700   access granted
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant