Chapter 2 · Cryptography· Advanced· ~22 min

Symmetric Cryptography

Past AEAD basics: nonce-misuse-resistant constructions, key wrap, HKDF's two-step proof, and what Grover's algorithm really costs symmetric crypto.

You will learn

  • How AES-GCM-SIV and Deoxys-II survive nonce reuse with bounded damage
  • What AES-KW is for and why "encrypt a key" is its own primitive
  • HKDF's extract-and-expand structure, and why it is provably safe even with non-uniform input
  • The exact symmetric impact of Grover (it halves bit-strength, full stop)

Nonce-misuse-resistant AEAD

AES-GCM and ChaCha20-Poly1305 are catastrophic on nonce reuse: the keystream repeats, plaintexts XOR is revealed, and the polynomial MAC's authentication key leaks, letting an attacker forge tags for arbitrary messages. Nonce reuse happens more than it should: VM clones with the same RNG seed, restored backups, bad library wrappers.

AES-GCM-SIV (RFC 8452) addresses this with synthetic IVs. The nonce and the plaintext together derive a per-message authentication key and an IV via POLYVAL plus AES. The result: if the nonce repeats with different plaintexts, the worst the attacker learns is whether two messages were identical. They do not get keystream collisions or tag forgery.

Deoxys-II (CAESAR portfolio winner) and AES-OCB are alternatives. OCB had a long IP problem (now expired) and is faster than GCM but less widely supported. For new designs where nonce discipline cannot be perfectly guaranteed, AES-GCM-SIV is the conservative choice.

Key wrap: encrypting keys

"Encrypt this key with this other key" sounds trivial but has its own primitive for a reason. AES Key Wrap (KW, KWP, AES-GCM-KW) is designed for short, fixed-size inputs (typically 128 to 256 bits) and includes built-in integrity. The output is the same size as the input plus 8 bytes for the integrity tag.

Why not just AES-GCM with a nonce? Two reasons:

  • Key material is rare; nonces for general AEAD assume many messages and one key. Key wrap inverts that: many keys, rarely.
  • Key-wrapping algorithms are designed to be deterministic when needed (KW) and to provide integrity without random nonces. Useful for storing in HSMs or KMS-style services.

Real systems: AWS KMS, Google Cloud KMS, and HashiCorp Vault all use AES-KW or KWP under the hood when they "envelope encrypt" data with a customer master key.

HKDF: extract then expand

HKDF (RFC 5869) has two phases:

PRK     = HMAC(salt, IKM)               // Extract: condense to uniform pseudorandom key
output  = HKDF-Expand(PRK, info, L)     // Expand: stretch to L bytes with domain separation

The extract step is the key insight: an arbitrary input (an ECDH shared secret, a TLS pre-master, the output of a KEM) is fed through HMAC with a salt to produce a uniform PRK. The expand step then derives any number of session keys from that PRK by labelling.

The "info" string is critical for domain separation: deriving a "client write key" and a "server write key" use the same PRK but different info, so the keys are independent. Forgetting to vary info gives you the same key for different purposes, which has been a real bug in many protocols.

HKDF is provably secure if the underlying HMAC is. The proof is in the RFC and uses standard PRF assumptions. This is why TLS 1.3 uses HKDF for its entire key schedule.

The Grover impact (precise version)

Grover's algorithm on a sufficiently large quantum computer finds a preimage of a one-way function in O(sqrt(N)) operations instead of O(N). For an n-bit symmetric key:

  • Classical key search: 2^n operations.
  • Quantum Grover search: 2^(n/2) operations.

So a 128-bit AES key gives ~64-bit security post-quantum, which is borderline today. A 256-bit AES key gives 128-bit post-quantum security, which is comfortably out of reach.

What this does NOT mean:

  • Grover does not "break" AES. The work is still exponential, just with a halved exponent.
  • It does not affect AES's other security properties (collision resistance of the underlying permutation, etc.).
  • Quantum collision search on hashes is more subtle: it costs O(2^(n/3)) with quantum memory, but realistic quantum-memory constraints push it closer to classical for now.

Practical advice: switch new designs to AES-256 if you have not already. Hash functions with 256-bit output stay comfortable for collision resistance even with quantum.

Specific CVEs worth knowing

  • CVE-2016-2107 (Lucky 13 variant on OpenSSL AES-NI CBC): padding-oracle through a microarchitectural timing difference. Patched by constant-time CBC decryption.
  • POODLE (CVE-2014-3566): SSL 3.0 padding oracle on CBC mode. Killed SSL 3.0.
  • CCS Injection (CVE-2014-0224): OpenSSL accepted ChangeCipherSpec messages out of order, letting a MITM inject keys.
  • Sweet32 (CVE-2016-2183): birthday-bound attack on 64-bit block ciphers (3DES) in long-lived TLS connections.

Pattern: most real-world breaks of symmetric crypto come from implementation bugs, padding handling, or protocol-level confusion. The primitives themselves rarely fall.