Re: [PATCH RFC] selftests/x86: Add a selftest for SGX
On Wed, Nov 14, 2018 at 08:09:42AM -0800, Sean Christopherson wrote: > On Tue, Nov 13, 2018 at 11:40:09PM +0200, Jarkko Sakkinen wrote: > > Add a selftest for SGX. It is a trivial test where a simple enclave > > copies one 64-bit word of memory between two memory locations given to > > the enclave as arguments. > > > > Signed-off-by: Jarkko Sakkinen > > --- > > +SUBDIRS_64 := sgx > > +ASSERT(!DEFINED(.altinstructions), "ALTERNATIVES are not supported in the > > SGX LE") > > +ASSERT(!DEFINED(.altinstr_replacement), "ALTERNATIVES are not supported in > > the SGX LE") > > +ASSERT(!DEFINED(.discard.retpoline_safe), "RETPOLINE ALTERNATIVES are not > > supported in the SGX LE") > > +ASSERT(!DEFINED(.discard.nospec), "RETPOLINE ALTERNATIVES are not > > supported in the SGX LE") > > Maybe this? > > s/LE/Test Enclave Sure. > > diff --git a/tools/testing/selftests/x86/sgx/encl_bootstrap.S > > b/tools/testing/selftests/x86/sgx/encl_bootstrap.S > > new file mode 100644 > > index ..62251c7d9927 > > --- /dev/null > > +++ b/tools/testing/selftests/x86/sgx/encl_bootstrap.S > > @@ -0,0 +1,94 @@ > > +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ > > +/* > > + * Copyright(c) 2016-18 Intel Corporation. > > + */ > > + > > + .macro ENCLU > > + .byte 0x0f, 0x01, 0xd7 > > + .endm > > + > > + .section ".tcs", "a" > > + .balign 4096 > > + > > + .fill 1, 8, 0 # STATE (set by CPU) > > + .fill 1, 8, 0 # FLAGS > > + .long encl_ssa# OSSA > > Any reason not to do .quad for OSSA and OENTRY? Probably not. > > + .fill 1, 4, 0 > > + .fill 1, 4, 0 # CSSA (set by CPU) > > + .fill 1, 4, 1 # NSSA > > + .long encl_entry # OENTRY > > + .fill 1, 4, 0 > > + .fill 1, 8, 0 # AEP (set by EENTER and ERESUME) > > + .fill 1, 8, 0 # OFSBASE > > + .fill 1, 8, 0 # OGSBASE > > + .fill 1, 4, 0x# FSLIMIT > > + .fill 1, 4, 0x# GSLIMIT > > + .fill 503, 8, 0 # Reserved > > I'd prefer to do 1-byte fill with a size of 4024 to match the SDM. Sure. > > + > > + .text > > + > > +encl_entry: > > + # %rbx contains the base address for TCS, which is also the first > > + # address inside the enclave. By adding $le_stack_end to it, we get the > > + # absolute address for the stack. > > + lea (encl_stack)(%rbx), %rax > > + xchg%rsp, %rax > > + push%rax > > + > > + push%rcx # push the address after EENTER > > + push%rbx # push the enclave base address > > + > > + callencl_body > > + > > + pop %rbx # pop the enclave base address > > + > > + # Restore XSAVE registers to a synthetic state. > > + mov $0x, %rax > > + mov $0x, %rdx > > + lea (xsave_area)(%rbx), %rdi > > + fxrstor (%rdi) > > + > > + # Clear GPRs > > + xor %rcx, %rcx > > + xor %rdx, %rdx > > + xor %rdi, %rdi > > + xor %rsi, %rsi > > + xor %r8, %r8 > > + xor %r9, %r9 > > + xor %r10, %r10 > > + xor %r11, %r11 > > + xor %r12, %r12 > > + xor %r13, %r13 > > + xor %r14, %r14 > > + xor %r15, %r15 > > + > > + # Reset status flags > > + add %rdx, %rdx # OF = SF = AF = CF = 0; ZF = PF = 1 > > + > > + pop %rbx # pop the address after EENTER > > Probably worth expanding the comment to explain that ENCLU[EEXIT] takes the > target address via %rbx, i.e. we're "returning" from the EENTER "call". Thank you for the feedback. I'll do all of these updates. /Jarkko
Re: [PATCH RFC] selftests/x86: Add a selftest for SGX
On Wed, Nov 14, 2018 at 08:09:42AM -0800, Sean Christopherson wrote: > On Tue, Nov 13, 2018 at 11:40:09PM +0200, Jarkko Sakkinen wrote: > > Add a selftest for SGX. It is a trivial test where a simple enclave > > copies one 64-bit word of memory between two memory locations given to > > the enclave as arguments. > > > > Signed-off-by: Jarkko Sakkinen > > --- > > +SUBDIRS_64 := sgx > > +ASSERT(!DEFINED(.altinstructions), "ALTERNATIVES are not supported in the > > SGX LE") > > +ASSERT(!DEFINED(.altinstr_replacement), "ALTERNATIVES are not supported in > > the SGX LE") > > +ASSERT(!DEFINED(.discard.retpoline_safe), "RETPOLINE ALTERNATIVES are not > > supported in the SGX LE") > > +ASSERT(!DEFINED(.discard.nospec), "RETPOLINE ALTERNATIVES are not > > supported in the SGX LE") > > Maybe this? > > s/LE/Test Enclave Sure. > > diff --git a/tools/testing/selftests/x86/sgx/encl_bootstrap.S > > b/tools/testing/selftests/x86/sgx/encl_bootstrap.S > > new file mode 100644 > > index ..62251c7d9927 > > --- /dev/null > > +++ b/tools/testing/selftests/x86/sgx/encl_bootstrap.S > > @@ -0,0 +1,94 @@ > > +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ > > +/* > > + * Copyright(c) 2016-18 Intel Corporation. > > + */ > > + > > + .macro ENCLU > > + .byte 0x0f, 0x01, 0xd7 > > + .endm > > + > > + .section ".tcs", "a" > > + .balign 4096 > > + > > + .fill 1, 8, 0 # STATE (set by CPU) > > + .fill 1, 8, 0 # FLAGS > > + .long encl_ssa# OSSA > > Any reason not to do .quad for OSSA and OENTRY? Probably not. > > + .fill 1, 4, 0 > > + .fill 1, 4, 0 # CSSA (set by CPU) > > + .fill 1, 4, 1 # NSSA > > + .long encl_entry # OENTRY > > + .fill 1, 4, 0 > > + .fill 1, 8, 0 # AEP (set by EENTER and ERESUME) > > + .fill 1, 8, 0 # OFSBASE > > + .fill 1, 8, 0 # OGSBASE > > + .fill 1, 4, 0x# FSLIMIT > > + .fill 1, 4, 0x# GSLIMIT > > + .fill 503, 8, 0 # Reserved > > I'd prefer to do 1-byte fill with a size of 4024 to match the SDM. Sure. > > + > > + .text > > + > > +encl_entry: > > + # %rbx contains the base address for TCS, which is also the first > > + # address inside the enclave. By adding $le_stack_end to it, we get the > > + # absolute address for the stack. > > + lea (encl_stack)(%rbx), %rax > > + xchg%rsp, %rax > > + push%rax > > + > > + push%rcx # push the address after EENTER > > + push%rbx # push the enclave base address > > + > > + callencl_body > > + > > + pop %rbx # pop the enclave base address > > + > > + # Restore XSAVE registers to a synthetic state. > > + mov $0x, %rax > > + mov $0x, %rdx > > + lea (xsave_area)(%rbx), %rdi > > + fxrstor (%rdi) > > + > > + # Clear GPRs > > + xor %rcx, %rcx > > + xor %rdx, %rdx > > + xor %rdi, %rdi > > + xor %rsi, %rsi > > + xor %r8, %r8 > > + xor %r9, %r9 > > + xor %r10, %r10 > > + xor %r11, %r11 > > + xor %r12, %r12 > > + xor %r13, %r13 > > + xor %r14, %r14 > > + xor %r15, %r15 > > + > > + # Reset status flags > > + add %rdx, %rdx # OF = SF = AF = CF = 0; ZF = PF = 1 > > + > > + pop %rbx # pop the address after EENTER > > Probably worth expanding the comment to explain that ENCLU[EEXIT] takes the > target address via %rbx, i.e. we're "returning" from the EENTER "call". Thank you for the feedback. I'll do all of these updates. /Jarkko
Re: [PATCH RFC] selftests/x86: Add a selftest for SGX
On Tue, Nov 13, 2018 at 01:51:06PM -0800, Dave Hansen wrote: > On 11/13/18 1:40 PM, Jarkko Sakkinen wrote: > > +int main(int argc, char **argv) > > +{ > > + unsigned long bin_size = (unsigned long)_bin_end - > > +(unsigned long)_bin; > > + struct sgx_secs secs; > > + uint64_t result = 0; > > + > > + if (!encl_load(, bin_size)) > > + exit(1); > > + > > + sgx_call((void *), , (void *)secs.base); > > + if (result != MAGIC) { > > + fprintf(stderr, "0x%lx != 0x%lx\n", result, MAGIC); > > + exit(1); > > + } > > + > > + exit(0); > > +} > > Well, I guess 100 lines of code for something a wee bit shy of hello > world isn't bad. :) > > In general, this looks fine, but probably needs some better commenting > and probably some messages that make it a bit more clear what is going on. > > It would be _nice_, for instance to try to do some CPUID detection of > SGX so that the error (or success?) message can tell you whether you're > missing hardware support or kernel support. > > Thanks for doing this, though. It's sorely needed. Great, thanks, I see what I can do. /Jarkko
Re: [PATCH RFC] selftests/x86: Add a selftest for SGX
On Tue, Nov 13, 2018 at 01:51:06PM -0800, Dave Hansen wrote: > On 11/13/18 1:40 PM, Jarkko Sakkinen wrote: > > +int main(int argc, char **argv) > > +{ > > + unsigned long bin_size = (unsigned long)_bin_end - > > +(unsigned long)_bin; > > + struct sgx_secs secs; > > + uint64_t result = 0; > > + > > + if (!encl_load(, bin_size)) > > + exit(1); > > + > > + sgx_call((void *), , (void *)secs.base); > > + if (result != MAGIC) { > > + fprintf(stderr, "0x%lx != 0x%lx\n", result, MAGIC); > > + exit(1); > > + } > > + > > + exit(0); > > +} > > Well, I guess 100 lines of code for something a wee bit shy of hello > world isn't bad. :) > > In general, this looks fine, but probably needs some better commenting > and probably some messages that make it a bit more clear what is going on. > > It would be _nice_, for instance to try to do some CPUID detection of > SGX so that the error (or success?) message can tell you whether you're > missing hardware support or kernel support. > > Thanks for doing this, though. It's sorely needed. Great, thanks, I see what I can do. /Jarkko
Re: [PATCH RFC] selftests/x86: Add a selftest for SGX
On Tue, Nov 13, 2018 at 11:40:09PM +0200, Jarkko Sakkinen wrote: > Add a selftest for SGX. It is a trivial test where a simple enclave > copies one 64-bit word of memory between two memory locations given to > the enclave as arguments. > > Signed-off-by: Jarkko Sakkinen > --- > +SUBDIRS_64 := sgx > +ASSERT(!DEFINED(.altinstructions), "ALTERNATIVES are not supported in the > SGX LE") > +ASSERT(!DEFINED(.altinstr_replacement), "ALTERNATIVES are not supported in > the SGX LE") > +ASSERT(!DEFINED(.discard.retpoline_safe), "RETPOLINE ALTERNATIVES are not > supported in the SGX LE") > +ASSERT(!DEFINED(.discard.nospec), "RETPOLINE ALTERNATIVES are not supported > in the SGX LE") Maybe this? s/LE/Test Enclave > diff --git a/tools/testing/selftests/x86/sgx/encl_bootstrap.S > b/tools/testing/selftests/x86/sgx/encl_bootstrap.S > new file mode 100644 > index ..62251c7d9927 > --- /dev/null > +++ b/tools/testing/selftests/x86/sgx/encl_bootstrap.S > @@ -0,0 +1,94 @@ > +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ > +/* > + * Copyright(c) 2016-18 Intel Corporation. > + */ > + > + .macro ENCLU > + .byte 0x0f, 0x01, 0xd7 > + .endm > + > + .section ".tcs", "a" > + .balign 4096 > + > + .fill 1, 8, 0 # STATE (set by CPU) > + .fill 1, 8, 0 # FLAGS > + .long encl_ssa# OSSA Any reason not to do .quad for OSSA and OENTRY? > + .fill 1, 4, 0 > + .fill 1, 4, 0 # CSSA (set by CPU) > + .fill 1, 4, 1 # NSSA > + .long encl_entry # OENTRY > + .fill 1, 4, 0 > + .fill 1, 8, 0 # AEP (set by EENTER and ERESUME) > + .fill 1, 8, 0 # OFSBASE > + .fill 1, 8, 0 # OGSBASE > + .fill 1, 4, 0x# FSLIMIT > + .fill 1, 4, 0x# GSLIMIT > + .fill 503, 8, 0 # Reserved I'd prefer to do 1-byte fill with a size of 4024 to match the SDM. > + > + .text > + > +encl_entry: > + # %rbx contains the base address for TCS, which is also the first > + # address inside the enclave. By adding $le_stack_end to it, we get the > + # absolute address for the stack. > + lea (encl_stack)(%rbx), %rax > + xchg%rsp, %rax > + push%rax > + > + push%rcx # push the address after EENTER > + push%rbx # push the enclave base address > + > + callencl_body > + > + pop %rbx # pop the enclave base address > + > + # Restore XSAVE registers to a synthetic state. > + mov $0x, %rax > + mov $0x, %rdx > + lea (xsave_area)(%rbx), %rdi > + fxrstor (%rdi) > + > + # Clear GPRs > + xor %rcx, %rcx > + xor %rdx, %rdx > + xor %rdi, %rdi > + xor %rsi, %rsi > + xor %r8, %r8 > + xor %r9, %r9 > + xor %r10, %r10 > + xor %r11, %r11 > + xor %r12, %r12 > + xor %r13, %r13 > + xor %r14, %r14 > + xor %r15, %r15 > + > + # Reset status flags > + add %rdx, %rdx # OF = SF = AF = CF = 0; ZF = PF = 1 > + > + pop %rbx # pop the address after EENTER Probably worth expanding the comment to explain that ENCLU[EEXIT] takes the target address via %rbx, i.e. we're "returning" from the EENTER "call". > + > + # Restore the caller stack. > + pop %rax > + mov %rax, %rsp > + > + # EEXIT > + mov $4, %rax > + enclu > + > + .section ".data", "aw" > + > +encl_ssa: > + .space 4096 > + > +xsave_area: > + .fill 1, 4, 0x037F# FCW > + .fill 5, 4, 0 > + .fill 1, 4, 0x1F80# MXCSR > + .fill 1, 4, 0x# MXCSR_MASK > + .fill 123, 4, 0 > + .fill 1, 4, 0x8000# XCOMP_BV[63] = 1, compaction mode > + .fill 12, 4, 0 > + > + .balign 4096 > + .space 8192 > +encl_stack:
Re: [PATCH RFC] selftests/x86: Add a selftest for SGX
On Tue, Nov 13, 2018 at 11:40:09PM +0200, Jarkko Sakkinen wrote: > Add a selftest for SGX. It is a trivial test where a simple enclave > copies one 64-bit word of memory between two memory locations given to > the enclave as arguments. > > Signed-off-by: Jarkko Sakkinen > --- > +SUBDIRS_64 := sgx > +ASSERT(!DEFINED(.altinstructions), "ALTERNATIVES are not supported in the > SGX LE") > +ASSERT(!DEFINED(.altinstr_replacement), "ALTERNATIVES are not supported in > the SGX LE") > +ASSERT(!DEFINED(.discard.retpoline_safe), "RETPOLINE ALTERNATIVES are not > supported in the SGX LE") > +ASSERT(!DEFINED(.discard.nospec), "RETPOLINE ALTERNATIVES are not supported > in the SGX LE") Maybe this? s/LE/Test Enclave > diff --git a/tools/testing/selftests/x86/sgx/encl_bootstrap.S > b/tools/testing/selftests/x86/sgx/encl_bootstrap.S > new file mode 100644 > index ..62251c7d9927 > --- /dev/null > +++ b/tools/testing/selftests/x86/sgx/encl_bootstrap.S > @@ -0,0 +1,94 @@ > +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ > +/* > + * Copyright(c) 2016-18 Intel Corporation. > + */ > + > + .macro ENCLU > + .byte 0x0f, 0x01, 0xd7 > + .endm > + > + .section ".tcs", "a" > + .balign 4096 > + > + .fill 1, 8, 0 # STATE (set by CPU) > + .fill 1, 8, 0 # FLAGS > + .long encl_ssa# OSSA Any reason not to do .quad for OSSA and OENTRY? > + .fill 1, 4, 0 > + .fill 1, 4, 0 # CSSA (set by CPU) > + .fill 1, 4, 1 # NSSA > + .long encl_entry # OENTRY > + .fill 1, 4, 0 > + .fill 1, 8, 0 # AEP (set by EENTER and ERESUME) > + .fill 1, 8, 0 # OFSBASE > + .fill 1, 8, 0 # OGSBASE > + .fill 1, 4, 0x# FSLIMIT > + .fill 1, 4, 0x# GSLIMIT > + .fill 503, 8, 0 # Reserved I'd prefer to do 1-byte fill with a size of 4024 to match the SDM. > + > + .text > + > +encl_entry: > + # %rbx contains the base address for TCS, which is also the first > + # address inside the enclave. By adding $le_stack_end to it, we get the > + # absolute address for the stack. > + lea (encl_stack)(%rbx), %rax > + xchg%rsp, %rax > + push%rax > + > + push%rcx # push the address after EENTER > + push%rbx # push the enclave base address > + > + callencl_body > + > + pop %rbx # pop the enclave base address > + > + # Restore XSAVE registers to a synthetic state. > + mov $0x, %rax > + mov $0x, %rdx > + lea (xsave_area)(%rbx), %rdi > + fxrstor (%rdi) > + > + # Clear GPRs > + xor %rcx, %rcx > + xor %rdx, %rdx > + xor %rdi, %rdi > + xor %rsi, %rsi > + xor %r8, %r8 > + xor %r9, %r9 > + xor %r10, %r10 > + xor %r11, %r11 > + xor %r12, %r12 > + xor %r13, %r13 > + xor %r14, %r14 > + xor %r15, %r15 > + > + # Reset status flags > + add %rdx, %rdx # OF = SF = AF = CF = 0; ZF = PF = 1 > + > + pop %rbx # pop the address after EENTER Probably worth expanding the comment to explain that ENCLU[EEXIT] takes the target address via %rbx, i.e. we're "returning" from the EENTER "call". > + > + # Restore the caller stack. > + pop %rax > + mov %rax, %rsp > + > + # EEXIT > + mov $4, %rax > + enclu > + > + .section ".data", "aw" > + > +encl_ssa: > + .space 4096 > + > +xsave_area: > + .fill 1, 4, 0x037F# FCW > + .fill 5, 4, 0 > + .fill 1, 4, 0x1F80# MXCSR > + .fill 1, 4, 0x# MXCSR_MASK > + .fill 123, 4, 0 > + .fill 1, 4, 0x8000# XCOMP_BV[63] = 1, compaction mode > + .fill 12, 4, 0 > + > + .balign 4096 > + .space 8192 > +encl_stack:
Re: [PATCH RFC] selftests/x86: Add a selftest for SGX
On 11/13/18 1:40 PM, Jarkko Sakkinen wrote: > +int main(int argc, char **argv) > +{ > + unsigned long bin_size = (unsigned long)_bin_end - > + (unsigned long)_bin; > + struct sgx_secs secs; > + uint64_t result = 0; > + > + if (!encl_load(, bin_size)) > + exit(1); > + > + sgx_call((void *), , (void *)secs.base); > + if (result != MAGIC) { > + fprintf(stderr, "0x%lx != 0x%lx\n", result, MAGIC); > + exit(1); > + } > + > + exit(0); > +} Well, I guess 100 lines of code for something a wee bit shy of hello world isn't bad. :) In general, this looks fine, but probably needs some better commenting and probably some messages that make it a bit more clear what is going on. It would be _nice_, for instance to try to do some CPUID detection of SGX so that the error (or success?) message can tell you whether you're missing hardware support or kernel support. Thanks for doing this, though. It's sorely needed.
Re: [PATCH RFC] selftests/x86: Add a selftest for SGX
On 11/13/18 1:40 PM, Jarkko Sakkinen wrote: > +int main(int argc, char **argv) > +{ > + unsigned long bin_size = (unsigned long)_bin_end - > + (unsigned long)_bin; > + struct sgx_secs secs; > + uint64_t result = 0; > + > + if (!encl_load(, bin_size)) > + exit(1); > + > + sgx_call((void *), , (void *)secs.base); > + if (result != MAGIC) { > + fprintf(stderr, "0x%lx != 0x%lx\n", result, MAGIC); > + exit(1); > + } > + > + exit(0); > +} Well, I guess 100 lines of code for something a wee bit shy of hello world isn't bad. :) In general, this looks fine, but probably needs some better commenting and probably some messages that make it a bit more clear what is going on. It would be _nice_, for instance to try to do some CPUID detection of SGX so that the error (or success?) message can tell you whether you're missing hardware support or kernel support. Thanks for doing this, though. It's sorely needed.
[PATCH RFC] selftests/x86: Add a selftest for SGX
Add a selftest for SGX. It is a trivial test where a simple enclave copies one 64-bit word of memory between two memory locations given to the enclave as arguments. Signed-off-by: Jarkko Sakkinen --- Since this is my very first addition to selftests, I decided to roll out an RFC patch before including this to the main SGX series. tools/testing/selftests/x86/Makefile | 10 + tools/testing/selftests/x86/sgx/Makefile | 47 ++ tools/testing/selftests/x86/sgx/encl.c| 20 + tools/testing/selftests/x86/sgx/encl.lds | 33 ++ .../selftests/x86/sgx/encl_bootstrap.S| 94 tools/testing/selftests/x86/sgx/encl_piggy.S | 16 + tools/testing/selftests/x86/sgx/encl_piggy.h | 13 + .../testing/selftests/x86/sgx/sgx-selftest.c | 146 + tools/testing/selftests/x86/sgx/sgx_arch.h| 109 tools/testing/selftests/x86/sgx/sgx_call.S| 20 + tools/testing/selftests/x86/sgx/sgx_uapi.h| 100 tools/testing/selftests/x86/sgx/sgxsign.c | 503 ++ .../testing/selftests/x86/sgx/signing_key.pem | 39 ++ 13 files changed, 1150 insertions(+) create mode 100644 tools/testing/selftests/x86/sgx/Makefile create mode 100644 tools/testing/selftests/x86/sgx/encl.c create mode 100644 tools/testing/selftests/x86/sgx/encl.lds create mode 100644 tools/testing/selftests/x86/sgx/encl_bootstrap.S create mode 100644 tools/testing/selftests/x86/sgx/encl_piggy.S create mode 100644 tools/testing/selftests/x86/sgx/encl_piggy.h create mode 100644 tools/testing/selftests/x86/sgx/sgx-selftest.c create mode 100644 tools/testing/selftests/x86/sgx/sgx_arch.h create mode 100644 tools/testing/selftests/x86/sgx/sgx_call.S create mode 100644 tools/testing/selftests/x86/sgx/sgx_uapi.h create mode 100644 tools/testing/selftests/x86/sgx/sgxsign.c create mode 100644 tools/testing/selftests/x86/sgx/signing_key.pem diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index 186520198de7..4fc9a42f56ea 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 + +SUBDIRS_64 := sgx + all: include ../lib.mk @@ -67,6 +70,13 @@ all_32: $(BINARIES_32) all_64: $(BINARIES_64) +all_64: $(SUBDIRS_64) + @for DIR in $(SUBDIRS_64); do \ + BUILD_TARGET=$(OUTPUT)/$$DIR; \ + mkdir $$BUILD_TARGET -p; \ + make OUTPUT=$$BUILD_TARGET -C $$DIR $@; \ + done + EXTRA_CLEAN := $(BINARIES_32) $(BINARIES_64) $(BINARIES_32): $(OUTPUT)/%_32: %.c diff --git a/tools/testing/selftests/x86/sgx/Makefile b/tools/testing/selftests/x86/sgx/Makefile new file mode 100644 index ..04004d244de4 --- /dev/null +++ b/tools/testing/selftests/x86/sgx/Makefile @@ -0,0 +1,47 @@ +top_srcdir = ../../../../.. + +include ../../lib.mk + +HOST_CFLAGS := -Wall -Werror -g +ENCL_CFLAGS := -Wall -Werror -static -nostdlib -nostartfiles -fPIC \ + -fno-stack-protector -mrdrnd + +TEST_CUSTOM_PROGS := $(OUTPUT)/sgx-selftest +all_64: $(TEST_CUSTOM_PROGS) + +$(TEST_CUSTOM_PROGS): $(OUTPUT)/sgx-selftest.o $(OUTPUT)/sgx_call.o \ + $(OUTPUT)/encl_piggy.o + $(CC) $(HOST_CFLAGS) -o $@ $^ + +$(OUTPUT)/sgx-selftest.o: sgx-selftest.c + $(CC) $(HOST_CFLAGS) -c $< -o $@ + +$(OUTPUT)/sgx_call.o: sgx_call.S + $(CC) $(HOST_CFLAGS) -c $< -o $@ + +$(OUTPUT)/encl_piggy.o: $(OUTPUT)/encl.bin $(OUTPUT)/encl.ss + +$(OUTPUT)/encl.bin: $(OUTPUT)/encl.elf $(OUTPUT)/sgxsign + objcopy --remove-section=.got.plt -O binary $< $@ + +$(OUTPUT)/encl.elf: $(OUTPUT)/encl.o $(OUTPUT)/encl_bootstrap.o + $(CC) $(ENCL_CFLAGS) -T encl.lds -o $@ $^ + +$(OUTPUT)/encl.o: encl.c + $(CC) $(ENCL_CFLAGS) -c $< -o $@ + +$(OUTPUT)/encl_bootstrap.o: encl_bootstrap.S + $(CC) $(ENCL_CFLAGS) -c $< -o $@ + +$(OUTPUT)/encl.ss: $(OUTPUT)/encl.bin $(OUTPUT)/sgxsign + $(OUTPUT)/sgxsign signing_key.pem $(OUTPUT)/encl.bin $(OUTPUT)/encl.ss + +$(OUTPUT)/sgxsign: sgxsign.c + $(CC) -o $@ $< -lcrypto + +EXTRA_CLEAN := $(OUTPUT)/sgx-selftest $(OUTPUT)/sgx-selftest.o \ + $(OUTPUT)/sgx_call.o $(OUTPUT)/encl.bin $(OUTPUT)/encl.ss \ + $(OUTPUT)/encl.elf $(OUTPUT)/encl.o $(OUTPUT)/encl_bootstrap.o \ + $(OUTPUT)/sgxsign + +.PHONY: clean diff --git a/tools/testing/selftests/x86/sgx/encl.c b/tools/testing/selftests/x86/sgx/encl.c new file mode 100644 index ..eb6aa318d3f1 --- /dev/null +++ b/tools/testing/selftests/x86/sgx/encl.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +// Copyright(c) 2016-18 Intel Corporation. + +#include +#include "sgx_arch.h" + +static void *memcpy(void *dest, const void *src, size_t n) +{ + size_t i; + + for (i = 0; i < n; i++) + ((char *)dest)[i] = ((char *)src)[i]; + + return dest; +} + +void encl_body(void *rdi, void *rsi) +{ +
[PATCH RFC] selftests/x86: Add a selftest for SGX
Add a selftest for SGX. It is a trivial test where a simple enclave copies one 64-bit word of memory between two memory locations given to the enclave as arguments. Signed-off-by: Jarkko Sakkinen --- Since this is my very first addition to selftests, I decided to roll out an RFC patch before including this to the main SGX series. tools/testing/selftests/x86/Makefile | 10 + tools/testing/selftests/x86/sgx/Makefile | 47 ++ tools/testing/selftests/x86/sgx/encl.c| 20 + tools/testing/selftests/x86/sgx/encl.lds | 33 ++ .../selftests/x86/sgx/encl_bootstrap.S| 94 tools/testing/selftests/x86/sgx/encl_piggy.S | 16 + tools/testing/selftests/x86/sgx/encl_piggy.h | 13 + .../testing/selftests/x86/sgx/sgx-selftest.c | 146 + tools/testing/selftests/x86/sgx/sgx_arch.h| 109 tools/testing/selftests/x86/sgx/sgx_call.S| 20 + tools/testing/selftests/x86/sgx/sgx_uapi.h| 100 tools/testing/selftests/x86/sgx/sgxsign.c | 503 ++ .../testing/selftests/x86/sgx/signing_key.pem | 39 ++ 13 files changed, 1150 insertions(+) create mode 100644 tools/testing/selftests/x86/sgx/Makefile create mode 100644 tools/testing/selftests/x86/sgx/encl.c create mode 100644 tools/testing/selftests/x86/sgx/encl.lds create mode 100644 tools/testing/selftests/x86/sgx/encl_bootstrap.S create mode 100644 tools/testing/selftests/x86/sgx/encl_piggy.S create mode 100644 tools/testing/selftests/x86/sgx/encl_piggy.h create mode 100644 tools/testing/selftests/x86/sgx/sgx-selftest.c create mode 100644 tools/testing/selftests/x86/sgx/sgx_arch.h create mode 100644 tools/testing/selftests/x86/sgx/sgx_call.S create mode 100644 tools/testing/selftests/x86/sgx/sgx_uapi.h create mode 100644 tools/testing/selftests/x86/sgx/sgxsign.c create mode 100644 tools/testing/selftests/x86/sgx/signing_key.pem diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index 186520198de7..4fc9a42f56ea 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 + +SUBDIRS_64 := sgx + all: include ../lib.mk @@ -67,6 +70,13 @@ all_32: $(BINARIES_32) all_64: $(BINARIES_64) +all_64: $(SUBDIRS_64) + @for DIR in $(SUBDIRS_64); do \ + BUILD_TARGET=$(OUTPUT)/$$DIR; \ + mkdir $$BUILD_TARGET -p; \ + make OUTPUT=$$BUILD_TARGET -C $$DIR $@; \ + done + EXTRA_CLEAN := $(BINARIES_32) $(BINARIES_64) $(BINARIES_32): $(OUTPUT)/%_32: %.c diff --git a/tools/testing/selftests/x86/sgx/Makefile b/tools/testing/selftests/x86/sgx/Makefile new file mode 100644 index ..04004d244de4 --- /dev/null +++ b/tools/testing/selftests/x86/sgx/Makefile @@ -0,0 +1,47 @@ +top_srcdir = ../../../../.. + +include ../../lib.mk + +HOST_CFLAGS := -Wall -Werror -g +ENCL_CFLAGS := -Wall -Werror -static -nostdlib -nostartfiles -fPIC \ + -fno-stack-protector -mrdrnd + +TEST_CUSTOM_PROGS := $(OUTPUT)/sgx-selftest +all_64: $(TEST_CUSTOM_PROGS) + +$(TEST_CUSTOM_PROGS): $(OUTPUT)/sgx-selftest.o $(OUTPUT)/sgx_call.o \ + $(OUTPUT)/encl_piggy.o + $(CC) $(HOST_CFLAGS) -o $@ $^ + +$(OUTPUT)/sgx-selftest.o: sgx-selftest.c + $(CC) $(HOST_CFLAGS) -c $< -o $@ + +$(OUTPUT)/sgx_call.o: sgx_call.S + $(CC) $(HOST_CFLAGS) -c $< -o $@ + +$(OUTPUT)/encl_piggy.o: $(OUTPUT)/encl.bin $(OUTPUT)/encl.ss + +$(OUTPUT)/encl.bin: $(OUTPUT)/encl.elf $(OUTPUT)/sgxsign + objcopy --remove-section=.got.plt -O binary $< $@ + +$(OUTPUT)/encl.elf: $(OUTPUT)/encl.o $(OUTPUT)/encl_bootstrap.o + $(CC) $(ENCL_CFLAGS) -T encl.lds -o $@ $^ + +$(OUTPUT)/encl.o: encl.c + $(CC) $(ENCL_CFLAGS) -c $< -o $@ + +$(OUTPUT)/encl_bootstrap.o: encl_bootstrap.S + $(CC) $(ENCL_CFLAGS) -c $< -o $@ + +$(OUTPUT)/encl.ss: $(OUTPUT)/encl.bin $(OUTPUT)/sgxsign + $(OUTPUT)/sgxsign signing_key.pem $(OUTPUT)/encl.bin $(OUTPUT)/encl.ss + +$(OUTPUT)/sgxsign: sgxsign.c + $(CC) -o $@ $< -lcrypto + +EXTRA_CLEAN := $(OUTPUT)/sgx-selftest $(OUTPUT)/sgx-selftest.o \ + $(OUTPUT)/sgx_call.o $(OUTPUT)/encl.bin $(OUTPUT)/encl.ss \ + $(OUTPUT)/encl.elf $(OUTPUT)/encl.o $(OUTPUT)/encl_bootstrap.o \ + $(OUTPUT)/sgxsign + +.PHONY: clean diff --git a/tools/testing/selftests/x86/sgx/encl.c b/tools/testing/selftests/x86/sgx/encl.c new file mode 100644 index ..eb6aa318d3f1 --- /dev/null +++ b/tools/testing/selftests/x86/sgx/encl.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +// Copyright(c) 2016-18 Intel Corporation. + +#include +#include "sgx_arch.h" + +static void *memcpy(void *dest, const void *src, size_t n) +{ + size_t i; + + for (i = 0; i < n; i++) + ((char *)dest)[i] = ((char *)src)[i]; + + return dest; +} + +void encl_body(void *rdi, void *rsi) +{ +