Skip to content

crypto-lab-nonce-guard

AES-GCM vs AES-GCM-SIV — nonce misuse resistance compared

A — The Nonce Problem

A1 — What is a nonce?

A nonce (number used once) in AEAD schemes is a per-encryption value that must be unique for every encryption under the same key. It does not need to be secret. AES-GCM uses a 96-bit nonce (12 bytes). The security proof assumes the nonce is never reused.

NIST SP 800-38D calls it an Initialization Vector (IV); RFC 5116 calls it a nonce — same concept.

96-BIT NONCE (12 BYTES)

A2 — Why nonce reuse breaks AES-GCM

Level 1 — Keystream reuse (confidentiality failure)

AES-GCM encrypts by XORing plaintext with a keystream derived from (key, nonce, counter). If the same (key, nonce) pair is used twice:

C₁ = P₁ ⊕ KS
C₂ = P₂ ⊕ KS
C₁ ⊕ C₂ = P₁ ⊕ P₂

The attacker recovers the XOR of the two plaintexts — which often recovers both plaintexts in practice.

Level 2 — Authentication key recovery (integrity failure)

AES-GCM's tag is built from GHASH, a polynomial hash over GF(2¹²⁸) keyed by H = E_K(0¹²⁸) — a value fixed by the key alone. For a 96-bit nonce the tag is:

tag = GHASH_H(AAD, C) ⊕ E_K(nonce ‖ 0³¹1)

The masking term E_K(nonce ‖ 0³¹1) depends only on (key, nonce), so two messages under the same nonce share it. Subtracting their tags cancels the mask:

tag₁ ⊕ tag₂ = GHASH_H(A₁,C₁) ⊕ GHASH_H(A₂,C₂)

GHASH is a polynomial in H, so this is one polynomial equation in the single unknown H over GF(2¹²⁸). Finding its roots yields a small set of candidate values for H — this is Joux's "forbidden attack." Recovering H also exposes the mask, after which the attacker can forge valid tags for arbitrary ciphertexts under that nonce — total integrity failure. This is not theoretical: a 2016 survey (Böck, Zauner, Devlin et al.) found production HTTPS servers reusing AES-GCM nonces, making them vulnerable to exactly this attack.

The Live Attack Demo below actually performs this: with the nonce reused it encrypts two single-block probes, recovers H from their ciphertexts and tags alone (using the closed-form single-block case T₁ ⊕ T₂ = (C₁ ⊕ C₂)·H²), then forges a valid tag that the real AES-GCM decryptor accepts.

A3 — The SIV construction (RFC 8452)

AES-GCM-SIV uses a synthetic IV approach:

  1. Derive a per-nonce authentication key and encryption key from the master key and nonce
  2. Hash the plaintext (and AAD) with POLYVAL — a GF(2¹²⁸) hash defined in RFC 8452 — then XOR in the nonce and AES-encrypt the result to produce the tag
  3. Use that tag (top bit set) as the synthetic IV for AES-CTR encryption

The IV is derived from the plaintext itself. If the same (key, nonce) pair encrypts two different plaintexts, the two IVs differ. Nonce reuse degrades to leaking only whether two plaintexts were identical — not the keystream, not the authentication key.

B — Live Nonce Reuse Attack Demo

First plaintext message for encryption
Second plaintext message for encryption

🔓 AES-GCM Vulnerable

Click "Encrypt Both" to begin

🔒 AES-GCM-SIV Resistant

Click "Encrypt Both" to begin

C — Synthetic IV Construction Visualizer

C1 — Key Derivation

AES-GCM-SIV derives per-nonce keys from the master key. For each counter it AES-encrypts the block counter ‖ nonce (counter is a 32-bit little-endian value; nonce is 96 bits) and keeps the low 8 bytes of the output, concatenating them:

For a 128-bit master key the encryption key uses only counters 2–3 (two blocks).

C2 — POLYVAL Authentication

POLYVAL is a GF(2¹²⁸) polynomial hash defined in RFC 8452 — essentially GHASH's mirror in a little-endian-friendly field representation. Its key H is derived per-nonce from (key, nonce). But the decisive difference from AES-GCM is the final step: the POLYVAL result is AES-encrypted before it is output as the tag.

S = POLYVAL(H, AAD, PT); XOR nonce into bytes 0–11; clear MSB of byte 15
tag = AESKenc(S)

Because the attacker only ever sees AESKenc(S) — never POLYVAL's raw output — the "subtract two tags" trick from AES-GCM no longer linearizes anything. The AES pseudorandom permutation hides the polynomial structure, so even reusing a nonce (which does reuse H) never leaks the authentication key.

C3 — Tag-as-IV (Interactive)

The 128-bit tag (the AES-encrypted POLYVAL result) is reused as the initial AES-CTR counter block — with the most significant bit of its last byte set to 1. That is the same bit cleared on the input to the tag-generating AES call, so the value encrypted to form the tag can never coincide with any CTR counter block. Changing any byte of plaintext completely changes the tag and therefore the IV.

Type any message to see how the AES-GCM-SIV tag changes with each character

D — When to Use Which

D1 — Comparison Table

Comparison of AES-GCM and AES-GCM-SIV properties
PropertyAES-GCMAES-GCM-SIV
StandardNIST SP 800-38DRFC 8452
Nonce size96 bits96 bits
Nonce reuse consequenceKey recovery + full plaintext XORIdentical plaintext detection only
Performance~1 pass~2 passes (extra POLYVAL)
FIPS approvedYesNo — an IRTF CFRG spec (RFC 8452), not a NIST mode
Hardware accelerationAES-NI + PCLMULQDQAES-NI + PCLMULQDQ
Online encryptionYesNo — must buffer full plaintext
Deployed inTLS 1.3, QUIC, IPsecGoogle internal, QUIC experiments
Recommendation✅ Nonce uniqueness guaranteed✅ Nonce uniqueness uncertain

D2 — Decision Guidance

Scenario 1 — Single server, sequential encryption

AES-GCM with a counter nonce is safe. Nonce uniqueness is easy to guarantee. No need for SIV overhead.

Scenario 2 — Distributed system, multiple encryptors

Coordinating nonces across servers is error-prone. AES-GCM-SIV degrades gracefully on accidental reuse. Use SIV or use random 96-bit nonces with AES-GCM (collision risk is low at < 2³² messages per key).

Scenario 3 — Key wrapping and key storage

AES-GCM-SIV is designed for this — short messages, repeated access to the same key, nonce coordination difficult. Google's Tink library uses it for key wrapping.

D3 — Honest Limitations of AES-GCM-SIV

  • Not FIPS-approved — cannot use in FIPS 140-2/3 contexts
  • No online encryption — must have full plaintext before starting (not suitable for streaming)
  • Two passes over the data — the tag must be computed before encryption can begin, so throughput can approach half that of single-pass AES-GCM on long messages, though hardware-optimized (AES-NI + PCLMULQDQ) implementations narrow the gap
  • Not yet widely deployed — operational experience is thin compared to AES-GCM