What a side channel is
A side-channel attack recovers secret information not by attacking the mathematics of an algorithm, but by observing something about how it runs: how long an operation takes, how much power a chip draws, which memory addresses get accessed (and therefore which CPU cache lines get touched), or even electromagnetic emissions. None of these leaks require breaking AES or RSA mathematically — they exploit the physical reality of the implementation.
Timing attacks in TLS: Lucky Thirteen
The 2013 Lucky Thirteen attack exploited tiny timing differences in how some TLS implementations processed CBC-mode padding — a valid-padding check took a measurably different amount of time than an invalid one, letting an attacker who could send many requests and measure response timing gradually recover plaintext, echoing the Bleichenbacher padding-oracle pattern covered in the RSA padding module but at the symmetric-cipher layer.
Lucky Thirteen, simplified
- 1
Modify a captured ciphertext
The attacker tweaks bytes of an intercepted CBC-encrypted TLS record.
- 2
Resubmit and measure response time
A record with valid padding takes a measurably different code path (and time) to process than one with invalid padding.
- 3
Repeat thousands of times
Statistical averaging filters out network noise from the microsecond-scale timing signal.
- 4
Recover the plaintext byte by byte
Each timing measurement narrows down one byte of the original encrypted data.
Cache-timing attacks
Early software AES implementations used lookup tables for the SubBytes step. Because CPU caches are shared and timing-observable, an attacker running unrelated code on the same physical machine (relevant in cloud/virtualized environments) could sometimes infer which table entries were accessed, and from that recover key bits — a cache-timing attack. This is one of the reasons modern CPUs ship dedicated AES instructions (AES-NI), which execute in constant time regardless of data.
The mitigation: constant-time code
The general defense is constant-time programming: writing cryptographic code so its execution time, memory access pattern, and power draw never depend on secret data — no data-dependent branches, no data-dependent array indexing. This is precisely why cryptography guidelines insist on vetted libraries over custom implementations: constant-time discipline is easy to state and notoriously easy to violate by accident.