Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support initializing enclaves without a launch token #138

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion sgx.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ int sgx_encl_create(struct sgx_secs *secs);
int sgx_encl_add_page(struct sgx_encl *encl, unsigned long addr, void *data,
struct sgx_secinfo *secinfo, unsigned int mrmask);
int sgx_encl_init(struct sgx_encl *encl, struct sgx_sigstruct *sigstruct,
struct sgx_einittoken *einittoken);
struct sgx_einittoken *einittoken, bool use_flc);
struct sgx_encl_page *sgx_encl_augment(struct vm_area_struct *vma,
unsigned long addr, bool write);
void sgx_encl_release(struct kref *ref);
Expand Down Expand Up @@ -282,4 +282,6 @@ long modify_range(struct sgx_range *rg, unsigned long flags);
int remove_page(struct sgx_encl *encl, unsigned long address, bool trim);
int sgx_get_encl(unsigned long addr, struct sgx_encl **encl);
int sgx_vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr, resource_size_t pa);

void sgx_reset_pubkey_hash(void *failed);
#endif /* __ARCH_X86_INTEL_SGX_H__ */
24 changes: 23 additions & 1 deletion sgx_encl.c
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,7 @@ static int sgx_einit(struct sgx_encl *encl, struct sgx_sigstruct *sigstruct,
* @encl: an enclave
* @sigstruct: SIGSTRUCT for the enclave
* @token: EINITTOKEN for the enclave
* @use_flc: write LEHASH MSRs prior to calling EINIT, and restore them after
*
* Retries a few times in order to perform EINIT operation on an enclave
* because there could be potentially an interrupt storm.
Expand All @@ -926,9 +927,10 @@ static int sgx_einit(struct sgx_encl *encl, struct sgx_sigstruct *sigstruct,
* SGX error code
*/
int sgx_encl_init(struct sgx_encl *encl, struct sgx_sigstruct *sigstruct,
struct sgx_einittoken *token)
struct sgx_einittoken *token, bool use_flc)
{
int ret;
int wrmsr_fail;
int i;
int j;

Expand All @@ -943,8 +945,28 @@ int sgx_encl_init(struct sgx_encl *encl, struct sgx_sigstruct *sigstruct,

for (i = 0; i < SGX_EINIT_SLEEP_COUNT; i++) {
for (j = 0; j < SGX_EINIT_SPIN_COUNT; j++) {
wrmsr_fail = 0;

preempt_disable();

if (use_flc) {
wrmsr_fail |= wrmsrl_safe(MSR_IA32_SGXLEPUBKEYHASH0, ((u64*)token->payload.mrsigner)[0]);
wrmsr_fail |= wrmsrl_safe(MSR_IA32_SGXLEPUBKEYHASH1, ((u64*)token->payload.mrsigner)[1]);
wrmsr_fail |= wrmsrl_safe(MSR_IA32_SGXLEPUBKEYHASH2, ((u64*)token->payload.mrsigner)[2]);
wrmsr_fail |= wrmsrl_safe(MSR_IA32_SGXLEPUBKEYHASH3, ((u64*)token->payload.mrsigner)[3]);
}

ret = sgx_einit(encl, sigstruct, token);

if (use_flc) {
sgx_reset_pubkey_hash(&wrmsr_fail);
}

preempt_enable();

if (wrmsr_fail)
sgx_dbg(encl, "WRMSR SGXLEPUBKEYHASH failed\n");

if (ret == SGX_UNMASKED_EVENT)
continue;
else
Expand Down
63 changes: 54 additions & 9 deletions sgx_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
#include <linux/slab.h>
#include <linux/hashtable.h>
#include <linux/shmem_fs.h>
#include <crypto/hash.h>

int sgx_get_encl(unsigned long addr, struct sgx_encl **encl)
{
Expand Down Expand Up @@ -202,6 +203,31 @@ static long sgx_ioc_enclave_add_page(struct file *filep, unsigned int cmd,
return ret;
}

static int __sgx_get_key_hash(struct crypto_shash *tfm, const void *modulus,
void *hash)
{
SHASH_DESC_ON_STACK(shash, tfm);

shash->tfm = tfm;

return crypto_shash_digest(shash, modulus, SGX_MODULUS_SIZE, hash);
}

static int sgx_get_key_hash(const void *modulus, void *hash)
{
struct crypto_shash *tfm;
int ret;

tfm = crypto_alloc_shash("sha256", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm))
return PTR_ERR(tfm);

ret = __sgx_get_key_hash(tfm, modulus, hash);

crypto_free_shash(tfm);
return ret;
}

/**
* sgx_ioc_enclave_init - handler for %SGX_IOC_ENCLAVE_INIT
*
Expand All @@ -218,16 +244,28 @@ static long sgx_ioc_enclave_add_page(struct file *filep, unsigned int cmd,
static long sgx_ioc_enclave_init(struct file *filep, unsigned int cmd,
unsigned long arg)
{
struct sgx_enclave_init *initp = (struct sgx_enclave_init *)arg;
unsigned long sigstructp = (unsigned long)initp->sigstruct;
unsigned long einittokenp = (unsigned long)initp->einittoken;
unsigned long encl_id = initp->addr;
unsigned long sigstructp;
unsigned long einittokenp;
unsigned long encl_id;
struct sgx_enclave_init *initp;
struct sgx_enclave_init_no_token *initntp;
struct sgx_sigstruct *sigstruct;
struct sgx_einittoken *einittoken;
struct sgx_encl *encl;
struct page *initp_page;
int ret;

if (cmd == SGX_IOC_ENCLAVE_INIT_NO_TOKEN) {
initntp = (struct sgx_enclave_init_no_token *)arg;
sigstructp = (unsigned long)initntp->sigstruct;
encl_id = initntp->addr;
} else {
initp = (struct sgx_enclave_init *)arg;
sigstructp = (unsigned long)initp->sigstruct;
einittokenp = (unsigned long)initp->einittoken;
encl_id = initp->addr;
}

initp_page = alloc_page(GFP_HIGHUSER);
if (!initp_page)
return -ENOMEM;
Expand All @@ -241,16 +279,22 @@ static long sgx_ioc_enclave_init(struct file *filep, unsigned int cmd,
if (ret)
goto out;

ret = copy_from_user(einittoken, (void __user *)einittokenp,
sizeof(*einittoken));
if (ret)
goto out;
if (cmd != SGX_IOC_ENCLAVE_INIT_NO_TOKEN) {
ret = copy_from_user(einittoken, (void __user *)einittokenp,
sizeof(*einittoken));
if (ret)
goto out;
} else {
ret = sgx_get_key_hash(sigstruct->modulus, einittoken->payload.mrsigner);
if (ret)
goto out;
}

ret = sgx_get_encl(encl_id, &encl);
if (ret)
goto out;

ret = sgx_encl_init(encl, sigstruct, einittoken);
ret = sgx_encl_init(encl, sigstruct, einittoken, cmd == SGX_IOC_ENCLAVE_INIT_NO_TOKEN);

kref_put(&encl->refcount, sgx_encl_release);

Expand Down Expand Up @@ -394,6 +438,7 @@ long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
handler = sgx_ioc_enclave_add_page;
break;
case SGX_IOC_ENCLAVE_INIT:
case SGX_IOC_ENCLAVE_INIT_NO_TOKEN:
handler = sgx_ioc_enclave_init;
break;
case SGX_IOC_ENCLAVE_EMODPR:
Expand Down
15 changes: 13 additions & 2 deletions sgx_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ u64 sgx_xfrm_mask = 0x3;
u32 sgx_misc_reserved;
u32 sgx_xsave_size_tbl[64];
bool sgx_has_sgx2;
bool sgx_dev_alt_name;

static int sgx_mmap(struct file *file, struct vm_area_struct *vma)
{
Expand Down Expand Up @@ -168,6 +169,13 @@ static struct miscdevice sgx_dev = {
.mode = 0666,
};

static struct miscdevice sgx_dev_alt = {
.minor = MISC_DYNAMIC_MINOR,
.name = "sgx",
.fops = &sgx_fops,
.mode = 0666,
};

static int sgx_pm_suspend(struct device *dev)
{
struct sgx_tgid_ctx *ctx;
Expand All @@ -184,7 +192,7 @@ static int sgx_pm_suspend(struct device *dev)
return 0;
}

static void sgx_reset_pubkey_hash(void *failed)
void sgx_reset_pubkey_hash(void *failed)
{
if (wrmsrl_safe(MSR_IA32_SGXLEPUBKEYHASH0, 0xa6053e051270b7acULL) ||
wrmsrl_safe(MSR_IA32_SGXLEPUBKEYHASH1, 0x6cfbe8ba8b3b413dULL) ||
Expand Down Expand Up @@ -275,7 +283,7 @@ static int sgx_dev_init(struct device *parent)
}

sgx_dev.parent = parent;
ret = misc_register(&sgx_dev);
ret = misc_register(sgx_dev_alt_name ? &sgx_dev_alt : &sgx_dev);
if (ret) {
pr_err("intel_sgx: misc_register() failed\n");
goto out_workqueue;
Expand Down Expand Up @@ -408,3 +416,6 @@ module_init(init_sgx_module);
module_exit(cleanup_sgx_module);

MODULE_LICENSE("Dual BSD/GPL");

module_param_named(devsgx, sgx_dev_alt_name, bool, 0444);
MODULE_PARM_DESC(sgx_dev_alt_name, "Device name is sgx instead of isgx");
13 changes: 13 additions & 0 deletions sgx_user.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@
_IOW(SGX_MAGIC, 0x01, struct sgx_enclave_add_page)
#define SGX_IOC_ENCLAVE_INIT \
_IOW(SGX_MAGIC, 0x02, struct sgx_enclave_init)
#define SGX_IOC_ENCLAVE_INIT_NO_TOKEN \
_IOW(SGX_MAGIC, 0x02, struct sgx_enclave_init_no_token)
#define SGX_IOC_ENCLAVE_EMODPR \
_IOW(SGX_MAGIC, 0x09, struct sgx_modification_param)
#define SGX_IOC_ENCLAVE_MKTCS \
Expand Down Expand Up @@ -147,6 +149,17 @@ struct sgx_enclave_init {
__u64 einittoken;
} __attribute__((__packed__));

/**
* struct sgx_enclave_init - parameter structure for the
* %SGX_IOC_ENCLAVE_INIT ioctl
* @addr: address in the ELRANGE
* @sigstruct: address for the page data
*/
struct sgx_enclave_init_no_token {
__u64 addr;
__u64 sigstruct;
} __attribute__((__packed__));

/*
* SGX2.0 definitions
*/
Expand Down