Class PacketKey

java.lang.Object
io.github.mahmoudimus.quic.crypto.PacketKey

public final class PacketKey extends Object
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

    Fields
    Modifier and Type
    Field
    Description
    static final long
    The AES-GCM confidentiality limit: packets sealed under one key (RFC 9001 section 6.6).
    static final long
    The AES-GCM integrity limit: failed openings under one key (RFC 9001 section 6.6).
    static final long
    The ChaCha20-Poly1305 confidentiality limit.
    static final long
    The ChaCha20-Poly1305 integrity limit (RFC 9001 section 6.6).
    static final int
    The nonce (and IV) length of every QUIC AEAD, in bytes.
    static final int
    The authentication tag length of every QUIC AEAD, in bytes.
  • Method Summary

    Modifier and Type
    Method
    Description
    long
    How many packets may be sealed with this key before it must be updated.
    static PacketKey
    fromSecret(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).
    long
    How 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 PacketKey
    of(CipherSuite suite, byte[] key, byte[] iv)
    A key from its raw parts.
    int
    open(long packetNumber, byte[] packet, int headerStart, int payloadStart, int end)
    Opens a payload held in an array; see open(long, ByteBuffer, int, int, int).
    int
    open(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.
    int
    seal(long packetNumber, byte[] packet, int headerStart, int payloadStart, int payloadEnd)
    Seals a payload held in an array; see seal(long, ByteBuffer, int, int, int).
    int
    seal(long packetNumber, ByteBuffer packet, int headerStart, int payloadStart, int payloadEnd)
    Seals a payload in place.
    The cipher suite.
    int
    The authentication tag length.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • TAG_LENGTH

      public static final int TAG_LENGTH
      The authentication tag length of every QUIC AEAD, in bytes.
      See Also:
    • NONCE_LENGTH

      public static final int NONCE_LENGTH
      The nonce (and IV) length of every QUIC AEAD, in bytes.
      See Also:
    • AES_GCM_CONFIDENTIALITY_LIMIT

      public static final long AES_GCM_CONFIDENTIALITY_LIMIT
      The 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_LIMIT
      The 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_LIMIT
      The 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_LIMIT
      The ChaCha20-Poly1305 integrity limit (RFC 9001 section 6.6).
      See Also:
  • Method Details

    • of

      public static PacketKey of(CipherSuite suite, byte[] key, byte[] iv)
      A key from its raw parts.
      Parameters:
      suite - the cipher suite
      key - the AEAD key, CipherSuite.keyLength() bytes
      iv - the 12-byte IV
      Returns:
      the key
      Throws:
      IllegalArgumentException - if a length is wrong
    • fromSecret

      public static PacketKey fromSecret(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).
      Parameters:
      suite - the cipher suite the secret belongs to
      secret - the traffic secret
      version - the QUIC version, which picks the labels
      Returns:
      the key
    • suite

      public CipherSuite 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 after payloadEnd. Indexes are absolute; the buffer's position and limit are not changed.
      Parameters:
      packetNumber - the full packet number
      packet - the packet buffer
      headerStart - the index of the first header byte
      payloadStart - the index of the first payload byte, just past the packet number
      payloadEnd - 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

      public int open(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. Indexes are absolute; the buffer's position and limit are not changed.
      Parameters:
      packetNumber - the full packet number
      packet - the packet buffer
      headerStart - the index of the first header byte
      payloadStart - the index of the first ciphertext byte
      end - 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; see seal(long, ByteBuffer, int, int, int).
      Parameters:
      packetNumber - the full packet number
      packet - the packet bytes
      headerStart - the index of the first header byte
      payloadStart - the index of the first payload byte
      payloadEnd - 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; see open(long, ByteBuffer, int, int, int).
      Parameters:
      packetNumber - the full packet number
      packet - the packet bytes
      headerStart - the index of the first header byte
      payloadStart - the index of the first ciphertext byte
      end - the index just past the tag
      Returns:
      the index just past the plaintext, or -1 if authentication fails