aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Freudenberger <freude@linux.vnet.ibm.com>2017-03-17 05:46:31 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2017-04-26 07:41:35 -0400
commit4c637cd8de43416c1b1eef6113e7aa06abacf18d (patch)
tree6609483d58b446c515a94b70e91cc55e7fc481a0
parentf75fa65d70e2423a03c1b7391bfca410d554b1c5 (diff)
s390/crypto: Provide s390 specific arch random functionality.
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>
-rw-r--r--arch/s390/Kbuild2
-rw-r--r--arch/s390/Kconfig15
-rw-r--r--arch/s390/crypto/Makefile1
-rw-r--r--arch/s390/crypto/arch_random.c31
-rw-r--r--arch/s390/include/asm/archrandom.h69
5 files changed, 117 insertions, 1 deletions
diff --git a/arch/s390/Kbuild b/arch/s390/Kbuild
index e256592eb66e..eae2c64cf69d 100644
--- a/arch/s390/Kbuild
+++ b/arch/s390/Kbuild
@@ -1,7 +1,7 @@
1obj-y += kernel/ 1obj-y += kernel/
2obj-y += mm/ 2obj-y += mm/
3obj-$(CONFIG_KVM) += kvm/ 3obj-$(CONFIG_KVM) += kvm/
4obj-$(CONFIG_CRYPTO_HW) += crypto/ 4obj-y += crypto/
5obj-$(CONFIG_S390_HYPFS_FS) += hypfs/ 5obj-$(CONFIG_S390_HYPFS_FS) += hypfs/
6obj-$(CONFIG_APPLDATA_BASE) += appldata/ 6obj-$(CONFIG_APPLDATA_BASE) += appldata/
7obj-y += net/ 7obj-y += net/
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 249c2771be0e..ebc0bf7c84d0 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -507,6 +507,21 @@ source kernel/Kconfig.preempt
507 507
508source kernel/Kconfig.hz 508source kernel/Kconfig.hz
509 509
510config ARCH_RANDOM
511 def_bool y
512 prompt "s390 architectural random number generation API"
513 help
514 Enable the s390 architectural random number generation API
515 to provide random data for all consumers within the Linux
516 kernel.
517
518 When enabled the arch_random_* functions declared in linux/random.h
519 are implemented. The implementation is based on the s390 CPACF
520 instruction subfunction TRNG which provides a real true random
521 number generator.
522
523 If unsure, say Y.
524
510endmenu 525endmenu
511 526
512menu "Memory setup" 527menu "Memory setup"
diff --git a/arch/s390/crypto/Makefile b/arch/s390/crypto/Makefile
index 402c530c6da5..678d9863e3f0 100644
--- a/arch/s390/crypto/Makefile
+++ b/arch/s390/crypto/Makefile
@@ -10,5 +10,6 @@ obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o paes_s390.o
10obj-$(CONFIG_S390_PRNG) += prng.o 10obj-$(CONFIG_S390_PRNG) += prng.o
11obj-$(CONFIG_CRYPTO_GHASH_S390) += ghash_s390.o 11obj-$(CONFIG_CRYPTO_GHASH_S390) += ghash_s390.o
12obj-$(CONFIG_CRYPTO_CRC32_S390) += crc32-vx_s390.o 12obj-$(CONFIG_CRYPTO_CRC32_S390) += crc32-vx_s390.o
13obj-$(CONFIG_ARCH_RANDOM) += arch_random.o
13 14
14crc32-vx_s390-y := crc32-vx.o crc32le-vx.o crc32be-vx.o 15crc32-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
index 000000000000..9317b3e645e2
--- /dev/null
+++ b/arch/s390/crypto/arch_random.c
@@ -0,0 +1,31 @@
1/*
2 * s390 arch random implementation.
3 *
4 * Copyright IBM Corp. 2017
5 * Author(s): Harald Freudenberger <freude@de.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License (version 2 only)
9 * as published by the Free Software Foundation.
10 *
11 */
12
13#include <linux/kernel.h>
14#include <linux/atomic.h>
15#include <linux/static_key.h>
16#include <asm/cpacf.h>
17
18DEFINE_STATIC_KEY_FALSE(s390_arch_random_available);
19
20atomic64_t s390_arch_random_counter = ATOMIC64_INIT(0);
21EXPORT_SYMBOL(s390_arch_random_counter);
22
23static int __init s390_arch_random_init(void)
24{
25 /* check if subfunction CPACF_PRNO_TRNG is available */
26 if (cpacf_query_func(CPACF_PRNO, CPACF_PRNO_TRNG))
27 static_branch_enable(&s390_arch_random_available);
28
29 return 0;
30}
31arch_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
index 000000000000..6033901a40b2
--- /dev/null
+++ b/arch/s390/include/asm/archrandom.h
@@ -0,0 +1,69 @@
1/*
2 * Kernel interface for the s390 arch_random_* functions
3 *
4 * Copyright IBM Corp. 2017
5 *
6 * Author: Harald Freudenberger <freude@de.ibm.com>
7 *
8 */
9
10#ifndef _ASM_S390_ARCHRANDOM_H
11#define _ASM_S390_ARCHRANDOM_H
12
13#ifdef CONFIG_ARCH_RANDOM
14
15#include <linux/static_key.h>
16#include <linux/atomic.h>
17#include <asm/cpacf.h>
18
19DECLARE_STATIC_KEY_FALSE(s390_arch_random_available);
20extern atomic64_t s390_arch_random_counter;
21
22static void s390_arch_random_generate(u8 *buf, unsigned int nbytes)
23{
24 cpacf_trng(NULL, 0, buf, nbytes);
25 atomic64_add(nbytes, &s390_arch_random_counter);
26}
27
28static inline bool arch_has_random(void)
29{
30 if (static_branch_likely(&s390_arch_random_available))
31 return true;
32 return false;
33}
34
35static inline bool arch_has_random_seed(void)
36{
37 return arch_has_random();
38}
39
40static inline bool arch_get_random_long(unsigned long *v)
41{
42 if (static_branch_likely(&s390_arch_random_available)) {
43 s390_arch_random_generate((u8 *)v, sizeof(*v));
44 return true;
45 }
46 return false;
47}
48
49static inline bool arch_get_random_int(unsigned int *v)
50{
51 if (static_branch_likely(&s390_arch_random_available)) {
52 s390_arch_random_generate((u8 *)v, sizeof(*v));
53 return true;
54 }
55 return false;
56}
57
58static inline bool arch_get_random_seed_long(unsigned long *v)
59{
60 return arch_get_random_long(v);
61}
62
63static inline bool arch_get_random_seed_int(unsigned int *v)
64{
65 return arch_get_random_int(v);
66}
67
68#endif /* CONFIG_ARCH_RANDOM */
69#endif /* _ASM_S390_ARCHRANDOM_H */