BryanJacobs / FIDO2Applet

FIDO2 Javacard Applet
MIT License
76 stars 15 forks source link

CTAP 2.1 hmac-secret: Semantics with and without UV #1

Closed lxgr closed 1 year ago

lxgr commented 1 year ago

First of all, thank you for this project – this is amazing!

Something I'm having trouble wrapping my head around after reading the documentation (specifically the point on CTAP 2.1 hmac-secret compliance) and peeking at the code:

Does "Implemented with one secret (requiring UV) not two" mean that hmac-secret will only work when a PIN is provided during get() (and will reject either the extension or the entire get() operation otherwise)? Or will it just derive the same secret whether or not a PIN is provided during get()?

BryanJacobs commented 1 year ago

The CTAP 2.1 standard says that authenticators are supposed to use one hmac-secret key if UV is provided, and a different one if UV is not provided.

This authenticator implementation is really geared around always using a PIN (as a UV method). It sends the alwaysUv flag in response to authenticatorGetInfo requests. That flag means that every use of a credential (every authentication) requires UV - the PIN. Note that in practice this means you type your PIN one time per authenticator power-up, not one time per use: the app will store a "pinToken" which is valid until you power-cycle the smartcard.

Since every use of a credential (including for hmac-secret) requires a PIN, there's no need for a second key here, and the hmac-secret implementation is standards-compliant but incomplete if you were to edit the source code and enable non-UV operations.

lxgr commented 1 year ago

Ah, that makes sense!

So in other words, any attempt to use any credential (whether using hmac-secret or not) without a PIN will be outright declined by the authenticator, but compliant clients/browsers should not attempt to send any PIN-less commands in the first place (due to alwaysUV being set)?

BryanJacobs commented 1 year ago

Correct - the authenticator can't even use the credential when a PIN is set but not provided, because the master secret is encrypted using the PIN.

A standards-compliant platform implementation won't even try to use the credential without collecting a PIN.

lxgr commented 1 year ago

Makes sense. Thank you, appreciate the clarification!