Chapter 05 · Modes of operation
One block is not enough: ECB, CBC, CTR, GCM
AES encrypts sixteen bytes. Everything else (how to chain blocks, where the randomness goes, how to detect tampering) is the job of the mode of operation, and that is where most real-world breaks happen: patterns that show through, padding oracles, reused nonces, ciphertexts an attacker can edit.
In this chapter
A block cipher is a beautiful object with a small job: it maps 16 bytes to 16 bytes under a key. Real messages are longer, have arbitrary lengths, and are sent many times under the same key. A mode of operation turns the block cipher into a cipher for messages. Choosing it badly can undo all the work of the previous chapter: the strongest AES in a weak mode is a weak cipher.
ECB: the codebook
The naive mode, electronic codebook, cuts the message into blocks and encrypts each one on its own: . It is a gigantic codebook with entries, and it has the flaw of every codebook: equal plaintext blocks give equal ciphertext blocks. Whatever repeats in the plaintext repeats in the ciphertext.
No deterministic encryption scheme, in which the same message under the same key always gives the same ciphertext, can be semantically secure against an adversary who sees several ciphertexts: encrypting the same message twice is visible. Secure encryption must be randomised (a fresh random IV) or stateful (a counter, a nonce that never repeats).
ECB still appears in the wild. In 2013 a leak of 153 million Adobe passwords, encrypted with triple DES in ECB mode, let researchers find the most common passwords by counting identical ciphertexts and reading the users' password hints next to them. The desktop app offers ECB for compatibility with cryptoKit 1.0 and marks it in red.
CBC: chaining with an IV
Cipher block chaining, patented by Ehrsam, Meyer, Smith and Tuchman at IBM in 1976 and standardised with DES in 1980, XORs each plaintext block with the previous ciphertext block before encrypting it; the first block is XORed with an initialisation vector:
Equal plaintext blocks now give different ciphertext blocks, because what goes into is different each time. The IV must be unpredictable: TLS 1.0 used the last ciphertext block of the previous message as the next IV, and in 2011 the BEAST attack used that predictability to decrypt cookies. The IV is not secret; it travels in front of the ciphertext, which is what the desktop app does when you leave the IV field empty.
Padding
CBC encrypts whole blocks, so the message is padded. The standard scheme, PKCS#7, adds bytes of value , from 1 to 16; a message that already fills its last block gets a whole extra block of sixteen 16s, so that the padding can always be removed unambiguously.
Padding became a weapon. In 2002 Serge Vaudenay showed that if a server reveals whether the padding of a decrypted message is valid (by an error message, or just by taking longer), an attacker can decrypt any ciphertext, one byte at a time, by sending modified versions: a padding oracle. Variants broke ASP.NET in 2010, TLS in 2013 (Lucky Thirteen) and SSL 3.0 in 2014 (POODLE). CBC is not broken, but it is very easy to use insecurely.
CTR: a block cipher becomes a stream cipher
Counter mode, proposed by Diffie and Hellman in 1979, encrypts successive values of a counter and XORs the results with the message:
It needs no padding, it is parallel (every block can be computed independently, on every core) and it only uses the encryption direction of the cipher. It is a stream cipher: a pseudorandom keystream XORed with the data, the computational version of the one-time pad. And it inherits the one rule of the one-time pad.
If two messages are encrypted in CTR mode with the same key and the same nonce, then : the keystream cancels, and the attacker is back to the two-time pad.
Encryption is not integrity
CTR has a second property that surprises many people: it is malleable. Flipping a bit of the ciphertext flips exactly the same bit of the decrypted plaintext. An attacker who knows (or guesses) part of a message can change it into anything of the same length without knowing the key: decrypts to . CBC is malleable too, in a slightly messier way.
So confidentiality is not enough: real systems need authenticated encryption. One way is to add a message authentication code. The order matters.
If the encryption scheme is secure against chosen-plaintext attacks and the MAC is strongly unforgeable, then encrypt-then-MAC (encrypt, then authenticate the ciphertext) gives authenticated encryption, secure against chosen-ciphertext attacks. MAC-then-encrypt and encrypt-and-MAC do not in general.
SSH used encrypt-and-MAC, TLS used MAC-then-encrypt (hence the padding oracles), IPsec used encrypt-then-MAC. Rather than leaving the composition to each protocol, cryptographers designed modes that do both at once: AEAD, authenticated encryption with associated data.
GCM: counter mode with a polynomial
Galois/Counter Mode, by David McGrew and John Viega (2004, NIST SP 800-38D in 2007), encrypts with CTR and authenticates with GHASH, a polynomial evaluated in the field . With the hash key and the ciphertext blocks (and associated data) ,
and the 16-byte tag is , where is derived from the nonce. Two different messages give two different polynomials, and a polynomial of degree has at most roots, so a forgery succeeds with probability at most about . Associated data (a header, a packet number, a database row id) is authenticated but not encrypted: it cannot be changed without being detected.
GCM is fast (processors have carry-less multiplication instructions for GHASH), parallel, and the default of TLS 1.3. It is also unforgiving: if a nonce is ever reused, the attacker can solve for (Antoine Joux's “forbidden attack”, 2006) and forge any message. A 2016 Internet scan found 184 HTTPS servers repeating GCM nonces. With 96-bit random nonces, NIST limits a key to messages. The desktop app generates a random nonce unless you type one, and warns you if you do.
ChaCha20-Poly1305
Not every processor has AES instructions; phones in the early 2010s did not, and software AES is slow and leaks through cache timing. Daniel J. Bernstein's ChaCha20 (2008) is a stream cipher built only from 32-bit additions, rotations and XORs (“ARX”), fast and naturally constant-time in software; Poly1305 (2005) is a one-time authenticator that evaluates a polynomial modulo the prime . Together, as standardised in RFC 7539 (2015) and RFC 8439, they form an AEAD used by TLS 1.3, SSH, WireGuard and Google's QUIC. Both AES-GCM and ChaCha20-Poly1305 are marked as recommended in the desktop app.
Which mode?
| Mode | What it gives | What to watch |
|---|---|---|
| ECB | nothing beyond one block | never for data: patterns show |
| CBC | confidentiality | unpredictable IV; padding oracles; add a MAC |
| CTR | confidentiality, parallel | never reuse a nonce; malleable; add a MAC |
| GCM | authenticated encryption | never reuse a nonce |
| ChaCha20-Poly1305 | authenticated encryption | never reuse a nonce |
Further reading
- Serge Vaudenay, “Security Flaws Induced by CBC Padding”, EUROCRYPT 2002.
- Mihir Bellare and Chanathip Namprempre, “Authenticated Encryption: Relations among Notions and Analysis of the Generic Composition Paradigm”, ASIACRYPT 2000.
- David McGrew and John Viega, “The Galois/Counter Mode of Operation (GCM)” (2004); NIST SP 800-38D (2007).
- Yoav Nir and Adam Langley, RFC 8439, ChaCha20 and Poly1305 for IETF Protocols (2018).