@@ -4,7 +4,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2016 Intel Corporation.
+ * Copyright(c) 2016,2017 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -60,115 +60,15 @@
#ifndef _ASM_X86_SGX_H
#define _ASM_X86_SGX_H
+#include <asm/sgx_arch.h>
#include <asm/asm.h>
#include <linux/bitops.h>
#include <linux/err.h>
#include <linux/types.h>
-#define SGX_CPUID 0x12
-
-enum sgx_page_type {
- SGX_PAGE_TYPE_SECS = 0x00,
- SGX_PAGE_TYPE_TCS = 0x01,
- SGX_PAGE_TYPE_REG = 0x02,
- SGX_PAGE_TYPE_VA = 0x03,
-};
-
-enum sgx_secinfo_flags {
- SGX_SECINFO_R = 0x01,
- SGX_SECINFO_W = 0x02,
- SGX_SECINFO_X = 0x04,
- SGX_SECINFO_SECS = 0x000ULL,
- SGX_SECINFO_TCS = 0x100ULL,
- SGX_SECINFO_REG = 0x200ULL,
-};
-
-struct sgx_secinfo {
- u64 flags;
- u64 reserved[7];
-} __aligned(128);
-
-struct sgx_einittoken {
- u32 valid;
- u8 reserved1[206];
- u16 isvsvnle;
- u8 reserved2[92];
-} __aligned(512);
-
-enum isgx_secs_attributes {
- SGX_SECS_A_DEBUG = BIT_ULL(1),
- SGX_SECS_A_MODE64BIT = BIT_ULL(2),
- SGX_SECS_A_PROVISION_KEY = BIT_ULL(4),
- SGX_SECS_A_LICENSE_KEY = BIT_ULL(5),
- SGX_SECS_A_RESERVED_MASK = (BIT_ULL(0) |
- BIT_ULL(3) |
- GENMASK_ULL(63, 6)),
-};
-
-#define SGX_SECS_RESERVED1_SIZE 28
-#define SGX_SECS_RESERVED2_SIZE 32
-#define SGX_SECS_RESERVED3_SIZE 96
-#define SGX_SECS_RESERVED4_SIZE 3836
-
-struct sgx_secs {
- u64 size;
- u64 base;
- u32 ssaframesize;
- uint8_t reserved1[SGX_SECS_RESERVED1_SIZE];
- u64 flags;
- u64 xfrm;
- u32 mrenclave[8];
- uint8_t reserved2[SGX_SECS_RESERVED2_SIZE];
- u32 mrsigner[8];
- uint8_t reserved3[SGX_SECS_RESERVED3_SIZE];
- u16 isvvprodid;
- u16 isvsvn;
- uint8_t reserved[SGX_SECS_RESERVED4_SIZE];
-};
-
-struct sgx_tcs {
- u64 state;
- u64 flags;
- u64 ossa;
- u32 cssa;
- u32 nssa;
- u64 oentry;
- u64 aep;
- u64 ofsbase;
- u64 ogsbase;
- u32 fslimit;
- u32 gslimit;
- u64 reserved[503];
-};
-
-enum sgx_secinfo_masks {
- SGX_SECINFO_PERMISSION_MASK = GENMASK_ULL(2, 0),
- SGX_SECINFO_PAGE_TYPE_MASK = GENMASK_ULL(15, 8),
- SGX_SECINFO_RESERVED_MASK = (GENMASK_ULL(7, 3) |
- GENMASK_ULL(63, 16)),
-};
-
-struct sgx_pcmd {
- struct sgx_secinfo secinfo;
- u64 enclave_id;
- u8 reserved[40];
- u8 mac[16];
-};
-
-struct sgx_page_info {
- u64 linaddr;
- u64 srcpge;
- union {
- u64 secinfo;
- u64 pcmd;
- };
- u64 secs;
-} __aligned(32);
-
-#define SIGSTRUCT_SIZE 1808
-#define EINITTOKEN_SIZE 304
+#define SGX_CPUID 0x12
-enum {
+enum sgx_commands {
ECREATE = 0x0,
EADD = 0x1,
EINIT = 0x2,
@@ -240,7 +140,7 @@ enum {
})
#endif
-static inline unsigned long __ecreate(struct sgx_page_info *pginfo, void *secs)
+static inline unsigned long __ecreate(struct sgx_pageinfo *pginfo, void *secs)
{
return __encls(ECREATE, pginfo, secs, "d"(0));
}
@@ -250,7 +150,7 @@ static inline int __eextend(void *secs, void *epc)
return __encls(EEXTEND, secs, epc, "d"(0));
}
-static inline int __eadd(struct sgx_page_info *pginfo, void *epc)
+static inline int __eadd(struct sgx_pageinfo *pginfo, void *epc)
{
return __encls(EADD, pginfo, epc, "d"(0));
}
@@ -315,12 +215,12 @@ static inline int __epa(void *epc)
return __encls(EPA, rbx, epc, "d"(0));
}
-static inline int __ewb(struct sgx_page_info *pginfo, void *epc, void *va)
+static inline int __ewb(struct sgx_pageinfo *pginfo, void *epc, void *va)
{
return __encls_ret(EWB, pginfo, epc, va);
}
-static inline int __eaug(struct sgx_page_info *pginfo, void *epc)
+static inline int __eaug(struct sgx_pageinfo *pginfo, void *epc)
{
return __encls(EAUG, pginfo, epc, "d"(0));
}
new file mode 100644
@@ -0,0 +1,256 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2016,2017 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Contact Information:
+ * Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+ * Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation.
+ *
+ * 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.
+ *
+ * Authors:
+ *
+ * Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+ * Suresh Siddha <suresh.b.siddha@intel.com>
+ * Serge Ayoun <serge.ayoun@intel.com>
+ * Shay Katz-zamir <shay.katz-zamir@intel.com>
+ */
+
+#ifndef _ASM_X86_SGX_ARCH_H
+#define _ASM_X86_SGX_ARCH_H
+
+enum sgx_attribute {
+ SGX_ATTR_DEBUG = 0x01,
+ SGX_ATTR_MODE64BIT = 0x04,
+ SGX_ATTR_PROVISIONKEY = 0x10,
+ SGX_ATTR_EINITTOKENKEY = 0x20,
+};
+
+#define SGX_ATTR_RESERVED_MASK 0xFFFFFFFFFFFFFFC9L
+
+#define SGX_SECS_RESERVED1_SIZE 24
+#define SGX_SECS_RESERVED2_SIZE 32
+#define SGX_SECS_RESERVED3_SIZE 96
+#define SGX_SECS_RESERVED4_SIZE 3836
+
+struct sgx_secs {
+ uint64_t size;
+ uint64_t base;
+ uint32_t ssaframesize;
+ uint32_t miscselect;
+ uint8_t reserved1[SGX_SECS_RESERVED1_SIZE];
+ uint64_t attributes;
+ uint64_t xfrm;
+ uint32_t mrenclave[8];
+ uint8_t reserved2[SGX_SECS_RESERVED2_SIZE];
+ uint32_t mrsigner[8];
+ uint8_t reserved3[SGX_SECS_RESERVED3_SIZE];
+ uint16_t isvvprodid;
+ uint16_t isvsvn;
+ uint8_t reserved4[SGX_SECS_RESERVED4_SIZE];
+};
+
+struct sgx_tcs {
+ uint64_t state;
+ uint64_t flags;
+ uint64_t ossa;
+ uint32_t cssa;
+ uint32_t nssa;
+ uint64_t oentry;
+ uint64_t aep;
+ uint64_t ofsbase;
+ uint64_t ogsbase;
+ uint32_t fslimit;
+ uint32_t gslimit;
+ uint64_t reserved[503];
+};
+
+struct sgx_pageinfo {
+ uint64_t linaddr;
+ uint64_t srcpge;
+ union {
+ uint64_t secinfo;
+ uint64_t pcmd;
+ };
+ uint64_t secs;
+} __attribute__((aligned(32)));
+
+
+#define SGX_SECINFO_PERMISSION_MASK 0x0000000000000007L
+#define SGX_SECINFO_PAGE_TYPE_MASK 0x000000000000FF00L
+#define SGX_SECINFO_RESERVED_MASK 0xFFFFFFFFFFFF00F8L
+
+enum sgx_page_type {
+ SGX_PAGE_TYPE_SECS = 0x00,
+ SGX_PAGE_TYPE_TCS = 0x01,
+ SGX_PAGE_TYPE_REG = 0x02,
+ SGX_PAGE_TYPE_VA = 0x03,
+};
+
+enum sgx_secinfo_flags {
+ SGX_SECINFO_R = 0x01,
+ SGX_SECINFO_W = 0x02,
+ SGX_SECINFO_X = 0x04,
+ SGX_SECINFO_SECS = 0x000ULL,
+ SGX_SECINFO_TCS = 0x100ULL,
+ SGX_SECINFO_REG = 0x200ULL,
+};
+
+struct sgx_secinfo {
+ uint64_t flags;
+ uint64_t reserved[7];
+} __attribute__((aligned(128)));
+
+struct sgx_pcmd {
+ struct sgx_secinfo secinfo;
+ uint64_t enclave_id;
+ uint8_t reserved[40];
+ uint8_t mac[16];
+};
+
+#define SGX_MODULUS_SIZE 384
+
+struct sgx_sigstruct_header {
+ uint64_t header1[2];
+ uint32_t vendor;
+ uint32_t date;
+ uint64_t header2[2];
+ uint32_t swdefined;
+ uint8_t reserved1[84];
+};
+
+struct sgx_sigstruct_body {
+ uint32_t miscselect;
+ uint32_t miscmask;
+ uint8_t reserved2[20];
+ uint64_t attributes;
+ uint64_t xfrm;
+ uint8_t attributemask[16];
+ uint8_t mrenclave[32];
+ uint8_t reserved3[32];
+ uint16_t isvprodid;
+ uint16_t isvsvn;
+} __attribute__((__packed__));
+
+struct sgx_sigstruct {
+ struct sgx_sigstruct_header header;
+ uint8_t modulus[SGX_MODULUS_SIZE];
+ uint32_t exponent;
+ uint8_t signature[SGX_MODULUS_SIZE];
+ struct sgx_sigstruct_body body;
+ uint8_t reserved4[12];
+ uint8_t q1[SGX_MODULUS_SIZE];
+ uint8_t q2[SGX_MODULUS_SIZE];
+};
+
+struct sgx_sigstruct_payload {
+ struct sgx_sigstruct_header header;
+ struct sgx_sigstruct_body body;
+};
+
+struct sgx_einittoken_payload {
+ uint32_t valid;
+ uint32_t reserved1[11];
+ uint64_t attributes;
+ uint64_t xfrm;
+ uint8_t mrenclave[32];
+ uint8_t reserved2[32];
+ uint8_t mrsigner[32];
+ uint8_t reserved3[32];
+};
+
+struct sgx_einittoken {
+ struct sgx_einittoken_payload payload;
+ uint8_t cpusvnle[16];
+ uint16_t isvprodidle;
+ uint16_t isvsvnle;
+ uint8_t reserved2[24];
+ uint32_t maskedmiscselectle;
+ uint64_t maskedattributesle;
+ uint64_t maskedxfrmle;
+ uint8_t keyid[32];
+ uint8_t mac[16];
+};
+
+struct sgx_report {
+ uint8_t cpusvn[16];
+ uint32_t miscselect;
+ uint8_t reserved1[28];
+ uint64_t attributes;
+ uint64_t xfrm;
+ uint8_t mrenclave[32];
+ uint8_t reserved2[32];
+ uint8_t mrsigner[32];
+ uint8_t reserved3[96];
+ uint16_t isvprodid;
+ uint16_t isvsvn;
+ uint8_t reserved4[60];
+ uint8_t reportdata[64];
+ uint8_t keyid[32];
+ uint8_t mac[16];
+};
+
+struct sgx_targetinfo {
+ uint8_t mrenclave[32];
+ uint64_t attributes;
+ uint64_t xfrm;
+ uint8_t reserved1[4];
+ uint32_t miscselect;
+ uint8_t reserved2[456];
+};
+
+struct sgx_keyrequest {
+ uint16_t keyname;
+ uint16_t keypolicy;
+ uint16_t isvsvn;
+ uint16_t reserved1;
+ uint8_t cpusvn[16];
+ uint64_t attributemask;
+ uint64_t xfrmmask;
+ uint8_t keyid[32];
+ uint32_t miscmask;
+ uint8_t reserved2[436];
+};
+
+#endif /* _ASM_X86_SGX_ARCH_H */
@@ -192,7 +192,7 @@ static int sgx_add_page(struct sgx_epc_page *secs_page,
struct sgx_secinfo *secinfo,
struct page *backing)
{
- struct sgx_page_info pginfo;
+ struct sgx_pageinfo pginfo;
void *epc_page_vaddr;
int ret;
@@ -323,10 +323,10 @@ static int sgx_validate_secs(const struct sgx_secs *secs)
u32 tmp;
int i;
- if (secs->flags & SGX_SECS_A_RESERVED_MASK)
+ if (secs->attributes & SGX_ATTR_RESERVED_MASK)
return -EINVAL;
- if (secs->flags & SGX_SECS_A_MODE64BIT) {
+ if (secs->attributes & SGX_ATTR_MODE64BIT) {
#ifdef CONFIG_X86_64
if (secs->size > sgx_encl_size_max_64)
return -EINVAL;
@@ -379,7 +379,7 @@ static int sgx_validate_secs(const struct sgx_secs *secs)
return -EINVAL;
for (i = 0; i < SGX_SECS_RESERVED4_SIZE; i++)
- if (secs->reserved[i])
+ if (secs->reserved4[i])
return -EINVAL;
return 0;
@@ -413,7 +413,7 @@ static long sgx_ioc_enclave_create(struct file *filep, unsigned int cmd,
{
struct sgx_enclave_create *createp = (struct sgx_enclave_create *)arg;
unsigned long src = (unsigned long)createp->src;
- struct sgx_page_info pginfo;
+ struct sgx_pageinfo pginfo;
struct sgx_secinfo secinfo;
struct sgx_encl *encl = NULL;
struct sgx_secs *secs = NULL;
@@ -514,10 +514,9 @@ static long sgx_ioc_enclave_create(struct file *filep, unsigned int cmd,
encl->secs_page.epc_page = secs_epc;
createp->src = (unsigned long)encl->base;
- if (secs->flags & SGX_SECS_A_DEBUG)
+ if (secs->attributes & SGX_ATTR_DEBUG)
encl->flags |= SGX_ENCL_DEBUG;
-
encl->mmu_notifier.ops = &sgx_mmu_notifier_ops;
ret = mmu_notifier_register(&encl->mmu_notifier, encl->mm);
if (ret) {
@@ -779,7 +778,8 @@ static long sgx_ioc_enclave_add_page(struct file *filep, unsigned int cmd,
return ret;
}
-static int __sgx_encl_init(struct sgx_encl *encl, char *sigstruct,
+static int __sgx_encl_init(struct sgx_encl *encl,
+ struct sgx_sigstruct *sigstruct,
struct sgx_einittoken *einittoken)
{
int ret = SGX_UNMASKED_EVENT;
@@ -788,7 +788,8 @@ static int __sgx_encl_init(struct sgx_encl *encl, char *sigstruct,
int i;
int j;
- if (einittoken->valid && einittoken->isvsvnle < sgx_isvsvnle_min)
+ if (einittoken->payload.valid &&
+ einittoken->isvsvnle < sgx_isvsvnle_min)
return SGX_LE_ROLLBACK;
for (i = 0; i < SGX_EINIT_SLEEP_COUNT; i++) {
@@ -843,7 +844,7 @@ static long sgx_ioc_enclave_init(struct file *filep, unsigned int cmd,
unsigned long sigstructp = (unsigned long)initp->sigstruct;
unsigned long einittokenp = (unsigned long)initp->einittoken;
unsigned long encl_id = initp->addr;
- char *sigstruct;
+ struct sgx_sigstruct *sigstruct;
struct sgx_einittoken *einittoken;
struct sgx_encl *encl;
struct page *initp_page;
@@ -858,14 +859,14 @@ static long sgx_ioc_enclave_init(struct file *filep, unsigned int cmd,
((unsigned long)sigstruct + PAGE_SIZE / 2);
ret = copy_from_user(sigstruct, (void __user *)sigstructp,
- SIGSTRUCT_SIZE);
+ sizeof(*sigstruct));
if (ret)
goto out_free_page;
/* A valid token is not needed if MRSIGNER is IA32_SGXLEPUBKEYHASH. */
if (einittokenp) {
ret = copy_from_user(einittoken, (void __user *)einittokenp,
- EINITTOKEN_SIZE);
+ sizeof(*einittoken));
if (ret)
goto out_free_page;
}
@@ -224,7 +224,7 @@ static void sgx_isolate_pages(struct sgx_encl *encl,
static int __sgx_ewb(struct sgx_encl *encl,
struct sgx_encl_page *encl_page)
{
- struct sgx_page_info pginfo;
+ struct sgx_pageinfo pginfo;
struct page *backing;
struct page *pcmd;
unsigned long pcmd_offset;
@@ -191,7 +191,7 @@ static int sgx_eldu(struct sgx_encl *encl,
struct page *backing;
struct page *pcmd;
unsigned long pcmd_offset;
- struct sgx_page_info pginfo;
+ struct sgx_pageinfo pginfo;
void *secs_ptr = NULL;
void *epc_ptr;
void *va_ptr;
Split asm/sgx_arch.h from asm/sgx.h and clean it up to be common header with kernel and the in-kernel user space. Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> --- arch/x86/include/asm/sgx.h | 116 +---------- arch/x86/include/asm/sgx_arch.h | 256 ++++++++++++++++++++++++ drivers/platform/x86/intel_sgx/sgx_ioctl.c | 25 +-- drivers/platform/x86/intel_sgx/sgx_page_cache.c | 2 +- drivers/platform/x86/intel_sgx/sgx_util.c | 2 +- 5 files changed, 279 insertions(+), 122 deletions(-) create mode 100644 arch/x86/include/asm/sgx_arch.h