]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
s390/crypto: Provide s390 specific arch random functionality.
authorHarald Freudenberger <freude@linux.vnet.ibm.com>
Fri, 17 Mar 2017 09:46:31 +0000 (10:46 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Wed, 26 Apr 2017 11:41:35 +0000 (13:41 +0200)
This patch introduces s390 specific arch random functionality.
There exists a generic kernel API for arch specific random
number implementation (see include/linux/random.h). Here
comes the header file and a very small static code part
implementing the arch_random_* API based on the TRNG
subfunction coming with the reworked PRNG instruction.

The arch random implementation hooks into the kernel
initialization and checks for availability of the TRNG
function. In accordance to the arch random API all functions
return false if the TRNG is not available. Otherwise the new
high quality entropy source provides fresh random on each
invocation.

The s390 arch random feature build is controlled via
CONFIG_ARCH_RANDOM. This config option located in
arch/s390/Kconfig is enabled by default and appears
as entry "s390 architectural random number generation API"
in the submenu "Processor type and features" for s390 builds.

Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/Kbuild
arch/s390/Kconfig
arch/s390/crypto/Makefile
arch/s390/crypto/arch_random.c [new file with mode: 0644]
arch/s390/include/asm/archrandom.h [new file with mode: 0644]

index e256592eb66e515d2305bc12fa40afc9ca4f95de..eae2c64cf69d1cc8d6d4d920d8ae4ec18b520bb4 100644 (file)
@@ -1,7 +1,7 @@
 obj-y                          += kernel/
 obj-y                          += mm/
 obj-$(CONFIG_KVM)              += kvm/
-obj-$(CONFIG_CRYPTO_HW)                += crypto/
+obj-y                          += crypto/
 obj-$(CONFIG_S390_HYPFS_FS)    += hypfs/
 obj-$(CONFIG_APPLDATA_BASE)    += appldata/
 obj-y                          += net/
index 249c2771be0e1d79b52daea6ad8d908a151eb8e0..ebc0bf7c84d05a1f6e0f48b582e9a85c479cc5f2 100644 (file)
@@ -507,6 +507,21 @@ source kernel/Kconfig.preempt
 
 source kernel/Kconfig.hz
 
+config ARCH_RANDOM
+       def_bool y
+       prompt "s390 architectural random number generation API"
+       help
+         Enable the s390 architectural random number generation API
+         to provide random data for all consumers within the Linux
+         kernel.
+
+         When enabled the arch_random_* functions declared in linux/random.h
+         are implemented. The implementation is based on the s390 CPACF
+         instruction subfunction TRNG which provides a real true random
+         number generator.
+
+         If unsure, say Y.
+
 endmenu
 
 menu "Memory setup"
index 402c530c6da50d9bc724dcbcfa8c35c8085adef5..678d9863e3f07943c5ec692b10bd152383da961f 100644 (file)
@@ -10,5 +10,6 @@ obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o paes_s390.o
 obj-$(CONFIG_S390_PRNG) += prng.o
 obj-$(CONFIG_CRYPTO_GHASH_S390) += ghash_s390.o
 obj-$(CONFIG_CRYPTO_CRC32_S390) += crc32-vx_s390.o
+obj-$(CONFIG_ARCH_RANDOM) += arch_random.o
 
 crc32-vx_s390-y := crc32-vx.o crc32le-vx.o crc32be-vx.o
diff --git a/arch/s390/crypto/arch_random.c b/arch/s390/crypto/arch_random.c
new file mode 100644 (file)
index 0000000..9317b3e
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * s390 arch random implementation.
+ *
+ * Copyright IBM Corp. 2017
+ * Author(s): Harald Freudenberger <freude@de.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (version 2 only)
+ * as published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/atomic.h>
+#include <linux/static_key.h>
+#include <asm/cpacf.h>
+
+DEFINE_STATIC_KEY_FALSE(s390_arch_random_available);
+
+atomic64_t s390_arch_random_counter = ATOMIC64_INIT(0);
+EXPORT_SYMBOL(s390_arch_random_counter);
+
+static int __init s390_arch_random_init(void)
+{
+       /* check if subfunction CPACF_PRNO_TRNG is available */
+       if (cpacf_query_func(CPACF_PRNO, CPACF_PRNO_TRNG))
+               static_branch_enable(&s390_arch_random_available);
+
+       return 0;
+}
+arch_initcall(s390_arch_random_init);
diff --git a/arch/s390/include/asm/archrandom.h b/arch/s390/include/asm/archrandom.h
new file mode 100644 (file)
index 0000000..6033901
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Kernel interface for the s390 arch_random_* functions
+ *
+ * Copyright IBM Corp. 2017
+ *
+ * Author: Harald Freudenberger <freude@de.ibm.com>
+ *
+ */
+
+#ifndef _ASM_S390_ARCHRANDOM_H
+#define _ASM_S390_ARCHRANDOM_H
+
+#ifdef CONFIG_ARCH_RANDOM
+
+#include <linux/static_key.h>
+#include <linux/atomic.h>
+#include <asm/cpacf.h>
+
+DECLARE_STATIC_KEY_FALSE(s390_arch_random_available);
+extern atomic64_t s390_arch_random_counter;
+
+static void s390_arch_random_generate(u8 *buf, unsigned int nbytes)
+{
+       cpacf_trng(NULL, 0, buf, nbytes);
+       atomic64_add(nbytes, &s390_arch_random_counter);
+}
+
+static inline bool arch_has_random(void)
+{
+       if (static_branch_likely(&s390_arch_random_available))
+               return true;
+       return false;
+}
+
+static inline bool arch_has_random_seed(void)
+{
+       return arch_has_random();
+}
+
+static inline bool arch_get_random_long(unsigned long *v)
+{
+       if (static_branch_likely(&s390_arch_random_available)) {
+               s390_arch_random_generate((u8 *)v, sizeof(*v));
+               return true;
+       }
+       return false;
+}
+
+static inline bool arch_get_random_int(unsigned int *v)
+{
+       if (static_branch_likely(&s390_arch_random_available)) {
+               s390_arch_random_generate((u8 *)v, sizeof(*v));
+               return true;
+       }
+       return false;
+}
+
+static inline bool arch_get_random_seed_long(unsigned long *v)
+{
+       return arch_get_random_long(v);
+}
+
+static inline bool arch_get_random_seed_int(unsigned int *v)
+{
+       return arch_get_random_int(v);
+}
+
+#endif /* CONFIG_ARCH_RANDOM */
+#endif /* _ASM_S390_ARCHRANDOM_H */