linux-doc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v2 06/11] x86/cpu: Add a config option and a chicken bit for Key Locker
       [not found] <20210514201508.27967-1-chang.seok.bae@intel.com>
@ 2021-05-14 20:15 ` Chang S. Bae
  2021-05-14 20:15 ` [RFC PATCH v2 11/11] x86/cpu: Support the hardware randomization option for Key Locker internal key Chang S. Bae
  1 sibling, 0 replies; 2+ messages in thread
From: Chang S. Bae @ 2021-05-14 20:15 UTC (permalink / raw)
  To: tglx, mingo, bp, luto, x86, herbert
  Cc: dan.j.williams, dave.hansen, ravi.v.shankar, linux-crypto,
	linux-kernel, chang.seok.bae, linux-doc

Add a kernel config option to enable the feature (disabled by default) at
compile-time.

Also, add a new command-line parameter -- 'nokeylocker' to disable the
feature at boot-time.

Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
Cc: x86@kernel.org
Cc: linux-doc@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 Documentation/admin-guide/kernel-parameters.txt |  2 ++
 arch/x86/Kconfig                                | 14 ++++++++++++++
 arch/x86/kernel/cpu/common.c                    | 16 ++++++++++++++++
 3 files changed, 32 insertions(+)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index cb89dbdedc46..d0afe36c1802 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3284,6 +3284,8 @@
 
 	nohugevmalloc	[PPC] Disable kernel huge vmalloc mappings.
 
+	nokeylocker	[X86] Disables Key Locker hardware feature.
+
 	nosmt		[KNL,S390] Disable symmetric multithreading (SMT).
 			Equivalent to smt=1.
 
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 0045e1b44190..de8eeb705ed8 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1885,6 +1885,20 @@ config X86_INTEL_MEMORY_PROTECTION_KEYS
 
 	  If unsure, say y.
 
+config X86_KEYLOCKER
+	prompt "Key Locker"
+	def_bool n
+	depends on CPU_SUP_INTEL
+	help
+	  Key Locker is a new security feature to protect data encryption
+	  keys for the Advanced Encryption Standard (AES) algorithm.
+
+	  When enabled, every CPU has a unique internal key to wrap AES
+	  keys in an encoded format.  The internal key is not accessible
+	  to software once loaded.
+
+	  If unsure, say y.
+
 choice
 	prompt "TSX enable mode"
 	depends on CPU_SUP_INTEL
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 2e64371acb81..c655cce30c2b 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -353,6 +353,22 @@ static __always_inline void setup_umip(struct cpuinfo_x86 *c)
 /* These bits should not change their value after CPU init is finished. */
 static const unsigned long cr4_pinned_mask =
 	X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_UMIP | X86_CR4_FSGSBASE;
+
+static __init int x86_nokeylocker_setup(char *arg)
+{
+	/* Expect an exact match without trailing characters. */
+	if (strlen(arg))
+		return 0;
+
+	if (!cpu_feature_enabled(X86_FEATURE_KEYLOCKER))
+		return 1;
+
+	setup_clear_cpu_cap(X86_FEATURE_KEYLOCKER);
+	pr_info("x86/keylocker: Disabled by kernel command line.\n");
+	return 1;
+}
+__setup("nokeylocker", x86_nokeylocker_setup);
+
 static DEFINE_STATIC_KEY_FALSE_RO(cr_pinning);
 static unsigned long cr4_pinned_bits __ro_after_init;
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [RFC PATCH v2 11/11] x86/cpu: Support the hardware randomization option for Key Locker internal key
       [not found] <20210514201508.27967-1-chang.seok.bae@intel.com>
  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 ` Chang S. Bae
  1 sibling, 0 replies; 2+ messages in thread
From: Chang S. Bae @ 2021-05-14 20:15 UTC (permalink / raw)
  To: tglx, mingo, bp, luto, x86, herbert
  Cc: dan.j.williams, dave.hansen, ravi.v.shankar, linux-crypto,
	linux-kernel, chang.seok.bae, Mark Brown, linux-doc

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


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-05-14 20:20 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20210514201508.27967-1-chang.seok.bae@intel.com>
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 11/11] x86/cpu: Support the hardware randomization option for Key Locker internal key Chang S. Bae

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).