Class PacketKey
java.lang.Object
io.github.mahmoudimus.quic.crypto.PacketKey
The AEAD key and IV that protect packet payloads in one direction (RFC 9001 section 5.3). The
nonce of each packet is the IV XORed with its packet number; the associated data is the packet
header up to and including the packet number.
Payloads are sealed and opened in place inside the packet buffer, so no payload bytes are copied.
Thread confinement. A key holds one reusable Cipher, which is not
thread-safe: use a key from one thread at a time (a connection's keys belong to that
connection). The JDK also refuses to seal twice with the same packet number in a row, which
QUIC never does.
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final longThe AES-GCM confidentiality limit: packets sealed under one key (RFC 9001 section 6.6).static final longThe AES-GCM integrity limit: failed openings under one key (RFC 9001 section 6.6).static final longThe ChaCha20-Poly1305 confidentiality limit.static final longThe ChaCha20-Poly1305 integrity limit (RFC 9001 section 6.6).static final intThe nonce (and IV) length of every QUIC AEAD, in bytes.static final intThe authentication tag length of every QUIC AEAD, in bytes. -
Method Summary
Modifier and TypeMethodDescriptionlongHow many packets may be sealed with this key before it must be updated.static PacketKeyfromSecret(CipherSuite suite, byte[] secret, QuicVersion version) Derives a key from a traffic secret with the version's"quic key"and"quic iv"labels (RFC 9001 section 5.1).longHow many packets may fail authentication under this key before the connection must close.byte[]nonce(long packetNumber) The nonce for a packet number: the IV XORed with the 62-bit packet number, left-padded.static PacketKeyof(CipherSuite suite, byte[] key, byte[] iv) A key from its raw parts.intopen(long packetNumber, byte[] packet, int headerStart, int payloadStart, int end) Opens a payload held in an array; seeopen(long, ByteBuffer, int, int, int).intopen(long packetNumber, ByteBuffer packet, int headerStart, int payloadStart, int end) Opens a payload in place: authenticates[headerStart, payloadStart)and the ciphertext with its tag[payloadStart, end), and writes the plaintext over the ciphertext.intseal(long packetNumber, byte[] packet, int headerStart, int payloadStart, int payloadEnd) Seals a payload held in an array; seeseal(long, ByteBuffer, int, int, int).intseal(long packetNumber, ByteBuffer packet, int headerStart, int payloadStart, int payloadEnd) Seals a payload in place.suite()The cipher suite.intThe authentication tag length.
-
Field Details
-
TAG_LENGTH
public static final int TAG_LENGTHThe authentication tag length of every QUIC AEAD, in bytes.- See Also:
-
NONCE_LENGTH
public static final int NONCE_LENGTHThe nonce (and IV) length of every QUIC AEAD, in bytes.- See Also:
-
AES_GCM_CONFIDENTIALITY_LIMIT
public static final long AES_GCM_CONFIDENTIALITY_LIMITThe AES-GCM confidentiality limit: packets sealed under one key (RFC 9001 section 6.6).- See Also:
-
AES_GCM_INTEGRITY_LIMIT
public static final long AES_GCM_INTEGRITY_LIMITThe AES-GCM integrity limit: failed openings under one key (RFC 9001 section 6.6).- See Also:
-
CHACHA20_POLY1305_CONFIDENTIALITY_LIMIT
public static final long CHACHA20_POLY1305_CONFIDENTIALITY_LIMITThe ChaCha20-Poly1305 confidentiality limit. RFC 9001 section 6.6 sets it above the number of possible packets (262), so it is effectively unlimited.- See Also:
-
CHACHA20_POLY1305_INTEGRITY_LIMIT
public static final long CHACHA20_POLY1305_INTEGRITY_LIMITThe ChaCha20-Poly1305 integrity limit (RFC 9001 section 6.6).- See Also:
-
-
Method Details
-
of
A key from its raw parts.- Parameters:
suite- the cipher suitekey- the AEAD key,CipherSuite.keyLength()bytesiv- the 12-byte IV- Returns:
- the key
- Throws:
IllegalArgumentException- if a length is wrong
-
fromSecret
Derives a key from a traffic secret with the version's"quic key"and"quic iv"labels (RFC 9001 section 5.1).- Parameters:
suite- the cipher suite the secret belongs tosecret- the traffic secretversion- the QUIC version, which picks the labels- Returns:
- the key
-
suite
The cipher suite.- Returns:
- the suite
-
tagLength
public int tagLength()The authentication tag length.- Returns:
- 16
-
confidentialityLimit
public long confidentialityLimit()How many packets may be sealed with this key before it must be updated.- Returns:
- the confidentiality limit of the suite's AEAD
-
integrityLimit
public long integrityLimit()How many packets may fail authentication under this key before the connection must close.- Returns:
- the integrity limit of the suite's AEAD
-
nonce
public byte[] nonce(long packetNumber) The nonce for a packet number: the IV XORed with the 62-bit packet number, left-padded.- Parameters:
packetNumber- the full packet number- Returns:
- a new 12-byte nonce
-
seal
public int seal(long packetNumber, ByteBuffer packet, int headerStart, int payloadStart, int payloadEnd) Seals a payload in place. The header bytes[headerStart, payloadStart)are the associated data; the plaintext[payloadStart, payloadEnd)is replaced by the ciphertext and followed by the tag, so the buffer needs 16 more bytes of capacity afterpayloadEnd. Indexes are absolute; the buffer's position and limit are not changed.- Parameters:
packetNumber- the full packet numberpacket- the packet bufferheaderStart- the index of the first header bytepayloadStart- the index of the first payload byte, just past the packet numberpayloadEnd- the index just past the plaintext- Returns:
- the index just past the tag,
payloadEnd + 16 - Throws:
IllegalStateException- if the AEAD fails, as when a packet number is reused
-
open
Opens a payload in place: authenticates[headerStart, payloadStart)and the ciphertext with its tag[payloadStart, end), and writes the plaintext over the ciphertext. Indexes are absolute; the buffer's position and limit are not changed.- Parameters:
packetNumber- the full packet numberpacket- the packet bufferheaderStart- the index of the first header bytepayloadStart- the index of the first ciphertext byteend- the index just past the tag- Returns:
- the index just past the plaintext (
end - 16), or -1 if the packet fails authentication, in which case the payload bytes are unspecified
-
seal
public int seal(long packetNumber, byte[] packet, int headerStart, int payloadStart, int payloadEnd) Seals a payload held in an array; seeseal(long, ByteBuffer, int, int, int).- Parameters:
packetNumber- the full packet numberpacket- the packet bytesheaderStart- the index of the first header bytepayloadStart- the index of the first payload bytepayloadEnd- the index just past the plaintext- Returns:
- the index just past the tag
-
open
public int open(long packetNumber, byte[] packet, int headerStart, int payloadStart, int end) Opens a payload held in an array; seeopen(long, ByteBuffer, int, int, int).- Parameters:
packetNumber- the full packet numberpacket- the packet bytesheaderStart- the index of the first header bytepayloadStart- the index of the first ciphertext byteend- the index just past the tag- Returns:
- the index just past the plaintext, or -1 if authentication fails
-