Skip to content

PIN_UV Authentication

Rain Zhang edited this page Nov 6, 2025 · 2 revisions

PIN/UV Authentication Extension

Table of Contents

  1. Introduction
  2. Architecture Overview
  3. Core Components
  4. PIN Protocol Implementation
  5. Cryptographic Operations
  6. Authentication Token Derivation
  7. Security Considerations
  8. Error Handling
  9. Integration with Extensions Framework
  10. Test Examples
  11. Troubleshooting Guide

Introduction

The PIN/UV Authentication extension provides secure authentication mechanisms for FIDO2 authenticators through Personal Identification Numbers (PINs) and User Verification (UV) methods. This extension enables clients to establish secure channels with authenticators, authenticate using PINs or biometric verification, and derive authentication tokens with specific permissions for protected operations.

The implementation supports two protocol versions (v1 and v2) with enhanced security features in v2, including HKDF-based key derivation, separate AES and HMAC keys, and improved encryption mechanisms. The extension integrates seamlessly with the broader FIDO2 Extensions framework, allowing for permission-based access control and fine-grained authorization.

Architecture Overview

The PIN/UV Authentication system follows a layered architecture that separates protocol concerns from cryptographic operations and client interactions:

graph TB
subgraph "Client Layer"
Client[Client Application]
Extensions[Extensions Framework]
end
subgraph "PIN/UV Layer"
ClientPin[ClientPin Class]
PinProtocol[PinProtocol Interface]
PinProtocolV1[PinProtocolV1]
PinProtocolV2[PinProtocolV2]
end
subgraph "Cryptographic Layer"
ECDH[ECDH Key Agreement]
AES[AES Encryption]
HMAC[HMAC-SHA256]
HKDF[HKDF Key Derivation]
end
subgraph "Authenticator Layer"
CTAP2[CTAP2 Commands]
Info[Authenticator Info]
end
Client --> Extensions
Extensions --> ClientPin
ClientPin --> PinProtocol
PinProtocol --> PinProtocolV1
PinProtocol --> PinProtocolV2
PinProtocolV1 --> ECDH
PinProtocolV2 --> ECDH
ECDH --> AES
ECDH --> HMAC
ECDH --> HKDF
ClientPin --> CTAP2
CTAP2 --> Info
Loading

Diagram sources

  • fido2/ctap2/pin.py
  • fido2/ctap2/extensions.py

Core Components

ClientPin Class

The ClientPin class serves as the primary interface for PIN/UV authentication operations, providing methods for PIN management, token acquisition, and retry monitoring:

classDiagram
class ClientPin {
+Ctap2 ctap
+PinProtocol protocol
+PROTOCOLS : list
+CMD : IntEnum
+RESULT : IntEnum
+PERMISSION : IntFlag
+is_supported(info) bool
+is_token_supported(info) bool
+get_pin_token(pin, permissions, rpid) bytes
+get_uv_token(permissions, rpid, event, keepalive) bytes
+get_pin_retries() tuple
+get_uv_retries() int
+set_pin(pin) void
+change_pin(old_pin, new_pin) void
-_get_shared_secret() tuple
}
class PinProtocol {
<<abstract>>
+VERSION : ClassVar[int]
+encapsulate(peer_key) tuple
+encrypt(key, plaintext) bytes
+decrypt(key, ciphertext) bytes
+authenticate(key, message) bytes
+validate_token(token) bytes
}
class PinProtocolV1 {
+VERSION : int = 1
+IV : bytes
+kdf(z) bytes
+encapsulate(peer_key) tuple
+encrypt(key, plaintext) bytes
+decrypt(key, ciphertext) bytes
+authenticate(key, message) bytes
+validate_token(token) bytes
}
class PinProtocolV2 {
+VERSION : int = 2
+HKDF_SALT : bytes
+HKDF_INFO_HMAC : bytes
+HKDF_INFO_AES : bytes
+kdf(z) bytes
+encrypt(key, plaintext) bytes
+decrypt(key, ciphertext) bytes
+authenticate(key, message) bytes
+validate_token(token) bytes
}
ClientPin --> PinProtocol
PinProtocol <|-- PinProtocolV1
PinProtocol <|-- PinProtocolV2
Loading

Diagram sources

  • fido2/ctap2/pin.py

Permission System

The permission system allows fine-grained access control for authentication tokens:

Permission Value Description
MAKE_CREDENTIAL 0x01 Allows creation of new credentials
GET_ASSERTION 0x02 Enables authentication assertions
CREDENTIAL_MGMT 0x04 Permits credential management operations
BIO_ENROLL 0x08 Allows biometric enrollment
LARGE_BLOB_WRITE 0x10 Enables large blob storage writes
AUTHENTICATOR_CFG 0x20 Permits authenticator configuration
PERSISTENT_CREDENTIAL_MGMT 0x40 Allows persistent credential management

Section sources

  • fido2/ctap2/pin.py

PIN Protocol Implementation

Key Agreement Generation

The protocol establishes secure channels through Elliptic Curve Diffie-Hellman (ECDH) key exchange:

sequenceDiagram
participant Client as Client
participant Auth as Authenticator
participant ECDH as ECDH Engine
participant Crypto as Cryptographic Backend
Client->>Auth : GET_KEY_AGREEMENT
Auth->>Client : Public Key (COSE format)
Client->>ECDH : Generate private key
ECDH->>Crypto : secp256r1 key pair
Crypto-->>ECDH : Private/public key
ECDH->>ECDH : Exchange ECDH
ECDH->>Crypto : Compute shared secret
Crypto-->>ECDH : x-coordinate (32 bytes)
ECDH->>Client : Key agreement + shared secret
Client->>Client : Apply KDF/HKDF
Loading

Diagram sources

  • fido2/ctap2/pin.py

Protocol Version Differences

Feature PinProtocolV1 PinProtocolV2
Key Derivation SHA256 HKDF with separate keys
Encryption Mode CBC with fixed IV CBC with random IV
MAC Algorithm HMAC-SHA256 (16 bytes) HMAC-SHA256 (full)
Token Size 16 or 32 bytes 32 bytes
Salt None Fixed 32-byte zero salt

Section sources

  • fido2/ctap2/pin.py

Cryptographic Operations

ECDH Key Agreement

The ECDH implementation uses secp256r1 curve with COSE format for public key representation:

flowchart TD
Start([Generate Key Pair]) --> GenPriv["Generate secp256r1 Private Key"]
GenPriv --> GenPub["Derive Public Key"]
GenPub --> SendPub["Send Public Key to Authenticator"]
SendPub --> RecvPub["Receive Authenticator Public Key"]
RecvPub --> Validate["Validate COSE Format"]
Validate --> Exchange["Perform ECDH Exchange"]
Exchange --> Extract["Extract X-coordinate"]
Extract --> KDF["Apply KDF (SHA256 or HKDF)"]
KDF --> SharedSecret["Shared Secret Ready"]
SharedSecret --> End([Ready for Encryption])
Loading

Diagram sources

  • fido2/ctap2/pin.py

PIN Hashing Mechanism

PINs undergo a standardized hashing process before transmission:

flowchart TD
PIN[Input PIN String] --> Validate["Validate PIN Length (≥4 chars)"]
Validate --> Encode["Encode to UTF-8"]
Encode --> Pad["Pad to 64 bytes with zeros"]
Pad --> Align["Align to 16-byte boundary"]
Align --> Truncate["Truncate to 16 bytes SHA256 hash"]
Truncate --> Encrypt["Encrypt with shared secret"]
Encrypt --> Transmit["Transmit to Authenticator"]
Loading

Diagram sources

  • fido2/ctap2/pin.py
  • fido2/ctap2/pin.py

Encryption and Authentication

Both protocol versions implement robust encryption and authentication:

Operation PinProtocolV1 PinProtocolV2
Encryption AES-CBC (fixed IV) AES-CBC (random IV)
Authentication HMAC-SHA256 (16 bytes) HMAC-SHA256 (full)
Key Derivation SHA256 HKDF with separate keys

Section sources

  • fido2/ctap2/pin.py

Authentication Token Derivation

Token Acquisition Process

The token derivation process varies based on protocol version and authenticator capabilities:

sequenceDiagram
participant Client as Client
participant CP as ClientPin
participant Proto as PinProtocol
participant Auth as Authenticator
Client->>CP : get_pin_token(pin, permissions)
CP->>CP : _get_shared_secret()
CP->>Proto : encapsulate(peer_key)
Proto->>Proto : ECDH key exchange
Proto-->>CP : key_agreement + shared_secret
CP->>CP : hash_pin(pin)
CP->>Proto : encrypt(shared_secret, pin_hash)
Proto-->>CP : encrypted_pin_hash
CP->>Auth : client_pin(GET_TOKEN_USING_PIN, ...)
Auth->>Auth : Verify PIN + derive token
Auth-->>CP : encrypted_token
CP->>Proto : decrypt(shared_secret, token_enc)
Proto-->>CP : validated_token
CP-->>Client : authentication token
Loading

Diagram sources

  • fido2/ctap2/pin.py

Token Validation

Each protocol version implements specific token validation rules:

flowchart TD
Receive[Receive Token] --> CheckSize{"Token Size?"}
CheckSize --> |V1| V1Check{"16 or 32 bytes?"}
CheckSize --> |V2| V2Check{"Exactly 32 bytes?"}
V1Check --> |Yes| Valid[Valid Token]
V1Check --> |No| Error[ValueError]
V2Check --> |Yes| Valid
V2Check --> |No| Error
Valid --> Return[Return Token]
Error --> Raise[Raise Exception]
Loading

Diagram sources

  • fido2/ctap2/pin.py
  • fido2/ctap2/pin.py

Security Considerations

Brute Force Protection

The authenticator implements comprehensive brute force protection mechanisms:

Protection Level Behavior Recovery
Normal Attempts Decrease retry count Immediate
Soft Lock Block after 3+ failed attempts Power cycle required
Hard Lock Permanent block Factory reset required

Secure Channel Establishment

The secure channel establishment ensures confidentiality and authenticity:

graph LR
subgraph "Channel Security"
ECDH[ECDH Key Exchange]
AES[AES Encryption]
HMAC[HMAC Authentication]
KDF[Key Derivation]
end
subgraph "Security Guarantees"
Confidentiality[Confidentiality]
Integrity[Integrity]
ReplayAttack[Replay Attack Prevention]
ManInTheMiddle[MITM Protection]
end
ECDH --> KDF
KDF --> AES
KDF --> HMAC
AES --> Confidentiality
HMAC --> Integrity
ReplayAttack --> ReplayAttack
ManInTheMiddle --> ManInTheMiddle
Loading

Cryptographic Binding

The authenticator maintains cryptographic binding between PIN operations and the authenticator identity through:

  • Shared secret derived from ECDH
  • HMAC authentication of all messages
  • PIN hash verification
  • Token validation against authenticator state

Section sources

  • tests/device/test_clientpin.py

Error Handling

PIN Authentication Errors

The system handles various error conditions with specific error codes:

Error Condition Error Code Description
Incorrect PIN PIN_INVALID (0x31) Single incorrect PIN attempt
Auth Blocked PIN_AUTH_BLOCKED (0x34) Authentication temporarily blocked
PIN Blocked PIN_BLOCKED (0x32) PIN permanently blocked
PIN Not Set PIN_NOT_SET (0x35) Attempting PIN operations without PIN
Policy Violation PIN_POLICY_VIOLATION (0x37) PIN length or complexity violation

Retry Management

The authenticator tracks retry attempts and implements progressive locking:

stateDiagram-v2
[*] --> Active : Initial state
Active --> Active : Successful PIN
Active --> Active : Incorrect PIN (decrements counter)
Active --> SoftLocked : 3rd incorrect attempt
SoftLocked --> Active : Power cycle
SoftLocked --> HardLocked : Any PIN attempt
HardLocked --> [*] : Factory reset required
Loading

Diagram sources

  • fido2/ctap.py

Section sources

  • tests/device/test_clientpin.py

Integration with Extensions Framework

Availability Signaling

PIN/UV functionality is signaled through the CTAP2 Info object:

classDiagram
class Info {
+dict options
+list pin_uv_protocols
+bool clientPin
+bool pinUvAuthToken
+int min_pin_length
+get_identifier(pin_token) bytes
}
class ExtensionsFramework {
+list supported_extensions
+dict extension_inputs
+dict extension_outputs
+prepare_inputs() dict
+prepare_outputs() dict
}
Info --> ExtensionsFramework : signals availability
ExtensionsFramework --> ClientPin : enables functionality
Loading

Diagram sources

  • fido2/ctap2/base.py
  • fido2/ctap2/extensions.py

Permission-Based Access

Extensions integrate with PIN/UV permissions for fine-grained access control:

sequenceDiagram
participant Ext as Extension
participant CP as ClientPin
participant Auth as Authenticator
Ext->>CP : Request token with permissions
CP->>CP : Check authenticator support
CP->>Auth : Get token with permissions
Auth->>Auth : Validate permissions
Auth-->>CP : Token with granted permissions
CP-->>Ext : Authentication token
Ext->>Ext : Apply permissions to operations
Loading

Diagram sources

  • fido2/ctap2/extensions.py

Section sources

  • fido2/ctap2/extensions.py

Test Examples

PIN Validation Tests

The test suite demonstrates comprehensive PIN validation scenarios:

flowchart TD
Start[Test PIN Validation] --> CheckSupport["Check ClientPin Support"]
CheckSupport --> GetRetries["Get Initial Retries (8)"]
GetRetries --> WrongPin["Attempt Wrong PIN"]
WrongPin --> DecrementRetry["Retry Count Decrements"]
DecrementRetry --> SoftLock{"3+ Attempts?"}
SoftLock --> |Yes| SoftLocked["Soft Locked State"]
SoftLock --> |No| Continue["Continue Testing"]
SoftLocked --> BlockAttempts["Block All Attempts"]
BlockAttempts --> PowerCycle["Power Cycle Required"]
PowerCycle --> ResetRetries["Retries Reset"]
ResetRetries --> Unlock["Unlock with Correct PIN"]
Unlock --> Success["Validation Complete"]
Loading

Diagram sources

  • tests/device/test_clientpin.py

PIN Change Operations

The PIN change functionality demonstrates atomic operations:

sequenceDiagram
participant Test as Test Suite
participant CP as ClientPin
participant Auth as Authenticator
Test->>CP : get_pin_token(current_pin)
CP->>Auth : Authenticate with current PIN
Auth-->>CP : PIN token
Test->>CP : change_pin(old_pin, new_pin)
CP->>Auth : Verify old PIN + set new PIN
Auth->>Auth : Atomic PIN update
Auth-->>CP : Success
Test->>CP : get_pin_token(new_pin)
CP->>Auth : Authenticate with new PIN
Auth-->>CP : New PIN token
Test->>CP : get_pin_token(old_pin)
CP->>Auth : Attempt with old PIN
Auth-->>CP : PIN_INVALID error
Loading

Diagram sources

  • tests/device/test_clientpin.py

Section sources

  • tests/device/test_clientpin.py

Troubleshooting Guide

Common Issues and Solutions

Issue Symptoms Solution
PIN_AUTH_BLOCKED All PIN attempts fail immediately Power cycle authenticator
PIN_NOT_SET PIN operations unavailable Set PIN first
Protocol Mismatch Unsupported protocol version Check authenticator capabilities
Token Validation Failure Invalid token size Verify authenticator version

Debugging PIN Operations

Enable debug logging to trace PIN operations:

import logging
logging.getLogger('fido2.ctap2.pin').setLevel(logging.DEBUG)

Recovery Procedures

For locked authenticators:

  1. Soft Lock Recovery: Power cycle the authenticator
  2. Hard Lock Recovery: Perform factory reset
  3. PIN Reset: Use authenticator-specific reset procedures

Performance Considerations

  • Key agreement operations are computationally intensive
  • Network latency affects retry timing
  • Token caching improves performance for repeated operations

Section sources

  • fido2/ctap2/pin.py

Post-Quantum WebAuthn Platform

Getting Started

Architectural Foundations

Cryptography & Security

Authentication Platform

Core Protocol

Flows & Interfaces

Authenticator Capabilities

Server Platform

Frontend Platform

Architecture

Interaction & Utilities

Metadata Service (MDS)

Storage & Data Management

Data Models & Encoding

API Reference

Cross-Platform & HID

Operations & Troubleshooting

Glossary & References

Clone this wiki locally