README (6924B)
1CachePC 2======= 3 4This repository contains proof-of-concept code for a cache side-channel 5attack on AMD SEV-SNP dubbed Prime+Count. It extends the traditional Prime+Probe 6implementation of CacheSC through the use of performance counters for 7accurately detecting cache line evictions and provides and attack framework 8for single- and page-stepping SEV-SNP guests. 9 10 11tests 12----- 13 14Several test-cases were used to verify parts of the exploit chain separately: 15 16test/eviction: 17 Demonstrate that performance counters & our setup are accurate enough 18 to detect a single eviction in L1 cache and infer its cache set 19 through PRIME+COUNT 20 21test/kvm-eviction: 22 Demonstrate that the cache set of a memory access instruction can be 23 inferred in non-SEV / SEV / SEV-ES / SEV-SNP -enabled vms respectively. 24 25test/kvm-pagestep: 26 Demonstrate that a SEV-SNP enabled vm can be quickly single-stepped 27 and analyzed by tracking a single page at a time. This type 28 of tracking creates a page-wise profile of the guests execution, 29 which can be used to infer what the guest is doing and when to begin 30 fine-grained single-stepping. 31 32test/kvm-step: 33 Demonstrate that SEV-SNP enabled vms can be single-stepped using local 34 APIC timers to interrupt the guest and increment the interrupt interval 35 while observing the RIP+RFLAGS ciphertext in the VMSA for changes to 36 detect that a single instruction has been executed. 37 38test/kvm-targetstep: 39 Demonstrate that a combination of page- and singlestepping allows 40 for fine-grained control of when to single-step. In this case a vmmcall 41 by the guest alerts the host to when the guest is on a critical page. 42 The host sets the currently executed gfn as the target and begins 43 single-stepping only on that page. 44 45test/qemu-pagestep: 46 Replicate result from kvm-pagestep on a qemu-based vm running debian. 47 48 49incomplete 50---------- 51 52test/qemu-targetstep: 53 Replicate result from kvm-targetstep on a qemu-based vm running debian 54 using a specially crafted guest program to signal when measurement 55 should take place to infer the accessed set. 56 57test/qemu-aes: 58 Demonstrate that AES encryption keys can be leaked from a 59 modified qemu-based linux guest. 60 61test/qemu-poc: 62 Demonstrate that AES encryption keys can be leaked from an 63 unmodified qemu-based linux guest. 64 65 66track modes 67----------- 68 69The kernel module employs a few different modes of tracking described 70in more detail below: 71 72CPC_TRACK_FAULT_NO_RUN: 73 Tracks access to all guest pages and lets the guest page fault over and over 74 without untracking / handling any page faults. This results in a decent 75 baseline measurement when we dont want to step the vm. 76 77CPC_TRACK_EXIT_EVICTION: 78 Set apic timer such that for any reasonably short KVM_RUN no local apic 79 interrupts will occur to cause exits. Good for collecting Prime+Count 80 measurements over a clean run to a guest-invoked exit such as KVM_EXIT_HLT. 81 82CPC_TRACK_PAGES: 83 Track execution of all guest pages. While the guest is running, untrack 84 a single executable page at a time based on page-faults. Allows tracking 85 which guest pages are executed and how long using retired instructions. 86 87CPC_TRACK_STEPS: 88 Single-step guest exection. For each step, collect either only instruction 89 or instruction and data page-faults. Allows tracking not only which sets were 90 evicted but what gfns were involved in the access. A target page can 91 be set, such that we will first page-step until the page is reached, 92 then single-step while running instructions on that page. 93 94 95host setup 96---------- 97 98Testing was done on a Supermicro H12SSL-i V1.01 motherboard and AMD EPYC 72F3 99(Family 0x19, Model 0x01) cpu. The motherboard bios version is 2.4 and was 100released 2022-04-14. 101 102 103The host kernel and qemu were built using the AMDESE/AMDSEV repo on branch 104sev-snp-devel at commmit a480a51. Install the host kernel by running: 105 106# ./bulid.sh --package 107# cd snp-release-`date "+%Y-%m-%d"` 108# ./install.sh 109 110 111For the build to complete the following packages were needed following 112a clean install of debian linux-5.10.0-21: 113 114git build-essential flex dpkg bc rsync libelf-dev libssl-dev bison ninja-build 115 pkg-config libglib2.0-dev libpixman-1-dev python3 coda nasm uuid-dev iasl 116 117 118The following non-default BIOS settings were used: 119 120Advanced > CPU Configuration > Local APIC Mode = xAPIC 121Advanced > CPU Configuration > SMT Control = Disabled 122Advanced > CPU Configuration > Core Performance Boost = Disabled 123Advanced > CPU Configuration > Global C-state Control = Disabled 124Advanced > CPU Configuration > L1 Stream HW Prefetcher = Disabled 125Advanced > CPU Configuration > L2 Stream HW Prefetcher = Disabled 126Advanced > CPU Configuration > SMEE = Enabled 127Advanced > CPU Configuration > SEV ASID Count = 509 128Advanced > CPU Configuration > SEV ASID Space Limit Control = Manual 129Advanced > CPU Configuration > SEV ASID Space Limit = 110 130Advanced > CPU Configuration > SNP Memory (RMP Table) Coverage = Enabled 131Advanced > CPU Configuration > SVM Mode = Enabled 132Advanced > North Bridge Configuration > SEV-SNP Support = Enabled 133Advanced > North Bridge Configuration > Memory Configuration > TSME = Disabled 134 135 136The following host kernel parameters were used: 137 138kvm_amd.sev=1 kvm_amd.sev_es=1 nokaslr nosplash debug systemd.log_level=debug 139 isolcpus=2,10,3,11 nohz_full=2,10,3,11 rcu_nocbs=2,10,3,11 nmi_watchdog=0 140 transparent_hugepage=never apic lapic panic=-1 preempt=none 141 142 143To successfully build and load the kvm.ko and kvm-amd.ko modules after building 144cachepc, ensure that the full kernel was built atleast once beforehand by running: 145 146$ cp $(AMDSEV_REPO)/linux/host/.config linux/.config 147$ make linux 148 149 150guest setup 151----------- 152 153Generate a guest image and install debian by running qemu/install.sh. 154The virtual machine can either be controlled via vnc, or once the guest os 155is installed via ssh, port forwarded to localhost:8000. 156 157Once debian is installed, launch the guest by running qemu/launch.sh and 158copy over the compiled guest kernel packages from AMDSEV/linux on the host 159and install them. Reboot the guest, make sure that `uname -r` matches 160the expected version and copy that versions initrd and vmlinuz out of 161/boot on the guest to qemu/ on the host. Also copy the guests /proc/cmdline 162contents to qemu/cmdline on the host. 163 164Finally, run qemu/launch-victim.sh to launch a qemu guest ready to 165be attacked. 166 167 168troubleshooting 169--------------- 170 171In case SEV-SNP initialization fails due to a low firmware version, the 172firmware can be updated to v1.51 by running: 173 174# cp extra/amd_sev_fam19h_model0xh_1.51.03.sbin /lib/firmware/amd/amd_sev_fam19h_model0xh.sbin 175# rmmod ccp 176# sudo insmod /lib/modules/$(uname -r)/kernel/drivers/crypto/ccp/ccp.ko dyndbg="+p" 177 178 179Note, the checked out commit of the modified kernel (previously the kernel 180patch file) may be incorrect for revisions older than 864f5fa9d539. 181