Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp830145ybt; Wed, 17 Jun 2020 15:19:36 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzPhMaFy3OeciecP2GMvkFi6OE4t/lk7pFuTr+S7lNYzaQCNKwqv4dGxOjBxXUVzhwYK2YX X-Received: by 2002:a17:90b:46cf:: with SMTP id jx15mr1133795pjb.121.1592432376173; Wed, 17 Jun 2020 15:19:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1592432376; cv=none; d=google.com; s=arc-20160816; b=iIBswSiPc6iApp7xlk0kkU6x63FXH6rwb9PgkAtHnM2Z4aq0lJMuXEY6bMO4xHSt19 gbYhGOBW2dKe1afdtEt+67zxnPPZfqb4gR211CGBKZ1C7ezawMrGX2942mx0wV5yzg1A ckXCz3Alx2CJBLV5zeHpzoCqpTpYAzukQrRAMNqGl4R2ucmumKlHBrXpW/yda0z8LB2c OVQtpciqrcjOQRi6M86PFHikfLzBLHFBR5Le3bJzwe+Z9eIddyn6EMH/C0bGCx30H8Ik ER3FEkUnJW0xALh0UZgYxiLGEbGziOhsozWsk3vCt9Nk06tBGw2svLDrC622zZflZjQi gF/Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :ironport-sdr:ironport-sdr; bh=1hpg9FAhfnTRLjpkufOFnUCVVjwgaRPq/YEOptL1La0=; b=l2+rRC4vY+7tMS/mKKE3gV6BgW34zrDOhtnlQ39XrjHOUan+tWa5SEH4BBwGU5VEK0 fiR0znyu0FkyhfXOeNrTsXxtC0xC6Fzik7YtNTHaflg2nUOoGxLJt3MYVwrNgp0e/5dw cuy99vRssUWOfoZNg3UdD3JzWri5/eJ+VLFHQo9PtncldltpDyL/nOXnmjD4dUq7AfG5 Pa9y3SvqhtDtdEFiaCdnpxW+QH2roOEJ6nEJunPLHu6yc4lhdmRwPWdemel4rPeFl5PA bPj4OgLrkfF1/ouXIMcMdhK+ur2WojJb0r1K/0OFYlMs3fKnvNbo5VzlV8He3KRT6hs5 PJHA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id 193si638500pgh.391.2020.06.17.15.18.50; Wed, 17 Jun 2020 15:19:36 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727010AbgFQWL6 (ORCPT + 99 others); Wed, 17 Jun 2020 18:11:58 -0400 Received: from mga18.intel.com ([134.134.136.126]:26655 "EHLO mga18.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726912AbgFQWL5 (ORCPT ); Wed, 17 Jun 2020 18:11:57 -0400 IronPort-SDR: 3FCjy0nrOQ7qxI9N/c9P+PzEi2aXvlmVHqYod8HIiGZfh/7ICJDMA9MSDzli82tGdLHlAnnEj3 XkCs0B5/1G/w== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jun 2020 15:11:57 -0700 IronPort-SDR: v8O4N2wXMLBdPSSghu9eXd0rSOYPkPVmnwecX9oKXQrW0F+AA5h4y6funAZQSSA+CM/Dv5a3Qq k+ua3JvQMm0Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,523,1583222400"; d="scan'208";a="421288422" Received: from ysharon1-mobl1.ger.corp.intel.com (HELO localhost) ([10.252.49.131]) by orsmga004.jf.intel.com with ESMTP; 17 Jun 2020 15:11:43 -0700 From: Jarkko Sakkinen To: x86@kernel.org, linux-sgx@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Jarkko Sakkinen , linux-security-module@vger.kernel.org, Jethro Beekman , Andy Lutomirski , akpm@linux-foundation.org, andriy.shevchenko@linux.intel.com, asapek@google.com, bp@alien8.de, cedric.xing@intel.com, chenalexchen@google.com, conradparker@google.com, cyhanish@google.com, dave.hansen@intel.com, haitao.huang@intel.com, josh@joshtriplett.org, kai.huang@intel.com, kai.svahn@intel.com, kmoy@google.com, ludloff@google.com, nhorman@redhat.com, npmccallum@redhat.com, puiterwijk@redhat.com, rientjes@google.com, sean.j.christopherson@intel.com, tglx@linutronix.de, yaozhangx@google.com Subject: [PATCH v33 12/21] x86/sgx: Allow a limited use of ATTRIBUTE.PROVISIONKEY for attestation Date: Thu, 18 Jun 2020 01:08:34 +0300 Message-Id: <20200617220844.57423-13-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200617220844.57423-1-jarkko.sakkinen@linux.intel.com> References: <20200617220844.57423-1-jarkko.sakkinen@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Provisioning Certification Enclave (PCE), the root of trust for other enclaves, generates a signing key from a fused key called Provisioning Certification Key. PCE can then use this key to certify an attestation key of a QE, e.g. we get the chain of trust down to the hardware if the Intel signed PCE is used. To use the needed keys, ATTRIBUTE.PROVISIONKEY is required but should be only allowed for those who actually need it so that only the trusted parties can certify QE's. Obviously the attestation service should know the public key of the used PCE and that way detect illegit attestation, but whitelisting the legit users still adds an additional layer of defence. Add new device file called /dev/sgx/provision. The sole purpose of this file is to provide file descriptors that act as privilege tokens to allow to build enclaves with ATTRIBUTE.PROVISIONKEY set. A new ioctl called SGX_IOC_ENCLAVE_SET_ATTRIBUTE is used to assign this token to an enclave. Cc: linux-security-module@vger.kernel.org Acked-by: Jethro Beekman Suggested-by: Andy Lutomirski Signed-off-by: Jarkko Sakkinen --- arch/x86/include/uapi/asm/sgx.h | 11 ++++++++ arch/x86/kernel/cpu/sgx/driver.c | 14 ++++++++++ arch/x86/kernel/cpu/sgx/driver.h | 2 ++ arch/x86/kernel/cpu/sgx/ioctl.c | 47 ++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+) diff --git a/arch/x86/include/uapi/asm/sgx.h b/arch/x86/include/uapi/asm/sgx.h index 5edb08ab8fd0..57d0d30c79b3 100644 --- a/arch/x86/include/uapi/asm/sgx.h +++ b/arch/x86/include/uapi/asm/sgx.h @@ -25,6 +25,8 @@ enum sgx_page_flags { _IOWR(SGX_MAGIC, 0x01, struct sgx_enclave_add_pages) #define SGX_IOC_ENCLAVE_INIT \ _IOW(SGX_MAGIC, 0x02, struct sgx_enclave_init) +#define SGX_IOC_ENCLAVE_SET_ATTRIBUTE \ + _IOW(SGX_MAGIC, 0x03, struct sgx_enclave_set_attribute) /** * struct sgx_enclave_create - parameter structure for the @@ -63,4 +65,13 @@ struct sgx_enclave_init { __u64 sigstruct; }; +/** + * struct sgx_enclave_set_attribute - parameter structure for the + * %SGX_IOC_ENCLAVE_SET_ATTRIBUTE ioctl + * @attribute_fd: file handle of the attribute file in the securityfs + */ +struct sgx_enclave_set_attribute { + __u64 attribute_fd; +}; + #endif /* _UAPI_ASM_X86_SGX_H */ diff --git a/arch/x86/kernel/cpu/sgx/driver.c b/arch/x86/kernel/cpu/sgx/driver.c index b4aa7b9f8376..d90114cec1c3 100644 --- a/arch/x86/kernel/cpu/sgx/driver.c +++ b/arch/x86/kernel/cpu/sgx/driver.c @@ -150,6 +150,13 @@ static struct miscdevice sgx_dev_enclave = { .fops = &sgx_encl_fops, }; +static struct miscdevice sgx_dev_provision = { + .minor = MISC_DYNAMIC_MINOR, + .name = "provision", + .nodename = "sgx/provision", + .fops = &sgx_provision_fops, +}; + int __init sgx_drv_init(void) { unsigned int eax, ebx, ecx, edx; @@ -190,5 +197,12 @@ int __init sgx_drv_init(void) return ret; } + ret = misc_register(&sgx_dev_provision); + if (ret) { + pr_err("Creating /dev/sgx/provision failed with %d.\n", ret); + misc_deregister(&sgx_dev_enclave); + return ret; + } + return 0; } diff --git a/arch/x86/kernel/cpu/sgx/driver.h b/arch/x86/kernel/cpu/sgx/driver.h index e4063923115b..72747d01c046 100644 --- a/arch/x86/kernel/cpu/sgx/driver.h +++ b/arch/x86/kernel/cpu/sgx/driver.h @@ -23,6 +23,8 @@ extern u64 sgx_attributes_reserved_mask; extern u64 sgx_xfrm_reserved_mask; extern u32 sgx_xsave_size_tbl[64]; +extern const struct file_operations sgx_provision_fops; + long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); int sgx_drv_init(void); diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c index 420d13fc03da..721096f1d5ba 100644 --- a/arch/x86/kernel/cpu/sgx/ioctl.c +++ b/arch/x86/kernel/cpu/sgx/ioctl.c @@ -669,6 +669,50 @@ static long sgx_ioc_enclave_init(struct sgx_encl *encl, void __user *arg) return ret; } +/** + * sgx_ioc_enclave_set_attribute - handler for %SGX_IOC_ENCLAVE_SET_ATTRIBUTE + * @filep: open file to /dev/sgx + * @arg: userspace pointer to a struct sgx_enclave_set_attribute instance + * + * Mark the enclave as being allowed to access a restricted attribute bit. + * The requested attribute is specified via the attribute_fd field in the + * provided struct sgx_enclave_set_attribute. The attribute_fd must be a + * handle to an SGX attribute file, e.g. "/dev/sgx/provision". + * + * Failure to explicitly request access to a restricted attribute will cause + * sgx_ioc_enclave_init() to fail. Currently, the only restricted attribute + * is access to the PROVISION_KEY. + * + * Note, access to the EINITTOKEN_KEY is disallowed entirely. + * + * Return: 0 on success, -errno otherwise + */ +static long sgx_ioc_enclave_set_attribute(struct sgx_encl *encl, + void __user *arg) +{ + struct sgx_enclave_set_attribute params; + struct file *attribute_file; + int ret; + + if (copy_from_user(¶ms, arg, sizeof(params))) + return -EFAULT; + + attribute_file = fget(params.attribute_fd); + if (!attribute_file) + return -EINVAL; + + if (attribute_file->f_op != &sgx_provision_fops) { + ret = -EINVAL; + goto out; + } + + encl->allowed_attributes |= SGX_ATTR_PROVISIONKEY; + ret = 0; + +out: + fput(attribute_file); + return ret; +} long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { @@ -694,6 +738,9 @@ long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) case SGX_IOC_ENCLAVE_INIT: ret = sgx_ioc_enclave_init(encl, (void __user *)arg); break; + case SGX_IOC_ENCLAVE_SET_ATTRIBUTE: + ret = sgx_ioc_enclave_set_attribute(encl, (void __user *)arg); + break; default: ret = -ENOIOCTLCMD; break; -- 2.25.1