Beispiel #1
0
extern "C" bool read_cpusvn_file(const char *config_path, sgx_cpu_svn_t *cpusvn_ptr)
{
    if(config_path == NULL || cpusvn_ptr == NULL)
        return false;

    FILE *fp = NULL;
    long fsize = 0;
    sgx_cpu_svn_t temp_cpusvn = {{0}};
    size_t result = 0;

    if(NULL == (fp = fopen(config_path, "rb")))
    {
        SE_TRACE(SE_TRACE_DEBUG, "Couldn't find/open the configuration file %s.\n", config_path);
        memcpy_s(cpusvn_ptr, sizeof(sgx_cpu_svn_t), &DEFAULT_CPUSVN, sizeof(DEFAULT_CPUSVN));
        return true;
    }

    //check and read configure file format
    if(fseek(fp, 0, SEEK_END))
    {
        memcpy_s(&temp_cpusvn, sizeof(temp_cpusvn), &DEFAULT_CPUSVN, sizeof(DEFAULT_CPUSVN));
        goto clean_return;
    }

    fsize = ftell(fp);
    rewind(fp);

    if(fsize != sizeof(sgx_cpu_svn_t))
    {
        SE_TRACE(SE_TRACE_DEBUG, "The configuration file format is not correct. Using default CPUSVN value.\n");
        memcpy_s(&temp_cpusvn, sizeof(temp_cpusvn), &DEFAULT_CPUSVN, sizeof(DEFAULT_CPUSVN));
        goto clean_return;
    }

    result = fread(&temp_cpusvn, 1, fsize, fp);
    if(result != (size_t)fsize)
    {
        SE_TRACE(SE_TRACE_DEBUG, "Failed to read configuration file. Using default CPUSVN value.\n");
        memcpy_s(&temp_cpusvn, sizeof(temp_cpusvn), &DEFAULT_CPUSVN, sizeof(DEFAULT_CPUSVN));
        goto clean_return;
    }

    if(memcmp(&temp_cpusvn, &DEFAULT_CPUSVN, sizeof(DEFAULT_CPUSVN)) &&
        memcmp(&temp_cpusvn, &UPGRADED_CPUSVN, sizeof(UPGRADED_CPUSVN)) &&
        memcmp(&temp_cpusvn, &DOWNGRADED_CPUSVN, sizeof(DOWNGRADED_CPUSVN)))
    {
        SE_TRACE(SE_TRACE_DEBUG, "The configuration file format is not correct. Using default CPUSVN value.\n");
        memcpy_s(&temp_cpusvn, sizeof(temp_cpusvn), &DEFAULT_CPUSVN, sizeof(DEFAULT_CPUSVN));
        goto clean_return;
    }

clean_return:
    fclose(fp);
    memcpy_s(cpusvn_ptr, sizeof(*cpusvn_ptr), &temp_cpusvn, sizeof(temp_cpusvn));
    return true;
 }
Beispiel #2
0
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;
}
Beispiel #3
0
static long int set_regset(pid_t pid, void* addr, void* data)
{
    int ret = 0;
    unsigned long type = (unsigned long)addr;

    if(!data)
        return -1;
    struct user_regs_struct regs;
    if(-1 == (ret = g_sys_ptrace(PTRACE_GETREGS, pid, 0, &regs)))
        return -1;

    if(is_eresume(pid, &regs))
    {
        if(NT_X86_XSTATE != type)
        {
            SE_TRACE(SE_TRACE_WARNING, "unexpected type for PTRACE_SETREGSET\n");
            return -1;
        }
        struct iovec *iov = (struct iovec *)data;
        if(iov->iov_base && iov->iov_len
            && set_ssa_xstate(pid, regs.REG(bx), iov->iov_len, (char *)iov->iov_base))
        {
            return 0;
        }
        else
            return -1;
    }
    else
    {
        return g_sys_ptrace(PTRACE_SETREGSET, pid, addr, data);
    }
}
Beispiel #4
0
int add_enclave_page(sgx_enclave_id_t enclave_id,
                     void             *source,
                     size_t           offset,
                     const sec_info_t &secinfo,
                     uint32_t         attr)
{
    sec_info_t   sinfo;
    page_info_t  pinfo;
    CEnclaveMngr *mngr;
    CEnclaveSim  *ce;

    UNUSED(attr);

    mngr = CEnclaveMngr::get_instance();
    ce = mngr->get_enclave(enclave_id);
    if (ce == NULL) {
        SE_TRACE(SE_TRACE_DEBUG,
                 "enclave (id = %llu) not found.\n",
                 enclave_id);
        return SGX_ERROR_INVALID_ENCLAVE_ID;
    }
    memset(&sinfo, 0, sizeof(sec_info_t));
    sinfo.flags = secinfo.flags;
    if(memcmp(&sinfo, &secinfo, sizeof(sec_info_t)))
        return SGX_ERROR_UNEXPECTED;

    memset(&pinfo, 0, sizeof(pinfo));
    pinfo.secs     = ce->get_secs();
    pinfo.lin_addr = (char*)ce->get_secs()->base + offset;
    pinfo.src_page = source;
    pinfo.sec_info = &sinfo;

    /* Passing NULL here when there is no EPC mgmt. */
    return (int)DoEADD_SW(&pinfo, GET_PTR(void, ce->get_secs()->base, offset));
}
Beispiel #5
0
/* Allocate linear address space. */
int create_enclave(secs_t           *secs,
                   sgx_enclave_id_t *enclave_id,
                   void             **start_addr)
{
    CEnclaveSim   *ce;
    sec_info_t    sinfo;
    page_info_t   pinfo;

    BUG_ON(secs == NULL, SGX_ERROR_UNEXPECTED);
    BUG_ON(enclave_id == NULL, SGX_ERROR_UNEXPECTED);
    BUG_ON(start_addr == NULL, SGX_ERROR_UNEXPECTED);

    memset(&sinfo, 0, sizeof(sinfo));
    sinfo.flags = SI_FLAGS_SECS;

    memset(&pinfo, 0, sizeof(pinfo));
    pinfo.src_page = secs;
    pinfo.sec_info = &sinfo;

    ce = reinterpret_cast<CEnclaveSim*>(DoECREATE_SW(&pinfo));
    if (ce == NULL) {
        SE_TRACE(SE_TRACE_DEBUG, "out of memory.\n");
        return SGX_ERROR_OUT_OF_MEMORY;
    }

    *start_addr = ce->get_secs()->base;
    *enclave_id = ce->get_enclave_id();
    secs->base = *start_addr;

    return SGX_SUCCESS;
}
Beispiel #6
0
int EnclaveCreatorHW::error_api2urts(uint32_t api_error)
{
    int ret = SGX_ERROR_UNEXPECTED;

    switch(api_error)
    {
     case ENCLAVE_ERROR_SUCCESS:
         ret = SGX_SUCCESS;
         break;
     case ENCLAVE_NOT_SUPPORTED:
         ret = SGX_ERROR_NO_DEVICE;
         break;
     case ENCLAVE_INVALID_SIG_STRUCT:
     case ENCLAVE_INVALID_SIGNATURE:
         ret = SGX_ERROR_INVALID_SIGNATURE;
         break;
     case ENCLAVE_INVALID_ATTRIBUTE:
         ret = SGX_ERROR_INVALID_ATTRIBUTE;
         break;
     case ENCLAVE_NOT_AUTHORIZED:
         ret = SGX_ERROR_SERVICE_INVALID_PRIVILEGE;
         break;
     case ENCLAVE_INVALID_MEASUREMENT:
         ret = SE_ERROR_INVALID_MEASUREMENT;
         break;
     case ENCLAVE_INVALID_ENCLAVE:
         ret = SGX_ERROR_INVALID_ENCLAVE;
         break;
     case ENCLAVE_LOST:
         ret = SGX_ERROR_ENCLAVE_LOST;
         break;
     case ENCLAVE_INVALID_PARAMETER:
         ret = SGX_ERROR_INVALID_PARAMETER;
         break;
     case ENCLAVE_OUT_OF_MEMORY:
     case ENCLAVE_DEVICE_NO_RESOURCES:
         ret = SGX_ERROR_OUT_OF_MEMORY;
         break;
     case ENCLAVE_SERVICE_TIMEOUT:
         ret = SGX_ERROR_SERVICE_TIMEOUT;
         break;
     default:
         SE_TRACE(SE_TRACE_WARNING, "unexpected error %#x from enclave common api, should be uRTS/driver bug\n", api_error);
         ret = SGX_ERROR_UNEXPECTED;
         break;
     }

     return ret;
}
Beispiel #7
0
int init_enclave(sgx_enclave_id_t  enclave_id,
                 enclave_css_t     *enclave_css,
                 token_t           *launch)
{
    CEnclaveMngr* mngr = CEnclaveMngr::get_instance();
    CEnclaveSim* ce = mngr->get_enclave(enclave_id);

    if (ce == NULL) {
        SE_TRACE(SE_TRACE_DEBUG,
                 "enclave (id = %llu) not found.\n",
                 enclave_id);
        return SGX_ERROR_INVALID_ENCLAVE_ID;
    }

    return (int)DoEINIT_SW(ce->get_secs(), enclave_css, launch);
}
Beispiel #8
0
int EnclaveCreatorHW::mktcs(uint64_t tcs_addr)
{
    sgx_range params;
    memset(&params, 0 ,sizeof(sgx_range));
    params.start_addr = (unsigned long)tcs_addr;
    params.nr_pages = 1;

    int ret = ioctl(m_hdevice, SGX_IOC_ENCLAVE_MKTCS, &params);
    if (ret)
    {
        SE_TRACE(SE_TRACE_ERROR, "MODIFY_TYPE failed %d\n", errno);
        return error_driver2urts(ret);
    }

    return SGX_SUCCESS;
}
Beispiel #9
0
int EnclaveCreatorHW::emodpr(uint64_t addr, uint64_t size, uint64_t flag)
{
    sgx_modification_param params;
    memset(&params, 0 ,sizeof(sgx_modification_param));
    params.range.start_addr = (unsigned long)addr;
    params.range.nr_pages = (unsigned int)(size/SE_PAGE_SIZE);
    params.flags = (unsigned long)flag;

    int ret = ioctl(m_hdevice, SGX_IOC_ENCLAVE_EMODPR, &params);
    if (ret)
    {
        SE_TRACE(SE_TRACE_ERROR, "SGX_IOC_ENCLAVE_EMODPR failed %d\n", errno);
        return error_driver2urts(ret);
    }

    return SGX_SUCCESS;
}
Beispiel #10
0
int EnclaveCreatorHW::trim_range(uint64_t fromaddr, uint64_t toaddr)
{
    sgx_range params;
    memset(&params, 0 ,sizeof(sgx_range));
    params.start_addr = (unsigned long)fromaddr;
    params.nr_pages = (unsigned int)((toaddr - fromaddr)/SE_PAGE_SIZE);

    int ret= ioctl(m_hdevice, SGX_IOC_ENCLAVE_TRIM, &params);
    if (ret)
    {
        SE_TRACE(SE_TRACE_ERROR, "SGX_IOC_ENCLAVE_TRIM failed %d\n", errno);
        return error_driver2urts(ret);
    }

    return SGX_SUCCESS;

}
Beispiel #11
0
int EnclaveCreatorHW::error_driver2urts(int driver_error)
{
    int ret = SGX_ERROR_UNEXPECTED;

    switch(driver_error)
    {
     case SGX_INVALID_ATTRIBUTE:
         ret = SGX_ERROR_INVALID_ATTRIBUTE;
         break;
     case SGX_INVALID_PRIVILEGE:
         ret = SGX_ERROR_SERVICE_INVALID_PRIVILEGE;
         break;
     case SGX_INVALID_MEASUREMENT:
         ret = SE_ERROR_INVALID_MEASUREMENT;
         break;
     case SGX_INVALID_SIG_STRUCT:
     case SGX_INVALID_SIGNATURE:
         ret = SGX_ERROR_INVALID_SIGNATURE;
         break;
     case SGX_INVALID_LICENSE:
         ret = SE_ERROR_INVALID_LAUNCH_TOKEN;
         break;
     case SGX_INVALID_CPUSVN:
         ret = SGX_ERROR_INVALID_CPUSVN;
         break;
     case SGX_INVALID_ISVSVN:
         ret = SGX_ERROR_INVALID_ISVSVN;
         break;
     case SGX_UNMASKED_EVENT:
         ret = SGX_ERROR_DEVICE_BUSY;
         break;
     case (int)SGX_POWER_LOST_ENCLAVE: // [-Wc++11-narrowing]
         ret = SGX_ERROR_ENCLAVE_LOST;
         break;
     case (int)SGX_LE_ROLLBACK:
         ret = SE_ERROR_INVALID_ISVSVNLE;
         break;
     default:
         SE_TRACE(SE_TRACE_WARNING, "unexpected error %#x from driver, should be uRTS/driver bug\n", driver_error);
         ret = SGX_ERROR_UNEXPECTED;
         break;
     }

     return ret;
 }
Beispiel #12
0
int EnclaveCreatorHW::trim_accept(uint64_t addr)
{
    sgx_range params;
    memset(&params, 0 ,sizeof(sgx_range));
    params.start_addr = (unsigned long)addr;
    params.nr_pages = 1;

    int ret = ioctl(m_hdevice, SGX_IOC_ENCLAVE_NOTIFY_ACCEPT, &params);


    if (ret)
    {
        SE_TRACE(SE_TRACE_ERROR, "TRIM_RANGE_COMMIT failed %d\n", errno);
        return error_driver2urts(ret);
    }

    return SGX_SUCCESS;
}
Beispiel #13
0
extern "C" sgx_status_t __sgx_create_enclave_ex(const char *file_name, 
                                                const int debug, 
                                                sgx_launch_token_t *launch_token, 
                                                int *launch_token_updated, 
                                                sgx_enclave_id_t *enclave_id, 
                                                sgx_misc_attribute_t *misc_attr,
                                                const uint32_t ex_features,
                                                const void* ex_features_p[32])
{
    sgx_status_t ret = SGX_SUCCESS;

    //Only true or false is valid
    if(TRUE != debug &&  FALSE != debug)
        return SGX_ERROR_INVALID_PARAMETER;

    if (!_check_ex_params_(ex_features, ex_features_p))
    {
        return SGX_ERROR_INVALID_PARAMETER;
    }

    int fd = open(file_name, O_RDONLY);
    if(-1 == fd)
    {
        SE_TRACE(SE_TRACE_ERROR, "Couldn't open the enclave file, error = %d\n", errno);
        return SGX_ERROR_ENCLAVE_FILE_ACCESS;
    }
    se_file_t file = {NULL, 0, false};
    char resolved_path[PATH_MAX];
    file.name = realpath(file_name, resolved_path);
    file.name_len = (uint32_t)strlen(resolved_path);

    ret = _create_enclave_ex(!!debug, fd, file, NULL, launch_token, launch_token_updated, enclave_id, misc_attr, ex_features, ex_features_p);
    if(SGX_SUCCESS != ret && misc_attr)
    {
        sgx_misc_attribute_t plat_cap;
        memset(&plat_cap, 0, sizeof(plat_cap));
        get_enclave_creator()->get_plat_cap(&plat_cap);
        memcpy_s(misc_attr, sizeof(sgx_misc_attribute_t), &plat_cap, sizeof(sgx_misc_attribute_t));
    }

    close(fd);

    return ret;
}
Beispiel #14
0
int EnclaveCreatorHW::remove_range(uint64_t fromaddr, uint64_t numpages)
{
    int ret = -1;
    uint64_t i;
    unsigned long start;

    for (i = 0; i < numpages; i++)
    {
        start = (unsigned long)fromaddr + (unsigned long)(i << SE_PAGE_SHIFT);
        ret = ioctl(m_hdevice, SGX_IOC_ENCLAVE_PAGE_REMOVE, &start);
        if (ret)
        {
            SE_TRACE(SE_TRACE_ERROR, "PAGE_REMOVE failed %d\n", errno);
            return error_driver2urts(ret);
        }
    }

    return SGX_SUCCESS;
}
Beispiel #15
0
int destroy_enclave(sgx_enclave_id_t enclave_id)
{
    CEnclaveMngr* mngr = CEnclaveMngr::get_instance();
    CEnclaveSim* ce = mngr->get_enclave(enclave_id);
    if (ce == NULL) {
        SE_TRACE(SE_TRACE_DEBUG,
                 "enclave (id = %llu) not found.\n",
                 enclave_id);
        return SGX_ERROR_INVALID_ENCLAVE_ID;
    }

    /* In simulation mode, all allocated pages will be freed upon the later
       `delete ce'.  Just remove the first page here. */
    DoEREMOVE_SW(0, ce->get_secs()->base);

    mngr->remove(ce);
    delete ce;

    return SGX_SUCCESS;
}
Beispiel #16
0
extern "C" int get_cpusvn(sgx_cpu_svn_t *cpu_svn)
{
    if( cpu_svn == NULL)
        return SGX_ERROR_INVALID_PARAMETER;

    sgx_cpu_svn_t temp_cpusvn = {{0}};

    char config_path[MAX_FILE_PATH];
    memset(config_path, 0, MAX_FILE_PATH);

    if((get_file_path(config_path, MAX_FILE_PATH)) == false)
    {
        SE_TRACE(SE_TRACE_DEBUG, "Get configuration file path failed. Using default CPUSVN value\n");
        memcpy_s(cpu_svn, sizeof(*cpu_svn), &DEFAULT_CPUSVN, sizeof(DEFAULT_CPUSVN));
        return SGX_SUCCESS;
    }

    bool r = read_cpusvn_file(config_path, &temp_cpusvn);
    (void)r, assert (r);

    memcpy_s(cpu_svn, sizeof(*cpu_svn), &temp_cpusvn, sizeof(temp_cpusvn));

    return SGX_SUCCESS;
}
Beispiel #17
0
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;
}
Beispiel #18
0
void dump_ssa_gregs(ssa_gpr_t* gpr)
{
    SE_TRACE(SE_TRACE_DEBUG, "ssa generic registers:\n");
    SE_TRACE(SE_TRACE_DEBUG, "xbx = %#lx\t", gpr->REG(bx));
    SE_TRACE(SE_TRACE_DEBUG, "xcx = %#lx\t", gpr->REG(cx));
    SE_TRACE(SE_TRACE_DEBUG, "xdx = %#lx\t", gpr->REG(dx));
    SE_TRACE(SE_TRACE_DEBUG, "xsi = %#lx\t", gpr->REG(si));
    SE_TRACE(SE_TRACE_DEBUG, "xdi = %#lx\t", gpr->REG(di));
    SE_TRACE(SE_TRACE_DEBUG, "xbp = %#lx\t", gpr->REG(bp));
    SE_TRACE(SE_TRACE_DEBUG, "xax = %#lx\t", gpr->REG(ax));
    SE_TRACE(SE_TRACE_DEBUG, "xip = %#lx\t", gpr->REG(ip));
    SE_TRACE(SE_TRACE_DEBUG, "xflags = %#lx\t", gpr->REG(flags));
    SE_TRACE(SE_TRACE_DEBUG, "xsp = %#lx\t", gpr->REG(sp));
}
Beispiel #19
0
void dump_regs(struct user_regs_struct *regs)
{
    SE_TRACE(SE_TRACE_DEBUG, "user regisers:\n");
    SE_TRACE(SE_TRACE_DEBUG, "xbx = %#x\t", regs->REG(bx));
    SE_TRACE(SE_TRACE_DEBUG, "xcx = %#x\t", regs->REG(cx));
    SE_TRACE(SE_TRACE_DEBUG, "xdx = %#x\t", regs->REG(dx));
    SE_TRACE(SE_TRACE_DEBUG, "xsi = %#x\t", regs->REG(si));
    SE_TRACE(SE_TRACE_DEBUG, "xdi = %#x\t", regs->REG(di));
    SE_TRACE(SE_TRACE_DEBUG, "xbp = %#x\t", regs->REG(bp));
    SE_TRACE(SE_TRACE_DEBUG, "xax = %#x\t", regs->REG(ax));
    SE_TRACE(SE_TRACE_DEBUG, "xip = %#x\t", regs->REG(ip));
    SE_TRACE(SE_TRACE_DEBUG, "xflags = %#x\t", regs->eflags);
    SE_TRACE(SE_TRACE_DEBUG, "xsp = %#x\t", regs->REG(sp));
}