LKML Archive mirror
 help / color / mirror / Atom feed
* [Resend PATCH 2/2] s390: provide hardware randomness from zcrypt card to /dev/random
@ 2013-09-12  9:41 Torsten Duwe
  2013-09-12 20:37 ` H. Peter Anvin
  0 siblings, 1 reply; 7+ messages in thread
From: Torsten Duwe @ 2013-09-12  9:41 UTC (permalink / raw
  To: tytso, ingo.tuchscherer
  Cc: linux-kernel, Hans-Georg Markgraf, Gerald Schaefer,
	Martin Schwidefsky, Heiko Carstens, Joe Perches


Running completely virtualised, system Z severely lacks good true random sources.
Gathering entropy in a virtual environment is difficult. To compensate, there is
specialised crypto hardware which includes a source for hardware randomness;
the zcrypt driver is able to access this random source. This patch adds a kernel
thread that feeds the random bits via the interface created with the previous patch.

Signed-off-by: Torsten Duwe <duwe@lst.de>

---
 zcrypt_api.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -38,6 +38,8 @@
 #include <linux/atomic.h>
 #include <asm/uaccess.h>
 #include <linux/hw_random.h>
+#include <linux/kthread.h>
+#include <linux/delay.h>
 #include <linux/debugfs.h>
 #include <asm/debug.h>
 
@@ -99,6 +99,13 @@ static ssize_t zcrypt_online_store(struc
 
 	if (sscanf(buf, "%d\n", &online) != 1 || online < 0 || online > 1)
 		return -EINVAL;
+	if (zdev->ops->rng) {
+		if (zdev->online == 0 && online == 1)
+			zcrypt_rng_device_add();
+		if (zdev->online == 1 && online == 0)
+			zcrypt_rng_device_remove();
+
+	}
 	zdev->online = online;
 	ZCRYPT_DBF_DEV(DBF_INFO, zdev, "dev%04xo%dman", zdev->ap_dev->qid,
 		       zdev->online);
@@ -1117,6 +1119,7 @@ static int zcrypt_rng_device_count;
 static u32 *zcrypt_rng_buffer;
 static int zcrypt_rng_buffer_index;
 static DEFINE_MUTEX(zcrypt_rng_mutex);
+static struct task_struct *zcrypt_hwrng_fill;
 
 static int zcrypt_rng_data_read(struct hwrng *rng, u32 *data)
 {
@@ -1141,6 +1144,36 @@ static struct hwrng zcrypt_rng_dev = {
 	.data_read	= zcrypt_rng_data_read,
 };
 
+static int zcrypt_hwrng_fillfn(void *unused)
+{
+	long rc;
+
+	while (!kthread_should_stop()) {
+		rc = zcrypt_rng((char *)zcrypt_rng_buffer);
+		if (rc == -ENODEV || rc == -EINVAL || rc == -ENOMEM) {
+			pr_err("zcrypt_rng unavailable: %ld\n", rc);
+			break;
+		}
+		if (rc == -EAGAIN || rc == -ERESTARTSYS) {
+			pr_info("zcrypt_rng interrupted: %ld\n", rc);
+			msleep_interruptible(1000);
+			continue;
+		}
+		if (rc == 0) {
+			pr_err("zcrypt_rng: no data available\n");
+			msleep_interruptible(10000);
+			continue;
+		}
+		if (rc < 0) {
+			pr_err("zcrypt_rng unknown error: %ld\n", rc);
+			break;
+		}
+		add_hwgenerator_randomness((void *)zcrypt_rng_buffer, rc);
+	}
+	zcrypt_hwrng_fill = 0;
+	return 0;
+}
+
 static int zcrypt_rng_device_add(void)
 {
 	int rc = 0;
@@ -1157,6 +1189,12 @@ static int zcrypt_rng_device_add(void)
 		if (rc)
 			goto out_free;
 		zcrypt_rng_device_count = 1;
+		zcrypt_hwrng_fill = kthread_run(zcrypt_hwrng_fillfn,
+			NULL, "zc_hwrng");
+		if (zcrypt_hwrng_fill == ERR_PTR(-ENOMEM)) {
+			pr_err("zcrypt_hwrng_fill thread creation failed\n");
+			zcrypt_hwrng_fill = 0;
+		}
 	} else
 		zcrypt_rng_device_count++;
 	mutex_unlock(&zcrypt_rng_mutex);
@@ -1174,6 +1211,10 @@ static void zcrypt_rng_device_remove(voi
 	mutex_lock(&zcrypt_rng_mutex);
 	zcrypt_rng_device_count--;
 	if (zcrypt_rng_device_count == 0) {
+		if (zcrypt_hwrng_fill) {
+			kthread_stop(zcrypt_hwrng_fill);
+			zcrypt_hwrng_fill = 0;
+		}
 		hwrng_unregister(&zcrypt_rng_dev);
 		free_page((unsigned long) zcrypt_rng_buffer);
 	}

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

* Re: [Resend PATCH 2/2] s390: provide hardware randomness from zcrypt card to /dev/random
  2013-09-12  9:41 [Resend PATCH 2/2] s390: provide hardware randomness from zcrypt card to /dev/random Torsten Duwe
@ 2013-09-12 20:37 ` H. Peter Anvin
  2013-09-19  8:47   ` Torsten Duwe
  0 siblings, 1 reply; 7+ messages in thread
From: H. Peter Anvin @ 2013-09-12 20:37 UTC (permalink / raw
  To: Torsten Duwe
  Cc: tytso, ingo.tuchscherer, linux-kernel, Hans-Georg Markgraf,
	Gerald Schaefer, Martin Schwidefsky, Heiko Carstens, Joe Perches

On 09/12/2013 02:41 AM, Torsten Duwe wrote:
> 
> Running completely virtualised, system Z severely lacks good true random sources.
> Gathering entropy in a virtual environment is difficult. To compensate, there is
> specialised crypto hardware which includes a source for hardware randomness;
> the zcrypt driver is able to access this random source. This patch adds a kernel
> thread that feeds the random bits via the interface created with the previous patch.
> 
> Signed-off-by: Torsten Duwe <duwe@lst.de>

>From what I can gather from the patch this is too heavyweight (need
locks and so on) to use as arch_get_random*().  There has been a lot of
discussion about the pros and cons of allowing the kernel to bypass
rngd, but I would think that any such plumbing -- once it gets past the
fully synchronous low latency properties of arch_get_random*() -- really
should be implemented as an option in the existing hwrng device
infrastructure.

In other words, start by implementing a hwrng device.  That will work
right now with rngd running.  Then we can consider if we want to allow
bypass of rngd for certain hwrng devices -- which may include zcrypt,
virtio_rng and so on.

	-hpa



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

* Re: [Resend PATCH 2/2] s390: provide hardware randomness from zcrypt card to /dev/random
  2013-09-12 20:37 ` H. Peter Anvin
@ 2013-09-19  8:47   ` Torsten Duwe
  2013-09-19 13:03     ` H. Peter Anvin
  2013-09-19 13:05     ` H. Peter Anvin
  0 siblings, 2 replies; 7+ messages in thread
From: Torsten Duwe @ 2013-09-19  8:47 UTC (permalink / raw
  To: H. Peter Anvin
  Cc: Torsten Duwe, tytso, ingo.tuchscherer, linux-kernel,
	Hans-Georg Markgraf, Gerald Schaefer, Martin Schwidefsky,
	Heiko Carstens, Joe Perches



On Thu, 12 Sep 2013, H. Peter Anvin wrote:

> From what I can gather from the patch this is too heavyweight (need
> locks and so on) to use as arch_get_random*().  There has been a lot of

Alas, I can see there's only x86 that currently has this implemented?

> discussion about the pros and cons of allowing the kernel to bypass
> rngd, but I would think that any such plumbing -- once it gets past the
> fully synchronous low latency properties of arch_get_random*() -- really
> should be implemented as an option in the existing hwrng device
> infrastructure.

As I wrote in the intro, the problem to solve is slow startup when ASLR is 
in effect; in that case: until rngd or haveged is finally running.

> In other words, start by implementing a hwrng device.  That will work
> right now with rngd running.  Then we can consider if we want to allow

That's already there, thanks to the IBM guys :)

> bypass of rngd for certain hwrng devices -- which may include zcrypt,
> virtio_rng and so on.

I'm currently thinking about some kind of buffer in zcrypt, where 
arch_get_random can get a long or int quickly, as "designed" after x86.
Device init or low water would trigger a work item to refill the buffer.
It might tun out though, that every device on every architecture that does
not quite match the x86 approach implements its own buffer.

What do you think?

Besides that, as you wrote, a generic mechanism to mix hwrngs into the 
input pool would be nice, triggered by user space policy. As far as I can 
see, some mixing of arch_get_random is done, but no entropy credited?

	Torsten


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

* Re: [Resend PATCH 2/2] s390: provide hardware randomness from zcrypt card to /dev/random
  2013-09-19  8:47   ` Torsten Duwe
@ 2013-09-19 13:03     ` H. Peter Anvin
  2013-09-19 13:05     ` H. Peter Anvin
  1 sibling, 0 replies; 7+ messages in thread
From: H. Peter Anvin @ 2013-09-19 13:03 UTC (permalink / raw
  To: Torsten Duwe, Torsten Duwe
  Cc: tytso, ingo.tuchscherer, linux-kernel, Hans-Georg Markgraf,
	Gerald Schaefer, Martin Schwidefsky, Heiko Carstens, Joe Perches

By the way, haveged is... worthy of suspicion (I doubt it is malicious, but still).  Its self-tests are completely useless (replace the entropy source with a constant "1" and they still pass) and there is as far as I know no analysis about the randomness other than "it passes some tests."



Torsten Duwe <duwe@lst.de> wrote:
>
>
>On Thu, 12 Sep 2013, H. Peter Anvin wrote:
>
>> From what I can gather from the patch this is too heavyweight (need
>> locks and so on) to use as arch_get_random*().  There has been a lot
>of
>
>Alas, I can see there's only x86 that currently has this implemented?
>
>> discussion about the pros and cons of allowing the kernel to bypass
>> rngd, but I would think that any such plumbing -- once it gets past
>the
>> fully synchronous low latency properties of arch_get_random*() --
>really
>> should be implemented as an option in the existing hwrng device
>> infrastructure.
>
>As I wrote in the intro, the problem to solve is slow startup when ASLR
>is 
>in effect; in that case: until rngd or haveged is finally running.
>
>> In other words, start by implementing a hwrng device.  That will work
>> right now with rngd running.  Then we can consider if we want to
>allow
>
>That's already there, thanks to the IBM guys :)
>
>> bypass of rngd for certain hwrng devices -- which may include zcrypt,
>> virtio_rng and so on.
>
>I'm currently thinking about some kind of buffer in zcrypt, where 
>arch_get_random can get a long or int quickly, as "designed" after x86.
>Device init or low water would trigger a work item to refill the
>buffer.
>It might tun out though, that every device on every architecture that
>does
>not quite match the x86 approach implements its own buffer.
>
>What do you think?
>
>Besides that, as you wrote, a generic mechanism to mix hwrngs into the 
>input pool would be nice, triggered by user space policy. As far as I
>can 
>see, some mixing of arch_get_random is done, but no entropy credited?
>
>	Torsten

-- 
Sent from my mobile phone.  Please pardon brevity and lack of formatting.

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

* Re: [Resend PATCH 2/2] s390: provide hardware randomness from zcrypt card to /dev/random
  2013-09-19  8:47   ` Torsten Duwe
  2013-09-19 13:03     ` H. Peter Anvin
@ 2013-09-19 13:05     ` H. Peter Anvin
  2014-03-17 16:48       ` [PATCH 00/03]: khwrngd (Was: s390: provide hardware randomness from zcrypt card to /dev/random) Torsten Duwe
  1 sibling, 1 reply; 7+ messages in thread
From: H. Peter Anvin @ 2013-09-19 13:05 UTC (permalink / raw
  To: Torsten Duwe, Torsten Duwe
  Cc: tytso, ingo.tuchscherer, linux-kernel, Hans-Georg Markgraf,
	Gerald Schaefer, Martin Schwidefsky, Heiko Carstens, Joe Perches

As I said, the option of doing feed from hwrng directly via a kernel thread seems the most logical thing to me, assuming you can convince Ted & co.  rngd doesn't really add much value for a whitened source.

Torsten Duwe <duwe@lst.de> wrote:
>
>
>On Thu, 12 Sep 2013, H. Peter Anvin wrote:
>
>> From what I can gather from the patch this is too heavyweight (need
>> locks and so on) to use as arch_get_random*().  There has been a lot
>of
>
>Alas, I can see there's only x86 that currently has this implemented?
>
>> discussion about the pros and cons of allowing the kernel to bypass
>> rngd, but I would think that any such plumbing -- once it gets past
>the
>> fully synchronous low latency properties of arch_get_random*() --
>really
>> should be implemented as an option in the existing hwrng device
>> infrastructure.
>
>As I wrote in the intro, the problem to solve is slow startup when ASLR
>is 
>in effect; in that case: until rngd or haveged is finally running.
>
>> In other words, start by implementing a hwrng device.  That will work
>> right now with rngd running.  Then we can consider if we want to
>allow
>
>That's already there, thanks to the IBM guys :)
>
>> bypass of rngd for certain hwrng devices -- which may include zcrypt,
>> virtio_rng and so on.
>
>I'm currently thinking about some kind of buffer in zcrypt, where 
>arch_get_random can get a long or int quickly, as "designed" after x86.
>Device init or low water would trigger a work item to refill the
>buffer.
>It might tun out though, that every device on every architecture that
>does
>not quite match the x86 approach implements its own buffer.
>
>What do you think?
>
>Besides that, as you wrote, a generic mechanism to mix hwrngs into the 
>input pool would be nice, triggered by user space policy. As far as I
>can 
>see, some mixing of arch_get_random is done, but no entropy credited?
>
>	Torsten

-- 
Sent from my mobile phone.  Please pardon brevity and lack of formatting.

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

* [PATCH 00/03]: khwrngd (Was: s390: provide hardware randomness from zcrypt card to /dev/random)
  2013-09-19 13:05     ` H. Peter Anvin
@ 2014-03-17 16:48       ` Torsten Duwe
  2014-03-17 16:50         ` [Patch 01/03]: provide an injection point for pure hardware randomness Torsten Duwe
  0 siblings, 1 reply; 7+ messages in thread
From: Torsten Duwe @ 2014-03-17 16:48 UTC (permalink / raw
  To: H. Peter Anvin, Theodore Ts'o, Greg Kroah-Hartman,
	Matt Mackall, Herbert Xu, Arnd Bergmann, Rusty Russell,
	Satoru Takeuchi
  Cc: ingo.tuchscherer, linux-kernel, Hans-Georg Markgraf,
	Gerald Schaefer, Martin Schwidefsky, Heiko Carstens, Joe Perches,
	duwe

On Thu, Sep 19, 2013 at 08:05:32AM -0500, H. Peter Anvin wrote:
> As I said, the option of doing feed from hwrng directly
> via a kernel thread seems the most logical thing to me,
> assuming you can convince Ted & co.
> rngd doesn't really add much value for a whitened source.

Following up on this on (time flies!) I have moved the code
up into the arch-independent hw_random code and split it into 3
patches. First generate the injection point for true HWRNGs,
then create a thread that makes use of it and finally add
some simple on/off switch. The latter could be replaced with
something far more sophisticated if desired.

	Torsten


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

* [Patch 01/03]: provide an injection point for pure hardware randomness
  2014-03-17 16:48       ` [PATCH 00/03]: khwrngd (Was: s390: provide hardware randomness from zcrypt card to /dev/random) Torsten Duwe
@ 2014-03-17 16:50         ` Torsten Duwe
  0 siblings, 0 replies; 7+ messages in thread
From: Torsten Duwe @ 2014-03-17 16:50 UTC (permalink / raw
  To: H. Peter Anvin, Theodore Ts'o, Greg Kroah-Hartman,
	Matt Mackall, Herbert Xu, Arnd Bergmann, Rusty Russell,
	Satoru Takeuchi
  Cc: ingo.tuchscherer, linux-kernel, Hans-Georg Markgraf,
	Gerald Schaefer, Martin Schwidefsky, Heiko Carstens, Joe Perches

This patch adds an interface to the random pool for feeding entropy in-kernel.
It may serve as a destination for dedicated HWRNGs.

It resembles -- and could be merged with -- the ioctl(RNDADDENTROPY) code, plus 
a sleep condition for eager writers.

Signed-off-by: Torsten Duwe <duwe@suse.de>

---
 include/linux/hw_random.h |    2 ++
 drivers/char/random.c     |   23 +++++++++++++++++++++++
 2 files changed, 25 insertions(+)

--- a/include/linux/hw_random.h
+++ b/include/linux/hw_random.h
@@ -47,5 +47,7 @@ struct hwrng {
 extern int hwrng_register(struct hwrng *rng);
 /** Unregister a Hardware Random Number Generator driver. */
 extern void hwrng_unregister(struct hwrng *rng);
+/** Feed random bits into the pool. */
+extern void add_hwgenerator_randomness(const char *buffer, size_t count, size_t entropy);
 
 #endif /* LINUX_HWRANDOM_H_ */
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -250,6 +250,7 @@
 #include <linux/interrupt.h>
 #include <linux/mm.h>
 #include <linux/spinlock.h>
+#include <linux/kthread.h>
 #include <linux/percpu.h>
 #include <linux/cryptohash.h>
 #include <linux/fips.h>
@@ -1347,3 +1347,25 @@ randomize_range(unsigned long start, uns
 		return 0;
 	return PAGE_ALIGN(get_random_int() % range + start);
 }
+
+/* Interface for in-kernel drivers of true hardware RNGs.
+ * Those devices may produce endless random bits and will be throttled
+ * when our pool is full.
+ */
+void add_hwgenerator_randomness(const char *buffer, size_t count,
+				 size_t entropy)
+{
+	struct entropy_store *poolp = &input_pool;
+
+	/* Suspend writing if we're above the trickle threshold.
+	 * We'll be woken up again once below random_write_wakeup_thresh,
+	 * or when the calling thread is about to terminate.
+	 */
+	wait_event_interruptible(random_write_wait, kthread_should_stop() ||
+				 input_pool.entropy_count
+					 <= random_write_wakeup_thresh);
+	mix_pool_bytes(poolp, buffer, count, NULL);
+	credit_entropy_bits(poolp, entropy);
+}
+EXPORT_SYMBOL_GPL(add_hwgenerator_randomness);
+

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

end of thread, other threads:[~2014-03-17 16:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-12  9:41 [Resend PATCH 2/2] s390: provide hardware randomness from zcrypt card to /dev/random Torsten Duwe
2013-09-12 20:37 ` H. Peter Anvin
2013-09-19  8:47   ` Torsten Duwe
2013-09-19 13:03     ` H. Peter Anvin
2013-09-19 13:05     ` H. Peter Anvin
2014-03-17 16:48       ` [PATCH 00/03]: khwrngd (Was: s390: provide hardware randomness from zcrypt card to /dev/random) Torsten Duwe
2014-03-17 16:50         ` [Patch 01/03]: provide an injection point for pure hardware randomness Torsten Duwe

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 read-only IMAP folder(s) and NNTP newsgroup(s).