quic_crypto (quic v1.3.1)
View SourceTLS 1.3 key schedule and cryptographic operations for QUIC.
This module implements the TLS 1.3 key schedule used by QUIC for deriving encryption keys at each handshake stage.
Key Schedule
TLS 1.3 uses a three-stage key schedule: 1. Early Secret (from PSK, or zeros for non-PSK) 2. Handshake Secret (from ECDHE shared secret) 3. Master Secret (for application data)
Traffic Secrets
From each secret, traffic secrets are derived for both client and server directions.
Summary
Functions
Map cipher suite to corresponding hash algorithm.
Compute the Finished verify_data. verify_data = HMAC(finished_key, Transcript-Hash(Handshake Context))
Compute the Finished verify_data with cipher-specific hash.
Compute PSK binder value for a pre_shared_key extension. RFC 8446 Section 4.2.11.2: binder_key = Derive-Secret(early_secret, "res binder" | "ext binder", "") binder = HMAC(binder_key, Transcript-Hash(Truncated ClientHello)) For resumption PSK, use "res binder". For external PSK, use "ext binder".
Compute PSK binder with cipher-specific hash.
Compute the integrity tag for a Retry packet. Used by servers to generate tags and by clients to verify.
Compute ECDHE shared secret. shared_secret = ECDH(our_private, their_public)
Derive client application traffic secret. client_application_traffic_secret_0 = Derive-Secret( master_secret, "c ap traffic", ClientHello...server Finished)
Derive client application traffic secret with cipher-specific hash.
Derive client early traffic secret. client_early_traffic_secret = Derive-Secret(early_secret, "c e traffic", ClientHello) This is used to encrypt 0-RTT data before the handshake completes.
Derive client early traffic secret with cipher-specific hash.
Derive client handshake traffic secret. client_handshake_traffic_secret = Derive-Secret( handshake_secret, "c hs traffic", ClientHello...ServerHello)
Derive client handshake traffic secret with cipher-specific hash.
Derive early exporter master secret. early_exporter_master_secret = Derive-Secret(early_secret, "e exp master", ClientHello)
Derive early secret without PSK (zeros). early_secret = HKDF-Extract(0, 0)
Derive early secret with PSK. early_secret = HKDF-Extract(0, PSK)
Derive early secret with cipher-specific hash.
Derive the finished key from a traffic secret. finished_key = HKDF-Expand-Label(BaseKey, "finished", "", Hash.length)
Derive the finished key with cipher-specific hash.
Derive handshake secret from early secret and ECDHE shared secret. handshake_secret = HKDF-Extract( Derive-Secret(early_secret, "derived", ""), shared_secret)
Derive handshake secret with cipher-specific hash.
Derive master secret from handshake secret. master_secret = HKDF-Extract( Derive-Secret(handshake_secret, "derived", ""), 0)
Derive master secret with cipher-specific hash.
Derive-Secret with raw messages (will be hashed). Derive-Secret(Secret, Label, Messages) = HKDF-Expand-Label(Secret, Label, Transcript-Hash(Messages), Hash.length)
Derive-Secret with specified hash algorithm.
Derive server application traffic secret. server_application_traffic_secret_0 = Derive-Secret( master_secret, "s ap traffic", ClientHello...server Finished)
Derive server application traffic secret with cipher-specific hash.
Derive server handshake traffic secret. server_handshake_traffic_secret = Derive-Secret( handshake_secret, "s hs traffic", ClientHello...ServerHello)
Derive server handshake traffic secret with cipher-specific hash.
Generate an ECDHE key pair for the specified curve. Returns {PublicKey, PrivateKey}
Compute transcript hash of handshake messages (default SHA-256).
Compute transcript hash with specified hash algorithm or cipher. Accepts both hash atoms (sha256, sha384) and cipher atoms (aes_128_gcm, aes_256_gcm).
Verify the integrity tag of a Retry packet. RFC 9001 Section 5.8: - Retry Pseudo-Packet = <ODCID length> <ODCID> <Retry packet without tag> - Tag = AES-128-GCM(Key, Nonce, AAD=Pseudo-Packet, "") Returns true if the tag is valid, false otherwise.
Functions
Map cipher suite to corresponding hash algorithm.
Compute the Finished verify_data. verify_data = HMAC(finished_key, Transcript-Hash(Handshake Context))
Compute the Finished verify_data with cipher-specific hash.
Compute PSK binder value for a pre_shared_key extension. RFC 8446 Section 4.2.11.2: binder_key = Derive-Secret(early_secret, "res binder" | "ext binder", "") binder = HMAC(binder_key, Transcript-Hash(Truncated ClientHello)) For resumption PSK, use "res binder". For external PSK, use "ext binder".
Compute PSK binder with cipher-specific hash.
-spec compute_retry_integrity_tag(binary(), binary(), non_neg_integer()) -> binary().
Compute the integrity tag for a Retry packet. Used by servers to generate tags and by clients to verify.
Derive client application traffic secret. client_application_traffic_secret_0 = Derive-Secret( master_secret, "c ap traffic", ClientHello...server Finished)
Derive client application traffic secret with cipher-specific hash.
Derive client early traffic secret. client_early_traffic_secret = Derive-Secret(early_secret, "c e traffic", ClientHello) This is used to encrypt 0-RTT data before the handshake completes.
Derive client early traffic secret with cipher-specific hash.
Derive client handshake traffic secret. client_handshake_traffic_secret = Derive-Secret( handshake_secret, "c hs traffic", ClientHello...ServerHello)
Derive client handshake traffic secret with cipher-specific hash.
Derive early exporter master secret. early_exporter_master_secret = Derive-Secret(early_secret, "e exp master", ClientHello)
-spec derive_early_secret() -> binary().
Derive early secret without PSK (zeros). early_secret = HKDF-Extract(0, 0)
Derive early secret with PSK. early_secret = HKDF-Extract(0, PSK)
Derive early secret with cipher-specific hash.
Derive the finished key from a traffic secret. finished_key = HKDF-Expand-Label(BaseKey, "finished", "", Hash.length)
Derive the finished key with cipher-specific hash.
Derive handshake secret from early secret and ECDHE shared secret. handshake_secret = HKDF-Extract( Derive-Secret(early_secret, "derived", ""), shared_secret)
Derive handshake secret with cipher-specific hash.
Derive master secret from handshake secret. master_secret = HKDF-Extract( Derive-Secret(handshake_secret, "derived", ""), 0)
Derive master secret with cipher-specific hash.
Derive-Secret with raw messages (will be hashed). Derive-Secret(Secret, Label, Messages) = HKDF-Expand-Label(Secret, Label, Transcript-Hash(Messages), Hash.length)
Derive-Secret with specified hash algorithm.
Derive server application traffic secret. server_application_traffic_secret_0 = Derive-Secret( master_secret, "s ap traffic", ClientHello...server Finished)
Derive server application traffic secret with cipher-specific hash.
Derive server handshake traffic secret. server_handshake_traffic_secret = Derive-Secret( handshake_secret, "s hs traffic", ClientHello...ServerHello)
Derive server handshake traffic secret with cipher-specific hash.
Generate an ECDHE key pair for the specified curve. Returns {PublicKey, PrivateKey}
Compute transcript hash of handshake messages (default SHA-256).
Compute transcript hash with specified hash algorithm or cipher. Accepts both hash atoms (sha256, sha384) and cipher atoms (aes_128_gcm, aes_256_gcm).
-spec verify_retry_integrity_tag(binary(), binary(), non_neg_integer()) -> boolean().
Verify the integrity tag of a Retry packet. RFC 9001 Section 5.8: - Retry Pseudo-Packet = <ODCID length> <ODCID> <Retry packet without tag> - Tag = AES-128-GCM(Key, Nonce, AAD=Pseudo-Packet, "") Returns true if the tag is valid, false otherwise.