CSEC3616Cybersecurity Engineering

    Modes of operation

    How ECB, CBC, CFB, OFB and CTR turn one block cipher into something that can encrypt a whole message, and what breaks when a mode's IV or nonce requirement is ignored.

    • Explain why a block cipher needs a mode of operation before it can encrypt more than one block.
    • State ECB's pattern-leakage failure and why it is not used in practice.
    • State CBC's IV requirement and explain how WEP's 24-bit IV broke it in practice.
    • Describe CFB, OFB and CTR, and state which of the five modes can be parallelised.
    • Trace what one flipped ciphertext bit does to CBC decryption, block by block.

    20 min read

    Intuition

    A block cipher only defines how to scramble one fixed-size block: 64 bits for DES, 128 for AES. Every real message is longer than that. A mode of operation is the rule for using that one-block operation, over and over, to encrypt a message of arbitrary length. The obvious rule, encrypt every block the same way, is not automatically safe: a deterministic function given the same input twice always produces the same output twice.

    Mechanism

    Electronic Codebook (ECB) is that obvious rule. Each plaintext block is encrypted independently, with no connection between blocks at all:

    Formula

    ECB

    Ci=Ek(Pi)C_i = E_k(P_i)
    PiP_i
    plaintext block i
    CiC_i
    ciphertext block i
    EkE_k
    the block cipher's encryption function under key k

    Electronic Codebook (ECB) — each block encrypted independently

    ECB — Electronic Codebook modeP1Enc_kC1P2Enc_kC2P3Enc_kC3no chaining — identical Pᵢ ⇒ identical Cᵢ

    ECB has no chaining and no IV: identical plaintext blocks always produce identical ciphertext blocks, which is why it leaks patterns (a plaintext image's outline survives encryption) and is not used in practice.

    Mechanism

    Because EkE_k is deterministic, two identical plaintext blocks under the same key always produce two identical ciphertext blocks. Real plaintext has repeating structure constantly: a run of the same byte in a file, or a large flat-coloured region of an image, generates the same plaintext block over and over, and ECB maps every one of those repeats to the same ciphertext block. The notes’ own illustration of this, an image encrypted block by block under ECB (Figure 15, “ECB Encryption Example”), shows exactly that failure: the image’s large repeated regions still show up as visibly repeated ciphertext, so the outline of the original picture survives “encryption” even though no individual pixel value can be read off directly. The figure itself did not survive PDF extraction, so it is not reproduced here, but the mechanism behind it is exactly the formula above: Pi=PjCi=CjP_i = P_j \Rightarrow C_i = C_j, for any two blocks encrypted under the same key.

    ECB has no IV and no chaining, which is also why it is trivially parallelisable, and why, beyond teaching this exact problem, it is not used.

    Threat

    Under ECB, identical plaintext blocks always encrypt to identical ciphertext blocks under the same key. An attacker who never recovers the key can still read the plaintext’s block-level structure directly off the ciphertext, which blocks repeat, where, and how often, enough to recover an image’s outline or a file’s large-scale layout without decrypting a single block.

    Control

    Make every block’s input differ even when two plaintext blocks are identical, by combining each block with something that changes: the previous ciphertext block, an encrypted counter, or a keystream built the same way. Every mode on the rest of this page exists specifically to close this gap.

    Mechanism

    Cipher Block Chaining (CBC) is the direct fix. Each plaintext block is XORed with the previous ciphertext block before encryption, so the input to EkE_k changes even when two plaintext blocks are identical:

    Formula

    CBC encrypt

    Ci=Ek(PiCi1)C_i = E_k(P_i \oplus C_{i-1})
    Pi,CiP_i, C_i
    plaintext and ciphertext block i
    Ci1C_{i-1}
    the previous ciphertext block, or the IV when i = 0

    Formula

    CBC decrypt

    Pi=Dk(Ci)Ci1P_i = D_k(C_i) \oplus C_{i-1}
    DkD_k
    the block cipher's decryption function under key k
    Ci,Ci1C_i, C_{i-1}
    the current and previous ciphertext blocks

    Mechanism

    The first block has no previous ciphertext to chain from, so it is XORed with an initialization vector (IV) instead: a value generated fresh for each message and used in place of C1C_{-1}. The IV does not need to be kept secret. It is usually sent alongside the ciphertext, because decryption needs it to reconstruct P0P_0: what protects the scheme is not the IV’s secrecy but its uniqueness.

    Cipher Block Chaining (CBC) — each block XORed with the previous ciphertext

    CBC — Cipher Block Chaining modeIVP1Enc_kC1feeds forwardP2Enc_kC2feeds forwardP3Enc_kC3

    Each plaintext block is XORed with the previous ciphertext block before encryption; the first block is XORed with an IV instead. The IV need not be secret, but must never repeat under the same key, or identical plaintext prefixes produce identical ciphertext again.

    Threat

    Reusing an IV under the same key regenerates the exact same P0IVP_0 \oplus \text{IV} input for any two messages that start with the same plaintext block, so those two messages encrypt to the same first ciphertext block, the identical-plaintext-identical-ciphertext failure ECB has, reappearing at the message level instead of the block level.

    Control

    Never reuse an IV under the same key. Generate a fresh IV, random or otherwise guaranteed not to repeat, for every message encrypted under that key. The IV’s job is to make each message’s encryption path unique, not to hide anything.

    Exam detail

    Wired Equivalent Privacy (WEP) is the lecture’s worked case of an IV-reuse failure in the wild. WEP encrypted wireless traffic with RC4, a stream cipher, by combining a secret key with a 24-bit IV. The same uniqueness requirement applies to a stream cipher’s IV as to CBC’s. 2242^{24} is small enough that on a busy network, IVs start repeating quickly. Once an attacker captures two packets encrypted under the same IV and key, RC4 produces the same keystream both times. Where the attacker knows or can guess part of one plaintext, such as a protocol header, they can strip the keystream off directly and start recovering the other plaintext; enough repeated-IV captures let them work back to the secret key itself.

    Mechanism

    The slides name two further modes, Cipher Feedback (CFB) and Output Feedback (OFB), grouped with CTR under “Other Block Modes,” but the extracted slide text carries only the three names next to diagram placeholders; the actual construction did not survive PDF extraction, in the cleaned notes or in the raw text dump. Both turn the block cipher into a stream cipher by using only its encrypt direction, even to decrypt. The standard construction, from the same Stallings textbook both the notes and slides cite for this section, is:

    CFB: Oi=Ek(Ci1)O_i = E_k(C_{i-1}), then Ci=PiOiC_i = P_i \oplus O_i, with C1C_{-1} replaced by the IV. Each block’s keystream is built by encrypting the previous ciphertext block.

    OFB: Oi=Ek(Oi1)O_i = E_k(O_{i-1}), then Ci=PiOiC_i = P_i \oplus O_i, with O1O_{-1} replaced by the IV. Each block’s keystream is built by encrypting the previous keystream output, never the ciphertext.

    The difference shows up in how a corrupted ciphertext block behaves on decryption. In CFB, a bit error in CiC_i changes PiP_i by exactly that bit, since PiP_i XORs straight against a keystream. The tampered CiC_i then feeds into Oi+1=Ek(Ci)O_{i+1} = E_k(C_i), so block i+1i+1‘s keystream comes out unrelated to the honest one and Pi+1P_{i+1} is garbled completely. In OFB, the keystream never depends on the ciphertext at all, so a bit error in CiC_i changes only PiP_i‘s matching bit and affects nothing else.

    Mechanism

    Counter (CTR) mode solves a different problem. CBC’s chaining is inherently sequential: block ii needs block i1i-1‘s ciphertext before it can be encrypted, so CBC cannot be parallelised. CTR builds a keystream instead of chaining ciphertext: a nonce is combined with a counter that increments once per block, and that combination is encrypted to produce each block’s keystream, then XORed with the plaintext.

    Formula

    CTR keystream

    Ci=PiEk(noncei)C_i = P_i \oplus E_k(\text{nonce} \Vert i)
    ii
    the per-block counter value, incremented once per block
    nonce\text{nonce}
    a value combined with the counter, never reused under the same key
    Ek(noncei)E_k(\text{nonce}\Vert i)
    the keystream block for position i

    Every block's keystream depends only on the nonce and its own counter value, never on another block's ciphertext.

    Counter (CTR) — a keystream from the nonce and counter, XORed with plaintext

    CTR — Counter modeNonce ‖ Ctr=1Enc_kP1C1keystreamNonce ‖ Ctr=2Enc_kP2C2keystreamNonce ‖ Ctr=3Enc_kP3C3keystreamno chaining — a distinct counter per block lets CTR run in parallel

    A nonce concatenated with a per-block counter is encrypted to build a keystream, which is then XORed with the plaintext — encryption becomes a stream cipher built from a block cipher. Blocks no longer depend on each other, so CTR parallelises where CBC cannot.

    Mechanism

    Because block ii‘s keystream depends only on the nonce and ii itself, not on any other block’s ciphertext, every block’s keystream can be computed independently, and in parallel, unlike CBC. The nonce plays the same role the IV plays elsewhere: it does not need to be secret, but reusing it under the same key is fatal.

    Threat

    Reusing a nonce (with the same counter value) under the same key regenerates the exact same keystream block for that position. If an attacker XORs the two resulting ciphertexts together, the keystream cancels out entirely, leaving the XOR of the two plaintexts, and from there, known- or guessable-plaintext techniques recover both messages.

    Control

    Never reuse a nonce-and-counter pair under a given key. In practice: draw a fresh nonce per message, whether random or a counter that is never reset while the key stays the same, and never re-encrypt under a nonce that has already been used with that key.

    Recall

    ECB, CBC and CTR are all built from the same underlying block cipher. Why does only CTR let every block be encrypted in parallel, without also having ECB's pattern-leakage problem?

    CTR’s keystream for block i, Ek(noncei)E_k(\text{nonce} \Vert i), depends only on the nonce and that block’s own counter value: nothing from any other block, and nothing that repeats across identical plaintext blocks either, since the counter changes every time. ECB is also parallelisable, but only because it has no chaining at all, which is exactly what makes it leak patterns. CBC’s input to block i is PiCi1P_i \oplus C_{i-1}, so block i cannot be encrypted until block i-1’s ciphertext exists, forcing it to run in sequence.

    Mechanism

    Tutorial 4 asks what happens when one byte of a CBC ciphertext is corrupted before decryption. The chaining structure above makes the answer fall out algebraically, one block at a time.

    Worked example

    AnswerBlock i's plaintext comes out unrelated to the original; block i+1's plaintext differs by exactly the flipped bit; every block from i+2 onward decrypts correctly.

    1. Start from the honest decryption of two consecutive blocks: Pi=Dk(Ci)Ci1P_i = D_k(C_i) \oplus C_{i-1} and Pi+1=Dk(Ci+1)CiP_{i+1} = D_k(C_{i+1}) \oplus C_i.
    2. An attacker flips one bit of ciphertext block ii only. Call the flipped bit Δ\Delta, an 8-bit string with a single 1, for example Δ=00001000\Delta = 00001000 for bit 3. The tampered block is Ci=CiΔC_i' = C_i \oplus \Delta. Every other ciphertext block, including Ci1C_{i-1} and Ci+1C_{i+1}, is untouched.
    3. Block ii. Decryption now computes Pi=Dk(Ci)Ci1=Dk(CiΔ)Ci1P_i' = D_k(C_i') \oplus C_{i-1} = D_k(C_i \oplus \Delta) \oplus C_{i-1}. DkD_k is the full block cipher’s decryption function, not a bitwise operation: every block cipher is built so that changing one input bit changes roughly half the output bits, unpredictably (the avalanche property). Dk(CiΔ)D_k(C_i \oplus \Delta) bears no simple relationship to Dk(Ci)D_k(C_i), so PiP_i' comes out unrelated to the true PiP_i: block ii is garbled.
    4. Block i+1i+1. Decryption computes Pi+1=Dk(Ci+1)CiP_{i+1}' = D_k(C_{i+1}) \oplus C_i'. Ci+1C_{i+1} itself was never touched, so Dk(Ci+1)D_k(C_{i+1}) is exactly what it was before the tamper. Call that value KK. By definition Pi+1=KCiP_{i+1} = K \oplus C_i, so K=Pi+1CiK = P_{i+1} \oplus C_i.
    5. Substitute Ci=CiΔC_i' = C_i \oplus \Delta and the expression for KK: Pi+1=KCi=(Pi+1Ci)(CiΔ)=Pi+1(CiCi)Δ=Pi+1ΔP_{i+1}' = K \oplus C_i' = (P_{i+1} \oplus C_i) \oplus (C_i \oplus \Delta) = P_{i+1} \oplus (C_i \oplus C_i) \oplus \Delta = P_{i+1} \oplus \Delta. The two CiC_i terms cancel, since xx=0x \oplus x = 0, leaving exactly the flipped bit.
    6. A concrete check with illustrative bytes, not tied to any specific message: let Ci=10110100C_i = 10110100. Flipping bit 3 gives Δ=00001000\Delta = 00001000 and Ci=1011010000001000=10111100C_i' = 10110100 \oplus 00001000 = 10111100. Let Pi+1=01100101P_{i+1} = 01100101, so K=Pi+1Ci=0110010110110100=11010001K = P_{i+1} \oplus C_i = 01100101 \oplus 10110100 = 11010001. Then Pi+1=KCi=1101000110111100=01101101P_{i+1}' = K \oplus C_i' = 11010001 \oplus 10111100 = 01101101. Directly, Pi+1Δ=0110010100001000=01101101P_{i+1} \oplus \Delta = 01100101 \oplus 00001000 = 01101101, the same value both ways, confirming block i+1i+1 differs from the honest plaintext in exactly bit 3 and nowhere else.
    7. Block i+2i+2 and beyond. Pi+2=Dk(Ci+2)Ci+1P_{i+2} = D_k(C_{i+2}) \oplus C_{i+1} uses only Ci+1C_{i+1} and Ci+2C_{i+2}, neither of which the tamper touched. Every block from i+2i+2 onward decrypts exactly as if nothing had happened.

    Aside

    This is worked through in the abstract, with Δ\Delta standing for one flipped bit and made-up illustrative bytes for the block-i+1i{+}1 check, deliberately not with Tutorial 4’s own ciphertext. Tutorial 4’s solutions have not been released, and its specific scenario is for the reader to work through directly, using the mechanism established above.

    Mechanism

    Try it directly: set the mode to CBC below, encrypt a few blocks, then flip one bit of one ciphertext block and decrypt. The trace shows exactly this pattern: one block garbled, the next block off by one bit, everything after untouched. Switching the mode to ECB or CTR and repeating the same tamper shows the contrast Tutorial 4 is really asking about: ECB confines the damage to the one tampered block and nothing else, while CTR flips exactly the targeted bit in that one block only, with no effect on any other block.

    Block mode visualiser

    Trace ECB, CBC, CFB, OFB and CTR block by block, then flip one ciphertext bit and see which plaintext blocks it corrupts.

    Teaching model — an 8-bit toy cipher, not real encryption. The mode is what is under test here, not the cipher.

    BlockPlaintextInputOutputCiphertextChain in

    Compare

    Sequential: block ii needs block i1i-1‘s ciphertext before it can be encrypted, so CBC cannot be parallelised. A flipped ciphertext bit garbles the block it is in, and flips exactly one bit of the next block; blocks after that decrypt correctly.

    Independent: block ii‘s keystream depends only on the nonce and ii, so every block can be encrypted or decrypted in parallel. A flipped ciphertext bit changes exactly that one bit of that one block’s plaintext, and nothing else. There is no next-block effect at all.

    Exam detail

    The full picture, across all five modes, on the four properties the exam actually asks about:

    ModeParallelisableOne flipped ciphertext bitNeedsLeaks patterns
    ECBYes, no chaining at allGarbles that one block entirely; nothing else affectedNothingYes
    CBCNo, sequential chainGarbles the tampered block; flips exactly one bit of the next blockAn IV, never reusedNo
    CFBNo, sequential chainFlips exactly one bit of that block; garbles the next block entirelyAn IV, never reusedNo
    OFBNo, keystream generation is sequentialFlips exactly one bit of that block; no effect on later blocksAn IV, never reusedNo
    CTRYes, every block’s keystream is independentFlips exactly one bit of that block; no effect on any other blockA nonce, never reusedNo

    Every row after ECB pays for its safety with something ECB does not need: an IV or nonce that must never repeat under the same key. That trade is what “distinguish between the modes” is really testing, not which one is fastest, but which properties each buys and at what cost.

    Pitfall

    Do not write that CBC “can’t be parallelised” as though this were unique to it among the chained modes. CFB shares it, since each block’s keystream is built by encrypting the previous ciphertext block. Only ECB (because it has no chaining) and CTR (because each block’s keystream depends only on its own counter) can run every block at once. ECB pays for that with the pattern-leakage failure this page opens with.