1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
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 guest-invoked 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:
Single-step guest exection. For each step, collect either only instruction
or instruction and page-faults. Allows tracking not only which sets were
evicted but what gfns were involved in the access. A target page can
be set, such that we will first page-step until the page is reached,
then single-step while running instructions on that page.
setup
-----
Testing was done on a Supermicro H12SSL-i V1.01 motherboard and AMD EPYC 72F3
(Family 0x19, Model 0x01) cpu. The motherboard bios version is 2.4 and was
released 2022-04-14.
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 host 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
In case SEV-SNP initialization fails due to a low firmware version, the
firmware can be updated to v1.51 by running:
# mv extra/amd_sev_fam19h_model0xh_1.51.03.sbin /lib/firmware/amd/amd_sev_fam19h_model0xh.sbin
# rmmod ccp
# sudo insmod /lib/modules/$(uname -r)/kernel/drivers/crypto/ccp/ccp.ko dyndbg="+p"
To successfully build and load the kvm.ko and kvm-amd.ko modules, ensure
that the full kernel was built atleast once by running:
$ cp $(AMDSEV_REPO)/linux/host/.config linux/.config
$ make linux
Note, the checked out commit of the modified kernel (previously the kernel
patch file) may be incorrect for revisions older than 864f5fa9d539.
|