From b7dd1602705f96835ce45fa512043f2daa18a0e4 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Thu, 13 Dec 2018 00:29:30 -0800 Subject: [PATCH] [Pal/Linux-SGX]: Clean-up of {enclave/sgx}_entry.S Helper asm functions are moved to static inline C functions with inline asm and correct signatures. This allows for better register scheduling. --- Pal/src/host/Linux-SGX/enclave_entry.S | 95 ---------------------- Pal/src/host/Linux-SGX/enclave_framework.c | 7 +- Pal/src/host/Linux-SGX/sgx_api.h | 76 +++++++++++++++-- Pal/src/host/Linux-SGX/sgx_arch.h | 2 + Pal/src/host/Linux-SGX/sgx_entry.S | 32 -------- 5 files changed, 74 insertions(+), 138 deletions(-) diff --git a/Pal/src/host/Linux-SGX/enclave_entry.S b/Pal/src/host/Linux-SGX/enclave_entry.S index e1aa9c81..856df04f 100644 --- a/Pal/src/host/Linux-SGX/enclave_entry.S +++ b/Pal/src/host/Linux-SGX/enclave_entry.S @@ -620,101 +620,6 @@ __morestack: popq %rbp retq -/* - * sgx_report: - * Generate SGX hardware signed report. - */ - .global sgx_report - .type sgx_report, @function - -sgx_report: - .cfi_startproc - - pushq %rbx - pushq %rcx - movq %rdi, %rbx - movq %rsi, %rcx - movq $EREPORT, %rax - ENCLU - popq %rcx - popq %rbx - retq - - .cfi_endproc - .size sgx_report, .-sgx_report - -/* - * sgx_getkey: - * Retreive SGX hardware enclave cryptography key. - */ - .global sgx_getkey - .type sgx_getkey, @function - -sgx_getkey: - .cfi_startproc - - pushq %rbx - pushq %rcx - movq %rdi, %rbx - movq %rsi, %rcx - movq $EGETKEY, %rax - ENCLU - popq %rcx - popq %rbx - retq - - .cfi_endproc - .size sgx_getkey, .-sgx_getkey - -/* - * rdrand: - * Get hardware generated random value. - */ - .global rdrand - .type rdrand, @function - -rdrand: - .cfi_startproc -.Lretry_rdrand: - .byte 0x0f, 0xc7, 0xf0 /* RDRAND %EAX */ - jnc .Lretry_rdrand - retq - - .cfi_endproc - .size rdrand, .-rdrand - -/* - * rdfsbase: - * read FS register (allowed in enclaves). - */ - .global rdfsbase - .type rdfsbase, @function - -rdfsbase: - .cfi_startproc - - .byte 0xf3, 0x48, 0x0f, 0xae, 0xc0 /* RDFSBASE %RAX */ - retq - - .cfi_endproc - .size rdfsbase, .-rdfsbase - -/* - * wrfsbase: - * modify FS register (allowed in enclaves). - */ - .global wrfsbase - .type wrfsbase, @function - -wrfsbase: - .cfi_startproc - - .byte 0xf3, 0x48, 0x0f, 0xae, 0xd7 /* WRFSBASE %RDI */ - retq - - .cfi_endproc - .size wrfsbase, .-wrfsbase - /* * Restore an sgx_context_t as generated by .Lhandle_exception. Execution will * continue as specified by the rip in the context. diff --git a/Pal/src/host/Linux-SGX/enclave_framework.c b/Pal/src/host/Linux-SGX/enclave_framework.c index 1173a8d1..4d6fa346 100644 --- a/Pal/src/host/Linux-SGX/enclave_framework.c +++ b/Pal/src/host/Linux-SGX/enclave_framework.c @@ -104,7 +104,7 @@ int sgx_get_report (sgx_arch_hash_t * mrenclave, int ret = sgx_report(&targetinfo, &state, report); if (ret) - return -PAL_ERROR_DENIED; + return -PAL_ERROR_INVAL; SGX_DBG(DBG_S, "Generated report:\n"); SGX_DBG(DBG_S, " cpusvn: %08lx %08lx\n", report->cpusvn[0], @@ -910,10 +910,9 @@ int init_enclave (void) sgx_arch_report_t report; int ret = sgx_report(&targetinfo, &reportdata, &report); - if (ret) { - SGX_DBG(DBG_E, "failed to get self report: %d\n", ret); + if (ret) return -PAL_ERROR_INVAL; - } + memcpy(pal_sec.mrenclave, report.mrenclave, sizeof(pal_sec.mrenclave)); memcpy(pal_sec.mrsigner, report.mrsigner, sizeof(pal_sec.mrsigner)); pal_sec.enclave_attributes = report.attributes; diff --git a/Pal/src/host/Linux-SGX/sgx_api.h b/Pal/src/host/Linux-SGX/sgx_api.h index d35533a3..bde8eca9 100644 --- a/Pal/src/host/Linux-SGX/sgx_api.h +++ b/Pal/src/host/Linux-SGX/sgx_api.h @@ -17,6 +17,7 @@ #ifndef SGX_API_H #define SGX_API_H +#include "sgx_arch.h" #include "pal_error.h" int sgx_ocall (unsigned long code, void * ms); @@ -31,10 +32,6 @@ void sgx_reset_ustack(void); bool sgx_copy_ptr_to_enclave(void** ptr, void* uptr, uint64_t size); uint64_t sgx_copy_to_enclave(const void* ptr, uint64_t maxsize, const void* uptr, uint64_t usize); -int sgx_report (sgx_arch_targetinfo_t * targetinfo, - void * reportdata, sgx_arch_report_t * report); - -int sgx_getkey (sgx_arch_keyrequest_t * keyrequest, sgx_arch_key128_t * key); int sgx_get_report (sgx_arch_hash_t * mrenclave, sgx_arch_attributes_t * attributes, @@ -43,9 +40,74 @@ int sgx_get_report (sgx_arch_hash_t * mrenclave, int sgx_verify_report (sgx_arch_report_t * report); -uint32_t rdrand (void); -uint64_t rdfsbase (void); -void wrfsbase (uint64_t addr); +/* + * sgx_report: + * Generate SGX hardware signed report. + */ +static inline int sgx_report (sgx_arch_targetinfo_t * targetinfo, + void * reportdata, sgx_arch_report_t * report) +{ + __asm__ volatile( + ENCLU "\n" + :: "a"(EREPORT), "b"(targetinfo), "c"(reportdata), "d"(report) + : "memory"); + return 0; +} + +/* + * sgx_getkey: + * Retrieve SGX hardware enclave cryptography key. + */ +static inline int64_t sgx_getkey (sgx_arch_keyrequest_t * keyrequest, + sgx_arch_key128_t * key) +{ + int64_t rax = EGETKEY; + __asm__ volatile( + ENCLU "\n" + : "+a"(rax) + : "b"(keyrequest), "c"(key) + : "memory"); + return rax; +} + +/* + * rdrand: + * Get hardware generated random value. + */ +static inline uint32_t rdrand (void) +{ + uint32_t ret; + __asm__ volatile( + "1: .byte 0x0f, 0xc7, 0xf0\n" /* RDRAND %EAX */ + "jnc 1b\n" + :"=a"(ret) + :: "cc"); + return ret; +} + +/* + * rdfsbase: + * read FS register (allowed in enclaves). + */ +static inline uint64_t rdfsbase (void) +{ + uint64_t fsbase; + __asm__ volatile( + ".byte 0xf3, 0x48, 0x0f, 0xae, 0xc0\n" /* RDFSBASE %RAX */ + : "=a"(fsbase)); + return fsbase; +} + +/* + * wrfsbase: + * modify FS register (allowed in enclaves). + */ +static inline void wrfsbase (uint64_t addr) +{ + __asm__ volatile( + ".byte 0xf3, 0x48, 0x0f, 0xae, 0xd7\n" /* WRFSBASE %RDI */ + :: "D"(addr)); +} void restore_sgx_context(sgx_context_t *ctx); void _restore_sgx_context(sgx_context_t *ctx); diff --git a/Pal/src/host/Linux-SGX/sgx_arch.h b/Pal/src/host/Linux-SGX/sgx_arch.h index a4a107da..e41f1e40 100644 --- a/Pal/src/host/Linux-SGX/sgx_arch.h +++ b/Pal/src/host/Linux-SGX/sgx_arch.h @@ -251,6 +251,8 @@ typedef struct { typedef uint8_t sgx_arch_key128_t[16] __attribute__((aligned(16))); +#define ENCLU ".byte 0x0f, 0x01, 0xd7" + #else /* !__ASSEMBLER__ */ /* microcode to call ENCLU */ diff --git a/Pal/src/host/Linux-SGX/sgx_entry.S b/Pal/src/host/Linux-SGX/sgx_entry.S index 70d042a2..ff6667b9 100644 --- a/Pal/src/host/Linux-SGX/sgx_entry.S +++ b/Pal/src/host/Linux-SGX/sgx_entry.S @@ -75,35 +75,3 @@ sgx_entry_return: # RSI - external event jmp .Ldo_ecall .cfi_endproc - -/* - * rdfsbase: - * read FS register (allowed in enclaves). - */ - .global rdfsbase - .type rdfsbase, @function - -rdfsbase: - .cfi_startproc - - .byte 0xf3, 0x48, 0x0f, 0xae, 0xc0 /* RDFSBASE %RAX */ - retq - - .cfi_endproc - .size rdfsbase, .-rdfsbase - -/* - * wrfsbase: - * modify FS register (allowed in enclaves). - */ - .global wrfsbase - .type wrfsbase, @function - -wrfsbase: - .cfi_startproc - - .byte 0xf3, 0x48, 0x0f, 0xae, 0xd7 /* WRFSBASE %RDI */ - retq - - .cfi_endproc - .size wrfsbase, .-wrfsbase