Initial release of Intel SGX for Linux.

This release is used in conjunction with the linux-sgx-driver Intial release:
https://github.com/01org/linux-sgx-driver
commit-id: 0e865ce5e6b297a787bcdc12d98bada8174be6d7

Intel-id: 33399

Signed-off-by: Angie Chinchilla <angie.v.chinchilla@intel.com>
This commit is contained in:
Angie Chinchilla
2016-06-23 18:51:53 -04:00
parent ba82cfcbb0
commit 9441de4c38
2767 changed files with 820699 additions and 0 deletions

View File

@ -0,0 +1,77 @@
#
# Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#
include ../../../buildenv.mk
SIM_DIR := $(CUR_DIR)/..
ifndef DEBUG
CXXFLAGS += -DDISABLE_TRACE
CFLAGS += -DDISABLE_TRACE
endif
CPPFLAGS += $(ADDED_INC)
CPPFLAGS += -I$(COMMON_DIR)/inc/ \
-I$(COMMON_DIR)/inc/internal \
-I$(SIM_DIR)/assembly/ \
-I$(SIM_DIR)/assembly/linux \
-I$(LINUX_PSW_DIR)/urts \
-I$(LINUX_EXTERNAL_DIR)/crypto_px/include
CXXFLAGS += -Werror -fPIC
OBJ1 := linux/set_tls.o \
linux/restore_tls.o
LIBSESIMU_U := libsesimu_u.a
.PHONY:all
all: $(LIBSESIMU_U)
enclave_mngr.o: enclave_mngr.cpp
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@
# Explicitly disable optimization for 'u_instructions.cpp',
# since the '_SE3' function has assumptions on stack layout.
#
u_instructions.o: u_instructions.cpp
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -O0 -c $< -o $@
$(LIBSESIMU_U): u_instructions.o enclave_mngr.o $(OBJ1)
$(AR) rcs $@ $^
$(OBJ1):
$(MAKE) -C linux
.PHONY: clean
clean:
$(MAKE) -C linux clean
@$(RM) *.o *.a *.so

View File

@ -0,0 +1,253 @@
/*
* Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <string.h>
#include "se_memory.h"
#include "se_memcpy.h"
#include "util.h"
#include "enclave_mngr.h"
#include "se_atomic.h"
static uint32_t atomic_inc32(uint32_t volatile *val)
{
return se_atomic_inc(val);
}
uint32_t CEnclaveSim::m_counter = 1;
sgx_enclave_id_t CEnclaveSim::gen_enclave_id(void)
{
//getpid() is to simulate fork() scenario, refer to do_ecall in sig_handler.cpp
sgx_enclave_id_t id = ((uint64_t)getpid() << 32) | atomic_inc32(&m_counter);
return id;
}
CEnclaveSim::CEnclaveSim(const secs_t* secs)
{
m_cpages = static_cast<size_t>(secs->size >> SE_PAGE_SHIFT);
m_flags = new si_flags_t[m_cpages];
// pages flags are initialized to -1
memset(m_flags, 0xff, m_cpages * sizeof(si_flags_t));
memcpy_s(&m_secs, sizeof(m_secs), secs, sizeof(*secs));
m_enclave_id = gen_enclave_id();
}
CEnclaveSim::~CEnclaveSim()
{
delete[] m_flags;
se_virtual_free(m_secs.base, (size_t)m_secs.size, MEM_RELEASE);
}
sgx_enclave_id_t CEnclaveSim::get_enclave_id() const
{
return m_enclave_id;
}
secs_t* CEnclaveSim::get_secs()
{
return &m_secs;
}
size_t CEnclaveSim::get_pg_idx(const void* pgaddr) const
{
return PTR_DIFF(pgaddr, m_secs.base) >> SE_PAGE_SHIFT;
}
bool CEnclaveSim::validate_pg_and_flags(const void* addr, si_flags_t flags)
{
// Must be page aligned
if (!IS_PAGE_ALIGNED(addr))
return false;
size_t page_idx = get_pg_idx(addr);
// Must be within enclave address space
if (page_idx >= m_cpages)
return false;
// Requested flags should only set those visible by instuctions
if ((flags & (~SI_FLAGS_EXTERNAL)))
return false;
return true;
}
bool CEnclaveSim::add_page(const void* addr, si_flags_t flags)
{
if (!validate_pg_and_flags(addr, flags))
return false;
// We only deal with these flags
flags &= static_cast<si_flags_t>(SI_FLAGS_EXTERNAL);
// Must not have been added yet
size_t page_idx = get_pg_idx(addr);
if (m_flags[page_idx] != (si_flags_t)-1)
return false;
m_flags[page_idx] = flags;
return true;
}
bool CEnclaveSim::remove_page(const void* epc_lin_addr)
{
size_t page_idx = get_pg_idx(epc_lin_addr);
if (m_flags[page_idx] != (si_flags_t)-1) {
m_flags[page_idx] = (si_flags_t)-1;
return true;
}
return false;
}
bool CEnclaveSim::is_tcs_page(const void* addr) const
{
// Must be page aligned
if (!IS_PAGE_ALIGNED(addr))
return false;
size_t page_idx = get_pg_idx(addr);
// Must be within enclave address space
if (page_idx >= m_cpages)
return false;
return (m_flags[page_idx] & SI_FLAG_PT_MASK) == SI_FLAG_TCS;
}
//////////////////////////////////////////////////////////////////////
CEnclaveMngr::CEnclaveMngr()
{
se_mutex_init(&m_list_lock);
}
CEnclaveMngr::~CEnclaveMngr()
{
se_mutex_destroy(&m_list_lock);
std::list<CEnclaveSim*>::iterator it = m_enclave_list.begin();
for (; it != m_enclave_list.end(); ++it)
{
delete (*it);
}
}
// Note: this singleton implemenation is not multi-threading safe.
CEnclaveMngr* CEnclaveMngr::get_instance()
{
static CEnclaveMngr mngr;
return &mngr;
}
// Use constructor attribute to make sure that the later calling of
// CEnclaveMngr::get_instance() is MT-safe.
__attribute__ ((__constructor__)) static void build_mngr_instance()
{
CEnclaveMngr::get_instance();
}
void CEnclaveMngr::add(CEnclaveSim* ce)
{
if (ce != NULL)
{
se_mutex_lock(&m_list_lock);
m_enclave_list.push_back(ce);
se_mutex_unlock(&m_list_lock);
}
}
void CEnclaveMngr::remove(CEnclaveSim* ce)
{
if (ce != NULL)
{
se_mutex_lock(&m_list_lock);
m_enclave_list.remove(ce);
se_mutex_unlock(&m_list_lock);
}
}
CEnclaveSim* CEnclaveMngr::get_enclave(const sgx_enclave_id_t id)
{
CEnclaveSim* ce = NULL;
se_mutex_lock(&m_list_lock);
std::list<CEnclaveSim*>::iterator it = m_enclave_list.begin();
for (; it != m_enclave_list.end(); ++it)
{
if ((*it)->get_enclave_id() == id)
{
ce = *it;
break;
}
}
se_mutex_unlock(&m_list_lock);
return ce;
}
CEnclaveSim* CEnclaveMngr::get_enclave(const void* base_addr)
{
CEnclaveSim* ce = NULL;
se_mutex_lock(&m_list_lock);
std::list<CEnclaveSim*>::iterator it = m_enclave_list.begin();
for (; it != m_enclave_list.end(); ++it)
{
secs_t* secs = (*it)->get_secs();
if (base_addr >= secs->base &&
PTR_DIFF(base_addr, secs->base) < secs->size)
{
ce = *it;
break;
}
}
se_mutex_unlock(&m_list_lock);
return ce;
}
CEnclaveSim* CEnclaveMngr::get_enclave(const secs_t* secs)
{
// The pEnclaveSECS field might not have been initialized yet.
return get_enclave(secs->base);
}

View File

@ -0,0 +1,104 @@
/*
* Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef _SE_ENCLAVE_MNGR_H_
#define _SE_ENCLAVE_MNGR_H_
#include <list>
#include "arch.h"
#include "sgx_eid.h"
#include "se_thread.h"
class CEnclaveSim
{
public:
CEnclaveSim(const secs_t* secs);
virtual ~CEnclaveSim(void);
// The following functions are declared virtual so that they can
// be called from the tRTS instruction simulation functions.
virtual sgx_enclave_id_t get_enclave_id() const;
virtual secs_t* get_secs();
virtual size_t get_pg_idx(const void* pgaddr) const;
virtual bool add_page(const void* pgaddr, si_flags_t flags);
virtual bool remove_page(const void* epc_lin_addr);
virtual bool is_tcs_page(const void* pgaddr) const;
private:
secs_t m_secs;
si_flags_t* m_flags; // memory managed by CEnclaveSim
size_t m_cpages; // page count
sgx_enclave_id_t m_enclave_id; // an unique Id for the enclave
static uint32_t m_counter; // enclave counter
sgx_enclave_id_t gen_enclave_id(void);
bool validate_pg_and_flags(const void* pgaddr, si_flags_t flags);
CEnclaveSim(const CEnclaveSim& es);
CEnclaveSim& operator=(const CEnclaveSim& es);
};
class CEnclaveMngr
{
public:
// The factory method for CEnclaveMngr.
//
// Note: this factory is not thread-safe.
static CEnclaveMngr* get_instance();
~CEnclaveMngr();
void add(CEnclaveSim* ce);
void remove(CEnclaveSim* ce);
CEnclaveSim* get_enclave(const sgx_enclave_id_t id);
CEnclaveSim* get_enclave(const secs_t* secs);
CEnclaveSim* get_enclave(const void* base_addr);
private:
std::list<CEnclaveSim*> m_enclave_list;
// to protect the access to m_enclave_list
se_mutex_t m_list_lock;
CEnclaveMngr();
CEnclaveMngr(const CEnclaveMngr& em);
CEnclaveMngr& operator=(const CEnclaveMngr& em);
};
#endif

View File

@ -0,0 +1,58 @@
#
# Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#
include ../../../../buildenv.mk
SIM_DIR := $(CUR_DIR)/../..
ifndef DEBUG
CXXFLAGS += -DDISABLE_TRACE
CFLAGS += -DDISABLE_TRACE
endif
CFLAGS += -Werror -fPIC
CPPFLAGS += $(ADDED_INC) # for ubuntu 11 and later version
CPPFLAGS += -I.. \
-I$(SIM_DIR)/assembly \
-I$(SIM_DIR)/assembly/linux \
-I$(COMMON_DIR)/inc \
-I$(COMMON_DIR)/inc/internal
SOURCE := $(wildcard *.c)
OBJECT := $(SOURCE:.c=.o)
.PHONY: all
all: $(OBJECT)
.PHONY: clean
clean:
@$(RM) *.o *~

View File

@ -0,0 +1,46 @@
/*
* Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "td_mngr.h"
/*
* Get the TD address - this function needs to be called
* when the DTV value has not been restored yet.
*/
void* get_td_addr(void)
{
dtv_t* dtv = GET_DTV();
return read_dtv_val(dtv);
}
/* vim: set ts=4 sw=4 cin et: */

View File

@ -0,0 +1,58 @@
/*
* Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* restore_tls.c
* Implemente the TLS support in simulation mode
*/
#include "td_mngr.h"
/*
* Restore the old DTV value.
*/
int td_mngr_restore_td(tcs_t *tcs)
{
dtv_t* dtv __attribute__((unused));
tcs_sim_t *tcs_sim;
if (!tcs)
return 0;
dtv = GET_DTV();
tcs_sim = (tcs_sim_t *)tcs->reserved;
set_dtv_val(dtv, tcs_sim->saved_dtv);
SET_FS_GS_0(tcs_sim->saved_fs_gs_0);
return 1;
}
/* vim: set ts=4 sw=4 cin et: */

View File

@ -0,0 +1,66 @@
/*
* Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* set_tls.c
* Implemente the TLS support in simulation mode
*/
#include "td_mngr.h"
#include "util.h"
int td_mngr_set_td(void *enclave_base, tcs_t *tcs)
{
dtv_t* dtv;
tcs_sim_t *tcs_sim;
if (!tcs)
return 0;
/* save the old DTV[0].pointer->val */
dtv = GET_DTV();
tcs_sim = (tcs_sim_t *)tcs->reserved;
tcs_sim->saved_dtv = (uintptr_t)read_dtv_val(dtv);
/* save the old fs:0x0 or gs:0x0 value */
tcs_sim->saved_fs_gs_0 = GET_FS_GS_0();
/* set the DTV[0].pointer->val to TLS address */
uintptr_t *tib = GET_PTR(uintptr_t, enclave_base, tcs->ofs_base);
set_dtv_val(dtv, tib);
/* set the fs:0x0 or gs:0x0 to TLS address */
SET_FS_GS_0(tib);
return 1;
}
/* vim: set ts=4 sw=4 cin et: */

View File

@ -0,0 +1,73 @@
/*
* Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef _TD_MNGR_H_
#define _TD_MNGR_H_
#include "arch.h"
#include "rts.h"
// use tcs->reserved field to save some information
typedef struct _tcs_sim_t
{
uintptr_t saved_aep;
size_t tcs_state;
uintptr_t saved_dtv;
uintptr_t saved_fs_gs_0;
} tcs_sim_t;
#define TCS_STATE_INACTIVE 0 //The TCS is available for a normal EENTER
#define TCS_STATE_ACTIVE 1 //A Processor is currently executing in the context of this TCS
// The 1st parameter of enter_enclave function (enclave_enclave.S) is tcs.
// If the parameter is changed, or EENTER_PROLOG is changed, the macro should be updated accordingly.
#ifdef SE_GNU64
#define GET_TCS_PTR(xbp) (tcs_t *)(*(uintptr_t *)((size_t)(xbp) - 10 * sizeof(uintptr_t)))
#else
#define GET_TCS_PTR(xbp) (tcs_t *)(*(uintptr_t *)((size_t)(xbp) + 2 * sizeof(uintptr_t)))
#endif
#ifdef __cplusplus
extern "C" {
#endif
//Add the implementation to get the _tls_array pointer in GNU here.
#include "gnu_tls.h"
extern uint8_t __ImageBase;
int td_mngr_set_td(void *enclave_base, tcs_t *tcs);
int td_mngr_restore_td(tcs_t *tcs);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,320 @@
/*
* Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
// u_instructions.cpp -- It simulates Enclave instructions.
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "arch.h"
#include "util.h"
#include "se_memory.h"
#include "se_memcpy.h"
#include "se_trace.h"
#include "enclave.h"
#include "td_mngr.h"
#include "lowlib.h"
#include "sgxsim.h"
#include "enclave_mngr.h"
#include "u_instructions.h"
#include "ippcp.h"
static uintptr_t _EINIT(secs_t* secs, enclave_css_t* css, token_t* launch);
static uintptr_t _ECREATE (page_info_t* pi);
static uintptr_t _EADD (page_info_t* pi, void* epc_lin_addr);
static uintptr_t _EREMOVE(const void* epc_lin_addr);
////////////////////////////////////////////////////////////////////////
#define __GP__() exit(EXIT_FAILURE)
#define GP() do { \
SE_TRACE(SE_TRACE_DEBUG, "#GP on %s, line: %d\n", __FILE__, __LINE__); \
__GP__(); \
} while (0)
#define GP_ON(cond) if (cond) GP()
#define GP_ON_EENTER GP_ON
#define mcp_same_size(dst_ptr, src_ptr, size) memcpy_s(dst_ptr, size, src_ptr, size)
uintptr_t _EINIT(secs_t* secs, enclave_css_t *css, token_t *launch)
{
CEnclaveMngr *mngr = CEnclaveMngr::get_instance();
assert(mngr != NULL);
CEnclaveSim* ce = mngr->get_enclave(secs);
GP_ON(ce == NULL);
GP_ON((ce->get_secs()->attributes.flags & SGX_FLAGS_INITTED) != 0);
// Fill MREnclave, MRSigner, ISVPRODID, ISVSVN
secs_t* this_secs = ce->get_secs();
if (css != NULL) {
// Check signature
if ((css->body.attribute_mask.xfrm & this_secs->attributes.xfrm)
!= (css->body.attribute_mask.xfrm & css->body.attributes.xfrm))
{
SE_TRACE(SE_TRACE_DEBUG,
"SECS attributes.xfrm does NOT match signature attributes.xfrm\n");
return SGX_ERROR_INVALID_ATTRIBUTE;
}
if ((css->body.attribute_mask.flags & this_secs->attributes.flags)
!= (css->body.attribute_mask.flags & css->body.attributes.flags))
{
SE_TRACE(SE_TRACE_DEBUG,
"SECS attributes.flag does NOT match signature attributes.flag\n");
return SGX_ERROR_INVALID_ATTRIBUTE;
}
mcp_same_size(&this_secs->mr_enclave, &css->body.enclave_hash, sizeof(sgx_measurement_t));
this_secs->isv_prod_id = css->body.isv_prod_id;
this_secs->isv_svn = css->body.isv_svn;
ippsHashMessage(css->key.modulus, SE_KEY_SIZE, (Ipp8u*)&this_secs->mr_signer, IPP_ALG_HASH_SHA256);
}
// Check launch token
if (launch != NULL && launch->body.valid) {
if (memcmp(&launch->body.attributes, &this_secs->attributes, sizeof(sgx_attributes_t)))
{
SE_TRACE(SE_TRACE_DEBUG,
"SECS attributes does NOT match launch token attribuets\n");
return SGX_ERROR_INVALID_ATTRIBUTE;
}
}
// Mark it initialized
this_secs->attributes.flags |= SGX_FLAGS_INITTED;
return SGX_SUCCESS;
}
static inline bool is_power_of_two(size_t n)
{
return (n != 0) && (!(n & (n - 1)));
}
// Returns the pointer to the Enclave instance on success.
uintptr_t _ECREATE(page_info_t* pi)
{
secs_t* secs = reinterpret_cast<secs_t*>(pi->src_page);
// Enclave size must be at least 2 pages and a power of 2.
GP_ON(!is_power_of_two((size_t)secs->size));
GP_ON(secs->size < (SE_PAGE_SIZE << 1));
CEnclaveSim* ce = new CEnclaveSim(secs);
void* addr;
// `ce' is not checked against NULL, since it is not
// allocated with new(std::no_throw).
addr = se_virtual_alloc(NULL, (size_t)secs->size, MEM_COMMIT);
if (addr == NULL) {
delete ce;
return 0;
}
// Mark all the memory inaccessible.
se_virtual_protect(addr, (size_t)secs->size, SGX_PROT_NONE);
ce->get_secs()->base = addr;
CEnclaveMngr::get_instance()->add(ce);
return reinterpret_cast<uintptr_t>(ce);
}
uintptr_t _EADD(page_info_t* pi, void *epc_lin_addr)
{
void *src_page = pi->src_page;
CEnclaveMngr *mngr = CEnclaveMngr::get_instance();
CEnclaveSim *ce = mngr->get_enclave(pi->lin_addr);
if (ce == NULL) {
SE_TRACE(SE_TRACE_DEBUG, "failed to get enclave instance\n");
return SGX_ERROR_UNEXPECTED;
}
GP_ON(!IS_PAGE_ALIGNED(epc_lin_addr));
GP_ON((ce->get_secs()->attributes.flags & SGX_FLAGS_INITTED) != 0);
// Make the page writable before doing memcpy()
se_virtual_protect(epc_lin_addr, SE_PAGE_SIZE, SI_FLAGS_RW);
mcp_same_size(epc_lin_addr, src_page, SE_PAGE_SIZE);
se_virtual_protect(epc_lin_addr, SE_PAGE_SIZE, (uint32_t)pi->sec_info->flags);
GP_ON(!ce->add_page(pi->lin_addr, pi->sec_info->flags));
return SGX_SUCCESS;
}
uintptr_t _EREMOVE(const void *epc_lin_addr)
{
CEnclaveMngr *mngr = CEnclaveMngr::get_instance();
CEnclaveSim *ce = mngr->get_enclave(epc_lin_addr);
GP_ON(!ce);
GP_ON(!IS_PAGE_ALIGNED(epc_lin_addr));
return ce->remove_page(epc_lin_addr) ? 0 : -1;
}
////////////////////////////////////////////////////////////////////////
// Master entry functions
void _SE3(uintptr_t xax, uintptr_t xbx,
uintptr_t xcx, uintptr_t xdx,
uintptr_t xsi, uintptr_t xdi)
{
UNUSED(xdx);
switch (xax)
{
case SE_EENTER:
uintptr_t xip;
void * enclave_base_addr;
se_pt_regs_t* p_pt_regs;
tcs_t* tcs;
tcs_sim_t* tcs_sim;
ssa_gpr_t* p_ssa_gpr;
secs_t* secs;
CEnclaveMngr* mngr;
CEnclaveSim* ce;
// xbx contains the address of a TCS
tcs = reinterpret_cast<tcs_t*>(xbx);
// Is TCS pointer page-aligned?
GP_ON_EENTER(!IS_PAGE_ALIGNED(tcs));
mngr = CEnclaveMngr::get_instance();
assert(mngr != NULL);
// Is it really a TCS?
ce = mngr->get_enclave(tcs);
GP_ON_EENTER(ce == NULL);
GP_ON_EENTER(!ce->is_tcs_page(tcs));
// Check the EntryReason
tcs_sim = reinterpret_cast<tcs_sim_t *>(tcs->reserved);
GP_ON_EENTER(tcs_sim->tcs_state != TCS_STATE_INACTIVE);
GP_ON_EENTER(tcs->cssa >= tcs->nssa);
secs = ce->get_secs();
enclave_base_addr = secs->base;
p_ssa_gpr = reinterpret_cast<ssa_gpr_t*>(reinterpret_cast<uintptr_t>(enclave_base_addr) + static_cast<size_t>(tcs->ossa)
+ secs->ssa_frame_size * SE_PAGE_SIZE
- sizeof(ssa_gpr_t));
tcs_sim->saved_aep = xcx;
p_pt_regs = reinterpret_cast<se_pt_regs_t*>(get_bp());
p_ssa_gpr->REG(bp_u) = p_pt_regs->xbp;
p_ssa_gpr->REG(sp_u) = reinterpret_cast<uintptr_t>(p_pt_regs + 1);
xcx = p_pt_regs->xip;
xip = reinterpret_cast<uintptr_t>(enclave_base_addr);
GP_ON_EENTER(xip == 0);
//set the _tls_array to point to the self_addr of TLS section inside the enclave
GP_ON_EENTER(td_mngr_set_td(enclave_base_addr, tcs) == false);
// Destination depends on STATE
xip += (uintptr_t)tcs->oentry;
tcs_sim->tcs_state = TCS_STATE_ACTIVE;
// Link the TCS to the thread
GP_ON_EENTER((secs->attributes.flags & SGX_FLAGS_INITTED) == 0);
// Replace the return address on the stack with the enclave entry,
// so that when we return from this function, we'll enter the enclave.
enclu_regs_t regs;
regs.xax = tcs->cssa;
regs.xbx = reinterpret_cast<uintptr_t>(tcs);
regs.xcx = xcx;
regs.xdx = 0;
regs.xsi = xsi;
regs.xdi = xdi;
regs.xbp = p_ssa_gpr->REG(bp_u);
regs.xsp = p_ssa_gpr->REG(sp_u);
regs.xip = xip;
load_regs(&regs);
// Returning from this function enters the enclave
return;
default:
// There's only 1 ring 3 instruction outside the enclave: EENTER.
GP();
}
}
uintptr_t _SE0(uintptr_t xax, uintptr_t xbx,
uintptr_t xcx, uintptr_t xdx,
uintptr_t xsi, uintptr_t xdi)
{
UNUSED(xsi), UNUSED(xdi);
switch (xax)
{
case SE_ECREATE:
return _ECREATE(reinterpret_cast<page_info_t*>(xbx));
case SE_EADD:
return _EADD(reinterpret_cast<page_info_t*>(xbx),
reinterpret_cast<void*>(xcx));
case SE_EINIT:
return _EINIT(reinterpret_cast<secs_t*>(xbx),
reinterpret_cast<enclave_css_t *>(xcx),
reinterpret_cast<token_t *>(xdx));
case SE_EREMOVE:
return _EREMOVE(reinterpret_cast<void*>(xcx));
default:
GP();
}
return 0;
}

View File

@ -0,0 +1,72 @@
/*
* Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef _UINSTRUCTIONS_H__
#define _UINSTRUCTIONS_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// this struct defines the way the registers are stored on the
// stack during an EENTER.
typedef struct _se_pt_regs_t {
#if defined(__x86_64__)
uintptr_t xbp;
uintptr_t xip;
#else
uintptr_t xbp;
uintptr_t xip;
uintptr_t xax;
uintptr_t xbx;
uintptr_t xcx;
uintptr_t xdx;
uintptr_t xsi;
uintptr_t xdi;
#endif
} se_pt_regs_t;
uintptr_t _SE0(uintptr_t xax, uintptr_t xbx,
uintptr_t xcx, uintptr_t xdx,
uintptr_t xsi, uintptr_t xdi);
void _SE3(uintptr_t xax, uintptr_t xbx,
uintptr_t xcx, uintptr_t xdx,
uintptr_t xsi, uintptr_t xdi);
#ifdef __cplusplus
}
#endif
#endif