This entry details my solution for mitigating cold boot attacks. Future posts will delve into additional details and describe what other ideas (and problems) were considered on the path to finding a general-purpose solution.
Why is this blog called "Frozen Cache"? Because we're proposing the use of the CPU cache for thwarting cold boot attacks (at least on most X86 systems). In contrast to most blogs, the entries of this blog will appear in normal chronological order on the website (for a more paper-like reading). Feeds however, will be sorted as expected (reverse chronological order).
The concept is easy: by switching the cache into a special mode one can force that data remains in the cache and is not written to the backing RAM locations. Thus, the encryption key can't be extracted from RAM. This technique is actually not new: LinuxBIOS/CoreBoot calls this Cache-as-RAM. They use it to allow "RAM access", even before the memory controller is initialized.
The following (simplified and technically not 100% correct/complete) steps load and maintain a 256 bit encryption key in the CPU cache. The demo assembly code assumes the encryption key is stored at linear address X in RAM on a page boundary for simplicity:
- Load the encryption key from RAM into some CPU registers (like the SSE registers)
movq [X], %xmm0
movq [X+8], %xmm1
movq [X+16], %xmm2
movq [X+24], %xmm3
- Overwrite the encryption key in RAM with a zero-value
movq 0, [X]
movq 0, [X+8]
movq 0, [X+16]
movq 0, [X+24]
- Flush the cache (thus truly overwriting the encryption key in RAM)
- Add the desired RAM region to the CPU's MTRR (the 4K segment containing the key)
movl (X | MEMORY_TYPE_WRITEBACK), %eax
xorl %edx, %edx
movl 0x200, %ecx
movl ( ~(1) | MTRR_VALID ), %eax
movl 0x1, %edx
movl 0x201, %ecx
- Disable/freeze the CPU's cache (CR0.CD=1)
movl %cr0, %eax
orl 0x40000000, %eax
movl %eax, %cr0
- Write the encryption key from the CPU registers to RAM (data remains in the cache, doesn't get written to memory)
movq %xmm0, [X]
movq %xmm1, [X+8]
movq %xmm2, [X+16]
movq %xmm3, [X+24]
Please note that this post only described the very basic concept, there are many aspects that haven't been covered. Upcoming posts will address things like multi-CPU/Core issues, performance considerations/optimizations and lots of other stuff.