Microarchitecture security¶
Part 1: Timing the Cache vs. Main Memory¶
Prepare Ubuntu Environment and Install Required Tools and check


Go to the Lab Folder Navigate to the lab folder provided by your instructor. For example: cd ~/Part1-Timing Verify that you are in the correct folder and view its contents: ls

Understand the Files Open the main.c file to view and understand the program code.

Add Cache Timing Code and Add DRAM Timing Code



Save the file, compile the program and run

Discussion Question 1-1 Example answer:
Typical cache (L1) latency: 23 cycles Typical DRAM latency: 178 cycles Difference: 178 − 23 = 155 cycles DRAM access is significantly slower than cache access.
Discussion Question 1-2 Choose a threshold that separates the two groups.
For example: Cache: 20–30 cycles DRAM: 170–190 cycles A suitable threshold is: 100 cycles
Decision rule: Less than 100 cycles → Data was in the cache. 100 cycles or more → Data was fetched from DRAM.
Part 2: Capture the Flag with Flush+Reload¶
Open Ubuntu Terminal and Open a terminal:

Go to the Lab Folder
Navigate to the Flush+Reload lab:

Create shared_file.c

Save (Ctrl+O, Enter) and exit (Ctrl+X).
Fix attacker.c Open nano:

Save and exit.
Fix Makefile Open nano: nano Makefile


Build
Run: make clean and make

Run programs
Run victim: make run_victim

Run attacker:

Discussion Question 2-2
Some ways you could rewrite the victim:
Constant‑time access: Instead of reading only one cache line based on the flag, have the victim read all possible cache lines every iteration. That way, the attacker sees every line touched, and the secret can’t be inferred from which one was fast.
Dummy operations: Always perform the same number of loads regardless of the flag, but only use the result from the secret‑dependent one internally. The attacker sees identical cache activity each time.
Oblivious memory access: Use techniques like ORAM (Oblivious RAM) where the victim shuffles or randomizes its memory accesses so that the pattern doesn’t reveal the secret.
Computation instead of indexing: Rewrite the victim so it computes the needed value without using the secret as an array index. For example, use arithmetic or bitwise operations that don’t change which cache line is touched.
Masking or padding: Add extra accesses or padding so that every possible flag value results in the same observable memory footprint.