Skip to content

Commit

Permalink
riscv: new btb and bht attacks
Browse files Browse the repository at this point in the history
  • Loading branch information
niwis committed May 13, 2020
1 parent be3f35f commit 92737be
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 62 deletions.
36 changes: 36 additions & 0 deletions apps/side-bench/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,42 @@ config_option(
OFF
)

config_string(
BenchBTBEntries
BENCH_BTB_ENTRIES
"Number of entries in BTB"
DEFAULT
16
UNQUOTE
)

config_string(
BenchBTBAlign
BENCH_BTB_ALIGN
"Alignment of indirect branch instructions (bytes). This should guarantee iterating over all BTB indices."
DEFAULT
20
UNQUOTE
)

config_string(
BenchBHTEntries
BENCH_BHT_ENTRIES
"Number of entries in BHT"
DEFAULT
64
UNQUOTE
)

config_string(
BenchBHTAlign
BENCH_BHT_ALIGN
"Alignment of conditional branch instructions (bytes). This should guarantee iterating over all BHT indices."
DEFAULT
20
UNQUOTE
)

config_choice(
BenchCacheFlushChoice
BENCH_CACHE_FLUSH_CHOICE
Expand Down
13 changes: 7 additions & 6 deletions apps/side-bench/src/mastik_common/low.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,17 +236,18 @@
#define L1I_CACHELINE 16
#define L1I_STRIDE (L1I_CACHELINE * L1I_SETS)

#define L3_THRESHOLD 1
#define L3_ASSOCIATIVITY 1
#define L3_SIZE 1 /* 2MB */
#define L3_CACHELINE 1
#define L3_THRESHOLD 100
#define L3_ASSOCIATIVITY 8
#define L3_SIZE (512 * 1024) /* 512KiB */
#define L3_CACHELINE 64
// The number of cache sets in each slice.
#define L3_SETS_PER_SLICE 1
#define L3_SETS_PER_SLICE 64

// The number of cache sets in each page
#define L3_SETS_PER_PAGE 1

#define BTAC_ENTRIES 32
#define BTAC_ENTRIES 32
#define BHT_ENTRIES 64
#define TLB_ENTRIES 16
#define TLB_PROBE_PAGES 8

Expand Down
28 changes: 13 additions & 15 deletions apps/side-bench/src/mastik_riscv/bp.S
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,21 @@
#define X_16(a) X_4(X_4(a))
#define X_256(a) X_16(X_16(a))

#define JMP beqz t0, 1f
#define JMP_4 JMP; JMP; JMP; JMP
#define JMP_16 JMP_4; JMP_4; JMP_4; JMP_4
#define JMP_64 JMP_16; JMP_16; JMP_16; JMP_16
#define JMP_256 JMP_64; JMP_64; JMP_64; JMP_64; .align 4; 1:
#define CONFIGBHT_ENTRIES 64
#define JMP_HW_ALIGN CONFIG_BENCH_BHT_ALIGN/2

.global bp_probe
.type bp_probe, @function
.align 8
bp_probe:
mv t0, zero
JMP_256

rdtime t1
beqz a0, 2f
X_256(nop)
2:
.align 4
bp_probe:
rdtime t0
.rept CONFIG_BENCH_BHT_ENTRIES
.word 0x50A63 //beqz a0, 20. bloody compiler will rip this apart otherwise. 20 = CONFIG_BENCH_BHT_ALIGN
addi a0, a0, -1
.rept JMP_HW_ALIGN - 3
nop
.endr
.endr
rdtime a0
sub a0, a0, t1
sub a0, a0, t0
ret
26 changes: 15 additions & 11 deletions apps/side-bench/src/mastik_riscv/bp_spy.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,17 @@ int bp_trojan(bench_env_t *env) {

for (int i = 0; i < CONFIG_BENCH_DATA_POINTS; i++) {

if (i % 1000 == 0) printf("Data point %d\n", i);
if (i % 1000 == 0 || (i - 1) % 1000 == 0 || i == (CONFIG_BENCH_DATA_POINTS - 1)) printf("TROJAN: Data point %d\n", i);

secret = (random() / 2) & 1;
/*waiting for a system tick*/
newTimeSlice();

secret = random() % (BHT_ENTRIES + 1);
/*update the secret read by low*/
*share_vaddr = secret;

asm("");
uint32_t prev = rdtime();
for (;;) {
uint32_t cur = rdtime();
X_64(bp_probe(secret & 1);)
if (cur - prev > TS_THRESHOLD)
break;
prev = cur;
for (int i = 0; i < 16; i++) {
bp_probe(secret);
}

}
Expand All @@ -69,12 +66,19 @@ int bp_spy(bench_env_t *env) {

for (int i = 0; i < CONFIG_BENCH_DATA_POINTS; i++) {

if (i % 1000 == 0 || (i - 1) % 1000 == 0 || i == (CONFIG_BENCH_DATA_POINTS - 1)) printf("SPY: Data point %d\n", i);

newTimeSlice();

/*result is the total probing cost
secret is updated by trojan in the previous system tick*/
r_addr->result[i] = bp_probe(0);
r_addr->sec[i] = *secret;
r_addr->sec[i] = *secret;

/* Prime (make sure all saturation counters are reset) */
for (int i = 0; i < 16; i++) {
bp_probe(0);
}

}

Expand Down
40 changes: 32 additions & 8 deletions apps/side-bench/src/mastik_riscv/btb.S
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,42 @@
#include <manager/gen_config.h>
#include <side-bench/gen_config.h>

#define X_4(a) a; a; a; a
#define X_16(a) X_4(X_4(a))
#define X_256(a) X_16(X_16(a))
#define X_4096(a) X_256(X_16(a))
/*
ret
|=== block 1
spy || block 2 /\
\/ ... || trojan
block s ===|
...
ret
*/

#define JMP j 1f; .align 4; 1:
/* number of half words per block */
#define JUMP_HW_ALIGN CONFIG_BENCH_BTB_ALIGN/2

.global btb_probe
.type btb_probe, @function
.global btb_prime
.type btb_prime, @function

.align 4
/* end of prime */
ret
/* align. ret already takes one HW */
.rept JUMP_HW_ALIGN - 1
nop
.endr
btb_probe:
X_16(JMP)
X_16(JMP)
.rept CONFIG_BENCH_BTB_ENTRIES
/* a1 should either be +BTB_ALIGN (probe) or -BTB_ALIGN (prime)
a0 points to the next (probe) or previous (prime) block */
add a0, a0, a1 //
jalr x0, a0 //
/* align. add and ret already take three HWs */
.rept JUMP_HW_ALIGN - 3
nop
.endr
.endr
btb_prime:
ret
/* end of probe */
54 changes: 35 additions & 19 deletions apps/side-bench/src/mastik_riscv/btb_spy.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,41 @@
#include <channel-bench/bench_types.h>


#define JMP_ALIGN 16
#define BTB_ENTRIES BTAC_ENTRIES


// same function, once forwards and once backwards
extern void btb_probe(void);
extern void btb_prime(void);

int btb_jmp(bool spy, uint32_t s) {

unsigned long entry;
unsigned long increment;
unsigned long result;
if (spy)
{
/* start from the first indirect jump and jump forwards */
entry = (unsigned long)btb_probe;
increment = (signed long)CONFIG_BENCH_BTB_ALIGN;
}
else
{
/* calculate the jump entry based on the secret and jump backwards */
entry = (unsigned long)btb_prime - (CONFIG_BENCH_BTB_ENTRIES - s + 1) * CONFIG_BENCH_BTB_ALIGN;
increment = -(signed long)CONFIG_BENCH_BTB_ALIGN;
}



static void btb_jmp(uint32_t s) {

/*calculate the jump entry based on the secret*/
unsigned long entry = (unsigned long)btb_probe + (BTB_ENTRIES - s) * JMP_ALIGN;
volatile long ra;
asm volatile (
"sd ra, %0\n"
"jalr ra, %1\n"
"mv a0, %2\n"
"mv a1, %3\n"
"rdtime t0\n"
"jalr ra, a0\n"
"rdtime %1\n"
"sub %1, %1, t0\n"
"lw ra, %0\n"
: "+m"(ra) : "r" (entry));
: "+m"(ra), "=r"(result) : "r"(entry), "r"(increment));

return((int)result);
}

int btb_trojan(bench_env_t *env) {
Expand All @@ -45,16 +62,16 @@ int btb_trojan(bench_env_t *env) {
seL4_Send(args->ep, info);

for (int i = 0; i < CONFIG_BENCH_DATA_POINTS; i++) {
if (i % 1000 == 0) printf("Data point %d\n", i);
if (i % 1000 == 0 || (i - 1) % 1000 == 0 || i == (CONFIG_BENCH_DATA_POINTS - 1)) printf("TROJAN: Data point %d\n", i);

/*waiting for a system tick*/
newTimeSlice();

/*trojan: 0 - BTB_ENTRIES*/
secret = random() % (BTB_ENTRIES + 1);
secret = random() % (CONFIG_BENCH_BTB_ENTRIES + 1);

/*do the probe*/
btb_jmp(secret);
btb_jmp(0, secret);

/*update the secret read by low*/
*share_vaddr = secret;
Expand Down Expand Up @@ -82,12 +99,11 @@ int btb_spy(bench_env_t *env) {


for (int i = 0; i < CONFIG_BENCH_DATA_POINTS; i++) {
if (i % 1000 == 0 || (i - 1) % 1000 == 0 || i == (CONFIG_BENCH_DATA_POINTS - 1)) printf("SPY: Data point %d\n", i);

newTimeSlice();
start = rdtime();
btb_jmp(BTB_ENTRIES);

r_addr->result[i] = rdtime() - start;

r_addr->result[i] = btb_jmp(1, CONFIG_BENCH_BTB_ENTRIES);
r_addr->sec[i] = *secret;

}
Expand Down
3 changes: 2 additions & 1 deletion apps/side-bench/src/mastik_riscv/l1ispy.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ int l1i_trojan(bench_env_t *env) {
seL4_Send(args->ep, info);

for (int i = 0; i < CONFIG_BENCH_DATA_POINTS; i++) {
if (i % 1000 == 0) printf("TROJAN: data point %d\n", i);
if (i % 1000 == 0 || (i - 1) % 1000 == 0 || i == (CONFIG_BENCH_DATA_POINTS - 1)) printf("TROJAN: Data point %d\n", i);

/*waiting for a system tick*/
newTimeSlice();
Expand Down Expand Up @@ -109,6 +109,7 @@ int l1i_spy(bench_env_t *env) {


for (int i = 0; i < CONFIG_BENCH_DATA_POINTS; i++) {
if (i % 1000 == 0 || (i - 1) % 1000 == 0 || i == (CONFIG_BENCH_DATA_POINTS - 1)) printf("SPY: Data point %d\n", i);
newTimeSlice();
#ifdef CONFIG_MANAGER_PMU_COUNTER
pmu_start = sel4bench_get_counter(0);
Expand Down
3 changes: 2 additions & 1 deletion apps/side-bench/src/mastik_riscv/l1spy.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ int l1_trojan(bench_env_t *env) {


for (int i = 0; i < CONFIG_BENCH_DATA_POINTS; i++) {
if (i % 1000 == 0) printf("Data point %d\n", i);
if (i % 1000 == 0 || (i - 1) % 1000 == 0 || i == (CONFIG_BENCH_DATA_POINTS - 1)) printf("TROJAN: Data point %d\n", i);

/*waiting for a system tick*/
newTimeSlice();
Expand Down Expand Up @@ -88,6 +88,7 @@ int l1_spy(bench_env_t *env) {


for (int i = 0; i < CONFIG_BENCH_DATA_POINTS; i++) {
if (i % 1000 == 0 || (i - 1) % 1000 == 0 || i == (CONFIG_BENCH_DATA_POINTS - 1)) printf("SPY: Data point %d\n", i);

newTimeSlice();

Expand Down
3 changes: 2 additions & 1 deletion apps/side-bench/src/mastik_riscv/tlb_spy.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ int tlb_trojan(bench_env_t *env) {
seL4_Send(args->ep, info);

for (int i = 0; i < CONFIG_BENCH_DATA_POINTS; i++) {
if (i % 1000 == 0) printf("Data point %d\n", i);
if (i % 1000 == 0 || (i - 1) % 1000 == 0 || i == (CONFIG_BENCH_DATA_POINTS - 1)) printf("TROJAN: Data point %d\n", i);

newTimeSlice();
secret = random() % (TROJAN_TLB_PAGES+1);
Expand Down Expand Up @@ -107,6 +107,7 @@ int tlb_spy(bench_env_t *env) {


for (int i = 0; i < CONFIG_BENCH_DATA_POINTS; i++) {
if (i % 1000 == 0 || (i - 1) % 1000 == 0 || i == (CONFIG_BENCH_DATA_POINTS - 1)) printf("SPY: Data point %d\n", i);

newTimeSlice();
#ifdef CONFIG_MANAGER_PMU_COUNTER
Expand Down

0 comments on commit 92737be

Please sign in to comment.