How AES Breaks in Real Life: The Attacks That Never Touched the Cipher
AES-the-cipher has never been broken in the field -- its deployments have. KRACK, repeated GCM nonces, and cache timing broke the wrapper, never the block.
Permalink1. AES Is Unbroken. Your AES Traffic Was Decrypted Anyway.
The best publicly known attack on the full AES cipher costs roughly operations for AES-128 -- a number so far beyond feasible that its own discoverers wrote it does "not threaten the practical use of AES in any way" [1]. To put in scale: if every one of the billions of computers on Earth checked a billion keys a second, you would still wait longer than the age of the universe, many times over. By any honest measure, the cipher stands.
And yet, in the same decade that number was published, attackers decrypted live Wi-Fi sessions, forged authenticated HTTPS connections, and lifted AES keys straight out of running servers -- none of them going anywhere near that wall. How does a cipher nobody can break keep producing decrypted traffic and stolen keys?
The resolution is the thesis of this article, and you can hold it right now: none of these breaks touched the 128-bit block math. AES is a keyed permutation -- a function that scrambles one 16-byte block into another -- and nothing more. It is not a cryptosystem. To protect a real message you wrap that permutation in three things: an implementation that computes it on real silicon, a mode that chains it across a message, and a protocol that establishes keys and drives the mode. Each wrapper is a new, independent way to fail. And it was the wrappers, every time, that failed.
That gives you a diagnostic sentence to carry through the rest of this piece. When your encrypted traffic falls, the question is never "was AES broken?" It is: which layer around AES failed -- the implementation, the mode, or the protocol? By the end you will be able to drop KRACK, the GCM nonce scandal, and tomorrow's not-yet-published incident into that one question on sight.
To break AES in the field, you never touch AES. The table lookup leaks, the nonce repeats, the handshake rewinds -- and the 128-bit block math never moves.
This is Part 1 of How It Breaks in Real Life, a series with a single recurring claim: the primitive's mathematics almost never caused the break; the deployment did -- the nonce, the padding, key generation, a downgrade, a validation bug, or a deprecated-but-still-live algorithm. AES is the cleanest case, which is why it goes first. Its companion piece, How AES Would Break, asks what it would take to move the block itself: the key schedule, related-key cryptanalysis, the slow erosion of the security margin. That is the would-break-in-theory story. This is the did-break-in-the-field one.
If the cipher was intact and the block math never moved, then everything that broke was built around it. To see how "unbroken cipher" and "decrypted traffic" can both be true, you have to go back to what AES actually is -- and, more to the point, what it is not.
2. Why a Cipher Is Not a Cryptosystem
In October 2000, after a three-year open competition in which the world's cryptographers were invited to attack the candidates, NIST selected Joan Daemen and Vincent Rijmen's Rijndael as the Advanced Encryption Standard [7]. The choice followed a public evaluation of fifteen submissions narrowed to five finalists, judged on security, performance, and efficiency from servers to smart cards [8, 9, 10]. That adversarial process is why the core math has held for over two decades -- and why, when things break in the field, the fault lies elsewhere. Winning the competition made Rijndael a cipher, not a cryptosystem.
Here is the distinction the whole article turns on. AES, standardized as FIPS 197 in 2001 and editorially refreshed in 2023 with no technical change to the algorithm, is a keyed 128-bit permutation [11]. It maps one 128-bit block to one 128-bit block under a 128-, 192-, or 256-bit key, and that is all it does. AES applies 10, 12, or 14 rounds for the 128-, 192-, and 256-bit keys. The round function is identical across all three; key size changes only the round count and the key schedule that feeds it [11]. It has no notion of a message longer than 16 bytes, no integrity, no session or conversation. Feed it the same block and key twice and you get the same output twice. On its own it cannot safely encrypt a paragraph, let alone a Wi-Fi session.
A block cipher is a keyed permutation on fixed-size blocks -- AES maps one 16-byte block to another under a key. A mode of operation (CTR, CCM, GCM, and others) is the wrapper that chains that permutation across an arbitrary-length message and, in authenticated modes, adds integrity. The block cipher is the engine; the mode is the car. You do not drive an engine.
To turn that engine into something that protects real data, you add three wrappers, and each one is a new, independent failure surface:
- an implementation that computes the permutation on a real CPU, and may leak through timing or cache behavior;
- a mode of operation that chains the permutation across a whole message and, in AEAD modes, adds integrity -- and imposes a contract on how you feed it nonces;
- a protocol that establishes keys and drives the mode, and can mismanage them.
Diagram source
flowchart TD
B["AES 128-bit permutation -- never broken in the field"]
I["Implementation layer -- computes the block in code or silicon"]
M["Mode layer -- chains the block, adds integrity, imposes a nonce contract"]
P["Protocol layer -- establishes keys and drives the mode"]
B --> I --> M --> P
I -. break .-> AtkI["Cache timing leaks the key"]
M -. break .-> AtkM["A repeated nonce reuses a keystream"]
P -. break .-> AtkP["A replayed handshake rewinds the nonce"] This map is the lens for everything that follows. The block sits at the center, untouched. The implementation wraps it, the mode wraps that, the protocol wraps that -- and the three field breaks in this article land on the three outer rings, in order, working outward from the silicon.
One more piece of honesty before we watch the wrappers fail. The series this article opens says the primitive's math almost never causes the break -- "almost," not "never" -- and the hedge is load-bearing. Every break in this article is independent of key size. That is not a rhetorical flourish; it is a literal property of cache timing, nonce reuse, and handshake replay, none of which involve guessing key bits.
Three wrappers, three contracts, three ways to fail -- none of them the cipher. Before watching each one break in the field, you need to see the contracts up close: what a mode actually promises, what a nonce is, and why the humble table lookup is a loaded gun.
3. The Layers Around the Block, and the Contracts They Impose
Every one of the three field breaks is the violation of a single, specific promise. If you see the promise clearly now, the break will look obvious later. So here are all three contracts, one per layer, in order.
The implementation contract: a lookup should not leak what it looked up
Computing AES the naive way -- byte by byte through its S-box and its field multiplications -- is slow in software. So fast implementations fold an entire round into precomputed lookup tables. Four tables of about 1 KB each, conventionally called T0 through T3, turn each output column of a round into T0[a] XOR T1[b] XOR T2[c] XOR T3[d]: four reads and three XORs, so a full round is four of those -- sixteen reads in all [2].
A set of precomputed lookup tables (typically four tables of 256 four-byte entries, about 4 KB total) that fold AES's SubBytes, ShiftRows, and MixColumns steps into a handful of table reads per round. It is purely a speed optimization. The block permutation it computes is identical to the slow version -- but how it computes it now depends on secret-derived indices.
The mode contract: never repeat a (key, nonce) pair
A mode turns the one-block permutation into something that encrypts messages and detects tampering. Modern modes aim for AEAD.
Authenticated Encryption with Associated Data: a mode that provides confidentiality and integrity at once. It encrypts the plaintext and produces an authentication tag over both the ciphertext and some associated data (headers, sequence numbers) that is authenticated but not encrypted. GCM and CCM are AEAD modes; if the tag does not verify, the receiver rejects the message.
The workhorse construction is counter mode. AES is run on a counter to produce a keystream, and the keystream is XORed with the plaintext: keystream block , and ciphertext . This is elegant and fast and fully parallel. It also carries one absolute obligation.
A nonce is a "number used once." In counter-based modes the pair (key, nonce) must be unique for every encryption under that key. The nonce need not be secret or random -- a counter is fine -- but it must never repeat. This is the single most load-bearing rule in practical symmetric cryptography, and it is the rule every mode-and-protocol break in this article violates.
Watch what happens if you break it. If two messages are encrypted under the same key and the same nonce, they get the same keystream. XOR the two ciphertexts and the keystream cancels:
The key never appears. The attacker who captures two same-nonce ciphertexts learns the XOR of the two plaintexts, and if they know or can guess one, they get the other -- with the cipher fully intact.
The failure that follows from a repeated (key, nonce) in a counter-based mode: identical keystream for two messages, so . The plaintext XOR leaks and the key is never touched. This one mechanic drives both the GCM break and the WPA2/CCMP break later in this article.
A block cipher in a counter-based mode is a keystream generator. Feed it the same (key, nonce) twice and you get the same keystream, so -- the plaintext XOR leaks and the key is never touched. The nonce-uniqueness contract is the one promise that stops this. Break it and the strongest cipher in the world protects nothing.
You can watch the cancellation happen. Nothing below is real AES -- the toy keystream stands in for AES-CTR output -- but the XOR algebra is exactly the algebra of the real break.
// Same (key, nonce) => same keystream for BOTH messages. That is the whole bug.
const keystream = [0x9e, 0x37, 0xb1, 0xa4, 0x55, 0x0c, 0xd2, 0x6f];
function xorBytes(a, b) {
const out = [];
for (let i = 0; i < a.length; i++) out.push(a[i] ^ b[i]);
return out;
}
const toBytes = (s) => Array.from(s).map((c) => c.charCodeAt(0));
const p1 = toBytes("ATTACK 0");
const p2 = toBytes("defend!!");
const c1 = xorBytes(p1, keystream); // what the attacker sees
const c2 = xorBytes(p2, keystream); // what the attacker sees
const leaked = xorBytes(c1, c2); // C1 ^ C2, computed with NO key
const truth = xorBytes(p1, p2); // P1 ^ P2, the secret relationship
console.log("C1 ^ C2 =", leaked.join(","));
console.log("P1 ^ P2 =", truth.join(","));
console.log("keystream cancelled?", JSON.stringify(leaked) === JSON.stringify(truth));
// Know one plaintext, recover the other. The cipher stayed perfectly strong. Press Run to execute.
GCM adds one more thing to worry about. Its integrity tag is built from a secret authentication subkey derived from the key alone, and a repeated nonce exposes that subkey to attack as well -- which is how confidentiality loss becomes forgery. We will pull that thread in the next section.
Even with perfectly unique nonces, GCM has a budget. With random 96-bit nonces, NIST caps a single key at fewer than invocations, because random 96-bit values begin colliding around the birthday bound [14]. Uniqueness is not just a coding rule; it is a counting problem.The protocol contract: install a key once, so its nonce only ever counts up
A mode still needs a protocol to establish keys and supply nonces. WPA2's 4-way handshake derives a fresh Pairwise Transient Key, and AES-CCMP then encrypts each frame with a nonce built from an incrementing packet number; CCM, like GCM, forbids repeating that counter under one key [16, 17]. The assumption is simple and, on its face, obviously true: a key is installed exactly once, so the packet number only ever counts up and never rewinds.
Here are the three contracts side by side. Keep the last column in view -- it is the bill each violation runs up.
| Layer | What it is | The contract it imposes | What a violation costs |
|---|---|---|---|
| Implementation | Code or silicon that computes the AES round | A data-dependent lookup must not leak the data | Cache/timing side channel recovers the key |
| Mode | CTR, GCM, CCM chaining the block across a message | The (key, nonce) pair must be unique per encryption | Keystream reuse leaks ; in GCM, forgery |
| Protocol | Handshake and key management driving the mode | A key is installed once, so its nonce only counts up | A reinstalled key rewinds the nonce, forcing reuse |
Three contracts, each reasonable, each unenforced by the cipher -- the permutation cannot know whether you fed it a repeated nonce or read a leaky table. Which raises the only question that matters: in the real world, running on real servers and real routers, do these contracts actually hold? They do not. Here is where, when, and how each one broke.
4. Three Field Breaks, Three Layers, One Pattern
The comfortable belief is "we standardized a strong cipher, so our encrypted traffic is safe." What follows are three independent refutations of that inference -- one at each layer around the block, ordered by when the field break landed. Read them as a catalog, not a lineage: these are not ciphers that replaced one another but three simultaneous layers, every real deployment has all three at once, and the chronology is the attacker's frontier moving outward as each inner layer hardened.
Diagram source
timeline
title From the silicon outward -- one pattern, three layers
2005-2006 : Implementation layer : Cache timing recovers AES keys (Bernstein, Osvik-Shamir-Tromer)
2016 : Mode layer : 184 HTTPS servers repeat a GCM nonce (Böck et al., weaponizing Joux 2006)
2017 : Protocol layer : KRACK rewinds the AES-CCMP nonce (Vanhoef and Piessens) Generation 1: the implementation leaked (2005-2006)
In 2005, Daniel J. Bernstein did something the FIPS 197 math says is impossible: he recovered a full AES key remotely, over a network -- without breaking AES at all [2, 18]. The target was a server doing nothing but AES under clean timing conditions, so the demonstration was remote in principle rather than turnkey -- and alarming precisely because it was not purely local. It ran ordinary T-table AES, whose secret-dependent indices left the encryption's timing faintly correlated with the key; enough samples pinned the key bytes. A year later, Dag Arne Osvik, Adi Shamir, and Eran Tromer formalized the idea into two reusable cache attacks -- Prime+Probe and Evict+Time -- recovering keys with a modest number of encryptions on a shared machine [3].
Recovering a secret from the physical side effects of a computation -- its timing, its cache footprint, its power draw -- rather than from the algorithm's inputs and outputs. A cache-timing attack on T-table AES watches which cache lines the lookups touch; because the touched lines depend on key-derived indices, the access pattern leaks the key.
The mechanism is worth seeing as a chain, because every link is outside the cipher:
Diagram source
flowchart LR
K["Secret index = key byte XOR plaintext byte"] --> L["Which T-table cache line is touched"]
L --> M["Cache hit or miss changes measurable timing"]
M --> R["Attacker narrows and then pins the key byte"] You can feel the leak in miniature. A real CPU caches memory in lines of 64 bytes, so a 256-entry table falls into a handful of cache lines. The attacker never sees the secret index -- only which line was touched. Watch a single observation cut the keyspace:
// A CPU caches memory in 64-byte lines, so 256 one-byte table entries fall into
// a few "cache lines." The attacker sees ONLY which line was touched -- not the index.
const LINE = 64;
const touchedLine = (index) => Math.floor(index / LINE);
const secretKeyByte = 0xB7; // unknown to the attacker
const plaintextByte = 0x2A; // attacker-chosen, known
const realIndex = secretKeyByte ^ plaintextByte;
const observed = touchedLine(realIndex); // the only thing that leaks
// Which key bytes are consistent with the observed cache line?
const candidates = [];
for (let k = 0; k < 256; k++) {
if (touchedLine(k ^ plaintextByte) === observed) candidates.push(k);
}
console.log("observed cache line:", observed);
console.log("key-byte candidates remaining:", candidates.length, "of 256");
console.log("true key byte still in the set?", candidates.includes(secretKeyByte));
// One measurement: 256 -> 64. Vary the known plaintext, intersect the sets, and the byte falls out. Press Run to execute.
The insight is the sharpest edge of the whole thesis, so state it plainly.
The fix pointed straight at the next era, and it changed how AES is computed, never what AES computes. Two responses followed: constant-time bitsliced software, which replaces the tables with data-independent boolean logic so no secret ever indexes memory [19]; and, decisively, hardware AES-NI, which executes each round in silicon with no lookup tables and data-independent latency [20]. Once AES-NI reached mainstream CPUs in the early 2010s, this surface largely closed -- and the attacker's frontier moved one ring outward, to the mode. The formalization is due to Osvik, Shamir, and Tromer -- not Biham, a common misattribution [3].
Generation 2: the mode's contract was violated (2006, then 2016)
In June 2006, Antoine Joux submitted a public comment to NIST with a quietly devastating observation about GCM, now known as the "forbidden attack" [5]. GCM, designed by David McGrew and John Viega, authenticates with a one-time polynomial MAC over the field , keyed by a secret subkey derived from the encryption key alone [21].
GCM's authentication secret, computed as -- the encryption of an all-zero block under the key. Every authentication tag is a polynomial in evaluated over the ciphertext, masked by where comes from the nonce. Security depends on staying secret, which in turn depends on the nonce never repeating.
Joux's point: if a (key, nonce) pair repeats, the mask is identical across the two messages, so the difference of their tags becomes a polynomial equation over whose unknown is . Solve for the roots and you recover ; with in hand, you can forge a valid authentication tag for a message you chose -- universal forgery [5]. The confidentiality loss from keystream reuse was already bad; this makes integrity fall too.
Diagram source
flowchart TD
N["Same (key, nonce) used for two messages"] --> KS["Identical CTR keystream"]
KS --> C["C1 XOR C2 equals P1 XOR P2, confidentiality lost"]
N --> J["Identical tag mask AES_K of J0"]
J --> EQ["Tag difference becomes a polynomial equation in H over GF(2 to the 128)"]
EQ --> F["Roots reveal the subkey H, enabling forgery"] For ten years this was a footnote -- a warning about a contract nobody, surely, would break. Then, in 2016, Hanno Böck, Aaron Zauner, Sean Devlin, Juraj Somorovsky, and Philipp Jovanovic scanned the Internet and found it broken in the wild [4]. Their paper, "Nonce-Disrespecting Adversaries," reported 184 live HTTPS servers actually repeating GCM nonces -- "which fully breaks the authenticity of the connections" -- among them large corporations, financial institutions, and a credit-card company, plus more than 70,000 servers using random nonces at volume risk.
They then did the thing Joux only described: they weaponized the repeats into working forgeries and injected content into live sessions. The root cause was mundane and entirely operational -- buggy hardware and firmware nonce generators, and counters that reset. The mode's assumption failed; AES did exactly what it was told.
Two precisions keep this honest. First, the mechanism is layer-agnostic in the worst way: this is the same keystream-reuse atom from Section 3, now carrying a forgery payload because GCM's integrity also leans on the nonce. Second, resist the tempting overstatement. Precision lock. One nonce reuse is already a break: it immediately leaks and gives one root-finding equation for . But uniquely pinning for reliable universal forgery generally needs at least two collisions. Say "one reuse is already catastrophic, and more reuse pins the subkey" -- never "one reuse recovers the key" [5]. The evidence for live reuse is the Böck et al. scan, five authors, 184 servers -- not the frequently miscited IBM Domino CVE [4].
The fixes, once again, changed the usage and left the cipher alone: nonce-misuse-resistant AES-GCM-SIV, where a repeat leaks only whether two messages were equal [22], and TLS 1.3's deterministic per-record nonce, which deletes the implementation-chosen "explicit nonce" that RFC 5288 had exposed [23]. As the mode hardened, the frontier moved one final ring outward -- to the protocol.
Generation 3: the protocol reused the nonce (2017)
WPA2's 4-way handshake exists to install a fresh key on both sides. The client installs its Pairwise Transient Key after message 3, and AES-CCMP then encrypts every frame with a nonce built from a packet number that only counts up. For reliability, the standard lets message 3 be retransmitted -- and there the trap was set. In 2017, Mathy Vanhoef and Frank Piessens showed that an attacker who captures and replays message 3 forces the client to reinstall a key it is already using, resetting the CCMP packet number and replay counter to their starting values [6]. The nonce rewinds. The keystream repeats. This is KRACK: Key Reinstallation Attack.
Installing a key that is already in use. Because installing a key also initializes its associated nonce or packet-number counter, reinstalling an in-use key rewinds that counter to its starting value -- forcing the same (key, nonce) pairs, and therefore the same keystream, to be used again. KRACK triggers this by replaying a handshake message the protocol was willing to accept twice.
Diagram source
sequenceDiagram
participant C as Client
participant A as Access Point
participant M as Attacker
A->>C: Message 1 (ANonce)
C->>A: Message 2 (SNonce)
A->>C: Message 3 (install key)
Note over C: Installs PTK, packet number starts counting up
C->>A: Message 4 (acknowledge)
M->>C: Replay Message 3
Note over C: Reinstalls the same key, packet number resets to start
Note over C,A: Nonce reused, keystream repeats, frames become decryptable The insight is the same shape as before, delivered one layer further out: AES-CCMP did exactly what it was told. The permutation was flawless; the state machine told it to reuse a nonce, and it obeyed. The consequence is keystream reuse -- identical (key, nonce) yields -- so a known-plaintext frame yields the keystream and decrypts the colliding frame.
Scope lock. Against AES-CCMP specifically, KRACK forces nonce-reuse decryption and replay -- not forgery and not AES key recovery. Forgery arises for the TKIP and GCMP cases, not CCMP. The especially devastating all-zero-key variant was an Android and Linuxwpa_supplicant implementation bug that reinstalled an all-zero key, still not a break of AES [6].
The fix was a backwards-compatible patch to the handshake state machine -- refuse to reinstall an in-use key -- shipped across Android, Linux, Apple, Windows, and OpenBSD in 2017 [6]. Structurally, the Wi-Fi Alliance announced WPA3 in 2018 [24]; its Personal mode swaps WPA2's pre-shared-key authentication for the SAE (Dragonfly) key exchange and mandates anti-reinstallation checks plus management-frame protection. The 4-way handshake still installs the pairwise key, so KRACK immunity comes from that mandatory hardening -- the same defense WPA2 received as a patch -- not from SAE removing the handshake [25]. The protocol changed. AES did not.
The pattern, seen all at once
Put the three side by side and the shape is unmistakable. Same violated contract in three costumes; same untouched block every time.
| Incident | Year | Layer | Mechanism | Root cause | Fix (usage, not cipher) |
|---|---|---|---|---|---|
| Bernstein; Osvik-Shamir-Tromer cache timing [2, 3] | 2005-2006 | Implementation | Secret-dependent T-table indices leak via cache/timing | A data-dependent lookup leaks the data | Constant-time bitslicing; AES-NI |
| Joux forbidden attack; Böck et al. scan [5, 4] | 2006, 2016 | Mode | Repeated GCM nonce reuses keystream and exposes | Buggy nonce generators break uniqueness | AES-GCM-SIV; TLS 1.3 derived nonces |
| KRACK [6] | 2017 | Protocol | Replayed message 3 rewinds the CCMP nonce | State machine reinstalls an in-use key | Handshake patch; WPA3-SAE |
| Biclique baseline [1] | 2011 | The cipher itself | Best single-key attack: for AES-128 | -- | None needed -- "no practical impact" |
Seen one at a time, these look like three unrelated bugs -- a cache thing, a TLS thing, a Wi-Fi thing. Seen together, they are a single pattern: every time, a contract around the permutation was violated, real traffic or keys fell, and the 128-bit block math did not move. That pattern is the whole point, and it is worth naming out loud.
5. The Fixes Changed How AES Is Used, Never AES
Stop treating the three incidents as separate stories. Line them up and one realization collapses the subject: every field break attacked a layer around the permutation, and every fix changed how AES is used -- never AES itself.
This is not a eureka discovery. It is an engineering discipline, and it is visible only because the same shape repeats three times across 2005, 2016, and 2017. Look at what each fix actually touched:
- Implementation. Constant-time bitsliced code and hardware AES-NI compute the round with no data-dependent memory access [19, 20]. The tables are gone; the permutation they computed is unchanged.
- Mode. AES-GCM-SIV makes a repeated nonce merely detectable rather than catastrophic -- a repeat leaks only whether two messages were equal, never the subkey [22]. TLS 1.3 derives each nonce deterministically from the record sequence number, deleting the footgun RFC 5288 had exposed [23]. The nonce plumbing changed; AES did not.
- Protocol. The KRACK patch forbids reinstalling an in-use key, and WPA3 makes that anti-reinstallation defense mandatory (alongside management-frame protection) while swapping WPA2's pre-shared-key authentication for the SAE key exchange; the 4-way handshake persists, hardened rather than removed [6, 24, 25]. The state machine changed; AES did not.
Not one of these altered the block permutation. They hardened wrappers.
The cipher is the fixed point around which everything else evolved. Every field break attacked a layer around the permutation, and every remedy -- constant-time and AES-NI, misuse-resistant AEAD and derived nonces, patched handshakes and WPA3 -- hardened a wrapper. Soundness requires the weakest of the three layers to hold, and hardening any one of them is an exercise in usage, not cryptanalysis.
There is a dynamic hiding in the chronology, and it is no coincidence. As AES-NI closed the implementation gap around 2010, the weakest remaining link -- the attacker's frontier -- moved to the mode, where the 2016 scan found it. As misuse-resistant modes and derived nonces closed that, the frontier moved to the protocol, where KRACK found it in 2017. The layers did not take turns being weak; the attacker simply always works the current weakest one. That is why "we use a strong cipher" was never the right unit of analysis. The right unit is the weakest wrapper you are still running.
If every fix is a species of "use AES correctly," then the state of the art is just the catalog of what "correctly" means at each layer in 2026 -- and, tellingly, where even correct-by-the-book still is not quite enough.
6. What Correct AES Deployment Looks Like in 2026
The modern answer is unglamorous, and that is exactly the point: be sound at all three layers at once, because a hardened mode does nothing for a leaky implementation, and a constant-time implementation does nothing for a protocol that rewinds its nonce. Here is the correct-deployment endpoint, keyed to the three failure loci.
Implementation. Use hardware AES -- Intel and AMD AES-NI, or ARMv8's cryptographic extension -- which runs each round in silicon with no lookup tables and data-independent latency [20]. Where the CPU lacks AES instructions, fall back to a constant-time bitsliced software implementation that never lets a secret index memory [19]. Mainstream libraries typically make this selection at runtime, preferring hardware AES with a constant-time fallback.
Mode. Use a vetted AEAD, never a hand-rolled chain of primitives. AES-GCM is the performance leader when you can guarantee nonce uniqueness -- either random 96-bit nonces kept under the NIST budget of fewer than invocations per key [14], or TLS 1.3's deterministic per-record nonce derived from the sequence number [23]. Where uniqueness cannot be guaranteed, use AES-GCM-SIV, which survives a repeat gracefully [22].
An authenticated-encryption scheme that does not fail catastrophically when a nonce repeats. In an MRAE scheme such as AES-GCM-SIV, a repeated (nonce, message) pair leaks only the fact that the two plaintexts were identical -- never the keystream across distinct messages, never the subkey . It is the provably strongest guarantee achievable once you admit that nonces sometimes repeat.
Protocol. At the link layer, patch WPA2 against key reinstallation or move to WPA3, which mandates anti-reinstallation checks and management-frame protection to close the defect while still running a 4-way handshake to install the pairwise key [6, 24, 25]. At the transport layer, prefer TLS 1.3 over 1.2: it deletes the explicit-nonce footgun and the downgrade and renegotiation hazards that made 1.2 fragile [23].
There is one caveat that keeps this from being a victory lap, and it is a good illustration of how deep the "usage" story goes.
The practical upshot is that "constant-time" has quietly become a setting rather than an assumption. On recent Intel cores the mode is called DOITM (Data Operand Independent Timing Mode); on Arm it is the DIT (Data-Independent Timing) processor-state bit. Eric Biggers raised the cross-vendor issue publicly in 2023, and it is the reason security-sensitive code on the newest silicon must ask for timing guarantees rather than inherit them [28, 27].
"Use a vetted AEAD, use hardware AES, patch your handshake" is the whole answer for greenfield code. But engineers inherit constraints -- a fixed nonce source, a distributed system that cannot coordinate a counter, a CPU with no AES instructions. So the real question is rarely "what is best." It is "what are my options, ranked, and exactly when does each one apply?"
7. Closing Each Gap: The Competing Defenses
At two of the three layers a practitioner actually has a choice, and the honest framing is a set of trade-offs, not a single winner. Take the two design spaces in turn.
The side channel: hardware AES-NI versus software bitslicing
These two coexist because they optimize different constraints. Where the CPU has AES instructions, AES-NI is the fastest option and constant-time by construction (subject to the DOIT/DIT caveat from the previous section) [20]. Where it does not -- older cores, small embedded parts -- constant-time bitsliced software gives a verifiable timing guarantee at the cost of speed and implementation effort [19]. The one option that is never acceptable in security code is the original T-table implementation.
| Dimension | T-table AES (broken) | Bitsliced constant-time software | Hardware AES-NI / ARMv8 |
|---|---|---|---|
| Secret-dependent memory access | Yes (about 4 KB of tables) | None (boolean logic) | None (silicon datapath) |
| Timing side-channel resistance | Fails [2, 3] | Constant-time by construction | Data-independent by design; DOIT/DIT mode needed on Ice Lake+/Armv8.4+ [27] |
| Throughput | Fast (pre-attack) | Good when blocks are batched | Fastest; line-rate AEAD |
| Block-parallelism needed | No | Yes (weak for a single block) | No |
| Hardware requirement | None | None | CPU AES instructions |
| Best suited for | Nothing security-sensitive | No-AES-NI or verifiable software | Everything with the instruction |
The nonce: four live strategies
This is the design space where the 2016 scan drew blood, so it deserves the careful table. The four options trade nonce size, streaming ability, and misuse tolerance against each other.
| Dimension | AES-GCM, random 96-bit nonce | AES-GCM, TLS 1.3 counter nonce | AES-GCM-SIV (MRAE) | XChaCha20-Poly1305 |
|---|---|---|---|---|
| Nonce size | 96-bit | 96-bit (derived) | 96-bit | 192-bit |
| Passes | 1 (streaming) | 1 (streaming) | 2 (buffered) | 1 (streaming) |
| On accidental repeat | Catastrophic (leaks ; two collisions give and forgery) | Structurally prevented per connection | Graceful (leaks only message equality) | Catastrophic on a true repeat, but essentially never collides at random |
| Safe budget per key | Under messages [14] | Per-connection sequence, no reuse if the counter is sound | Effectively unbounded against misuse | About random nonces before collision risk |
| Relative speed | Fastest (line rate) | Fastest | About 0.92 cpb on Broadwell, 14-19% slower than OpenSSL GCM [29] | Fast in constant-time software, no AES-NI needed |
| Primitive | AES | AES | AES | ChaCha20 (not AES) |
Read the table as a decision, not a ranking. If you own a reliable per-connection counter, deterministic-nonce AES-GCM is both fastest and safe -- that is what TLS 1.3 does [23]. If you cannot guarantee uniqueness -- distributed writers, stateless functions, restart- or clone-prone systems -- AES-GCM-SIV is the provably strongest answer under misuse, at the price of a second pass and a buffered message [22, 30]. And if AES is not mandated and you just want "a random nonce is always safe," XChaCha20-Poly1305's 192-bit nonce makes accidental collision astronomically unlikely [31] -- a different primitive, included as the most common answer to the nonce footgun rather than as an AES deployment.
Every option here changes how AES is used -- or swaps AES out entirely -- and each buys its safety with a specific cost: a pass, a throughput hit, a hardware dependency, a different primitive. Which makes the honest way to close the technical arc a question about limits: how little does the attacker actually need, and how much can the defender actually guarantee?
8. Theoretical Limits: What Is Provably True on Both Sides
The thesis has two sides, and each has its own provable frontier. The surprise is the asymmetry: the cipher side is essentially closed, and all the hard, unavoidable limits live in the deployment.
The cipher side: the math that did not break
Biclique cryptanalysis is the entire published erosion of the full-cipher security margin. Bogdanov, Khovratovich, and Rechberger reported the first single-key attacks on the full cipher at , , and for AES-128, AES-192, and AES-256 -- with no related-key assumption [1]. Against brute force at , , and , that is a gain of at most roughly 1.6 to 2.3 bits: a factor of a few, not a factor that matters. A "bit" of security is a doubling of attacker work, so shaving 2 bits makes the attack about four times faster than brute force -- still astronomically far from feasible.
| Metric | AES-128 | AES-192 | AES-256 |
|---|---|---|---|
| Brute-force cost | |||
| Best known single-key attack (biclique) | |||
| Margin removed | about 1.9 bits | about 2.3 bits | about 1.6 bits |
| Practical threat | None | None | None |
| Relevance to the field breaks above | Zero | Zero | Zero |
There is no proof that any attack on AES must cost as much as exhaustive search -- concrete block ciphers essentially never come with such a theorem -- so confidence rests on more than two decades of open cryptanalysis since the competition, not on an impossibility result [11]. But the reading is unambiguous, and the authors said it themselves.
The best known attacks on the full AES "do not threaten the practical use of AES in any way." -- Bogdanov, Khovratovich, and Rechberger, 2011 [1]
Notice the defender's column in the table never moves, and key size is irrelevant to every operational break in the sections above. The cipher side is, for practical purposes, a closed question.
The deployment side: where the real limits live
Now the asymmetry. Three provable boundaries constrain real systems, and none of them is about AES's strength:
- The GCM birthday bound. With random 96-bit nonces, collision risk grows by the birthday bound, so NIST caps a single key at fewer than invocations [14]. This is a structural limit of random-nonce GCM, independent of the cipher -- the mathematical reason "just use random nonces at massive scale" eventually fails.
- The AEAD trilemma. No single scheme is simultaneously single-pass and line-rate, fully nonce-misuse-resistant, and large-nonce. GCM gives you the first, GCM-SIV the second, XChaCha the third-and-a-half; you cannot have all three at once [22]. And misuse-resistant AE is provably the strongest possible guarantee once nonces may repeat -- an attacker can always at least detect that the same message was encrypted, and a well-designed SIV scheme leaks nothing more [30].
- ISA-guaranteed whole-machine constant time is impossible in general. The instruction set does not, in general, promise data-independent instruction timing, so even AES and XOR instructions may be data-dependent on recent cores unless the timing mode is enabled [27, 28]. A constant-time algorithm cannot by itself guarantee constant-time execution; part of the guarantee lives below the software, and the general craft of getting it right is the subject of the secure-implementation sibling.
The cipher-secure and system-secure claims are different, and the gap between them is inherent, not accidental. The cipher side has a negligible margin nibble -- under two bits. The deployment side has the real, provable limits: the GCM birthday bound, the single-pass / misuse-resistant / large-nonce trilemma, and the structural impossibility of ISA-guaranteed constant time. Key size buys nothing against any of them.
If the cipher side is closed and the deployment side has hard limits, then the live frontier is wherever those deployment limits are still being hit in the wild. That is not a solved problem. It is an active one.
9. Open Problems: Where AES Still Breaks in the Field
The cipher side is closed; the deployment side is not. Here are the places the same three-layer pattern is still live -- each an operational frontier, consistent with the thesis that the weakest link is the wrapper, not the block.
Guaranteeing nonce uniqueness in distributed, multi-writer, restart-prone systems. This is the exact gap that produced Generation 2: buggy counters and generators on 184 live servers repeated GCM nonces [4]. The best partial answer, MRAE via AES-GCM-SIV, makes a repeat detectable rather than catastrophic [22] -- but the single-pass, fully misuse-resistant, large-nonce scheme the trilemma forbids remains unrealized. In a world of stateless functions, cloned VMs, and shared keys across a fleet, "just keep a counter" is still an unsolved systems problem, not a solved one.
Cross-VM cache side channels in multi-tenant clouds. The 2005-2006 threat model assumed a shared physical machine; virtualization brought it back at scale. Irazoqui, Inci, Eisenbarth, and Sunar recovered AES keys across virtual-machine boundaries using Flush+Reload with memory deduplication [32]. Hardware AES removes the table channel, which is why AES-NI and constant-time code remain load-bearing in 2026. Even instruction timing can be data-dependent on recent cores unless the timing mode is enabled, so cloud tenancy keeps the Generation-1 question open even for hardware AES [28].
Fault and differential-fault attacks. Inducing a computation fault -- through voltage glitching, a laser, or rowhammer-style effects -- can recover an AES key from a handful of faulty ciphertexts [33]. This is again an implementation and hardware failure, not a cipher failure; the depth belongs to the secure-implementation sibling, but it is a live operational locus wherever an attacker has physical or near-physical access.
The long tail of devices without hardware AES. Constant-time software is slower than AES-NI, and the performance gap quietly tempts developers back toward leaky tables on the smallest parts [19]. On many of those devices the pragmatic answer is to ship a constant-time stream cipher such as ChaCha20 instead of fighting AES's software side channels [31].
Formal verification of protocol state machines, so the next KRACK is caught before it ships. TLS 1.3 was co-designed with formal analysis and has verified component implementations, such as those in the HACL* library [34]. Wi-Fi's SAE was not fully immunized: Dragonblood found downgrade, denial-of-service, and side-channel leaks the authors argue are "inherent to Dragonfly," and even patched software remained affected by a novel leak [25]. The state of the art at the protocol layer is better, not finished.
Every open problem here is the same sentence in new clothes: a contract around the permutation is hard to keep in the real world. Which means the practical guide almost writes itself -- it is the thesis made operational, each rule routed to the incident it prevents.
10. What to Do on Monday
Everything above collapses into a short decision procedure and a shorter list of nevers, each rule tied to the incident it prevents.
Diagram source
flowchart TD
S["Deploying AES"] --> Q1{"CPU has AES instructions?"}
Q1 -->|Yes| HW["Use AES-NI or ARMv8 crypto, enable timing mode on newest cores"]
Q1 -->|No| CT["Use constant-time bitsliced software"]
HW --> Q2{"Can you guarantee nonce uniqueness?"}
CT --> Q2
Q2 -->|Yes| GCM["AES-GCM with deterministic nonces, TLS 1.3 style"]
Q2 -->|No| Q3{"Is AES mandated?"}
Q3 -->|Yes| SIV["AES-GCM-SIV, misuse-resistant"]
Q3 -->|No| XC["XChaCha20-Poly1305, 192-bit nonce"] The rules behind the tree:
- Implementation. Use a library that selects AES-NI or ARMv8 crypto at runtime and falls back to constant-time software; never table-based AES in security code; on the newest cores, be aware the data-independent-timing mode may need to be requested [20, 27]. Prevents Generation 1: cache-timing key recovery.
- Mode and nonce. Reliable per-connection counter, as in TLS or QUIC? Use AES-GCM with deterministic nonces [23]. Cannot guarantee uniqueness across restarts, threads, or clones? Use AES-GCM-SIV [22]. Want "a random nonce is always safe" and AES is not mandated? Use XChaCha20-Poly1305 [31]. Never hand-roll a mode, and never choose your own explicit GCM nonce. Prevents Generation 2: nonce reuse and forgery.
- Protocol. Patch WPA2 against key reinstallation or move to WPA3, keep clients updated, and prefer TLS 1.3 over 1.2 [6, 23]. Prevents Generation 3: handshake-driven nonce rewind.
The single highest-value check you can add to code review is a nonce-reuse detector. It is the exact contract the 184 servers violated, and it fits in a few lines.
// Scan a stream of (key, nonce) pairs and flag the first repeat.
function findNonceReuse(records) {
const seen = new Set();
for (const r of records) {
const tag = r.key + "|" + r.nonce;
if (seen.has(tag)) return { reused: true, key: r.key, nonce: r.nonce };
seen.add(tag);
}
return { reused: false };
}
const stream = [
{ key: "k1", nonce: "00000001" },
{ key: "k1", nonce: "00000002" },
{ key: "k1", nonce: "00000001" }, // counter reset after a restart -- the bug
];
console.log(findNonceReuse(stream));
// { reused: true, key: 'k1', nonce: '00000001' } -- catch it in review, not in an incident. Press Run to execute.
Now hold each pitfall up to the mirror. Every one of these confident sentences reproduces a specific, named incident.
| The confident mistake | The incident it reproduces | The fix |
|---|---|---|
| Table-based AES is fine in security code | Bernstein; Osvik-Shamir-Tromer cache timing [2, 3] | AES-NI or constant-time software |
| Repeating a nonce across restarts, threads, or clones is unlikely to matter | The 184-server GCM forgery scan [4] | AES-GCM-SIV or a disciplined counter |
| AES-256 is safer against these attacks | Every break here -- key size is irrelevant [4] | Fix the wrapper, not the key size |
| Constant-time source means constant-time execution | The DOIT/DIT timing caveat [27, 28] | Enable the timing mode where required |
| An unpatched WPA2 handshake is good enough | KRACK [6] | Patch WPA2 or deploy WPA3 |
A one-line reflex for code review
When you review encryption code, find where the nonce comes from and ask exactly one question: can this value repeat across a restart, a fork, a thread, or a clone? If you cannot prove it never repeats, you are reading a latent Generation-2 incident. Reach for AES-GCM-SIV or a 192-bit-nonce AEAD instead of arguing about how improbable a collision seems.
The checklist is short because the lesson is one sentence. Before restating it, clear the handful of confident, wrong sentences that keep this bug alive in design meetings.
11. Frequently Asked Questions
Misconceptions, precisely corrected
Is AES broken?
No. The best publicly known attack on the full cipher, biclique cryptanalysis, costs about operations for AES-128 -- a fraction-of-a-bit improvement over brute force with zero practical impact, and its authors say it does "not threaten the practical use of AES in any way" [1]. Every break in this article happened in a layer around the cipher, not in the cipher.
Were AES keys ever stolen in the field?
Yes -- via cache-timing side channels [2, 3]. But that is not a break of the cipher. The T-table implementation's memory-access pattern leaked the key; the block permutation did not. Swap the leaky tables for a constant-time implementation and the key stops leaking while AES stays byte-for-byte identical. "Unbroken cipher" and "stolen key" are both true at once.
Does one nonce reuse hand over the key?
Be precise here. One reuse immediately leaks through keystream reuse, and it gives one equation for the GHASH subkey . But pinning for reliable universal forgery generally needs at least two collisions [5]. One reuse is already catastrophic -- do not understate it -- but do not say "one reuse recovers the key" either.
Is AES-256 safer against these attacks?
No. Every break here is implementation, mode, or protocol; key size provides no protection against cache timing, nonce reuse, or a reinstalled handshake key [4]. For the nonce-reuse and handshake breaks AES-256 fails exactly as fast as AES-128; for cache timing it is just as vulnerable, though a longer key takes proportionally more leakage to extract. If someone proposes AES-256 as the fix for any incident in this article, they have misdiagnosed the layer.
Did KRACK recover my Wi-Fi key?
No. Against AES-CCMP, KRACK forces nonce-reuse decryption and replay, not AES key recovery [6]. The especially damaging all-zero-key case was an Android and Linux wpa_supplicant implementation bug, not a weakness in AES. No block-math weakness is involved, and no AES key is recovered by the attack itself.
Is a padding-oracle attack an AES break?
No. A padding oracle is a mode-and-validation failure in CBC deployments -- the receiver leaks whether decrypted padding was valid -- and it never touches the AES permutation. It is the same moral as this article (a wrapper broke), in a different deployment, and it is covered in a dedicated padding-oracle sibling. AES itself is not the weak link there either.
Every correction points at the same root: the cipher was never the weak link. Time to say the sentence the whole article was built to earn.
12. To Break AES in the Field, You Never Touch AES
Return to the paradox we opened with, now resolved. The best attack on the full cipher is a fraction-of-a-bit shave with no practical impact [1] -- and yet Wi-Fi sessions were decrypted, HTTPS connections forged, and keys lifted from running servers, because every one of those breaks happened in a wrapper the cipher knows nothing about. The implementation leaked through cache timing [2, 3]. The mode's nonce contract was violated on 184 live servers, weaponizing Joux's decade-old forbidden attack into forgery [4, 5]. The protocol rewound its nonce when a replayed handshake reinstalled a key [6]. Three layers, three field breaks, and the 128-bit block math untouched in all three.
And every fix changed how AES is used, never AES: constant-time code and AES-NI at the implementation, misuse-resistant AEAD and derived nonces at the mode, patched handshakes and WPA3 at the protocol [19, 22, 23, 24]. The cipher is the fixed point; the engineering happened all around it.
A cipher is not a cryptosystem. When your traffic falls, do not ask whether AES broke -- ask which wrapper did: the implementation, the mode, or the protocol.
One last honesty, because the series depends on it. The claim is "almost never," not "never." Scoped to AES, the split is pristine -- the block math never fell in deployment. But some deployed primitives genuinely broke as math: DES's 56-bit key, RC4's keystream biases [12], and the MD5 and SHA-1 collisions [13]. AES has not joined them, and naming the cases where cryptanalysis won is what keeps the thesis honest rather than triumphant.
The cipher was never the weak link -- and no bigger key would have saved a single one of these systems. That is why this is Part 1 of a series about how things break in real life, not a chapter on block-cipher cryptanalysis. The companion piece, How AES Would Break, takes up the other question: what it would take to move the block itself. This one answered the question that actually decrypts traffic. It was never the cipher. It was the wrapper, every time.
Study guide
Key terms
- Block cipher vs. mode of operation
- AES is a keyed permutation on one 16-byte block; a mode (CTR, GCM, CCM) chains it across a whole message and turns it into a cryptosystem.
- Nonce / IV
- A number used once. Counter-based modes require the (key, nonce) pair to be unique per encryption, or the keystream repeats.
- AEAD
- Authenticated Encryption with Associated Data: confidentiality and integrity together, with headers authenticated but not encrypted. GCM and CCM are AEAD modes.
- Keystream reuse
- Identical (key, nonce) yields identical keystream, so the XOR of two ciphertexts equals the XOR of their plaintexts. The key is never touched.
- T-table
- Precomputed lookup tables that fold an AES round into a few reads. A speed optimization whose secret-dependent indices leak through the cache.
- Cache-timing attack
- Recovering a secret from the timing or cache footprint of data-dependent memory access, not from the algorithm output.
- GHASH subkey H
- GCM's authentication secret, the encryption of an all-zero block under the key. A repeated nonce turns tag differences into equations that reveal it.
- Key reinstallation
- Installing an already-in-use key, which rewinds its nonce or packet-number counter and forces keystream reuse. The mechanism KRACK exploits.
- MRAE
- Nonce-misuse-resistant authenticated encryption, such as AES-GCM-SIV, where a repeated nonce leaks only message equality, never the subkey.
References
- (2011). Biclique Cryptanalysis of the Full AES. https://eprint.iacr.org/2011/449 - Best single-key attack on full AES: 2^126.1 / 2^189.7 / 2^254.4; no practical threat. ↩
- (2005). Cache-timing attacks on AES. https://cr.yp.to/antiforgery/cachetiming-20050414.pdf - Remote AES key recovery from the timing of secret-dependent T-table lookups. ↩
- (2006). Cache Attacks and Countermeasures: The Case of AES. https://doi.org/10.1007/11605805_1 - Prime+Probe and Evict+Time cache attacks recover AES keys from T-table access patterns. ↩
- (2016). Nonce-Disrespecting Adversaries: Practical Forgery Attacks on GCM in TLS. https://eprint.iacr.org/2016/475 - 184 live HTTPS servers repeating AES-GCM nonces; Joux forbidden attack weaponized into forgery. ↩
- (2006). Authentication Failures in NIST version of GCM (the forbidden attack). https://csrc.nist.gov/csrc/media/projects/block-cipher-techniques/documents/bcm/comments/800-38-series-drafts/gcm/joux_comments.pdf - A repeated (key, nonce) yields polynomial equations over GF(2^128) recovering the GHASH subkey H. ↩
- (2017). Key Reinstallation Attacks: Forcing Nonce Reuse in WPA2. https://www.krackattacks.com/ - Replaying handshake message 3 resets the AES-CCMP packet-number nonce; decryption/replay, not key recovery. ↩
- (2000). Commerce Department Announces Winner of Global Information Security Competition. https://www.nist.gov/news-events/news/2000/10/commerce-department-announces-winner-global-information-security - Rijndael (Daemen and Rijmen) selected as AES. ↩
- (2000). AES Development project page. https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/archived-crypto-projects/aes-development - AES competition timeline; 128-bit block and 128/192/256-bit keys. ↩
- (1999). Status report on the first round of the development of the AES. https://doi.org/10.6028/jres.104.027 ↩
- (2001). Report on the development of the Advanced Encryption Standard (AES). https://doi.org/10.6028/jres.106.023 ↩
- (2001). FIPS 197: Advanced Encryption Standard (AES). https://csrc.nist.gov/pubs/fips/197/final - The standardized 128-bit-block permutation; 2023 refresh made no technical change. ↩
- (2013). On the Security of RC4 in TLS. https://www.usenix.org/conference/usenixsecurity13/technical-sessions/paper/alfardan - RC4 keystream biases yield plaintext recovery -- a primitive whose math genuinely failed. ↩
- (2017). SHAttered: the first SHA-1 collision. https://shattered.io/ - A genuine break of a hash function math (roughly 2^63 SHA-1 computations). ↩
- (2007). NIST SP 800-38D: Recommendation for Block Cipher Modes of Operation -- GCM and GMAC. https://csrc.nist.gov/pubs/sp/800/38/d/final - GCM nonce-uniqueness requirement; fewer than 2^32 invocations per key with random 96-bit nonces. ↩
- (2008). AES Galois Counter Mode (GCM) Cipher Suites for TLS. https://datatracker.ietf.org/doc/html/rfc5288 - Brought AES-GCM to TLS 1.2; documents the explicit-nonce Counter Reuse warning. ↩
- (2004). NIST SP 800-38C: Recommendation for Block Cipher Modes of Operation -- CCM. https://csrc.nist.gov/pubs/sp/800/38/c/upd1/final - CCM (CTR + CBC-MAC), the basis of AES-CCMP. ↩
- (2004). IEEE Std 802.11i-2004 (WPA2 / AES-CCMP amendment). - The WPA2 4-way handshake and AES-CCMP layer KRACK attacked; referenced by designation. ↩
- (2005). Index of formal scientific papers. https://cr.yp.to/papers.html ↩
- (2009). Faster and Timing-Attack Resistant AES-GCM. https://doi.org/10.1007/978-3-642-04138-9_1 - Bitsliced constant-time AES-GCM: data-independent boolean logic instead of tables. ↩
- (2010). Advanced Encryption Standard (AES) New Instructions Set. https://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf - AES rounds in silicon with no table lookups and data-independent latency. ↩
- (2004). The Security and Performance of the Galois/Counter Mode (GCM) of Operation. https://doi.org/10.1007/978-3-540-30556-9_27 - GCM = AES-CTR + GHASH; security conditioned on a unique (key, nonce). ↩
- (2019). AES-GCM-SIV: Nonce Misuse-Resistant Authenticated Encryption. https://datatracker.ietf.org/doc/html/rfc8452 - A repeated nonce leaks only message equality, never the subkey H. ↩
- (2018). The Transport Layer Security (TLS) Protocol Version 1.3. https://datatracker.ietf.org/doc/html/rfc8446 - Deterministic per-record nonce (sequence number XOR static IV) removes the explicit-nonce footgun. ↩
- (2018). Wi-Fi Alliance introduces security enhancements (WPA3). https://web.archive.org/web/20260626013119/https://www.wi-fi.org/news-events/newsroom/wi-fi-alliance-introduces-security-enhancements - WPA3 announced in 2018 as the structural protocol-layer successor. ↩
- (2019). Dragonblood: Analyzing the Dragonfly Handshake of WPA3 and EAP-pwd. https://eprint.iacr.org/2019/383 - WPA3-SAE side channels the authors argue are inherent to Dragonfly. ↩
- (2009). Related-Key Cryptanalysis of the Full AES-192 and AES-256. https://eprint.iacr.org/2009/317 - Related-key boomerang attacks on full AES-192/AES-256; exist only in the related-key model. ↩
- (2023). Data Operand Independent Timing ISA Guidance. https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/best-practices/data-operand-independent-timing-isa-guidance.html - AES-instruction timing is data-independent only when DOITM is enabled on Ice Lake and later. ↩
- (2023). Data operand dependent timing on Intel and Arm CPUs. https://www.openwall.com/lists/oss-security/2023/01/25/3 - Cross-vendor DOIT/DIT advisory; the source for the Arm DIT facility. ↩
- (2015). GCM-SIV: Full Nonce Misuse-Resistant Authenticated Encryption at Under One Cycle per Byte. https://eprint.iacr.org/2015/102 - 0.92 cpb on Broadwell; 14-19% slower than OpenSSL GCM. ↩
- (2006). Deterministic Authenticated-Encryption: A Provable-Security Treatment of the Key-Wrap Problem. https://eprint.iacr.org/2006/221 - Defines DAE / SIV / MRAE and its optimality under nonce misuse. ↩
- (2020). XChaCha: eXtended-nonce ChaCha and AEAD_XChaCha20_Poly1305. https://datatracker.ietf.org/doc/draft-irtf-cfrg-xchacha/ - 192-bit nonce; random nonces essentially never collide. ↩
- (2014). Wait a Minute! A fast, Cross-VM Attack on AES. https://doi.org/10.1007/978-3-319-11379-1_15 - Cross-VM cache attack recovers AES keys across VM boundaries. ↩
- (2003). A Differential Fault Attack Technique against SPN Structures, with Application to the AES and Khazad. https://doi.org/10.1007/978-3-540-45238-6_7 - Differential fault analysis recovers the AES key from about two faulty ciphertexts. ↩
- (2017). HACL*: A Verified Modern Cryptographic Library. https://eprint.iacr.org/2017/536 - Formally verified, timing-mitigated primitives. ↩