Skip to content

Commit

Permalink
Support initializing enclaves without a launch token
Browse files Browse the repository at this point in the history
  • Loading branch information
Jethro Beekman committed Aug 10, 2021
1 parent 2d2b795 commit c17afa6
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 13 deletions.
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__ */
19 changes: 18 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 ret2;
int i;
int j;

Expand All @@ -943,8 +945,23 @@ 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++) {
preempt_disable();

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

ret = sgx_einit(encl, sigstruct, token);

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

preempt_enable();

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

0 comments on commit c17afa6

Please sign in to comment.