nquic_keys (nquic v1.0.0)
View SourceQUIC key derivation per RFC 9001 Section 5.
Derives initial, handshake, and application traffic secrets using HKDF. Supports key update (RFC 9001 Section 6), 0-RTT early secrets, and connection ID generation.
Summary
Functions
Map a TLS cipher suite to its HKDF hash algorithm.
Derive key, IV, and header protection key from a traffic secret for a
QUIC version. RFC 9001 uses the "quic key/iv/hp" HKDF labels; RFC 9369
substitutes "quicv2 key/iv/hp" for QUIC v2 (0x6b3343cf).
Derive 0-RTT client secret without PSK.
Derive 0-RTT client secret with optional PSK for session resumption.
Generate a random 8-byte connection ID.
Generate a random connection ID of the given length (1-20 bytes).
Derive handshake traffic secrets from shared secret and transcript hash.
Derive handshake traffic secrets with explicit hash algorithm.
Derive handshake traffic secrets with optional PSK (RFC 8446 Section 7.1). When PSK is provided (session resumption), it is used as the IKM for EarlySecret. Without PSK, zeros are used (standard non-resumption path).
Return the initial salt for the given QUIC version.
Derive client and server initial secrets from the destination connection ID.
Derive initial secrets for the given QUIC version.
Return the local role's packet protection keys from a #{client => _, server => _}
map. The local side uses these to encrypt outbound packets.
Build a role key map from derive_packet_protection output.
For AES ciphers, includes a cached HP cipher context (hp_ctx) that
avoids per-packet EVP_CIPHER_CTX creation in the mask/unmask hot path.
ChaCha20 omits hp_ctx since its IV changes per packet.
Derive application traffic secrets from handshake secret and transcript hash.
Derive application traffic secrets with explicit hash algorithm.
Return the peer role's packet protection keys from a #{client => _, server => _}
map. The local side uses these to decrypt inbound packets.
QUIC HKDF-Expand-Label with sha256 default.
QUIC HKDF-Expand-Label with explicit hash algorithm.
Resolve a role_keys() map into {LocalKeys, PeerKeys} for the given
role. Convenience used at app-keys install time to populate the
per-role caches on #conn_crypto{} (app_send_keys / app_recv_keys)
in one map walk instead of separate local_keys/2 + peer_keys/2
calls.
Derive next traffic secret, key, and IV for key update.
RFC 9001 uses the "quic ku" label; RFC 9369 substitutes "quicv2 ku"
for QUIC v2.
Types
Functions
-spec cipher_to_hash(aes_128_gcm | aes_256_gcm | chacha20_poly1305) -> sha256 | sha384.
Map a TLS cipher suite to its HKDF hash algorithm.
-spec derive_packet_protection(binary(), aes_128_gcm | aes_256_gcm | chacha20_poly1305, non_neg_integer()) -> {Key :: binary(), IV :: binary(), HP :: binary()}.
Derive key, IV, and header protection key from a traffic secret for a
QUIC version. RFC 9001 uses the "quic key/iv/hp" HKDF labels; RFC 9369
substitutes "quicv2 key/iv/hp" for QUIC v2 (0x6b3343cf).
Derive 0-RTT client secret without PSK.
Derive 0-RTT client secret with optional PSK for session resumption.
-spec generate_connection_id() -> nquic:connection_id().
Generate a random 8-byte connection ID.
-spec generate_connection_id(pos_integer()) -> nquic:connection_id().
Generate a random connection ID of the given length (1-20 bytes).
-spec handshake_secrets(binary(), binary()) -> {ClientSecret :: binary(), ServerSecret :: binary(), HandshakeSecret :: binary()}.
Derive handshake traffic secrets from shared secret and transcript hash.
-spec handshake_secrets(binary(), binary(), sha256 | sha384) -> {ClientSecret :: binary(), ServerSecret :: binary(), HandshakeSecret :: binary()}.
Derive handshake traffic secrets with explicit hash algorithm.
-spec handshake_secrets(binary(), binary(), sha256 | sha384, binary() | undefined) -> {ClientSecret :: binary(), ServerSecret :: binary(), HandshakeSecret :: binary()}.
Derive handshake traffic secrets with optional PSK (RFC 8446 Section 7.1). When PSK is provided (session resumption), it is used as the IKM for EarlySecret. Without PSK, zeros are used (standard non-resumption path).
-spec initial_salt(non_neg_integer()) -> binary().
Return the initial salt for the given QUIC version.
-spec initial_secrets(nquic:connection_id()) -> {ClientSecret :: binary(), ServerSecret :: binary()}.
Derive client and server initial secrets from the destination connection ID.
-spec initial_secrets(nquic:connection_id(), non_neg_integer()) -> {ClientSecret :: binary(), ServerSecret :: binary()}.
Derive initial secrets for the given QUIC version.
Return the local role's packet protection keys from a #{client => _, server => _}
map. The local side uses these to encrypt outbound packets.
-spec make_role_keys(aes_128_gcm | aes_256_gcm | chacha20_poly1305, binary(), binary(), binary()) -> #{key := binary(), iv := binary(), hp := binary()}.
Build a role key map from derive_packet_protection output.
For AES ciphers, includes a cached HP cipher context (hp_ctx) that
avoids per-packet EVP_CIPHER_CTX creation in the mask/unmask hot path.
ChaCha20 omits hp_ctx since its IV changes per packet.
Derive application traffic secrets from handshake secret and transcript hash.
-spec master_secrets(binary(), binary(), sha256 | sha384) -> {ClientSecret :: binary(), ServerSecret :: binary()}.
Derive application traffic secrets with explicit hash algorithm.
Return the peer role's packet protection keys from a #{client => _, server => _}
map. The local side uses these to decrypt inbound packets.
-spec qhkdf_expand(binary(), binary(), binary(), pos_integer()) -> binary().
QUIC HKDF-Expand-Label with sha256 default.
-spec qhkdf_expand(binary(), binary(), binary(), pos_integer(), sha256 | sha384) -> binary().
QUIC HKDF-Expand-Label with explicit hash algorithm.
Resolve a role_keys() map into {LocalKeys, PeerKeys} for the given
role. Convenience used at app-keys install time to populate the
per-role caches on #conn_crypto{} (app_send_keys / app_recv_keys)
in one map walk instead of separate local_keys/2 + peer_keys/2
calls.
-spec update_traffic_secret(binary(), aes_128_gcm | aes_256_gcm | chacha20_poly1305, non_neg_integer()) -> {NewSecret :: binary(), Key :: binary(), IV :: binary()}.
Derive next traffic secret, key, and IV for key update.
RFC 9001 uses the "quic ku" label; RFC 9369 substitutes "quicv2 ku"
for QUIC v2.