linux-kernel.vger.kernel.org archive mirror
 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, 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 v2 11/11] x86/cpu: Support the hardware randomization option for Key Locker internal key
Date: Fri, 14 May 2021 13:15:08 -0700	[thread overview]
Message-ID: <20210514201508.27967-12-chang.seok.bae@intel.com> (raw)
In-Reply-To: <20210514201508.27967-1-chang.seok.bae@intel.com>

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

The feature's backup mechanism is required to distribute an internal key.
This is the only way to copy it to other CPUs if using hardware
randomization.

This 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/kernel/keylocker.c | 37 ++++++++++++++++++++++++++++++++-----
 drivers/char/random.c       |  6 ++++++
 include/linux/random.h      |  2 ++
 3 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/keylocker.c b/arch/x86/kernel/keylocker.c
index 0f60350944fa..5a784492195b 100644
--- a/arch/x86/kernel/keylocker.c
+++ b/arch/x86/kernel/keylocker.c
@@ -7,6 +7,7 @@
 #include <linux/random.h>
 #include <linux/acpi.h>
 #include <linux/delay.h>
+#include <linux/random.h>
 
 #include <asm/cacheflush.h>
 #include <asm/fpu/api.h>
@@ -15,27 +16,34 @@
 #include <asm/tlbflush.h>
 
 static bool keybackup_available;
+static bool keyhwrand_available;
 
 /* Internal (Wrapping) Key size fits in three 128-bit registers. */
 #define KEYSIZE_128BIT	3
 
 static struct _keydata {
 	bool valid;
+	bool hwrand;
 	struct reg_128_bit value[KEYSIZE_128BIT];
 } keydata;
 
 /**
  * make_keylocker_data() - Generate the internal key.
+ * @use_hwrand:	True if use hardware randomization; otherwise, false.
  *
  * Return:	Nothing
  */
-static void make_keylocker_data(void)
+static void make_keylocker_data(bool use_hwrand)
 {
 	int i;
 
 	for (i = 0; i < KEYSIZE_128BIT; 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 is not fully supported\n");
+
 	keydata.valid = true;
 }
 
@@ -59,6 +67,8 @@ void flush_keylocker_data(void)
 }
 
 #define KEYSRC_SWRAND		0
+#define KEYSRC_HWRAND		BIT(1)
+#define KEYSRC_HWRAND_RETRY	10
 
 /**
  * load_keylocker() - Load the internal key.
@@ -68,8 +78,16 @@ void flush_keylocker_data(void)
 static int load_keylocker(void)
 {
 	struct reg_128_bit zeros = { 0 };
-	u32 keysrc = KEYSRC_SWRAND;
-	int err;
+	int retry, err;
+	u32 keysrc;
+
+	if (keydata.hwrand) {
+		keysrc = KEYSRC_HWRAND;
+		retry = KEYSRC_HWRAND_RETRY;
+	} else {
+		keysrc = KEYSRC_SWRAND;
+		retry = 0;
+	}
 
 	kernel_fpu_begin();
 
@@ -78,13 +96,19 @@ static int load_keylocker(void)
 			 "m"(keydata.value[1]),
 			 "m"(keydata.value[2]));
 
-	err = loadiwkey(keysrc);
+	do {
+		err = loadiwkey(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)
+		flush_keylocker_data();
+
 	return err;
 }
 
@@ -138,6 +162,7 @@ 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();
 		u32 eax, ebx, ecx, edx;
 
 		cpuid_count(KEYLOCKER_CPUID, 0, &eax, &ebx, &ecx, &edx);
@@ -156,7 +181,9 @@ void setup_keylocker(struct cpuinfo_x86 *c)
 			goto disable;
 		}
 
-		make_keylocker_data();
+		keyhwrand_available = (ecx & KEYLOCKER_CPUID_ECX_RAND);
+
+		make_keylocker_data(use_hwrand);
 
 		err = load_keylocker();
 		if (err) {
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 605969ed0f96..a3ece5968497 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -771,6 +771,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:[~2021-05-14 20:21 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-14 20:14 [RFC PATCH v2 00/11] x86: Support Intel Key Locker Chang S. Bae
2021-05-14 20:14 ` [RFC PATCH v2 01/11] x86/cpufeature: Enumerate Key Locker feature Chang S. Bae
2021-05-14 20:14 ` [RFC PATCH v2 02/11] x86/insn: Add Key Locker instructions to the opcode map Chang S. Bae
2021-05-14 20:15 ` [RFC PATCH v2 03/11] x86/cpu: Load Key Locker internal key at boot-time Chang S. Bae
2021-05-14 20:15 ` [RFC PATCH v2 04/11] x86/msr-index: Add MSRs for Key Locker internal key Chang S. Bae
2021-05-14 20:15 ` [RFC PATCH v2 05/11] x86/power: Restore Key Locker internal key from the ACPI S3/4 sleep states Chang S. Bae
2021-05-24 14:21   ` Rafael J. Wysocki
2021-05-14 20:15 ` [RFC PATCH v2 06/11] x86/cpu: Add a config option and a chicken bit for Key Locker Chang S. Bae
2021-05-14 20:15 ` [RFC PATCH v2 07/11] selftests/x86: Test Key Locker internal key maintenance Chang S. Bae
2021-05-14 20:15 ` [RFC PATCH v2 08/11] crypto: x86/aes-ni - Improve error handling Chang S. Bae
2021-05-14 20:15 ` [RFC PATCH v2 09/11] crypto: x86/aes-ni - Refactor to prepare a new AES implementation Chang S. Bae
2021-05-14 20:15 ` [RFC PATCH v2 10/11] crypto: x86/aes-kl - Support AES algorithm using Key Locker instructions Chang S. Bae
2021-05-17 21:34   ` Eric Biggers
2021-05-17 22:20     ` Bae, Chang Seok
2021-05-17 23:33       ` Eric Biggers
2021-05-18 16:57   ` Andy Lutomirski
2021-05-14 20:15 ` Chang S. Bae [this message]
2021-05-15 18:01 ` [RFC PATCH v2 00/11] x86: Support Intel Key Locker Andy Lutomirski
2021-05-17 18:21   ` Bae, Chang Seok
2021-05-17 18:45     ` Dan Williams
2021-05-17 22:20       ` Bae, Chang Seok
2021-05-17 20:15     ` Sean Christopherson
2021-05-18 17:10     ` Andy Lutomirski
2021-05-18 17:52       ` Sean Christopherson
2021-05-19 23:26         ` Andy Lutomirski
2021-05-19 23:34           ` Sean Christopherson
2021-05-20  0:00             ` Sean Christopherson
2021-12-06 21:48       ` 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=20210514201508.27967-12-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=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=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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).