Chained Forgery
A service applies plain CBC-MAC to messages of different lengths without binding the length or domain. Use known one-block states to construct an accepted two-block message.
Objective
- Model CBC-MAC chaining across block boundaries.
- Explain why variable-length inputs require a safe construction or separation.
Before you begin
Open /challenge/insane/cbc-mac, fetch the public vectors, and review hexadecimal.
Concepts
With a zero IV, a one-block tag is the chaining state after that block. A carefully chosen next block can cancel the first state and make encryption begin from another known one-block input.
Plain CBC-MAC starts from a fixed initial state and repeatedly combines a message block with the previous state before block encryption. The final state is the tag. Security for fixed-length messages does not automatically carry over to variable-length inputs. Use a standard construction such as CMAC or HMAC for variable-length messages, with all relevant context authenticated.
Suggested tools
- Python: Hex-decode fixed 16-byte values, XOR byte strings, and re-encode the result without altering block boundaries.
Tool practice
Rehearse the worked tool exercise before using challenge data.
Decode each vector with bytes.fromhex and check its length before XOR. XOR pairs byte positions; concatenation appends blocks. The known one-block message is the required first block of the submitted message. Keep a table of block input, incoming state, and outgoing state.
Investigation
Rehearse XOR and block lengths locally
left = bytes.fromhex("1020")
right = bytes.fromhex("0102")
assert len(left) == len(right)
mixed = bytes(a ^ b for a, b in zip(left, right))
print(mixed.hex(), len(mixed)) # 1122 2
print((left + right).hex()) # 10200102
XOR combines corresponding bytes; + concatenates them. zip silently stops at the shorter input, so check equal lengths first. The two-byte practice inputs are unrelated to the game's block size.
Trace CBC-MAC with S0 = 0 and Si = E_K(Mi XOR S(i-1)). A one-block tag is S1; a two-block tag is S2. The same deterministic block operation maps the same input to the same output. Mark the input after XOR in each row before reasoning about the next block. This exercise uses a toy block operation; the lesson transfers to CBC-MAC chaining, not to breaking a production cipher.
Observe
Record both known messages, their tags, the required 32-byte length, and the required first block.
Form a hypothesis
Can the chaining state after one known message be used to connect to another known message without knowing the MAC key?
Test carefully
Construct exactly two blocks beginning with the required message. Submit its hex plus the known target tag once.
Progressive hints
Hint 1
Track the state entering each block-encryption step.
Hint 2
Ask what block would make a known incoming state reach another known input.
Hint 3
Check the required prefix and exact byte length before one submission.
Troubleshooting and reset
Check that every decoded value is 16 bytes and the forged message is 32 bytes. Hex output should have no 0x, spaces, or separators.