Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp2256777ybi; Sat, 13 Jul 2019 10:11:39 -0700 (PDT) X-Google-Smtp-Source: APXvYqzaxipQan+CtVeJmEvUFjKlKZGN0wX4iNX9wkA/6DhOi0EXD25qTDl54sucYkItgW0E5E6X X-Received: by 2002:a17:90a:71ca:: with SMTP id m10mr19517926pjs.27.1563037899378; Sat, 13 Jul 2019 10:11:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1563037899; cv=none; d=google.com; s=arc-20160816; b=khj3/pIsVS5CtqH7JYsrETWM+ck3VGYDuy7BO6RHyMw5vGiZRwaoE0uOTs36w0PP9u AL+Mn/unBEq+D1UyBo0xP5aJTdRTkJBDX0+4IkzSFyz0GC92MS+C0sAbGB3XsFbkbpb9 XOE3KEwELslCWguh3tbgsFmojc2Oy6wASlYLTPJiTX/hSwfgzUR2OFFmW6MkYKX69UlH A+HDY+XOv6w2GMmj+AyKYHUgUnff44e09ermfSF4z1GwKGzaCvXojl75vwbDSKsxJdLd d6pP3PwPhrKin6Tod4KUUVrbxoBlDIrswMaSFTvdxIQjcizdYd7nCQ7PFNZrMxXPdm1B tBtg== 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=Oe0rxKYw0DeLYsmWqLIjOsO0rFGX9Wgpc2wGOfPVwfY=; b=Bv+F6XaBCHwlqo6sYwlqnFJbG9CdF5lRDeq3/bGlCY7ETAZ/rSoiw20ABtpP1V9KV9 ZhplT5UqEjKJJXbNMKEt2hyk80JQdeh5kJpLwcfA7+I9H9vIEhNzoKwaXN6uj8C5R28Q f0hTxI6ruZjsVJmnyRuS5sh5rJoRRMHBIaeLQhMTv6EkvPKSU5zLETujLndHdM5YqAay oelS6zdUVOLiIaiVcy/suqau2ZQIRAbgT/fZdI5Gw8nFGYw4hORndt/xzLhFovS83euC OC6EZvAjZdPZfeC07ZrslFWeT4IQiQr5bLarhs4E+r70vNRD+VummMVl2WOHVvTOWP6G C1OQ== 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 s7si10793731plr.95.2019.07.13.10.11.24; Sat, 13 Jul 2019 10:11:39 -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 S1727950AbfGMRKx (ORCPT + 99 others); Sat, 13 Jul 2019 13:10:53 -0400 Received: from mga04.intel.com ([192.55.52.120]:24690 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727784AbfGMRKw (ORCPT ); Sat, 13 Jul 2019 13:10:52 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Jul 2019 10:10:52 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.63,487,1557212400"; d="scan'208";a="341981381" Received: from hbriegel-mobl.ger.corp.intel.com (HELO localhost) ([10.252.50.48]) by orsmga005.jf.intel.com with ESMTP; 13 Jul 2019 10:10:43 -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, Jarkko Sakkinen Subject: [PATCH v21 14/28] x86/sgx: Add sgx_einit() for initializing enclaves Date: Sat, 13 Jul 2019 20:07:50 +0300 Message-Id: <20190713170804.2340-15-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190713170804.2340-1-jarkko.sakkinen@linux.intel.com> References: <20190713170804.2340-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 Add a helper function to perform ENCLS(EINIT) with the correct LE hash MSR values. ENCLS[EINIT] initializes an enclave, verifying the enclave's measurement and preparing it for execution, i.e. the enclave cannot be run until it has been initialized. The measurement aspect of EINIT references the MSR_IA32_SGXLEPUBKEYHASH* MSRs, with the CPU comparing CPU compares the key (technically its hash) used to sign the enclave[1] with the key hash stored in the MSRs, and will reject EINIT if the keys do not match. A per-cpu cache is used to avoid writing the MSRs as writing the MSRs is extraordinarily expensive, e.g. 300-400 cycles per MSR. Because the cache may become stale, force update the MSRs and retry EINIT if the first EINIT fails due to an "invalid token". An invalid token error does not necessarily mean the MSRs need to be updated, but the cost of an unnecessary write is minimal relative to the cost of EINIT itself. [1] For EINIT's purposes, the effective signer of the enclave may be the enclave's owner, or a separate Launch Enclave that has created an EINIT token for the target enclave. When using an EINIT token, the key used to sign the token must match the MSRs in order for EINIT to succeed. Signed-off-by: Sean Christopherson Co-developed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- arch/x86/kernel/cpu/sgx/main.c | 51 ++++++++++++++++++++++++++++++++++ arch/x86/kernel/cpu/sgx/sgx.h | 2 ++ 2 files changed, 53 insertions(+) diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c index 6b4727df72ca..d3ed742e90fe 100644 --- a/arch/x86/kernel/cpu/sgx/main.c +++ b/arch/x86/kernel/cpu/sgx/main.c @@ -17,6 +17,9 @@ EXPORT_SYMBOL_GPL(sgx_epc_sections); int sgx_nr_epc_sections; +/* A per-cpu cache for the last known values of IA32_SGXLEPUBKEYHASHx MSRs. */ +static DEFINE_PER_CPU(u64 [4], sgx_lepubkeyhash_cache); + static struct sgx_epc_page *sgx_section_get_page( struct sgx_epc_section *section) { @@ -106,6 +109,54 @@ void sgx_free_page(struct sgx_epc_page *page) } EXPORT_SYMBOL_GPL(sgx_free_page); +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; +} +EXPORT_SYMBOL(sgx_einit); + static __init void sgx_free_epc_section(struct sgx_epc_section *section) { struct sgx_epc_page *page; diff --git a/arch/x86/kernel/cpu/sgx/sgx.h b/arch/x86/kernel/cpu/sgx/sgx.h index 210510a28ce0..41d4130c33a2 100644 --- a/arch/x86/kernel/cpu/sgx/sgx.h +++ b/arch/x86/kernel/cpu/sgx/sgx.h @@ -67,5 +67,7 @@ int sgx_page_reclaimer_init(void); struct sgx_epc_page *sgx_alloc_page(void); int __sgx_free_page(struct sgx_epc_page *page); void sgx_free_page(struct sgx_epc_page *page); +int sgx_einit(struct sgx_sigstruct *sigstruct, struct sgx_einittoken *token, + struct sgx_epc_page *secs, u64 *lepubkeyhash); #endif /* _X86_SGX_H */ -- 2.20.1