CachePC ======= This repository contains proof-of-concept code for a cache side-channel attack dubbed PRIME+COUNT that we demonstrate can be used to circumvent AMD's latest secure virtualization solution SEV-SNP to access sensitive guest information. tests ----- Several test-cases were used to verify parts of the exploit chain separately: test/eviction: Demonstrate that performance counters & our setup are accurate enough to detect a single eviction in L1 cache and infer its cache set through PRIME+COUNT test/kvm-eviction: Demonstrate that the cache set of a memory access instruction can be inferred in non-SEV / SEV / SEV-ES / SEV-SNP -enabled vms respectively. test/kvm-step: Demonstrate that SEV-SNP enabled vms can be single-stepped using local APIC timers to interrupt the guest and increment the interrupt interval while observing the RIP+RFLAGS ciphertext in the VMSA for changes to detect that a single instruction has been executed. test/kvm-pagestep: Demonstrate that a SEV-SNP enabled vm can be quickly single-stepped and analyzed by tracking a single page at a time. This type of tracking creates a page-wise profile of the guests execution, which can be used to infer what the guest is doing and to begin fine-grained single-stepping. test/qemu-pagestep: Replicate result from kvm-pagestep on a qemu-based vm running debian. test/qemu-eviction: Replicate result from kvm-eviction on a qemu-based vm running debian using a specially crafted guest program to signal when measurement should take place to infer the accessed set. test/qemu-aes: Demonstrate that AES encryption keys can be leaked from a modified qemu-based linux guest. test/qemu-poc: Demonstrate that AES encryption keys can be leaked from an unmodified qemu-based linux guest. modes ----- The kernel module employs a few different modes of tracking described in more detail below: CPC_TRACK_FAULT_NO_RUN: Tracks access to all guest pages and lets the guest page fault over and over without untracking / handling any page faults. This results in a decent baseline measurement when we dont want to step the vm. CPC_TRACK_EXIT_EVICTION: Set apic timer such that for any reasonably short KVM_RUN no local apic interrupts will occur to cause exits. Good for collecting PRIME+COUNT measurements over a clean run to a "natural" exit such as KVM_EXIT_HLT. CPC_TRACK_PAGES: Track execution of all guest pages. While the guest is running untrack a single executable page at a time based on page-faults. Allows tracking which guest pages are executed and how long using retired instructions. CPC_TRACK_STEPS_AND_FAULTS: Track access to all guest pages and single-step guest exection. For each step, collect all page-faults that needed to be handled to enable that step. Allows tracking not only which sets were evicted but what gfns were involved in the access. CPC_TRACK_STEPS_SIGNALLED: Track execution of a specific set of guest pages and single-step guest execution for only this set. A guest program makes a specific vmmcall to signal when to start and stop tracking. When a page-fault signals that the target pages were reached, single-stepping begins and the target pages are retracked to detect when the pages are left. setup ----- Testing was done on a Supermicro H12SSL-i V1.01 motherboard and AMD EPYC 72F3 (Family 0x19, Model 0x01) cpu. The following non-default BIOS settings were used: Advanced > CPU Configuration > Local APIC Mode = xAPIC Advanced > CPU Configuration > SMT Control = Disabled Advanced > CPU Configuration > Core Performance Boost = Disabled Advanced > CPU Configuration > Global C-state Control = Disabled Advanced > CPU Configuration > L1 Stream HW Prefetcher = Disabled Advanced > CPU Configuration > L2 Stream HW Prefetcher = Disabled Advanced > CPU Configuration > SMEE = Enabled Advanced > CPU Configuration > SEV ASID Count = 509 Advanced > CPU Configuration > SEV ASID Space Limit Control = Manual Advanced > CPU Configuration > SEV ASID Space Limit = 110 Advanced > CPU Configuration > SNP Memory (RMP Table) Coverage = Enabled Advanced > CPU Configuration > SVM Mode = Enabled Advanced > North Bridge Configuration > SEV-SNP Support = Enabled Advanced > North Bridge Configuration > Memory Configuration > TSME = Disabled The host kernel is built using the AMDESE/AMDSEV repo on branch sev-snp-devel at commmit a480a51. Build and install the the host kernel and qemu by running: # ./bulid.sh --package # cd snp-release-`date "+%Y-%m-%d"` # ./install.sh The following kernel parameters were used: kvm_amd.sev=1 kvm_amd.sev_es=1 nokaslr nosplash debug systemd.log_level=debug isolcpus=2,10,3,11 nohz_full=2,10,3,11 rcu_nocbs=2,10,3,11 nmi_watchdog=0 transparent_hugepage=never apic lapic panic=-1 preempt=none To successfully build and load the kvm.ko and kvm-amd.ko modules, ensure that the full kernel was build atleast once using `make linux`. Note, the checked out commit of the modified kernel (previously the kernel patch file) may be incorrect for revisions older than 864f5fa9d539.