github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/src/gosec/sgxlib.go (about)

     1  package gosec
     2  
     3  import (
     4  	"debug/elf"
     5  	"log"
     6  	"os"
     7  	"reflect"
     8  	"runtime"
     9  	"sort"
    10  	"syscall"
    11  	"unsafe"
    12  )
    13  
    14  const (
    15  	SGX_PATH = "/dev/isgx"
    16  	PSIZE    = uintptr(0x1000)
    17  	//TODO @aghosn this must be exactly the same as in amd64/obj.go
    18  	ENCLMASK = 0x040000000000
    19  	ENCLSIZE = 0x001000000000
    20  
    21  	MMMASK  = 0x050000000000
    22  	SIM_OFF = 0x08
    23  
    24  	SIM_FLAG  = 0x050000000008
    25  	MSGX_ADDR = 0x050000000020
    26  	//TLS is m0+m_tls+8
    27  	TLS_MSGX_OFF = (0x98 + 8)            // TODO this depends on m_tls which is bad.
    28  	NBTCS        = runtime.EnclaveMaxTls // how many tcs do we provide.
    29  )
    30  
    31  type SortedElfSections []*elf.Section
    32  
    33  func (s SortedElfSections) Len() int {
    34  	return len(s)
    35  }
    36  
    37  func (s SortedElfSections) Swap(i, j int) {
    38  	s[i], s[j] = s[j], s[i]
    39  }
    40  
    41  func (s SortedElfSections) Less(i, j int) bool {
    42  	return s[i].Addr < s[j].Addr
    43  }
    44  
    45  var (
    46  	sgxFd    *os.File = nil
    47  	enclWrap *sgx_wrapper
    48  	srcWrap  *sgx_wrapper
    49  )
    50  
    51  // asm_eenter calls the enclu.
    52  func asm_eenter(tcs, xcpt, rdi, rsi uint64)
    53  
    54  // asm_eresume calls enclu to resume execution
    55  func asm_eresume(tcs, xcpt uint64)
    56  
    57  // asm_exception does an eresume
    58  func asm_exception()
    59  
    60  func sgxLoadProgram(path string) {
    61  	sgxInit()
    62  	file, err := elf.Open(path)
    63  	check(err)
    64  	var secs *secs_t
    65  	secs, enclWrap = sgxCreateSecs(file)
    66  	enclWrap.isSim = false
    67  
    68  	// ECREATE & mmap enclave
    69  	sgxEcreate(secs)
    70  
    71  	// Allocate the equivalent region for the eadd page.
    72  	srcWrap = transposeOutWrapper(enclWrap)
    73  
    74  	src := srcWrap.base
    75  	prot := int(_PROT_READ | _PROT_WRITE)
    76  	srcptr, ret := syscall.RMmap(src, int(srcWrap.siz), prot,
    77  		_MAP_NORESERVE|_MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
    78  	check(ret)
    79  	srcWrap.alloc = srcptr
    80  
    81  	// Check that the sections are sorted now.
    82  	sort.Sort(SortedElfSections(file.Sections))
    83  
    84  	// EADD the different parts, mmap them at different offsets.
    85  	var aggreg []*elf.Section
    86  	for _, sec := range file.Sections {
    87  		if sec.Flags&elf.SHF_ALLOC != elf.SHF_ALLOC {
    88  			continue
    89  		}
    90  		if len(aggreg) == 0 || aggreg[len(aggreg)-1].Flags == sec.Flags {
    91  			aggreg = append(aggreg, sec)
    92  			continue
    93  		}
    94  
    95  		sgxMapSections(secs, aggreg, enclWrap, srcWrap)
    96  		aggreg = nil
    97  		aggreg = append(aggreg, sec)
    98  	}
    99  	sgxMapSections(secs, aggreg, enclWrap, srcWrap)
   100  
   101  	//Setup the stack arguments and Cooprt heap.
   102  	//This allows to make the argv part of the measurement.
   103  	stcs := srcWrap.defaultTcs()
   104  	_ = runtime.SetupEnclSysStack(stcs.Stack+stcs.Ssiz, enclWrap.mhstart)
   105  
   106  	// Mprotect and EADD stack and preallocated.
   107  	sgxEaddPrealloc(secs, enclWrap, srcWrap)
   108  	// initialize the TCSs and Eadd their elements.
   109  	sgxRegisterTCSs(enclWrap, srcWrap)
   110  
   111  	// EINIT: first get the token, then call the ioctl.
   112  	sgxHashFinalize()
   113  	tok := sgxTokenGetAesm(secs)
   114  	sgxEinit(secs, &tok)
   115  
   116  	//unmap the srcRegion
   117  	err = syscall.Munmap(srcptr)
   118  	check(err)
   119  
   120  	//transpstack := transposeIn(pstack)
   121  	fn := unsafe.Pointer(reflect.ValueOf(asm_eenter).Pointer())
   122  	enclWrap.entry = uintptr(fn)
   123  	runtime.Cooprt.Tcss = enclWrap.tcss
   124  	runtime.Cooprt.ExceptionHandler = uint64(reflect.ValueOf(asm_exception).Pointer())
   125  	stcs = srcWrap.defaultTcs()
   126  	dtcs := enclWrap.defaultTcs()
   127  	stcs.Used, dtcs.Used = true, true
   128  	sgxEEnter(uint64(0), dtcs, stcs, nil)
   129  }
   130  
   131  // palign does a page align.
   132  // If lower is true, it takes the lower address to start (align up)errno 0
   133  // Otherwise it takes the greater page alignment address (align down)
   134  func palign(addr uint64, lower bool) uint64 {
   135  	const mask = uint64(0xFFFFFFFFFFFFF000)
   136  	res := addr & mask
   137  	if res < addr && !lower {
   138  		return res + uint64(PSIZE)
   139  	}
   140  
   141  	return res
   142  }
   143  
   144  // sgxCreateSecs generates the SGX SECS struct according to the file.
   145  // It goes through the elf and computes the range of addresses needed for the
   146  // enclave ELRANGE. That includes the heap and the system stack.
   147  // It should not mmap anything. This will be done later on.
   148  func sgxCreateSecs(file *elf.File) (*secs_t, *sgx_wrapper) {
   149  	var aggreg []*elf.Section
   150  	fnFilter := func(e *elf.Section) bool {
   151  		return e.Flags&elf.SHF_ALLOC == elf.SHF_ALLOC
   152  	}
   153  	for _, sec := range file.Sections {
   154  		if fnFilter(sec) {
   155  			aggreg = append(aggreg, sec)
   156  		}
   157  	}
   158  	var baseAddr = uint64(ENCLMASK * 2)
   159  	var endAddr = uint64(0x0)
   160  	for _, sec := range aggreg {
   161  		if sec.Addr < baseAddr {
   162  			baseAddr = sec.Addr
   163  		}
   164  		if sec.Addr+sec.Size > endAddr {
   165  			endAddr = sec.Addr + sec.Size
   166  		}
   167  	}
   168  	// We can create the bounds that we want for the enclave as long as it contains
   169  	// the values from the binary.
   170  	if baseAddr < ENCLMASK {
   171  		log.Fatalf("gosec: < binary outside of enclave region: %x\n", baseAddr)
   172  	}
   173  
   174  	if endAddr > ENCLMASK+ENCLSIZE {
   175  		log.Fatalf("gosec: > binary outside of enclave region: %x\n", endAddr)
   176  	}
   177  	secs := &secs_t{}
   178  	secs.baseAddr = uint64(ENCLMASK)
   179  	secs.size = uint64(ENCLSIZE)
   180  	secs.xfrm = 0x7
   181  	secs.ssaFrameSize = 1
   182  	secs.attributes = 0x06
   183  	// Here we should setup stack | guard page | TCS | SSA
   184  	wrapper := &sgx_wrapper{}
   185  	wrapper.base = uintptr(secs.baseAddr)
   186  	wrapper.siz = uintptr(secs.size)
   187  	wrapper.tcss = make([]sgx_tcs_info, NBTCS)
   188  	wrapper.mtlsarr = getMtlsArr(file)
   189  	for i := 0; i < NBTCS; i++ {
   190  		ptcs := &wrapper.tcss[i]
   191  		ptcs.Stack = uintptr(palign(endAddr, false)) + 2*PSIZE
   192  		ptcs.Ssiz = uintptr(STACK_SIZE)
   193  		ptcs.Tcs = ptcs.Stack + uintptr(STACK_SIZE) + STACK_TCS_OFF
   194  		ptcs.Ssa = ptcs.Tcs + uintptr(TCS_SIZE) + TCS_SSA_OFF
   195  		endAddr = uint64(ptcs.Ssa + SSA_SIZE + SSA_MSGX_OFF + MSGX_SIZE + MSGX_TLS_OFF + TLS_SIZE)
   196  		ptcs.Msgx = wrapper.mtlsarr + uintptr(i)*(MSGX_SIZE+MSGX_TLS_OFF+TLS_SIZE)
   197  		ptcs.Tls = ptcs.Msgx + uintptr(MSGX_SIZE) + MSGX_TLS_OFF
   198  		ptcs.Entry = uintptr(file.Entry)
   199  		ptcs.Used = false
   200  	}
   201  	wrapper.mhstart = uintptr(endAddr) + TLS_MHSTART_OFF
   202  	wrapper.mhsize = runtime.EnclHeapSizeToAllocate()
   203  	wrapper.membuf = ENCLMASK + ENCLSIZE - PSIZE - MEMBUF_SIZE
   204  	if wrapper.membuf < wrapper.mhstart+wrapper.mhsize {
   205  		panic("gosec: reduce the amount of pages in membuf.")
   206  	}
   207  	wrapper.alloc = nil
   208  	if wrapper.mhstart+wrapper.mhsize > ENCLMASK+ENCLSIZE {
   209  		log.Printf("enclave limit: %x - end: %x\n", ENCLMASK+ENCLSIZE, wrapper.mhstart+wrapper.mhsize)
   210  		panic("gosec: Required size is out of enclave limits.")
   211  	}
   212  	wrapper.secs = secs
   213  	return secs, wrapper
   214  }
   215  
   216  //sgxTCSPrealloc eadds all preallocated memory (stacks, heap and membuf)
   217  func sgxEaddPrealloc(secs *secs_t, dest, src *sgx_wrapper) {
   218  	prot := uintptr(_PROT_READ | _PROT_WRITE)
   219  	for i, dtcs := range dest.tcss {
   220  		stcs := &src.tcss[i]
   221  		sgxAddRegion(secs, dtcs.Stack, stcs.Stack, dtcs.Ssiz, prot, SGX_SECINFO_REG)
   222  	}
   223  	//eadd heap and membuf
   224  	sgxAddRegion(secs, dest.mhstart, src.mhstart, dest.mhsize, prot, SGX_SECINFO_REG)
   225  	sgxAddRegion(secs, dest.membuf, src.membuf, MEMBUF_SIZE, prot, SGX_SECINFO_REG)
   226  }
   227  
   228  func sgxRegisterTCSs(dest, src *sgx_wrapper) {
   229  	if dest.secs == nil || dest.tcss == nil || len(dest.tcss) != len(src.tcss) {
   230  		panic("Uninitialized parameters.")
   231  	}
   232  
   233  	for i := range dest.tcss {
   234  		sgxInitEaddTCS(uint64(dest.tcss[i].Entry), dest.secs, &dest.tcss[i], &src.tcss[i])
   235  	}
   236  }
   237  
   238  func sgxInitEaddTCS(entry uint64, secs *secs_t, dest, src *sgx_tcs_info) {
   239  	tcs := (*tcs_t)(unsafe.Pointer(src.Tcs))
   240  	tcs.reserved1 = uint64(0)
   241  	tcs.flags = uint64(0)
   242  	tcs.ossa = uint64(dest.Ssa) - secs.baseAddr
   243  	tcs.cssa = uint32(0)
   244  	tcs.nssa = TCS_N_SSA
   245  	tcs.oentry = entry - secs.baseAddr
   246  	tcs.reserved2 = uint64(0)
   247  
   248  	tcs.ofsbasgx = uint64(dest.Tls) - secs.baseAddr
   249  	tcs.ogsbasgx = tcs.ofsbasgx
   250  	tcs.fslimit = SGX_FS_LIMIT
   251  	tcs.gslimit = SGX_GS_LIMIT
   252  	for i := range tcs.reserved3 {
   253  		tcs.reserved3[i] = uint64(0)
   254  	}
   255  
   256  	// Add the TCS
   257  	sgxAddRegion(secs, dest.Tcs, src.Tcs, PSIZE, _PROT_READ|_PROT_WRITE,
   258  		SGX_SECINFO_TCS)
   259  
   260  	// Add the SSA and FS.
   261  	sgxAddRegion(secs, dest.Ssa, src.Ssa,
   262  		SSA_SIZE, _PROT_READ|_PROT_WRITE, SGX_SECINFO_REG)
   263  
   264  	// TLS and MSGX are already mapped in BSS.
   265  }
   266  
   267  func sgxAddRegion(secs *secs_t, addr, src, siz, prot uintptr, tpe uint64) {
   268  	// First do the mprotect.
   269  	_, _, ret := syscall.Syscall(syscall.SYS_MPROTECT, addr, siz, prot)
   270  	if ret != 0 {
   271  		log.Println("gosec: sgxAddRegion mprotect failed ", ret)
   272  		panic("stopping execution.")
   273  	}
   274  	for x, y := addr, src; x < addr+siz; x, y = x+PSIZE, y+PSIZE {
   275  		sgxEadd(secs, x, y, prot, tpe)
   276  	}
   277  }
   278  
   279  func transposeOut(addr uintptr) uintptr {
   280  	if addr < ENCLMASK || addr > ENCLMASK+ENCLSIZE {
   281  		log.Fatalln("gosec: transpose out invalid address: ", addr)
   282  	}
   283  	return (addr - ENCLMASK + MMMASK)
   284  }
   285  
   286  func transposeIn(addr uintptr) uintptr {
   287  	if addr < MMMASK || addr > MMMASK+ENCLSIZE {
   288  		log.Fatalln("gosec: transpose in invalid address: ", addr)
   289  	}
   290  	return (addr - MMMASK + ENCLMASK)
   291  }
   292  
   293  func sgxMapSections(sgxsec *secs_t, secs []*elf.Section, wrap, srcRegion *sgx_wrapper) {
   294  	if len(secs) == 0 {
   295  		return
   296  	}
   297  
   298  	start := uintptr(palign(uint64(secs[0].Addr), true))
   299  	end := uintptr(palign(uint64(secs[len(secs)-1].Addr+secs[len(secs)-1].Size), false))
   300  	size := int(end - start)
   301  	if start >= end {
   302  		log.Fatalf("Error, sections are not ordered: %#x - %#x", start, end)
   303  	}
   304  	if start < wrap.base || end > wrap.base+wrap.siz {
   305  		panic("gosec: section is outside of the enclave region.")
   306  	}
   307  
   308  	for _, sec := range secs {
   309  		if sec.Type == elf.SHT_NOBITS {
   310  			continue
   311  		}
   312  		data, err := sec.Data()
   313  		check(err)
   314  		offset := int(sec.Addr - uint64(wrap.base))
   315  		for i := range data {
   316  			srcRegion.alloc[offset+i] = data[i]
   317  		}
   318  	}
   319  	prot := _PROT_READ
   320  	if (secs[0].Flags & elf.SHF_WRITE) == elf.SHF_WRITE {
   321  		prot |= _PROT_WRITE
   322  	}
   323  
   324  	if (secs[0].Flags & elf.SHF_EXECINSTR) == elf.SHF_EXECINSTR {
   325  		prot |= _PROT_EXEC
   326  	}
   327  
   328  	sgxAddRegion(sgxsec, start, transposeOut(start), uintptr(size), uintptr(prot), SGX_SECINFO_REG)
   329  }
   330  
   331  func sgxInit() int {
   332  	if sgxFd != nil {
   333  		return 0
   334  	}
   335  	var err error
   336  	sgxFd, err = os.OpenFile(SGX_PATH, os.O_RDWR, 0)
   337  	check(err)
   338  	// Initialize the signature.
   339  	sgxHashInit()
   340  	return 0
   341  }
   342  
   343  // sgxEcreate calls the IOCTL to create the enclave.
   344  // It first performs an mmap of the entire region that we use for the enclave.
   345  func sgxEcreate(secs *secs_t) {
   346  	prot := int32(_PROT_NONE)
   347  	mprot := int32(_MAP_SHARED | _MAP_FIXED)
   348  	fd := int32(sgxFd.Fd())
   349  	addr := uintptr(secs.baseAddr)
   350  	ptr, err := runtime.RMmap(unsafe.Pointer(addr), uintptr(secs.size), prot, mprot, fd, 0)
   351  	if err != 0 || addr != uintptr(ptr) {
   352  		log.Fatalln("gosec: unable to mmap the enclave: ", err)
   353  	}
   354  
   355  	parms := &sgx_enclave_create{}
   356  	parms.src = uint64(uintptr(unsafe.Pointer(secs)))
   357  	ptr2 := uintptr(unsafe.Pointer(parms))
   358  	_, _, ret := syscall.Syscall(syscall.SYS_IOCTL, uintptr(sgxFd.Fd()), uintptr(SGX_IOC_ENCLAVE_CREATE), ptr2)
   359  	if ret != 0 {
   360  		log.Println("The secs: ", secs)
   361  		log.Fatalln("Failed in call to ecreate: ", ret)
   362  	}
   363  
   364  	sgxHashEcreate(secs)
   365  }
   366  
   367  func sgxEadd(secs *secs_t, daddr, oaddr, prot uintptr, tpe uint64) {
   368  	eadd := &sgx_enclave_add_page{}
   369  	eadd.addr = uint64(daddr)
   370  	eadd.src = uint64(uintptr(oaddr))
   371  	eadd.mrmask = uint16(0xffff)
   372  	if prot&_PROT_WRITE != 0 && tpe != SGX_SECINFO_TCS {
   373  		eadd.mrmask = uint16(0x0)
   374  	}
   375  
   376  	secinfo := &isgx_secinfo{}
   377  	secinfo.flags = tpe
   378  	if prot&_PROT_EXEC != 0 {
   379  		secinfo.flags |= SGX_SECINFO_X
   380  	}
   381  	if prot&_PROT_READ != 0 {
   382  		secinfo.flags |= SGX_SECINFO_R
   383  	}
   384  	if prot&_PROT_WRITE != 0 {
   385  		secinfo.flags |= SGX_SECINFO_W
   386  	}
   387  
   388  	// Special case for the TCS, no protections.
   389  	if tpe == SGX_SECINFO_TCS {
   390  		secinfo.flags = SGX_SECINFO_TCS
   391  	}
   392  	eadd.secinfo = uint64(uintptr(unsafe.Pointer(secinfo)))
   393  	_, _, ret := syscall.Syscall(syscall.SYS_IOCTL, uintptr(sgxFd.Fd()), uintptr(SGX_IOC_ENCLAVE_ADD_PAGE), uintptr(unsafe.Pointer(eadd)))
   394  	if ret != 0 {
   395  		log.Println("Unable to add a page: ", daddr)
   396  		panic("Stopping execution before adding a page.")
   397  	}
   398  
   399  	// Add it to the hash.
   400  	sgxHashEadd(secs, secinfo, daddr)
   401  }
   402  
   403  func sgxEinit(secs *secs_t, tok *TokenGob) {
   404  	parm := &sgx_enclave_init{}
   405  	parm.addr = secs.baseAddr
   406  
   407  	//Create the proper size for enclave css.
   408  	signature := &tok.Meta.Enclave_css //&flat_enclave_css_t{}
   409  	if unsafe.Sizeof(*signature) != uintptr(1808) {
   410  		panic("gosec: the enclave_css is not the proper size.")
   411  	}
   412  
   413  	parm.sigstruct = uint64(uintptr(unsafe.Pointer(signature)))
   414  	parm.einittoken = uint64(uintptr(unsafe.Pointer(&tok.Token[0])))
   415  
   416  	ptr := uintptr(unsafe.Pointer(parm))
   417  	p1, _, ret := syscall.Syscall(syscall.SYS_IOCTL, uintptr(sgxFd.Fd()), uintptr(SGX_IOC_ENCLAVE_INIT), ptr)
   418  
   419  	if ret != 0 || p1 != 0 {
   420  		log.Println("gosec: sgxEinit failed with return code ", ret, "-- p1: ", p1)
   421  		panic("Stopping the execution before performing einit.")
   422  	}
   423  }
   424  
   425  //TODO @aghosn, this is bad, we should use the address from source,
   426  // we should also change the way the assembly works (maybe later).
   427  //go:nosplit
   428  func sgxEEnter(id uint64, dest, src *sgx_tcs_info, req *runtime.OExitRequest) {
   429  	prot := int32(_PROT_READ | _PROT_WRITE)
   430  	manon := int32(_MAP_ANON | _MAP_FIXED | _MAP_PRIVATE)
   431  
   432  	//mmap the unprotected stack
   433  	//_, ret := syscall.RMmap(src.stack, int(src.ssiz), prot, manon, -1, 0)
   434  	//check(ret)
   435  	_, ret := runtime.RMmap(unsafe.Pointer(src.Stack), src.Ssiz, prot, manon, -1, 0)
   436  	if ret != 0 {
   437  		panic("Unable to map tcs stack.")
   438  	}
   439  	swsptr := src.Stack + src.Ssiz
   440  	ptrs := (*uint64)(unsafe.Pointer(swsptr))
   441  
   442  	// Spawning a new thread for the enclave
   443  	if req != nil {
   444  		// the id for the procid - 72 RSP
   445  		swsptr -= unsafe.Sizeof(uint64(0))
   446  		ptrs = (*uint64)(unsafe.Pointer(swsptr))
   447  		*ptrs = id
   448  
   449  		// the target g - 64 RSP
   450  		swsptr -= unsafe.Sizeof(uint64(0))
   451  		ptrs = (*uint64)(unsafe.Pointer(swsptr))
   452  		*ptrs = uint64(req.Gp)
   453  
   454  		// the target m - 56 RSP
   455  		swsptr -= unsafe.Sizeof(uint64(0))
   456  		ptrs = (*uint64)(unsafe.Pointer(swsptr))
   457  		*ptrs = uint64(req.Mp)
   458  	}
   459  
   460  	// protected stack address - 48 RSP
   461  	swsptr -= unsafe.Sizeof(uint64(0))
   462  	ptrs = (*uint64)(unsafe.Pointer(swsptr))
   463  	// room for the argc argv, so sizeof(int32) + sizeof(ptr -- 64bits)
   464  	if req == nil {
   465  		argssiz := unsafe.Sizeof(int32(0)) + unsafe.Sizeof(uint64(0))
   466  		*ptrs = uint64(dest.Stack + dest.Ssiz - argssiz)
   467  	} else {
   468  		*ptrs = uint64(dest.Stack + dest.Ssiz)
   469  	}
   470  
   471  	// isSim flag - 40 RSP
   472  	simFlag := uint64(0)
   473  	if enclWrap.isSim {
   474  		simFlag = uint64(1)
   475  	}
   476  	swsptr -= unsafe.Sizeof(uint64(0))
   477  	ptrs = (*uint64)(unsafe.Pointer(swsptr))
   478  	*ptrs = uint64(simFlag)
   479  
   480  	// msgx address - 32 RSP
   481  	swsptr -= unsafe.Sizeof(uint64(0))
   482  	ptrs = (*uint64)(unsafe.Pointer(swsptr))
   483  	*ptrs = uint64(dest.Tls - TLS_MSGX_OFF)
   484  
   485  	// RSI - 24 RSP
   486  	swsptr -= unsafe.Sizeof(uint64(0))
   487  	ptrs = (*uint64)(unsafe.Pointer(swsptr))
   488  	*ptrs = uint64(uintptr(unsafe.Pointer(&dest.Rsi)))
   489  
   490  	// RDI - 16 RSP
   491  	swsptr -= unsafe.Sizeof(uint64(0))
   492  	ptrs = (*uint64)(unsafe.Pointer(swsptr))
   493  	*ptrs = uint64(uintptr(unsafe.Pointer(&dest.Rdi)))
   494  
   495  	// Xception - 8 RSP
   496  	xcpt := runtime.Cooprt.ExceptionHandler
   497  	swsptr -= unsafe.Sizeof(uint64(0))
   498  	ptrs = (*uint64)(unsafe.Pointer(swsptr))
   499  	*ptrs = xcpt
   500  
   501  	// tcs - 0 RSP
   502  	swsptr -= unsafe.Sizeof(uint64(0))
   503  	ptrs = (*uint64)(unsafe.Pointer(swsptr))
   504  	*ptrs = uint64(dest.Tcs)
   505  
   506  	runtime.StartEnclaveOSThread(swsptr, unsafe.Pointer(enclWrap.entry))
   507  }
   508  
   509  func testEntry() {
   510  	log.Println("Test and I am here")
   511  }
   512  
   513  func sgxException() {
   514  	log.Fatalln("SGX exception occured.")
   515  }