All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Chang S. Bae" <chang.seok.bae@intel.com>
To: tglx@linutronix.de, mingo@kernel.org, bp@suse.de,
	luto@kernel.org, x86@kernel.org, herbert@gondor.apana.org.au
Cc: dan.j.williams@intel.com, dave.hansen@intel.com,
	ravi.v.shankar@intel.com, ning.sun@intel.com,
	kumar.n.dwarakanath@intel.com, linux-crypto@vger.kernel.org,
	linux-kernel@vger.kernel.org, chang.seok.bae@intel.com,
	Mark Brown <broonie@kernel.org>,
	linux-doc@vger.kernel.org
Subject: [RFC PATCH 8/8] x86/cpu: Support the hardware randomization option for Key Locker internal key
Date: Wed, 16 Dec 2020 09:41:46 -0800	[thread overview]
Message-ID: <20201216174146.10446-9-chang.seok.bae@intel.com> (raw)
In-Reply-To: <20201216174146.10446-1-chang.seok.bae@intel.com>

Hardware can load the internal key with randomization. random.trust_cpu
determines the use of the CPU's random number generator. Take the parameter
to use the CPU's internal key randomization.

The backup mechanism is required to distribute the key. It is the only
way to copy the (unknown) key value to other CPUs.

This randomization option is disabled when hardware does not support the
key backup.

Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: x86@kernel.org
Cc: linux-doc@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 arch/x86/include/asm/keylocker.h |  2 +-
 arch/x86/kernel/cpu/common.c     |  3 ++-
 arch/x86/kernel/keylocker.c      | 31 ++++++++++++++++++++++++++++---
 drivers/char/random.c            |  6 ++++++
 include/linux/random.h           |  2 ++
 5 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/keylocker.h b/arch/x86/include/asm/keylocker.h
index 722574c305c2..a6774ced916a 100644
--- a/arch/x86/include/asm/keylocker.h
+++ b/arch/x86/include/asm/keylocker.h
@@ -19,7 +19,7 @@ bool check_keylocker_readiness(void);
 
 bool load_keylocker(void);
 
-void make_keylocker_data(void);
+void make_keylocker_data(bool use_hwrand);
 #ifdef CONFIG_X86_KEYLOCKER
 void invalidate_keylocker_data(void);
 #else
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index ba5bd79fbac2..48881d8ea559 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -485,12 +485,13 @@ static __always_inline void setup_keylocker(struct cpuinfo_x86 *c)
 	cr4_set_bits(X86_CR4_KEYLOCKER);
 
 	if (c == &boot_cpu_data) {
+		bool use_hwrand = check_random_trust_cpu();
 		bool keyloaded;
 
 		if (!check_keylocker_readiness())
 			goto disable_keylocker;
 
-		make_keylocker_data();
+		make_keylocker_data(use_hwrand);
 
 		keyloaded = load_keylocker();
 		if (!keyloaded) {
diff --git a/arch/x86/kernel/keylocker.c b/arch/x86/kernel/keylocker.c
index 229875ac80d5..e77e4c3d785e 100644
--- a/arch/x86/kernel/keylocker.c
+++ b/arch/x86/kernel/keylocker.c
@@ -13,6 +13,7 @@
 #include <asm/fpu/api.h>
 
 static bool keybackup_available;
+static bool keyhwrand_available;
 
 bool check_keylocker_readiness(void)
 {
@@ -33,25 +34,33 @@ bool check_keylocker_readiness(void)
 		pr_debug("x86/keylocker: no key backup support with possible S3/4\n");
 		return false;
 	}
+
+	keyhwrand_available = (ecx & KEYLOCKER_CPUID_ECX_RAND);
 	return true;
 }
 
 /* Load Internal (Wrapping) Key */
 #define LOADIWKEY		".byte 0xf3,0x0f,0x38,0xdc,0xd1"
 #define LOADIWKEY_NUM_OPERANDS	3
+#define LOADIWKEY_HWRAND_RETRY	10
 
 static struct key {
 	bool valid;
+	bool hwrand;
 	struct reg_128_bit value[LOADIWKEY_NUM_OPERANDS];
 } keydata;
 
-void make_keylocker_data(void)
+void make_keylocker_data(bool use_hwrand)
 {
 	int i;
 
 	for (i = 0; i < LOADIWKEY_NUM_OPERANDS; i++)
 		get_random_bytes(&keydata.value[i], sizeof(struct reg_128_bit));
 
+	keydata.hwrand = (use_hwrand && keyhwrand_available && keybackup_available);
+	if (use_hwrand && !keydata.hwrand)
+		pr_warn("x86/keylocker: hardware random key not fully supported\n");
+
 	keydata.valid = true;
 }
 
@@ -63,12 +72,22 @@ void invalidate_keylocker_data(void)
 }
 
 #define USE_SWKEY	0
+#define USE_HWRANDKEY	BIT(1)
 
 bool load_keylocker(void)
 {
 	struct reg_128_bit zeros = { 0 };
-	u32 keysrc = USE_SWKEY;
 	bool err = true;
+	u32 keysrc;
+	int retry;
+
+	if (keydata.hwrand) {
+		keysrc = USE_HWRANDKEY;
+		retry = LOADIWKEY_HWRAND_RETRY;
+	} else {
+		keysrc = USE_SWKEY;
+		retry = 0;
+	}
 
 	kernel_fpu_begin();
 
@@ -77,13 +96,19 @@ bool load_keylocker(void)
 			 "m"(keydata.value[1]),
 			 "m"(keydata.value[2]));
 
-	asm volatile (LOADIWKEY CC_SET(z) : CC_OUT(z) (err) : "a"(keysrc));
+	do {
+		asm volatile (LOADIWKEY CC_SET(z) : CC_OUT(z) (err) : "a"(keysrc));
+		retry--;
+	} while (err && retry >= 0);
 
 	asm volatile ("movdqu %0, %%xmm0; movdqu %0, %%xmm1; movdqu %0, %%xmm2;"
 		      :: "m"(zeros));
 
 	kernel_fpu_end();
 
+	if (keydata.hwrand)
+		invalidate_keylocker_data();
+
 	return err ? false : true;
 }
 
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 2a41b21623ae..3ee0d659ab2a 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -781,6 +781,12 @@ static int __init parse_trust_cpu(char *arg)
 }
 early_param("random.trust_cpu", parse_trust_cpu);
 
+bool check_random_trust_cpu(void)
+{
+	return trust_cpu;
+}
+EXPORT_SYMBOL(check_random_trust_cpu);
+
 static bool crng_init_try_arch(struct crng_state *crng)
 {
 	int		i;
diff --git a/include/linux/random.h b/include/linux/random.h
index f45b8be3e3c4..f08f44988b13 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -158,4 +158,6 @@ static inline bool __init arch_get_random_long_early(unsigned long *v)
 }
 #endif
 
+extern bool check_random_trust_cpu(void);
+
 #endif /* _LINUX_RANDOM_H */
-- 
2.17.1


  parent reply	other threads:[~2020-12-16 17:47 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-16 17:41 [RFC PATCH 0/8] x86: Support Intel Key Locker Chang S. Bae
2020-12-16 17:41 ` [RFC PATCH 1/8] x86/cpufeature: Enumerate Key Locker feature Chang S. Bae
2020-12-16 17:41 ` [RFC PATCH 2/8] x86/cpu: Load Key Locker internal key at boot-time Chang S. Bae
2020-12-16 17:41 ` [RFC PATCH 3/8] x86/msr-index: Add MSRs for Key Locker internal key Chang S. Bae
2020-12-16 17:41 ` [RFC PATCH 4/8] x86/power: Restore Key Locker internal key from the ACPI S3/4 sleep states Chang S. Bae
2020-12-17 19:10   ` Eric Biggers
2020-12-18  1:00     ` Bae, Chang Seok
2021-01-28 10:34   ` Rafael J. Wysocki
2021-01-28 16:10     ` Bae, Chang Seok
2020-12-16 17:41 ` [RFC PATCH 5/8] x86/cpu: Add a config option and a chicken bit for Key Locker Chang S. Bae
2020-12-16 17:41 ` [RFC PATCH 6/8] selftests/x86: Test Key Locker internal key maintenance Chang S. Bae
2020-12-18  9:59   ` Peter Zijlstra
2020-12-18 10:43     ` Bae, Chang Seok
2020-12-16 17:41 ` [RFC PATCH 7/8] crypto: x86/aes-kl - Support AES algorithm using Key Locker instructions Chang S. Bae
2020-12-17 10:16   ` Ard Biesheuvel
2021-05-14 20:36     ` Bae, Chang Seok
2020-12-17 20:54   ` Andy Lutomirski
2021-05-14 20:48     ` Bae, Chang Seok
2020-12-17 20:58   ` [NEEDS-REVIEW] " Dave Hansen
2020-12-18  9:56     ` Peter Zijlstra
2020-12-18 10:11   ` Peter Zijlstra
2020-12-18 10:34     ` Bae, Chang Seok
2020-12-18 11:00       ` Borislav Petkov
2020-12-18 14:33       ` Peter Zijlstra
2020-12-16 17:41 ` Chang S. Bae [this message]
2020-12-17 19:10 ` [RFC PATCH 0/8] x86: Support Intel Key Locker Eric Biggers
2020-12-17 20:07   ` Dan Williams
2020-12-18  1:08   ` Bae, Chang Seok
2020-12-19 18:59 ` Andy Lutomirski
2020-12-22 19:03   ` Bae, Chang Seok

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201216174146.10446-9-chang.seok.bae@intel.com \
    --to=chang.seok.bae@intel.com \
    --cc=bp@suse.de \
    --cc=broonie@kernel.org \
    --cc=dan.j.williams@intel.com \
    --cc=dave.hansen@intel.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=kumar.n.dwarakanath@intel.com \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mingo@kernel.org \
    --cc=ning.sun@intel.com \
    --cc=ravi.v.shankar@intel.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.