Goals of Cryptography Cryptography = Cryptology + Cryptanalysis Objectives: Security: Encryption systems: Symmetric (AES) Asymmetric (RSA, ECC, CRYSTALS-KYBER) Privacy Integrity: Hash functions Message Authentication Codes (MACs) Digital Signatures (digital certificates) Authentication Non-repudiation (Accountability) Availability AES (Rijndael) Basics Block size: 128 bits (state = $4 \times 4$ bytes). Key size: 128/192/256 bits; number of rounds = 10/12/14. Byte-oriented SPN (not Feistel). Round operations (encryption): SubBytes ($S$), ShiftRows, MixColumns, AddRoundKey. Last round omits MixColumns. AES Operations SubBytes: non-linear byte substitution via S-box derived from inversion in $GF(2^8)$ followed by an affine transformation. ShiftRows: row $i$ of the state is cyclically shifted left by $i$ bytes ($i=0, 1, 2, 3$) for diffusion. MixColumns: linear diffusion by multiplying each state column by a fixed MDS matrix over $GF(2^8)$. AddRoundKey: XORs the state with the round key; its own inverse. Round structure: Substitution-permutation network (SPN) with SubBytes $\rightarrow$ ShiftRows $\rightarrow$ MixColumns $\rightarrow$ AddRoundKey providing confusion and diffusion each round. AES SubBytes Overview (Substitution) SubBytes introduces non-linearity in AES. Each byte of the $4 \times 4$ state matrix is independently replaced by an S-box value. Examples: $S(0x00) = 0x63$, $S(0x53) = 0xED$, $S(0x19) = 0xD4$. AES Inverse SubBytes (Inverse Substitution) Examples: $S(0x63) = 0x00$, $S(0xED) = 0x53$, $S(0xD4) = 0x19$. AES ShiftRows Transformation ShiftRows rules: Row 0: no shift. Row 1: 1 byte left cyclic shift. Row 2: 2 bytes left cyclic shift. Row 3: 3 bytes left cyclic shift. AES Inverse ShiftRows Transformation Inverse ShiftRows rules: Row 0: no shift. Row 1: 1 byte right cyclic shift. Row 2: 2 bytes right cyclic shift. Row 3: 3 bytes right cyclic shift. AES MixColumns Transformation Multiplication in $GF(2^8)$ with irreducible polynomial $x^8 + x^4 + x^3 + x + 1$. AES AddRoundKey Transformation Each byte of the state matrix is XORed with the corresponding byte of the round key. This is the only step where the 128-bit round key directly enters the AES round. The same operation is used in both encryption and decryption. The $\oplus$ symbol denotes XOR, which is the same in both encryption and decryption. AES Key Schedule Purpose: Expand a short cryptographic key into multiple round keys. AES supports 128, 192, or 256-bit key sizes. The key is expanded into an array of 32-bit words: $\{W[1], W[2], ..., W[n-1]\}$. Number of rounds $N_r$ and expanded words: AES-128: $N_r = 10$, expanded key $n = 44$ words. AES-192: $N_r = 12$, expanded key $n = 52$ words. AES-256: $N_r = 14$, expanded key $n = 60$ words. Round keys = groups of 4 words (128 bits). Three core functions: RotWord: cyclically shifts a 4-byte word. SubWord: applies the S-box to each byte. Rcon: round constant $\{02^{i-1}, 00, 00, 00\}$ in $GF(2^8)$. Modes of Operation: Classification and Status Confidentiality only (legacy): ECB, CBC, CFB, OFB, CTR. Authenticated Encryption (AEAD): GCM/GMAC, CCM, SIV family (e.g., AES-GCM-SIV). Storage only: XTS-AES (no integrity, sector tweakable). Format Preserving Encryption (FPE): FF1, FF3-1 (specialized use). Modes of Operation: ECB, CBC, CFB, OFB, CTR in 2025 Legacy/Pedagogical: ECB: leaks patterns; do not use. CBC: vulnerable to padding oracles unless carefully paired with a MAC; not parallelizable on encryption. CFB/OFB: stream-like; rarely justifiable over modern AEAD. Still useful: CTR: good building block; but must be paired with MAC/AEAD. Easily parallelizable; careful counter management. Modes of Operation: AEAD Choices AES-GCM: fastest with AES-NI/ARMv8 crypto extensions; requires unique 96-bit nonce. AES-GCM-SIV: abuse-resistant (safe against nonce reuse with the same key); deterministic by (key, nonce, AAD, PT). CCM: used in constrained environments (e.g., 802.15.4); longer authentication latency. General AEAD Structure Guarantees: Confidentiality (encryption of plaintext). Integrity/Authentication (verification of ciphertext + AAD). Inputs: $K$: secret key $N$: nonce/IV $A$: associated data (authenticated but not encrypted) $P$: plaintext Outputs: $C$: ciphertext $T$: authentication tag AES-CTR Mode: Pseudocode # Encryption def AES_CTR_Encrypt(K, N, P): C = [] for i, block in enumerate(split_blocks(P)): counter = N || int_to_bytes(i) # Concatenate nonce and counter keystream = AES_Encrypt(K, counter) C_block = block ⊕ keystream C.append(C_block) return concat(C) # Decryption def AES_CTR_Decrypt(K, N, C): P = [] for i, block in enumerate(split_blocks(C)): counter = N || int_to_bytes(i) keystream = AES_Encrypt(K, counter) P_block = block ⊕ keystream P.append(P_block) return concat(P) AES-CCM: Pseudocode # CCM = CTR + CBC-MAC def AES_CCM_Encrypt(K, N, A, P): T = CBC_MAC(K, N, A, P) # Compute authentication tag C = AES_CTR_Encrypt(K, N, P) return (C, T) def AES_CCM_Decrypt(K, N, A, C, T): P = AES_CTR_Decrypt(K, N, C) T_check = CBC_MAC(K, N, A, P) if T_check != T: raise AuthenticationError return P AES-GCM-SIV: Pseudocode # Deterministic, abuse-resistant variant def AES_GCM_SIV_Encrypt(K, N, A, P): S = POLYVAL(K, A || P) # Compute synthetic IV C = AES_CTR_Encrypt(K, S, P) T = S return (C, T) def AES_GCM_SIV_Decrypt(K, N, A, C, T): P = AES_CTR_Decrypt(K, T, C) S_check = POLYVAL(K, A || P) if S_check != T: raise AuthenticationError return P AES-GCM: Pseudocode def AES_GCM_Encrypt(K, N, A, P): H = AES_Encrypt(K, 0^128) # GHASH key C = AES_CTR_Encrypt(K, N, P) # CTR encryption mode T = GHASH(H, A, C) ⊕ AES_Encrypt(K, N) return (C, T) def AES_GCM_Decrypt(K, N, A, C, T): H = AES_Encrypt(K, 0^128) P = AES_CTR_Decrypt(K, N, C) T_check = GHASH(H, A, C) ⊕ AES_Encrypt(K, N) if T_check != T: raise AuthenticationError return P GHASH: Polynomial Hash Function for AES-GCM Purpose: GHASH computes an authentication tag on the ciphertext and AAD in AES-GCM. It operates in the finite field $GF(2^{128})$. Inputs: $H$: hash subkey ($H = AES_K(0^{128})$) $A$: associated data $C$: ciphertext Output: $T$: authentication tag (before final XOR with encrypted nonce) # GHASH pseudocode def GHASH(H, A, C): X = 0^128 # Initialize accumulator for block in split_blocks(A): X = (X ⊕ block) * H # Multiplication in GF(2^128) for block in split_blocks(C): X = (X ⊕ block) * H X = X ⊕ length_block # XOR with concatenation of lengths of A and C return X Modes of Operation: XTS-AES (storage) and FPE (specialized) XTS-AES: sector-based/"tweakable" confidentiality for storage; no integrity . Use with file-system level authentication if tampering detection is needed. FPE (FF1, FF3-1): format-preserving (e.g., PANs); strict domain/parameter constraints; not a general-purpose AEAD replacement . Modes of Operation: IV/Nonce Rules (Critical!) AES-GCM: 96-bit (12-byte) nonce unique per key. Reuse is catastrophic (stream key and GHASH reuse). AES-CTR/OFB: never repeat nonce/counter; keep counters non-overlapping per key. CCM: unique nonce; no reuse per key; slightly slower than GCM. SIV modes (e.g., GCM-SIV): resistant to nonce reuse (deterministic AEAD) but still requires key hygiene. CBC: needs unpredictable IV; avoid for new protocols; padding oracle class pitfalls. AES-CBC Attack (part 1) CBC decryption formula for block $(i)$: $P_i = D_K(C_i) \oplus C_{i-1}$, where $(C_0)$ is the IV. Attacker's goal: alter some bits of $(P_1)$ by tampering with $(C_0)$ (the IV) or $(C_{i-1})$ without knowing the key $(K)$. Numerical example (16-byte AES block, shown as hex): Assume the block cipher output for the first ciphertext block is $D_K(C_1) = S = 00, 11, 22, 33, 44, 55, 66, 77, 88, 99, aa, bb, cc, dd, ee, ff$. Assume the original IV is $C_0 = IV = ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff$. Then the recovered plaintext block is $P_1 = S \oplus IV = ff, ee, dd, cc, bb, aa, 99, 88, 77, 66, 55, 44, 33, 22, 11, 00$. AES-CBC Attack (part 2) Now the attacker flips the least significant bit of the first byte of the IV: $IV' = fe, ff, ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff$. The recipient will compute $P'_1 = S \oplus IV' = fe, ee, dd, cc, bb, aa, 99, 88, 77, 66, 55, 44, 33, 22, 11, 00$. Comparing $(P_1)$ and $(P'_1)$: they differ in exactly the first bit/byte that the attacker flipped in the IV. The key point: the recipient will happily decrypt and get $(P'_1)$. Without an authentication check (MAC/AEAD), the recipient has no way of knowing that $(P'_1)$ has been tampered with. Padding Oracle: Idea and Attack Flow Setup (victim): AES-CBC with PKCS7 padding. Upon decryption, the service checks padding and returns an error (or a timing difference) if padding is invalid. CBC decryption (block (1)): $P_1 = D_K(C_1) \oplus C_0$, where $(C_0)$ is the IV (or any preceding ciphertext block). Attacker's goal: recover plaintext bytes of $(P_1)$ by sending modified ciphertexts and observing whether the service reports "valid padding" or "invalid padding" – the service is the oracle. High-level method: Attacker intercepts $((C_0, C_1))$. Attacker constructs variations of $((C'_0, C_1))$ and sends them to the oracle. For each $(C'_0)$ attempt, the oracle decrypts and checks padding on $(P'_1 = D_K(C_1) \oplus C'_0)$. The attacker observes if the padding is accepted. Carefully chosen $(C'_0)$ values allow the attacker to deduce the bytes of $(D_K(C_1))$, thereby recovering $(P_1)$ since $(P_1 = D_K(C_1) \oplus C_0)$. Note: This is fundamentally an adaptive oracle-based attack — complexity is typically $(\le 256 \times)$ (block size) attempts in naive implementations. Why Padding Oracles are Extremely Dangerous (Analogy) Oracle = tiny leak, huge consequences. A single bit of feedback ("padding valid" / "padding invalid" or a timing difference) acts as a boolean oracle that an attacker can adaptively use to recover a full plaintext block — byte by byte. Analogy: Blind SQL Injection. Both attacks: provide only a yes/no feedback channel, allow an attacker to make many adaptive queries, enable the attacker to extract secrets (database rows / plaintext bytes) without knowing the key or secret upfront. Thus, a padding oracle is essentially a cryptographic blind exploitation. Result: Complete confidentiality breakdown — attacker can recover all plaintext for a ciphertext (and often for many ciphertexts), yet the server may still appear to be functioning normally. Real-world impact examples: session tokens, personal data, credentials, or protocol-level secrets leaked silently. Mitigations: Operational Defenses (Practical Checklist) Use Authenticated Encryption: Prefer AEAD modes (AES-GCM, ChaCha20-Poly1305) or Encrypt-then-MAC. Verify the MAC/tag before any checks dependent on padding or plaintext. Don't disclose padding errors: Return identical error responses and constant-time processing for all decryption failures (but note: constant-time is hard; best is to verify auth tag first and fail fast). Fail closed and centralize checks: Perform authentication and integrity checks in a single trusted layer (avoid multiple code paths doing separate checks). Transport/Protocol Protection: Use TLS with AEAD ciphersuites and ensure end-to-end integrity where possible. Rate Limiting and Monitoring: Detect repetitive malformed ciphertext queries and throttle/block suspicious clients; alert on high volumes of decryption failures. Code Hygiene: Avoid different error messages/timings for padding vs. MAC vs. other failures. Use well-vetted cryptographic libraries and the latest stable primitives. Assume Compromise: Treat any unauthenticated ciphertext processing as insecure — design systems such that a single oracle cannot reveal high-value secrets. Incident Response Readiness: Have logs, IDS rules, and the ability to rotate secrets (keys/tokens) and revoke compromised sessions quickly. Modes of Operation: Where We Are in Real-World Protocols TLS 1.3: AEAD only (no CBC/RC4/stream-cipher suites). Common: AES_128/256_GCM, CHACHA20_POLY1305. SSH, QUIC, IPsec, WireGuard: all use AEAD; chacha20-poly1305 widely implemented where AES-NI is not present. Storage: full disk encryption uses XTS-AES plus separate authentication if tampering detection is needed. Dos and Don'ts Dos Use AEAD with an authenticating decrypt API (fail closed on tag errors). Use vetted libraries: OpenSSL 3.x, libsodium, BoringSSL, Go's crypto, Rust ring/aes-gcm/chacha20poly1305. Generate nonces with a counter or strong RNG; never reuse (except SIV). Wipe keys, separate keys for distinct purposes, rotate regularly. Don'ts Implement "encrypt-then-MAC" yourself unless you fully understand the pitfalls. Reuse key + nonce; serialize counters across processes without coordination. Ignore side channels: use constant-time primitives; avoid secret-dependent branches/table lookups. Operational Guidance (2025) Prioritize AES-GCM (with hardware crypto) or ChaCha20-Poly1305 ; consider AES-GCM-SIV if nonce management is risky. Enforce unique 96-bit nonces for GCM; use a counter or robust nonce generation scheme. Use constant-time AES (AES-NI/ARMv8) or side-channel-safe S-box code; avoid table lookups. Protect implementations from oracle failures; authenticate the tag before releasing any plaintext. Separate keys for distinct purposes; derive via domain-separated KDFs; rotate judiciously.