CBC Mode and PKCS#7 Padding

AES-CBC decrypts each block as P[i] = AES⁻¹(C[i]) ⊕ C[i−1]. The last block must end with valid PKCS#7 padding. An implementation that tells you whether padding is valid — even just via an error code — is a padding oracle.

CBC Decryption Flow

The padding check at the end is the oracle. An HTTP 200 vs 500, a TLS alert code, or even a measurable timing difference — all are sufficient to mount the full attack.

PKCS#7 Padding Rules

If n bytes of padding are needed, all n bytes must equal n. A full block of padding (n = 16) is always appended if plaintext fits exactly.

Valid Padding

Invalid Padding

The Oracle

HTTP HTTP 200 = Valid HTTP 500 = Invalid
TLS Handshake Alert = Valid Bad Record MAC = Invalid
Timing Faster response = Valid Slower response = Invalid

The oracle need not be explicit. Any distinguishable behavior (response time, error message content, error code) leaks one bit per query. That one bit, iterated, decrypts everything.