Internet-Draft | The AEGIS Family of Authenticated Encryp | October 2023 |
Denis & Lucas | Expires 10 April 2024 | [Page] |
This document describes AEGIS-128L and AEGIS-256, two AES-based authenticated encryption algorithms designed for high-performance applications. This document is a product of the Crypto Forum Research Group (CFRG). It is not an IETF product and is not a standard.¶
This note is to be removed before publishing as an RFC.¶
Source for this draft and an issue tracker can be found at https://github.com/jedisct1/draft-aegis-aead.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 10 April 2024.¶
Copyright (c) 2023 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document.¶
This document describes the AEGIS-128L and AEGIS-256 authenticated encryption with associated data (AEAD) algorithms [AEGIS], which were chosen as additional finalists for high-performance applications in the Competition for Authenticated Encryption: Security, Applicability, and Robustness (CAESAR). Whilst AEGIS-128 was selected as a winner for this use case, AEGIS-128L has a better security margin alongside improved performance and AEGIS-256 uses a 256-bit key [LIMS21]. All variants of AEGIS are constructed from the AES encryption round function [FIPS-AES]. This document specifies:¶
AEGIS-128L, which has a 128-bit key, a 128-bit nonce, a 1024-bit state, a 128- or 256-bit authentication tag, and processes 256-bit input blocks.¶
AEGIS-256, which has a 256-bit key, a 256-bit nonce, a 768-bit state, a 128- or 256-bit authentication tag, and processes 128-bit input blocks.¶
The AEGIS cipher family offers performance that significantly exceeds that of AES-GCM with hardware support for parallelizable AES block encryption [AEGIS]. Similarly, software implementations can also be faster, although to a lesser extent.¶
Unlike with AES-GCM, nonces can be safely chosen at random with no practical limit when using AEGIS-256. AEGIS-128L also allows for more messages to be safely encrypted when using random nonces.¶
With some existing AEAD schemes, such as AES-GCM, an attacker can generate a ciphertext that successfully decrypts under multiple different keys (a partitioning oracle attack) [LGR21]. This ability to craft a (ciphertext, authentication tag) pair that verifies under multiple keys significantly reduces the number of required interactions with the oracle in order to perform an exhaustive search, making it practical if the key space is small. For example, with password-based encryption, an attacker can guess a large number of passwords at a time by recursively submitting such a ciphertext to an oracle, which speeds up a password search by reducing it to a binary search.¶
In AEGIS, finding distinct (key, nonce) pairs that successfully decrypt a given (associated data, ciphertext, authentication tag) tuple is believed to have a complexity that depends on the tag size. A 128-bit tag provides 64-bit committing security, which is generally acceptable for interactive protocols. With a 256-bit tag, finding a collision becomes impractical.¶
Unlike most other AES-based AEAD constructions, leaking a state does not leak the key nor previous states.¶
Finally, an AEGIS key is not required after the setup phase, and there is no key schedule. Thus, ephemeral keys can be erased from memory before any data has been encrypted or decrypted, mitigating cold boot attacks.¶
Note that an earlier version of Hongjun Wu and Bart Preneel’s paper introducing AEGIS specified AEGIS-128L and AEGIS-256 sporting differences with regards to the computation of the authentication tag and the number of rounds in Finalize()
respectively. We follow the specification of [AEGIS] that is current at the time of writing, which can be found in the References section of this document.¶
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
Primitives:¶
{}
: an empty bit array.¶
|x|
: the length of x
in bits.¶
a ^ b
: the bitwise exclusive OR operation between a
and b
.¶
a & b
: the bitwise AND operation between a
and b
.¶
a || b
: the concatenation of a
and b
.¶
a mod b
: the remainder of the Euclidean division between a
as the dividend and b
as the divisor.¶
LE64(x)
: the little-endian encoding of unsigned 64-bit integer x
.¶
ZeroPad(x, n)
: padding operation. Trailing zeros are concatenated to x
until the total length is a multiple of n
bits.¶
Truncate(x, n)
: truncation operation. The first n
bits of x
are kept.¶
Split(x, n)
: splitting operation. x
is split into n
-bit blocks, ignoring partial blocks.¶
Tail(x, n)
: returns the last n
bits of x
.¶
AESRound(in, rk)
: a single round of the AES encryption round function, which is the composition of the SubBytes
, ShiftRows
, MixColums
and AddRoundKey
transformations, as defined in section 5 of [FIPS-AES]. Here, in
is the 128-bit AES input state, and rk
is the 128-bit round key.¶
Repeat(n, F)
: n
sequential evaluations of the function F
.¶
CtEq(a, b)
: compares a
and b
in constant-time, returning True
for an exact match, False
otherwise.¶
AEGIS internal functions:¶
Update(M0, M1)
: the state update function.¶
Init(key, nonce)
: the initialization function.¶
Absorb(ai)
: the input block absorption function.¶
Enc(xi)
: the input block encryption function.¶
Dec(ci)
: the input block decryption function.¶
DecPartial(cn)
: the input block decryption function for the last ciphertext bits when they do not fill an entire block.¶
Finalize(ad_len_bits, msg_len_bits)
: the authentication tag generation function.¶
Input blocks are 256 bits for AEGIS-128L and 128 bits for AEGIS-256.¶
AES blocks:¶
Si
: the i
-th AES block of the current state.¶
S'i
: the i
-th AES block of the next state.¶
{Si, ...Sj}
: the vector of the i
-th AES block of the current state to the j
-th block of the current state.¶
C0
: an AES block built from the following bytes in hexadecimal format: { 0x00, 0x01, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62 }
.¶
C1
: an AES block built from the following bytes in hexadecimal format: { 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd }
.¶
AES blocks are always 128 bits in length.¶
Input and output values:¶
AEGIS-128L has a 1024-bit state, made of eight 128-bit blocks {S0, ...S7}
.¶
The parameters for this algorithm, whose meaning is defined in [RFC5116], Section 4 are:¶
K_LEN
(key length) is 16 octets (128 bits).¶
P_MAX
(maximum length of the plaintext) is 261 octets (264 bits).¶
A_MAX
(maximum length of the associated data) is 261 octets (264 bits).¶
N_MIN
(minimum nonce length) = N_MAX
(maximum nonce length) = 16 octets (128 bits).¶
C_MAX
(maximum ciphertext length) = P_MAX
+ tag length = 261 + 16 or 32 octets (264 + 128 or 256 bits).¶
Distinct associated data inputs, as described in [RFC5116], Section 3 shall be unambiguously encoded as a single input. It is up to the application to create a structure in the associated data input if needed.¶
Encrypt(msg, ad, key, nonce)¶
The Encrypt
function encrypts a message and returns the ciphertext along with an authentication tag that verifies the authenticity of the message and associated data, if provided.¶
Security:¶
For a given key, the nonce MUST NOT be reused under any circumstances; doing so allows an attacker to recover the internal state.¶
The key MUST be randomly chosen from a uniform distribution.¶
Inputs:¶
msg
: the message to be encrypted (length MUST be less than P_MAX
).¶
ad
: the associated data to authenticate (length MUST be less than A_MAX
).¶
key
: the encryption key.¶
nonce
: the public nonce.¶
Outputs:¶
Steps:¶
Init(key, nonce) ct = {} ad_blocks = Split(ZeroPad(ad, 256), 256) for ai in ad_blocks: Absorb(ai) msg_blocks = Split(ZeroPad(msg, 256), 256) for xi in msg_blocks: ct = ct || Enc(xi) tag = Finalize(|ad|, |msg|) ct = Truncate(ct, |msg|) return ct and tag¶
Decrypt(ct, tag, ad, key, nonce)¶
The Decrypt
function decrypts a ciphertext, verifies that the authentication tag is correct, and returns the message on success or an error if tag verification failed.¶
Security:¶
If tag verification fails, the decrypted message and wrong message authentication tag MUST NOT be given as output. The decrypted message MUST be overwritten with zeros.¶
The comparison of the input tag
with the expected_tag
MUST be done in constant time.¶
Inputs:¶
ct
: the ciphertext to be decrypted (length MUST be less than C_MAX
).¶
tag
: the authentication tag.¶
ad
: the associated data to authenticate (length MUST be less than A_MAX
).¶
key
: the encryption key.¶
nonce
: the public nonce.¶
Outputs:¶
Either the decrypted message msg
or an error indicating that the authentication tag is invalid for the given inputs.¶
Steps:¶
Init(key, nonce) msg = {} ad_blocks = Split(ZeroPad(ad, 256), 256) for ai in ad_blocks: Absorb(ai) ct_blocks = Split(ct, 256) cn = Tail(ct, |ct| mod 256) for ci in ct_blocks: msg = msg || Dec(ci) if cn is not empty: msg = msg || DecPartial(cn) expected_tag = Finalize(|ad|, |msg|) if CtEq(tag, expected_tag) is False: erase msg return "verification failed" error else: return msg¶
Init(key, nonce)¶
The Init
function constructs the initial state {S0, ...S7}
using the given key
and nonce
.¶
Inputs:¶
Defines:¶
{S0, ...S7}
: the initial state.¶
Steps:¶
S0 = key ^ nonce S1 = C1 S2 = C0 S3 = C1 S4 = key ^ nonce S5 = key ^ C0 S6 = key ^ C1 S7 = key ^ C0 Repeat(10, Update(nonce, key))¶
Update(M0, M1)¶
The Update
function is the core of the AEGIS-128L algorithm.
It updates the state {S0, ...S7}
using two 128-bit values.¶
Inputs:¶
Modifies:¶
{S0, ...S7}
: the state.¶
Steps:¶
S'0 = AESRound(S7, S0 ^ M0) S'1 = AESRound(S0, S1) S'2 = AESRound(S1, S2) S'3 = AESRound(S2, S3) S'4 = AESRound(S3, S4 ^ M1) S'5 = AESRound(S4, S5) S'6 = AESRound(S5, S6) S'7 = AESRound(S6, S7) S0 = S'0 S1 = S'1 S2 = S'2 S3 = S'3 S4 = S'4 S5 = S'5 S6 = S'6 S7 = S'7¶
Absorb(ai)¶
The Absorb
function absorbs a 256-bit input block ai
into the state {S0, ...S7}
.¶
Inputs:¶
ai
: the 256-bit input block.¶
Steps:¶
t0, t1 = Split(ai, 128) Update(t0, t1)¶
Enc(xi)¶
The Enc
function encrypts a 256-bit input block xi
using the state {S0, ...S7}
.¶
Inputs:¶
xi
: the 256-bit input block.¶
Outputs:¶
ci
: the 256-bit encrypted block.¶
Steps:¶
z0 = S6 ^ S1 ^ (S2 & S3) z1 = S2 ^ S5 ^ (S6 & S7) t0, t1 = Split(xi, 128) out0 = t0 ^ z0 out1 = t1 ^ z1 Update(t0, t1) ci = out0 || out1 return ci¶
Dec(ci)¶
The Dec
function decrypts a 256-bit input block ci
using the state {S0, ...S7}
.¶
Inputs:¶
ci
: the 256-bit encrypted block.¶
Outputs:¶
xi
: the 256-bit decrypted block.¶
Steps:¶
z0 = S6 ^ S1 ^ (S2 & S3) z1 = S2 ^ S5 ^ (S6 & S7) t0, t1 = Split(ci, 128) out0 = t0 ^ z0 out1 = t1 ^ z1 Update(out0, out1) xi = out0 || out1 return xi¶
DecPartial(cn)¶
The DecPartial
function decrypts the last ciphertext bits cn
using the state {S0, ...S7}
when they do not fill an entire block.¶
Inputs:¶
cn
: the encrypted input.¶
Outputs:¶
xn
: the decryption of cn
.¶
Steps:¶
z0 = S6 ^ S1 ^ (S2 & S3) z1 = S2 ^ S5 ^ (S6 & S7) t0, t1 = Split(ZeroPad(cn, 256), 128) out0 = t0 ^ z0 out1 = t1 ^ z1 xn = Truncate(out0 || out1, |cn|) v0, v1 = Split(ZeroPad(xn, 256), 128) Update(v0, v1) return xn¶
Finalize(ad_len_bits, msg_len_bits)¶
The Finalize
function computes a 128- or 256-bit tag that authenticates the message and associated data.¶
Inputs:¶
ad_len_bits
: the length of the associated data in bits.¶
msg_len_bits
: the length of the message in bits.¶
Outputs:¶
tag
: the authentication tag.¶
Steps:¶
t = S2 ^ (LE64(ad_len_bits) || LE64(msg_len_bits)) Repeat(7, Update(t, t)) if tag_length == 16: # 128 bits tag = S0 ^ S1 ^ S2 ^ S3 ^ S4 ^ S5 ^ S6 else: # 256 bits tag = (S0 ^ S1 ^ S2 ^ S3) || (S4 ^ S5 ^ S6 ^ S7) return tag¶
AEGIS-256 has a 768-bit state, made of six 128-bit blocks {S0, ...S5}
.¶
The parameters for this algorithm, whose meaning is defined in [RFC5116], Section 4 are:¶
K_LEN
(key length) is 32 octets (256 bits).¶
P_MAX
(maximum length of the plaintext) is 261 octets (264 bits).¶
A_MAX
(maximum length of the associated data) is 261 octets (264 bits).¶
N_MIN
(minimum nonce length) = N_MAX
(maximum nonce length) = 32 octets (256 bits).¶
C_MAX
(maximum ciphertext length) = P_MAX
+ tag length = 261 + 16 or 32 octets (264 + 128 or 256 bits).¶
Distinct associated data inputs, as described in [RFC5116], Section 3 shall be unambiguously encoded as a single input. It is up to the application to create a structure in the associated data input if needed.¶
Encrypt(msg, ad, key, nonce)¶
The Encrypt
function encrypts a message and returns the ciphertext along with an authentication tag that verifies the authenticity of the message and associated data, if provided.¶
Security:¶
For a given key, the nonce MUST NOT be reused under any circumstances; doing so allows an attacker to recover the internal state.¶
The key MUST be randomly chosen from a uniform distribution.¶
Inputs:¶
msg
: the message to be encrypted (length MUST be less than P_MAX
).¶
ad
: the associated data to authenticate (length MUST be less than A_MAX
).¶
key
: the encryption key.¶
nonce
: the public nonce.¶
Outputs:¶
Steps:¶
Init(key, nonce) ct = {} ad_blocks = Split(ZeroPad(ad, 128), 128) for ai in ad_blocks: Absorb(ai) msg_blocks = Split(ZeroPad(msg, 128), 128) for xi in msg_blocks: ct = ct || Enc(xi) tag = Finalize(|ad|, |msg|) ct = Truncate(ct, |msg|) return ct and tag¶
Decrypt(ct, tag, ad, key, nonce)¶
The Decrypt
function decrypts a ciphertext, verifies that the authentication tag is correct, and returns the message on success or an error if tag verification failed.¶
Security:¶
If tag verification fails, the decrypted message and wrong message authentication tag MUST NOT be given as output. The decrypted message MUST be overwritten with zeros.¶
The comparison of the input tag
with the expected_tag
MUST be done in constant time.¶
Inputs:¶
ct
: the ciphertext to be decrypted (length MUST be less than C_MAX
).¶
tag
: the authentication tag.¶
ad
: the associated data to authenticate (length MUST be less than A_MAX
).¶
key
: the encryption key.¶
nonce
: the public nonce.¶
Outputs:¶
Either the decrypted message msg
or an error indicating that the authentication tag is invalid for the given inputs.¶
Steps:¶
Init(key, nonce) msg = {} ad_blocks = Split(ZeroPad(ad, 128), 128) for ai in ad_blocks: Absorb(ai) ct_blocks = Split(ZeroPad(ct, 128), 128) cn = Tail(ct, |ct| mod 128) for ci in ct_blocks: msg = msg || Dec(ci) if cn is not empty: msg = msg || DecPartial(cn) expected_tag = Finalize(|ad|, |msg|) if CtEq(tag, expected_tag) is False: erase msg return "verification failed" error else: return msg¶
Init(key, nonce)¶
The Init
function constructs the initial state {S0, ...S5}
using the given key
and nonce
.¶
Inputs:¶
Defines:¶
{S0, ...S5}
: the initial state.¶
Steps:¶
k0, k1 = Split(key, 128) n0, n1 = Split(nonce, 128) S0 = k0 ^ n0 S1 = k1 ^ n1 S2 = C1 S3 = C0 S4 = k0 ^ C0 S5 = k1 ^ C1 Repeat(4, Update(k0) Update(k1) Update(k0 ^ n0) Update(k1 ^ n1) )¶
Update(M)¶
The Update
function is the core of the AEGIS-256 algorithm.
It updates the state {S0, ...S5}
using a 128-bit value.¶
Inputs:¶
msg
: the block to be absorbed.¶
Modifies:¶
{S0, ...S5}
: the state.¶
Steps:¶
S'0 = AESRound(S5, S0 ^ M) S'1 = AESRound(S0, S1) S'2 = AESRound(S1, S2) S'3 = AESRound(S2, S3) S'4 = AESRound(S3, S4) S'5 = AESRound(S4, S5) S0 = S'0 S1 = S'1 S2 = S'2 S3 = S'3 S4 = S'4 S5 = S'5¶
Absorb(ai)¶
The Absorb
function absorbs a 128-bit input block ai
into the state {S0, ...S5}
.¶
Inputs:¶
ai
: the input block.¶
Steps:¶
Update(ai)¶
Enc(xi)¶
The Enc
function encrypts a 128-bit input block xi
using the state {S0, ...S5}
.¶
Inputs:¶
xi
: the input block.¶
Outputs:¶
ci
: the encrypted input block.¶
Steps:¶
z = S1 ^ S4 ^ S5 ^ (S2 & S3) Update(xi) ci = xi ^ z return ci¶
Dec(ci)¶
The Dec
function decrypts a 128-bit input block ci
using the state {S0, ...S5}
.¶
Inputs:¶
ci
: the encrypted input block.¶
Outputs:¶
xi
: the decrypted block.¶
Steps:¶
z = S1 ^ S4 ^ S5 ^ (S2 & S3) xi = ci ^ z Update(xi) return xi¶
DecPartial(cn)¶
The DecPartial
function decrypts the last ciphertext bits cn
using the state {S0, ...S5}
when they do not fill an entire block.¶
Inputs:¶
cn
: the encrypted input.¶
Outputs:¶
xn
: the decryption of cn
.¶
Steps:¶
z = S1 ^ S4 ^ S5 ^ (S2 & S3) t = ZeroPad(cn, 128) out = t ^ z xn = Truncate(out, |cn|) v = ZeroPad(xn, 128) Update(v) return xn¶
Finalize(ad_len_bits, msg_len_bits)¶
The Finalize
function computes a 128- or 256-bit tag that authenticates the message and associated data.¶
Inputs:¶
ad_len_bits
: the length of the associated data in bits.¶
msg_len_bits
: the length of the message in bits.¶
Outputs:¶
tag
: the authentication tag.¶
Steps:¶
t = S3 ^ (LE64(ad_len_bits) || LE64(msg_len_bits)) Repeat(7, Update(t)) if tag_length == 16: # 128 bits tag = S0 ^ S1 ^ S2 ^ S3 ^ S4 ^ S5 else: # 256 bits tag = (S0 ^ S1 ^ S2) || (S3 ^ S4 ^ S5) return tag¶
Applications MAY keep the ciphertext and the authentication tag in distinct structures or encode both as a single string.¶
In the latter case, the tag MUST immediately follow the ciphertext:¶
combined_ct = ct || tag¶
All AEGIS variants can also be used as stream ciphers.¶
Stream(len, key, nonce)¶
The Stream
function expands a key and an optional nonce into a variable-length, secure keystream.¶
Inputs:¶
len
: the length of the keystream to generate.¶
key
: the AEGIS key.¶
nonce
: the nonce. If unspecified, it is set to N_MAX
zero bytes.¶
Outputs:¶
stream
: the keystream.¶
Steps:¶
stream, tag = Encrypt(ZeroPad({}, len), {}, key, nonce) return stream¶
This is equivalent to encrypting a len
all-zero bytes message without associated data, and discarding the authentication tag.¶
Instead of relying on the generic Encrypt
function, implementations can skip the finalization step.¶
After initialization, the Update
function is called with constant parameters, allowing further optimizations.¶
AEGIS-256 offers 256-bit message security against plaintext and state recovery, whereas AEGIS-128L offers 128-bit security.¶
An authentication tag may verify under multiple keys, nonces, or associated data, but AEGIS is assumed to be key committing in the receiver-binding game, preventing common attacks when used with low-entropy keys such as passwords. Finding distinct keys and/or nonces that successfully verify the same (ad, ct, tag)
tuple is expected to require ~264 attempts with a 128-bit authentication tag and ~2128 attempts with a 256-bit tag.¶
However, it is NOT fully committing because the key doesn’t commit to the associated data. As shown in [IR23], with the ability to also alter ad
, it is possible to efficiently find multiple keys that will verify the same authenticated ciphertext.¶
Under the assumption that the secret key is unknown to the attacker both AEGIS-128L and AEGIS-256 target 128-bit security against forgery attacks regardless of the tag size.¶
Both algorithms MUST be used in a nonce-respecting setting: for a given key
, a nonce
MUST only be used once. Failure to do so would immediately reveal the bitwise difference between two messages.¶
If tag verification fails, the decrypted message and wrong message authentication tag MUST NOT be given as output. As shown in the analysis of the (robustness of CAESAR candidates beyond their guarantees)[VV18], even a partial leak of the plaintext without verification would facilitate chosen ciphertext attacks.¶
Every key MUST be randomly chosen from a uniform distribution.¶
The nonce MAY be public or predictable. It can be a counter, the output of a permutation, or a generator with a long period.¶
With AEGIS-128L, random nonces can safely encrypt up to 248 messages using the same key with negligible (~ 2-33, to align with NIST guidelines) collision probability.¶
With AEGIS-256, random nonces can be used with no practical limits.¶
Regardless of the variant, the key
and nonce
are only required by the Init
function; other functions only depend on the resulting state. Therefore, implementations can overwrite ephemeral keys with zeros right after the last Update
call of the initialization function.¶
The security of AEGIS against timing and physical attacks is limited by the implementation of the underlying AESRound()
function. Failure to implement AESRound()
in a fashion safe against timing and physical attacks, such as differential power analysis, timing analysis or fault injection attacks, may lead to leakage of secret key material or state information. The exact mitigations required for timing and physical attacks also depend on the threat model in question.¶
Security analyses of AEGIS can be found in Chapter 4 of [AEGIS], in [M14], in [ENP19], in [LIMS21], in [JLD21], in [STSI23], and in [IR23].¶
IANA has assigned the following identifiers in the AEAD Algorithms Registry:¶
Algorithm Name | ID |
---|---|
AEAD_AEGIS128L
|
32
|
AEAD_AEGIS256
|
33
|
IANA has also assigned the following TLS cipher suites in the TLS Cipher Suite Registry:¶
Cipher Suite Name | Value |
---|---|
TLS_AEGIS_256_SHA384
|
{0x13,0x06}
|
TLS_AEGIS_128L_SHA256
|
{0x13,0x07}
|
A 128-bit tag length must be used with these cipher suites.¶
IANA is requested to update the references of these entries to refer to the final version of this document.¶
In DTLS 1.3, record sequence numbers are encrypted as specified in [RFC9147].¶
For AEGIS-128L and AEGIS-256, the mask is generated using the AEGIS Stream
function with:¶
a 128-bit tag length¶
sn_key
, as defined in Section 4.2.3 of [RFC9147]¶
ciphertext[0..16]
: the first 16 bytes of the DTLS ciphertext¶
nonce_len
: the AEGIS nonce length¶
The 5-byte mask is computed as follows:¶
mask = Stream(5, sn_key, ZeroPad(ciphertext[0..16], nonce_len))¶
In QUIC, parts of the QUIC packet headers are encrypted as specified in [RFC9001].¶
For AEGIS-128L and AEGIS-256, the mask is generated using the AEGIS Encrypt
function with:¶
a 128-bit tag length¶
hp_key
, as defined in Section 5.4 of [RFC9001]¶
sample
: the 16 bytes QUIC ciphertext sample¶
nonce_len
: the AEGIS nonce length¶
The mask is computed as follows:¶
mask = Encrypt("", "", hp_key, ZeroPad(sample, nonce_len))¶
in : 000102030405060708090a0b0c0d0e0f rk : 101112131415161718191a1b1c1d1e1f out : 7a7b4e5638782546a8c0477a3b813f43¶
S0 : 9b7e60b24cc873ea894ecc07911049a3 S1 : 330be08f35300faa2ebf9a7b0d274658 S2 : 7bbd5bd2b049f7b9b515cf26fbe7756c S3 : c35a00f55ea86c3886ec5e928f87db18 S4 : 9ebccafce87cab446396c4334592c91f S5 : 58d83e31f256371e60fc6bb257114601 S6 : 1639b56ea322c88568a176585bc915de S7 : 640818ffb57dc0fbc2e72ae93457e39a M0 : 033e6975b94816879e42917650955aa0 M1 : 033e6975b94816879e42917650955aa0 After Update: S0 : 596ab773e4433ca0127c73f60536769d S1 : 790394041a3d26ab697bde865014652d S2 : 38cf49e4b65248acd533041b64dd0611 S3 : 16d8e58748f437bfff1797f780337cee S4 : 69761320f7dd738b281cc9f335ac2f5a S5 : a21746bb193a569e331e1aa985d0d729 S6 : 09d714e6fcf9177a8ed1cde7e3d259a6 S7 : 61279ba73167f0ab76f0a11bf203bdff¶
key : 10010000000000000000000000000000 nonce : 10000200000000000000000000000000 ad : msg : 00000000000000000000000000000000 ct : c1c0e58bd913006feba00f4b3cc3594e tag128: abe0ece80c24868a226a35d16bdae37a tag256: 25835bfbb21632176cf03840687cb968 cace4617af1bd0f7d064c639a5c79ee4¶
key : 10010000000000000000000000000000 nonce : 10000200000000000000000000000000 ad : msg : ct : tag128: c2b879a67def9d74e6c14f708bbcc9b4 tag256: 1360dc9db8ae42455f6e5b6a9d488ea4 f2184c4e12120249335c4ee84bafe25d¶
key : 10010000000000000000000000000000 nonce : 10000200000000000000000000000000 ad : 0001020304050607 msg : 000102030405060708090a0b0c0d0e0f 101112131415161718191a1b1c1d1e1f ct : 79d94593d8c2119d7e8fd9b8fc77845c 5c077a05b2528b6ac54b563aed8efe84 tag128: cc6f3372f6aa1bb82388d695c3962d9a tag256: 022cb796fe7e0ae1197525ff67e30948 4cfbab6528ddef89f17d74ef8ecd82b3¶
key : 10010000000000000000000000000000 nonce : 10000200000000000000000000000000 ad : 0001020304050607 msg : 000102030405060708090a0b0c0d ct : 79d94593d8c2119d7e8fd9b8fc77 tag128: 5c04b3dba849b2701effbe32c7f0fab7 tag256: 86f1b80bfb463aba711d15405d094baf 4a55a15dbfec81a76f35ed0b9c8b04ac¶
key : 10010000000000000000000000000000 nonce : 10000200000000000000000000000000 ad : 000102030405060708090a0b0c0d0e0f 101112131415161718191a1b1c1d1e1f 20212223242526272829 msg : 101112131415161718191a1b1c1d1e1f 202122232425262728292a2b2c2d2e2f 3031323334353637 ct : b31052ad1cca4e291abcf2df3502e6bd b1bfd6db36798be3607b1f94d34478aa 7ede7f7a990fec10 tag128: 7542a745733014f9474417b337399507 tag256: b91e2947a33da8bee89b6794e647baf0 fc835ff574aca3fc27c33be0db2aff98¶
This test MUST return a “verification failed” error.¶
key : 10000200000000000000000000000000 nonce : 10010000000000000000000000000000 ad : 0001020304050607 ct : 79d94593d8c2119d7e8fd9b8fc77 tag128: 5c04b3dba849b2701effbe32c7f0fab7 tag256: 86f1b80bfb463aba711d15405d094baf 4a55a15dbfec81a76f35ed0b9c8b04ac¶
This test MUST return a “verification failed” error.¶
key : 10010000000000000000000000000000 nonce : 10000200000000000000000000000000 ad : 0001020304050607 ct : 79d94593d8c2119d7e8fd9b8fc78 tag128: 5c04b3dba849b2701effbe32c7f0fab7 tag256: 86f1b80bfb463aba711d15405d094baf 4a55a15dbfec81a76f35ed0b9c8b04ac¶
This test MUST return a “verification failed” error.¶
key : 10010000000000000000000000000000 nonce : 10000200000000000000000000000000 ad : 0001020304050608 ct : 79d94593d8c2119d7e8fd9b8fc77 tag128: 5c04b3dba849b2701effbe32c7f0fab7 tag256: 86f1b80bfb463aba711d15405d094baf 4a55a15dbfec81a76f35ed0b9c8b04ac¶
This test MUST return a “verification failed” error.¶
key : 10010000000000000000000000000000 nonce : 10000200000000000000000000000000 ad : 0001020304050607 ct : 79d94593d8c2119d7e8fd9b8fc77 tag128: 6c04b3dba849b2701effbe32c7f0fab8 tag256: 86f1b80bfb463aba711d15405d094baf 4a55a15dbfec81a76f35ed0b9c8b04ad¶
S0 : 1fa1207ed76c86f2c4bb40e8b395b43e S1 : b44c375e6c1e1978db64bcd12e9e332f S2 : 0dab84bfa9f0226432ff630f233d4e5b S3 : d7ef65c9b93e8ee60c75161407b066e7 S4 : a760bb3da073fbd92bdc24734b1f56fb S5 : a828a18d6a964497ac6e7e53c5f55c73 M : b165617ed04ab738afb2612c6d18a1ec After Update: S0 : e6bc643bae82dfa3d991b1b323839dcd S1 : 648578232ba0f2f0a3677f617dc052c3 S2 : ea788e0e572044a46059212dd007a789 S3 : 2f1498ae19b80da13fba698f088a8590 S4 : a54c2ee95e8c2a2c3dae2ec743ae6b86 S5 : a3240fceb68e32d5d114df1b5363ab67¶
key : 10010000000000000000000000000000 00000000000000000000000000000000 nonce : 10000200000000000000000000000000 00000000000000000000000000000000 ad : msg : 00000000000000000000000000000000 ct : 754fc3d8c973246dcc6d741412a4b236 tag128: 3fe91994768b332ed7f570a19ec5896e tag256: 1181a1d18091082bf0266f66297d167d 2e68b845f61a3b0527d31fc7b7b89f13¶
key : 10010000000000000000000000000000 00000000000000000000000000000000 nonce : 10000200000000000000000000000000 00000000000000000000000000000000 ad : msg : ct : tag128: e3def978a0f054afd1e761d7553afba3 tag256: 6a348c930adbd654896e1666aad67de9 89ea75ebaa2b82fb588977b1ffec864a¶
key : 10010000000000000000000000000000 00000000000000000000000000000000 nonce : 10000200000000000000000000000000 00000000000000000000000000000000 ad : 0001020304050607 msg : 000102030405060708090a0b0c0d0e0f 101112131415161718191a1b1c1d1e1f ct : f373079ed84b2709faee373584585d60 accd191db310ef5d8b11833df9dec711 tag128: 8d86f91ee606e9ff26a01b64ccbdd91d tag256: b7d28d0c3c0ebd409fd22b4416050307 3a547412da0854bfb9723020dab8da1a¶
key : 10010000000000000000000000000000 00000000000000000000000000000000 nonce : 10000200000000000000000000000000 00000000000000000000000000000000 ad : 0001020304050607 msg : 000102030405060708090a0b0c0d ct : f373079ed84b2709faee37358458 tag128: c60b9c2d33ceb058f96e6dd03c215652 tag256: 8c1cc703c81281bee3f6d9966e14948b 4a175b2efbdc31e61a98b4465235c2d9¶
key : 10010000000000000000000000000000 00000000000000000000000000000000 nonce : 10000200000000000000000000000000 00000000000000000000000000000000 ad : 000102030405060708090a0b0c0d0e0f 101112131415161718191a1b1c1d1e1f 20212223242526272829 msg : 101112131415161718191a1b1c1d1e1f 202122232425262728292a2b2c2d2e2f 3031323334353637 ct : 57754a7d09963e7c787583a2e7b859bb 24fa1e04d49fd550b2511a358e3bca25 2a9b1b8b30cc4a67 tag128: ab8a7d53fd0e98d727accca94925e128 tag256: a3aca270c006094d71c20e6910b5161c 0826df233d08919a566ec2c05990f734¶
This test MUST return a “verification failed” error.¶
key : 10000200000000000000000000000000 00000000000000000000000000000000 nonce : 10010000000000000000000000000000 00000000000000000000000000000000 ad : 0001020304050607 ct : f373079ed84b2709faee37358458 tag128: c60b9c2d33ceb058f96e6dd03c215652 tag256: 8c1cc703c81281bee3f6d9966e14948b 4a175b2efbdc31e61a98b4465235c2d9¶
This test MUST return a “verification failed” error.¶
key : 10010000000000000000000000000000 00000000000000000000000000000000 nonce : 10000200000000000000000000000000 00000000000000000000000000000000 ad : 0001020304050607 ct : f373079ed84b2709faee37358459 tag128: c60b9c2d33ceb058f96e6dd03c215652 tag256: 8c1cc703c81281bee3f6d9966e14948b 4a175b2efbdc31e61a98b4465235c2d9¶
This test MUST return a “verification failed” error.¶
key : 10010000000000000000000000000000 00000000000000000000000000000000 nonce : 10000200000000000000000000000000 00000000000000000000000000000000 ad : 0001020304050608 ct : f373079ed84b2709faee37358458 tag128: c60b9c2d33ceb058f96e6dd03c215652 tag256: 8c1cc703c81281bee3f6d9966e14948b 4a175b2efbdc31e61a98b4465235c2d9¶
This test MUST return a “verification failed” error.¶
key : 10010000000000000000000000000000 00000000000000000000000000000000 nonce : 10000200000000000000000000000000 00000000000000000000000000000000 ad : 0001020304050607 ct : f373079ed84b2709faee37358458 tag128: c60b9c2d33ceb058f96e6dd03c215653 tag256: 8c1cc703c81281bee3f6d9966e14948b 4a175b2efbdc31e61a98b4465235c2da¶
The AEGIS authenticated encryption algorithm was invented by Hongjun Wu and Bart Preneel.¶
The round function leverages the AES permutation invented by Joan Daemen and Vincent Rijmen. They also authored the Pelican MAC that partly motivated the design of the AEGIS MAC.¶
We would like to thank the following individuals for their contributions:¶
Eric Lagergren and Daniel Bleichenbacher for catching a broken test vector and Daniel Bleichenbacher for many helpful suggestions.¶
John Preuß Mattsson for his review of the draft, and for suggesting how AEGIS should be used in the context of DTLS and QUIC.¶
Bart Mennink and Charlotte Lefevre as well as Takanori Isobe and Mostafizar Rahman for investigating the commitment security of the schemes specified in this document.¶