Received: by 2002:a25:d7c1:0:0:0:0:0 with SMTP id o184csp3981204ybg; Mon, 28 Oct 2019 23:53:07 -0700 (PDT) X-Google-Smtp-Source: APXvYqzrEsuTHvaEtKYuRwF+bfofwsP//B8OBsvJ/S6PtPMdkxIliLBStLX2XPNUlLJJ7y3lDnZO X-Received: by 2002:a17:906:bfc6:: with SMTP id us6mr1650457ejb.51.1572331987311; Mon, 28 Oct 2019 23:53:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1572331987; cv=none; d=google.com; s=arc-20160816; b=K+rViVO4YWHL9pinzECELNV22narcH8DFtVmVgTahHlOZ+/rkZt7LREhQ9zZqANY8d 6Kusijz6HsCgwi0vUb6stau7b2PRFSpCuDIhtj1lA3CghtlPkfVZS6O7SdApJNTfwjG9 H3B9fpVF8GqnvE0oCjIkDM72kHMtd2vXhgX8Q+fodRi9BWj1hweCbfV58pIDzDnE9xbM 3JooA8drOvitNsdl8GTyzTpCXP8pOZYVyv0BWexnZtcHDUbEmsqrYDd10VtiSufNMHW2 O55ytzgbQhhVCZVnlhkwRHmrCQhAA9VlxBd3TxD1quY+kaaStG5jNihzDG3Wwm8HA+6Y goqA== 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; bh=C4dZgZMjuwLY2Mdcb+pdnQyE7ZQ40dcQfGDD5bIZAmE=; b=zD28XVsdKEuHeCikVY7D2QZKifvMSHUBVNzjZ4GnZHXzY/Vputox/Jp4nHB7lO+v4d azm//13lMjVPUGsz7z71BGbX11bfKC9l1w0cM8pEhSsGqQeyKN/gHJZImWPqx0T4SylD IyXbjnSZetXsbbgPpfEHvWOAJAUIJc/enFuthJoWBp7GIfv6J9eaCIXuY/qfF0+hLTqZ CkIzeo31gQRbm13gEnut+EkEiYNIugvVtB6vnzHauYEHBDcUY/t2a9ifMAFqnF5vQh9A J7z3HOAQdsJZhWGB6cBoSJ1kYFUvo3TfSPwrTjIKtXZPZPYEPOBGzYUPlncVM2Nf7w09 yPjQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 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. [209.132.180.67]) by mx.google.com with ESMTP id v20si9107815edm.254.2019.10.28.23.52.44; Mon, 28 Oct 2019 23:53:07 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 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 S2389251AbfJ1VFR (ORCPT + 99 others); Mon, 28 Oct 2019 17:05:17 -0400 Received: from mga04.intel.com ([192.55.52.120]:49912 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389225AbfJ1VFR (ORCPT ); Mon, 28 Oct 2019 17:05:17 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Oct 2019 14:05:16 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,241,1569308400"; d="scan'208";a="224759670" Received: from shrehore-mobl1.ti.intel.com (HELO localhost) ([10.251.82.5]) by fmsmga004.fm.intel.com with ESMTP; 28 Oct 2019 14:05:08 -0700 From: Jarkko Sakkinen To: linux-kernel@vger.kernel.org, x86@kernel.org, linux-sgx@vger.kernel.org Cc: akpm@linux-foundation.org, dave.hansen@intel.com, sean.j.christopherson@intel.com, nhorman@redhat.com, npmccallum@redhat.com, serge.ayoun@intel.com, shay.katz-zamir@intel.com, haitao.huang@intel.com, andriy.shevchenko@linux.intel.com, tglx@linutronix.de, kai.svahn@intel.com, bp@alien8.de, josh@joshtriplett.org, luto@kernel.org, kai.huang@intel.com, rientjes@google.com, cedric.xing@intel.com, puiterwijk@redhat.com, Jarkko Sakkinen Subject: [PATCH v23 10/24] x86/sgx: Add sgx_einit() for wrapping ENCLS[EINIT] Date: Mon, 28 Oct 2019 23:03:10 +0200 Message-Id: <20191028210324.12475-11-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191028210324.12475-1-jarkko.sakkinen@linux.intel.com> References: <20191028210324.12475-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 From: Sean Christopherson Enclaves are SGX hosted measured and signed software entities. ENCLS[EINIT] leaf function checks that the enclave has a legit signed measurement and transforms the enclave to the state ready for execution. The signed measurement is provided by the caller in the form of SIGSTRUCT data structure [1]. Wrap ENCLS[EINIT] into sgx_einit(). Set MSR_IA32_SGXLEPUBKEYHASH* MSRs to match the public key contained in the SIGSTRUCT [2]. This sets Linux to enforce a policy where the provided public key is as long as the signed measurement matches the enclave contents in memory. Add a per-cpu cache to avoid unnecessary reads and write to the MSRs as they are expensive operations. [1] Intel SDM: 37.1.3 ENCLAVE SIGNATURE STRUCTURE (SIGSTRUCT) [2] Intel SDM: 38.1.4 Intel SGX Launch Control Configuration Signed-off-by: Sean Christopherson Co-developed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- arch/x86/kernel/cpu/sgx/Makefile | 1 + arch/x86/kernel/cpu/sgx/encls.c | 57 ++++++++++++++++++++++++++++++++ arch/x86/kernel/cpu/sgx/encls.h | 3 ++ 3 files changed, 61 insertions(+) create mode 100644 arch/x86/kernel/cpu/sgx/encls.c diff --git a/arch/x86/kernel/cpu/sgx/Makefile b/arch/x86/kernel/cpu/sgx/Makefile index 2dec75916a5e..874492d9e3bd 100644 --- a/arch/x86/kernel/cpu/sgx/Makefile +++ b/arch/x86/kernel/cpu/sgx/Makefile @@ -1,3 +1,4 @@ obj-y += \ + encls.o \ main.o \ reclaim.o diff --git a/arch/x86/kernel/cpu/sgx/encls.c b/arch/x86/kernel/cpu/sgx/encls.c new file mode 100644 index 000000000000..44291062967a --- /dev/null +++ b/arch/x86/kernel/cpu/sgx/encls.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +// Copyright(c) 2016-19 Intel Corporation. + +#include +#include +#include "encls.h" +#include "sgx.h" + +/* A per-cpu cache for the last known values of IA32_SGXLEPUBKEYHASHx MSRs. */ +static DEFINE_PER_CPU(u64 [4], sgx_lepubkeyhash_cache); + +static void sgx_update_lepubkeyhash_msrs(u64 *lepubkeyhash, bool enforce) +{ + u64 *cache; + int i; + + cache = per_cpu(sgx_lepubkeyhash_cache, smp_processor_id()); + for (i = 0; i < 4; i++) { + if (enforce || (lepubkeyhash[i] != cache[i])) { + wrmsrl(MSR_IA32_SGXLEPUBKEYHASH0 + i, lepubkeyhash[i]); + cache[i] = lepubkeyhash[i]; + } + } +} + +/** + * sgx_einit - initialize an enclave + * @sigstruct: a pointer a SIGSTRUCT + * @token: a pointer an EINITTOKEN (optional) + * @secs: a pointer a SECS + * @lepubkeyhash: the desired value for IA32_SGXLEPUBKEYHASHx MSRs + * + * Execute ENCLS[EINIT], writing the IA32_SGXLEPUBKEYHASHx MSRs according + * to @lepubkeyhash (if possible and necessary). + * + * Return: + * 0 on success, + * -errno or SGX error on failure + */ +int sgx_einit(struct sgx_sigstruct *sigstruct, struct sgx_einittoken *token, + struct sgx_epc_page *secs, u64 *lepubkeyhash) +{ + int ret; + + if (!boot_cpu_has(X86_FEATURE_SGX_LC)) + return __einit(sigstruct, token, sgx_epc_addr(secs)); + + preempt_disable(); + sgx_update_lepubkeyhash_msrs(lepubkeyhash, false); + ret = __einit(sigstruct, token, sgx_epc_addr(secs)); + if (ret == SGX_INVALID_EINITTOKEN) { + sgx_update_lepubkeyhash_msrs(lepubkeyhash, true); + ret = __einit(sigstruct, token, sgx_epc_addr(secs)); + } + preempt_enable(); + return ret; +} diff --git a/arch/x86/kernel/cpu/sgx/encls.h b/arch/x86/kernel/cpu/sgx/encls.h index d6381e4f6eb2..af94bbfe4cf6 100644 --- a/arch/x86/kernel/cpu/sgx/encls.h +++ b/arch/x86/kernel/cpu/sgx/encls.h @@ -248,4 +248,7 @@ static inline int __ewb(struct sgx_pageinfo *pginfo, void *addr, return __encls_ret_3(EWB, pginfo, addr, va); } +int sgx_einit(struct sgx_sigstruct *sigstruct, struct sgx_einittoken *token, + struct sgx_epc_page *secs, u64 *lepubkeyhash); + #endif /* _X86_ENCLS_H */ -- 2.20.1