Skip to content

feat(webauthn): support hmac-secret-mc CTAP 2.2 extension (fix #147)#212

Merged
AlfioEmanueleFresta merged 1 commit into
masterfrom
pr-147
May 14, 2026
Merged

feat(webauthn): support hmac-secret-mc CTAP 2.2 extension (fix #147)#212
AlfioEmanueleFresta merged 1 commit into
masterfrom
pr-147

Conversation

@AlfioEmanueleFresta
Copy link
Copy Markdown
Member

@AlfioEmanueleFresta AlfioEmanueleFresta commented May 12, 2026

Adds CTAP 2.2 hmac-secret-mc so prf.eval at create() time skips the GA round-trip on authenticators that advertise it. Falls back to hmac-secret: true (PRF via GA) when unsupported.

Wire format and decryption reuse the GA hmac-secret helpers (CalculatedHMACGetSecretInput / Ctap2HMACGetSecretOutput). Ctap2MakeCredentialRequest::needs_shared_secret gates ECDH on advertised support + buffered input; hmac-secret-mc is never sent without hmac-secret: true (§ 12.8). The PRF→HMAC salt mapping is extracted to PRFValue::to_hmac_secret_input and shared with the GA path.

Test plan

  • cargo test --workspace --all-features — 182 unit + 5 integration
  • cargo clippy --workspace --all-features --tests --examples -- -D warnings, cargo fmt --check --all
  • Virtual HID integration test for graceful degradation (test_webauthn_prf_eval_at_create_degrades_when_unsupported)
  • Smoke test on a CTAP 2.1 YubiKey: graceful degradation works, GA replay unaffected (see comment below)
  • Success path on a CTAP 2.2 authenticator advertising hmac-secret-mc — not available to me; reviewers welcome to validate

@AlfioEmanueleFresta
Copy link
Copy Markdown
Member Author

AlfioEmanueleFresta commented May 12, 2026

Smoke-tested against a YubiKey reporting CTAP 2.1 (hmac-secret yes, hmac-secret-mc no). Exercises the graceful-degradation path only.

extensions  = ["credProtect", "hmac-secret", "largeBlobKey", "credBlob", "minPinLength"]
MC response  = hmac_secret: Some(true), hmac_secret_mc: None
prf output   = enabled: Some(true), results: None
GA replay    = first=fee01481…, second=ac3a6831…

Credential created with hmac-secret: true only, no hmac-secret-mc on the wire, GA replay returns expected PRF outputs. The success path still needs validation on a CTAP 2.2 authenticator.

Copy link
Copy Markdown
Member

@iinuwa iinuwa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested this branch with a CTAP 2.3 key; hmac-secret-mc is returned correctly

@AlfioEmanueleFresta AlfioEmanueleFresta marked this pull request as ready for review May 14, 2026 17:37
Enables PRF evaluation at MakeCredential time on authenticators that
advertise hmac-secret-mc. Falls back gracefully to hmac-secret: true
(PRF via GetAssertion) when the extension is unsupported.

Wire format and processing reuse the existing GA hmac-secret path.
@AlfioEmanueleFresta AlfioEmanueleFresta merged commit 95db65c into master May 14, 2026
4 checks passed
@AlfioEmanueleFresta AlfioEmanueleFresta deleted the pr-147 branch May 14, 2026 19:21
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.

2 participants