All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH, RFC -v2] random: introduce getrandom(2) system call
@ 2014-07-17 21:38 Theodore Ts'o
       [not found] ` <1405633100-4889-1-git-send-email-tytso-3s7WtUTddSA@public.gmane.org>
  0 siblings, 1 reply; 9+ messages in thread
From: Theodore Ts'o @ 2014-07-17 21:38 UTC (permalink / raw)
  To: Linux Kernel Developers List
  Cc: linux-crypto, linux-api, beck, Theodore Ts'o

The getrandom(2) system call was requested by the LibreSSL Portable
developers.  It is analoguous to the getentropy(2) system call in
OpenBSD.

The rationale of this system call is to provide resiliance against
file descriptor exhaustion attacks, where the attacker consumes all
available file descriptors, forcing the use of the fallback code where
/dev/[u]random is not available.  Since the fallback code is often not
well-tested, it is better to eliminate this potential failure mode
entirely.

The other feature provided by this new system call is the ability to
request randomness from the /dev/urandom entropy pool, but to block
until at least 128 bits of entropy has been accumulated in the
/dev/urandom entropy pool.  Historically, the emphasis in the
/dev/urandom development has been to ensure that urandom pool is
initialized as quickly as possible after system boot, and preferably
before the init scripts start execution.  This is because changing
/dev/urandom reads to block represents an interface change that could
potentially break userspace which is not acceptable.  In practice, on
most x86 desktop and server systems, in general the entropy pool can
be initialized before it is needed (and in modern kernels, we will
printk a warning message if not).  However, on an embedded system,
this may not be hte case.  And so with a new interface, we can provide
this requested functionality of blocking until the urandom pool has
been initialized.  Any userspace program which uses this new
functionality must make sure that if it is used in early boot, that it
will not cause the boot up scripts or other portions of the system
startup to hang indefinitely.

SYNOPSIS
	#include <linux/random.h>

	int getrandom(void *buf, size_t buflen, unsigned int flags);

DESCRIPTION
	The system call getrandom() fills the buffer pointed to by buf
	with up to buflen random bytes which can be used to seed user
	space random number generators (i.e., DRBG's) or for other
	cryptographic processes.  It should not be used Monte Carlo
	simulations or for other probabilistic sampling applications.

	If the GRND_RANDOM flags bit is set, then draw from the
	/dev/random pool instead of the /dev/urandom pool.  The
	/dev/random pool is limited based on the entropy that can be
	obtained from environmental noise, so if there is insufficient
	entropy, the requested number of bytes may not be returned.
	If there is no entropy available at all, getrandom(2) will
	either block, or return an error with errno set to EAGAIN if
	the GRND_NONBLOCK bit is set in flags.

	If the GRND_RANDOM bit is not set, then the /dev/urandom pool
	will be used.  Unlike using read(2) to fetch data from
	/dev/urandom, if the urandom pool has not been sufficiently
	initialized, getrandom(2) will block or return -1 with the
	errno set to EGAIN if the GRND_NONBLOCK bit is set in flags.

	The getentropy(2) system call in OpenBSD can be emulated using
	the following function:

	    int getentropy(void *buf, size_t buflen)
	    {
	            int     ret;

		    ret = getentropy(buf, buflen, 0);
		    return (ret > 0) ? 0 : ret;
	    }

RETURN VALUE
       On success, the number of bytes that was filled in the buf is
       returned.  This may not be all the bytes requested by the
       caller via buflen if insufficient entropy was present in the
       /dev/random pool, or if the system call was interrupted by a
       signal.

       On error, -1 is returned, and errno is set appropriately.

ERRORS
	EINVAL		An invalid flag was passed to getrandom(2)

	EFAULT		buf is outside your accessible address space.

	EAGAIN		The requested entropy was not available, and the
			getentropy(2) would have blocked if GRND_BLOCK flag
			was set.

	EINTR		While blocked waiting for entropy, the call was
			interrupted by a signal handler; see the description
			of how interrupted read(2) calls on "slow" devices
			are handled with and without the SA_RESTART flag
			in the signal(7) man page.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
 arch/x86/syscalls/syscall_32.tbl  |  1 +
 arch/x86/syscalls/syscall_64.tbl  |  1 +
 drivers/char/random.c             | 39 +++++++++++++++++++++++++++++++++++++--
 include/linux/syscalls.h          |  3 +++
 include/uapi/asm-generic/unistd.h |  4 +++-
 include/uapi/linux/random.h       |  9 +++++++++
 6 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
index d6b8679..f484e39 100644
--- a/arch/x86/syscalls/syscall_32.tbl
+++ b/arch/x86/syscalls/syscall_32.tbl
@@ -360,3 +360,4 @@
 351	i386	sched_setattr		sys_sched_setattr
 352	i386	sched_getattr		sys_sched_getattr
 353	i386	renameat2		sys_renameat2
+354	i386	getrandom		sys_getrandom
diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl
index ec255a1..6705032 100644
--- a/arch/x86/syscalls/syscall_64.tbl
+++ b/arch/x86/syscalls/syscall_64.tbl
@@ -323,6 +323,7 @@
 314	common	sched_setattr		sys_sched_setattr
 315	common	sched_getattr		sys_sched_getattr
 316	common	renameat2		sys_renameat2
+317	common	getrandom		sys_getrandom
 
 #
 # x32-specific system call numbers start at 512 to avoid cache impact
diff --git a/drivers/char/random.c b/drivers/char/random.c
index aa22fe5..3c8429e 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -258,6 +258,8 @@
 #include <linux/kmemcheck.h>
 #include <linux/workqueue.h>
 #include <linux/irq.h>
+#include <linux/syscalls.h>
+#include <linux/completion.h>
 
 #include <asm/processor.h>
 #include <asm/uaccess.h>
@@ -469,6 +471,8 @@ static struct entropy_store nonblocking_pool = {
 					push_to_pool),
 };
 
+static DECLARE_COMPLETION(urandom_initialized);
+
 static __u32 const twist_table[8] = {
 	0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
 	0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
@@ -657,6 +661,7 @@ retry:
 		r->entropy_total = 0;
 		if (r == &nonblocking_pool) {
 			prandom_reseed_late();
+			complete_all(&urandom_initialized);
 			pr_notice("random: %s pool is initialized\n", r->name);
 		}
 	}
@@ -1355,7 +1360,7 @@ static int arch_random_refill(void)
 }
 
 static ssize_t
-random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
+_random_read(int nonblock, char __user *buf, size_t nbytes)
 {
 	ssize_t n;
 
@@ -1379,7 +1384,7 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 		if (arch_random_refill())
 			continue;
 
-		if (file->f_flags & O_NONBLOCK)
+		if (nonblock)
 			return -EAGAIN;
 
 		wait_event_interruptible(random_read_wait,
@@ -1391,6 +1396,12 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 }
 
 static ssize_t
+random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
+{
+	return _random_read(file->f_flags & O_NONBLOCK, buf, nbytes);
+}
+
+static ssize_t
 urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 {
 	int ret;
@@ -1533,6 +1544,30 @@ const struct file_operations urandom_fops = {
 	.llseek = noop_llseek,
 };
 
+SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count,
+		unsigned int, flags)
+{
+	int r;
+
+	if (flags & ~(GRND_NONBLOCK|GRND_RANDOM))
+		return -EINVAL;
+
+	if (count > INT_MAX)
+		count = INT_MAX;
+
+	if (flags & GRND_RANDOM)
+		return _random_read(flags & GRND_NONBLOCK, buf, count);
+	if (flags & GRND_NONBLOCK) {
+		if (!completion_done(&urandom_initialized))
+			return -EAGAIN;
+	} else {
+		r = wait_for_completion_interruptible(&urandom_initialized);
+		if (r)
+			return r;
+	}
+	return urandom_read(NULL, buf, count, NULL);
+}
+
 /***************************************************************
  * Random UUID interface
  *
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index b0881a0..cd82f72f 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -866,4 +866,7 @@ asmlinkage long sys_process_vm_writev(pid_t pid,
 asmlinkage long sys_kcmp(pid_t pid1, pid_t pid2, int type,
 			 unsigned long idx1, unsigned long idx2);
 asmlinkage long sys_finit_module(int fd, const char __user *uargs, int flags);
+asmlinkage long sys_getrandom(char __user * buf, size_t count,
+			      unsigned int flags);
+
 #endif
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 3336406..2926b1d 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -699,9 +699,11 @@ __SYSCALL(__NR_sched_setattr, sys_sched_setattr)
 __SYSCALL(__NR_sched_getattr, sys_sched_getattr)
 #define __NR_renameat2 276
 __SYSCALL(__NR_renameat2, sys_renameat2)
+#define __NR_getrandom 277
+__SYSCALL(__NR_getrandom, sys_getrandom)
 
 #undef __NR_syscalls
-#define __NR_syscalls 277
+#define __NR_syscalls 278
 
 /*
  * All syscalls below here should go away really,
diff --git a/include/uapi/linux/random.h b/include/uapi/linux/random.h
index fff3528..3f93d16 100644
--- a/include/uapi/linux/random.h
+++ b/include/uapi/linux/random.h
@@ -40,4 +40,13 @@ struct rand_pool_info {
 	__u32	buf[0];
 };
 
+/*
+ * Flags for getrandom(2)
+ *
+ * GRND_NONBLOCK	Don't block and return EAGAIN instead
+ * GRND_RANDOM		Use the /dev/random pool instead of /dev/urandom
+ */
+#define GRND_NONBLOCK	0x0001
+#define GRND_RANDOM	0x0002
+
 #endif /* _UAPI_LINUX_RANDOM_H */
-- 
2.0.0

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

* Re: [PATCH, RFC -v2] random: introduce getrandom(2) system call
  2014-07-17 21:38 [PATCH, RFC -v2] random: introduce getrandom(2) system call Theodore Ts'o
@ 2014-07-17 21:57     ` Zach Brown
  0 siblings, 0 replies; 9+ messages in thread
From: Zach Brown @ 2014-07-17 21:57 UTC (permalink / raw)
  To: Theodore Ts'o
  Cc: Linux Kernel Developers List,
	linux-crypto-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA, beck-7YlrpqBBQ3VAfugRpC6u6w

On Thu, Jul 17, 2014 at 05:38:20PM -0400, Theodore Ts'o wrote:
> The getrandom(2) system call was requested by the LibreSSL Portable
> developers.  It is analoguous to the getentropy(2) system call in
> OpenBSD.

> +SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count,
> +		unsigned int, flags)
> +{
> +	int r;
> +
> +	if (flags & ~(GRND_NONBLOCK|GRND_RANDOM))
> +		return -EINVAL;
> +
> +	if (count > INT_MAX)
> +		count = INT_MAX;
> +
> +	if (flags & GRND_RANDOM)
> +		return _random_read(flags & GRND_NONBLOCK, buf, count);
> +	if (flags & GRND_NONBLOCK) {
> +		if (!completion_done(&urandom_initialized))
> +			return -EAGAIN;
> +	} else {
> +		r = wait_for_completion_interruptible(&urandom_initialized);
> +		if (r)
> +			return r;
> +	}
> +	return urandom_read(NULL, buf, count, NULL);
> +}

I like how tiny this ends up being.  Feel free to add my rb:.

Reviewed-by: Zach Brown <zab-ugsP4Wv/S6ZeoWH0uzbU5w@public.gmane.org>

- z

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

* Re: [PATCH, RFC -v2] random: introduce getrandom(2) system call
@ 2014-07-17 21:57     ` Zach Brown
  0 siblings, 0 replies; 9+ messages in thread
From: Zach Brown @ 2014-07-17 21:57 UTC (permalink / raw)
  To: Theodore Ts'o
  Cc: Linux Kernel Developers List, linux-crypto, linux-api, beck

On Thu, Jul 17, 2014 at 05:38:20PM -0400, Theodore Ts'o wrote:
> The getrandom(2) system call was requested by the LibreSSL Portable
> developers.  It is analoguous to the getentropy(2) system call in
> OpenBSD.

> +SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count,
> +		unsigned int, flags)
> +{
> +	int r;
> +
> +	if (flags & ~(GRND_NONBLOCK|GRND_RANDOM))
> +		return -EINVAL;
> +
> +	if (count > INT_MAX)
> +		count = INT_MAX;
> +
> +	if (flags & GRND_RANDOM)
> +		return _random_read(flags & GRND_NONBLOCK, buf, count);
> +	if (flags & GRND_NONBLOCK) {
> +		if (!completion_done(&urandom_initialized))
> +			return -EAGAIN;
> +	} else {
> +		r = wait_for_completion_interruptible(&urandom_initialized);
> +		if (r)
> +			return r;
> +	}
> +	return urandom_read(NULL, buf, count, NULL);
> +}

I like how tiny this ends up being.  Feel free to add my rb:.

Reviewed-by: Zach Brown <zab@zabbo.net>

- z

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

* Re: [PATCH, RFC -v2] random: introduce getrandom(2) system call
  2014-07-17 21:38 [PATCH, RFC -v2] random: introduce getrandom(2) system call Theodore Ts'o
@ 2014-07-17 23:22     ` Theodore Ts'o
  0 siblings, 0 replies; 9+ messages in thread
From: Theodore Ts'o @ 2014-07-17 23:22 UTC (permalink / raw)
  To: Linux Kernel Developers List
  Cc: linux-crypto-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA, beck-7YlrpqBBQ3VAfugRpC6u6w

This is just an update to the commit description (and so I've only
included it_.  A few more minor typos fixedup, and it includes Zach's
reviewed-by.

						- Ted

random: introduce getrandom(2) system call

The getrandom(2) system call was requested by the LibreSSL Portable
developers.  It is analoguous to the getentropy(2) system call in
OpenBSD.

The rationale of this system call is to provide resiliance against
file descriptor exhaustion attacks, where the attacker consumes all
available file descriptors, forcing the use of the fallback code where
/dev/[u]random is not available.  Since the fallback code is often not
well-tested, it is better to eliminate this potential failure mode
entirely.

The other feature provided by this new system call is the ability to
request randomness from the /dev/urandom entropy pool, but to block
until at least 128 bits of entropy has been accumulated in the
/dev/urandom entropy pool.  Historically, the emphasis in the
/dev/urandom development has been to ensure that urandom pool is
initialized as quickly as possible after system boot, and preferably
before the init scripts start execution.

This is because changing /dev/urandom reads to block represents an
interface change that could potentially break userspace which is not
acceptable.  In practice, on most x86 desktop and server systems, in
general the entropy pool can be initialized before it is needed (and
in modern kernels, we will printk a warning message if not).  However,
on an embedded system, this may not be the case.  And so with this new
interface, we can provide the functionality of blocking until the
urandom pool has been initialized.  Any userspace program which uses
this new functionality must take care to assure that if it is used
during the boot process, that it will not cause the init scripts or
other portions of the system startup to hang indefinitely.

SYNOPSIS
	#include <linux/random.h>

	int getrandom(void *buf, size_t buflen, unsigned int flags);

DESCRIPTION
	The system call getrandom() fills the buffer pointed to by buf
	with up to buflen random bytes which can be used to seed user
	space random number generators (i.e., DRBG's) or for other
	cryptographic processes.  It should not be used Monte Carlo
	simulations or for other probabilistic sampling applications.

	If the GRND_RANDOM flags bit is set, then draw from the
	/dev/random pool instead of the /dev/urandom pool.  The
	/dev/random pool is limited based on the entropy that can be
	obtained from environmental noise, so if there is insufficient
	entropy, the requested number of bytes may not be returned.
	If there is no entropy available at all, getrandom(2) will
	either block, or return an error with errno set to EAGAIN if
	the GRND_NONBLOCK bit is set in flags.

	If the GRND_RANDOM bit is not set, then the /dev/urandom pool
	will be used.  Unlike using read(2) to fetch data from
	/dev/urandom, if the urandom pool has not been sufficiently
	initialized, getrandom(2) will block or return -1 with the
	errno set to EGAIN if the GRND_NONBLOCK bit is set in flags.

	The getentropy(2) system call in OpenBSD can be emulated using
	the following function:

	    int getentropy(void *buf, size_t buflen)
	    {
	            int     ret;

		    ret = getentropy(buf, buflen, 0);
		    return (ret > 0) ? 0 : ret;
	    }

RETURN VALUE
       On success, the number of bytes that was filled in the buf is
       returned.  This may not be all the bytes requested by the
       caller via buflen if insufficient entropy was present in the
       /dev/random pool, or if the system call was interrupted by a
       signal.

       On error, -1 is returned, and errno is set appropriately.

ERRORS
	EINVAL		An invalid flag was passed to getrandom(2)

	EFAULT		buf is outside the accessible address space.

	EAGAIN		The requested entropy was not available, and the
			getentropy(2) would have blocked if GRND_BLOCK flag
			was set.

	EINTR		While blocked waiting for entropy, the call was
			interrupted by a signal handler; see the description
			of how interrupted read(2) calls on "slow" devices
			are handled with and without the SA_RESTART flag
			in the signal(7) man page.

Signed-off-by: Theodore Ts'o <tytso-3s7WtUTddSA@public.gmane.org>
Reviewed-by: Zach Brown <zab-ugsP4Wv/S6ZeoWH0uzbU5w@public.gmane.org>

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

* Re: [PATCH, RFC -v2] random: introduce getrandom(2) system call
@ 2014-07-17 23:22     ` Theodore Ts'o
  0 siblings, 0 replies; 9+ messages in thread
From: Theodore Ts'o @ 2014-07-17 23:22 UTC (permalink / raw)
  To: Linux Kernel Developers List; +Cc: linux-crypto, linux-api, beck

This is just an update to the commit description (and so I've only
included it_.  A few more minor typos fixedup, and it includes Zach's
reviewed-by.

						- Ted

random: introduce getrandom(2) system call

The getrandom(2) system call was requested by the LibreSSL Portable
developers.  It is analoguous to the getentropy(2) system call in
OpenBSD.

The rationale of this system call is to provide resiliance against
file descriptor exhaustion attacks, where the attacker consumes all
available file descriptors, forcing the use of the fallback code where
/dev/[u]random is not available.  Since the fallback code is often not
well-tested, it is better to eliminate this potential failure mode
entirely.

The other feature provided by this new system call is the ability to
request randomness from the /dev/urandom entropy pool, but to block
until at least 128 bits of entropy has been accumulated in the
/dev/urandom entropy pool.  Historically, the emphasis in the
/dev/urandom development has been to ensure that urandom pool is
initialized as quickly as possible after system boot, and preferably
before the init scripts start execution.

This is because changing /dev/urandom reads to block represents an
interface change that could potentially break userspace which is not
acceptable.  In practice, on most x86 desktop and server systems, in
general the entropy pool can be initialized before it is needed (and
in modern kernels, we will printk a warning message if not).  However,
on an embedded system, this may not be the case.  And so with this new
interface, we can provide the functionality of blocking until the
urandom pool has been initialized.  Any userspace program which uses
this new functionality must take care to assure that if it is used
during the boot process, that it will not cause the init scripts or
other portions of the system startup to hang indefinitely.

SYNOPSIS
	#include <linux/random.h>

	int getrandom(void *buf, size_t buflen, unsigned int flags);

DESCRIPTION
	The system call getrandom() fills the buffer pointed to by buf
	with up to buflen random bytes which can be used to seed user
	space random number generators (i.e., DRBG's) or for other
	cryptographic processes.  It should not be used Monte Carlo
	simulations or for other probabilistic sampling applications.

	If the GRND_RANDOM flags bit is set, then draw from the
	/dev/random pool instead of the /dev/urandom pool.  The
	/dev/random pool is limited based on the entropy that can be
	obtained from environmental noise, so if there is insufficient
	entropy, the requested number of bytes may not be returned.
	If there is no entropy available at all, getrandom(2) will
	either block, or return an error with errno set to EAGAIN if
	the GRND_NONBLOCK bit is set in flags.

	If the GRND_RANDOM bit is not set, then the /dev/urandom pool
	will be used.  Unlike using read(2) to fetch data from
	/dev/urandom, if the urandom pool has not been sufficiently
	initialized, getrandom(2) will block or return -1 with the
	errno set to EGAIN if the GRND_NONBLOCK bit is set in flags.

	The getentropy(2) system call in OpenBSD can be emulated using
	the following function:

	    int getentropy(void *buf, size_t buflen)
	    {
	            int     ret;

		    ret = getentropy(buf, buflen, 0);
		    return (ret > 0) ? 0 : ret;
	    }

RETURN VALUE
       On success, the number of bytes that was filled in the buf is
       returned.  This may not be all the bytes requested by the
       caller via buflen if insufficient entropy was present in the
       /dev/random pool, or if the system call was interrupted by a
       signal.

       On error, -1 is returned, and errno is set appropriately.

ERRORS
	EINVAL		An invalid flag was passed to getrandom(2)

	EFAULT		buf is outside the accessible address space.

	EAGAIN		The requested entropy was not available, and the
			getentropy(2) would have blocked if GRND_BLOCK flag
			was set.

	EINTR		While blocked waiting for entropy, the call was
			interrupted by a signal handler; see the description
			of how interrupted read(2) calls on "slow" devices
			are handled with and without the SA_RESTART flag
			in the signal(7) man page.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Zach Brown <zab@zabbo.net>

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

* Re: [PATCH, RFC -v2] random: introduce getrandom(2) system call
  2014-07-17 21:38 [PATCH, RFC -v2] random: introduce getrandom(2) system call Theodore Ts'o
@ 2014-07-18  9:39     ` Florian Weimer
  0 siblings, 0 replies; 9+ messages in thread
From: Florian Weimer @ 2014-07-18  9:39 UTC (permalink / raw)
  To: Theodore Ts'o, Linux Kernel Developers List
  Cc: linux-crypto-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA, beck-7YlrpqBBQ3VAfugRpC6u6w

On 07/17/2014 11:38 PM, Theodore Ts'o wrote:
> 	If the GRND_RANDOM flags bit is set, then draw from the
> 	/dev/random pool instead of the /dev/urandom pool.  The
> 	/dev/random pool is limited based on the entropy that can be
> 	obtained from environmental noise, so if there is insufficient
> 	entropy, the requested number of bytes may not be returned.
> 	If there is no entropy available at all, getrandom(2) will
> 	either block, or return an error with errno set to EAGAIN if
> 	the GRND_NONBLOCK bit is set in flags.

Can we get a GRND_INIT flag or something like that which means 
"block/return EAGAIN until the kernel pool is initialized"?  Thanks.

(See the previous discussion about pool initialization.)

-- 
Florian Weimer / Red Hat Product Security

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

* Re: [PATCH, RFC -v2] random: introduce getrandom(2) system call
@ 2014-07-18  9:39     ` Florian Weimer
  0 siblings, 0 replies; 9+ messages in thread
From: Florian Weimer @ 2014-07-18  9:39 UTC (permalink / raw)
  To: Theodore Ts'o, Linux Kernel Developers List
  Cc: linux-crypto, linux-api, beck

On 07/17/2014 11:38 PM, Theodore Ts'o wrote:
> 	If the GRND_RANDOM flags bit is set, then draw from the
> 	/dev/random pool instead of the /dev/urandom pool.  The
> 	/dev/random pool is limited based on the entropy that can be
> 	obtained from environmental noise, so if there is insufficient
> 	entropy, the requested number of bytes may not be returned.
> 	If there is no entropy available at all, getrandom(2) will
> 	either block, or return an error with errno set to EAGAIN if
> 	the GRND_NONBLOCK bit is set in flags.

Can we get a GRND_INIT flag or something like that which means 
"block/return EAGAIN until the kernel pool is initialized"?  Thanks.

(See the previous discussion about pool initialization.)

-- 
Florian Weimer / Red Hat Product Security

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

* Re: [PATCH, RFC -v2] random: introduce getrandom(2) system call
  2014-07-18  9:39     ` Florian Weimer
@ 2014-07-18 10:21         ` Theodore Ts'o
  -1 siblings, 0 replies; 9+ messages in thread
From: Theodore Ts'o @ 2014-07-18 10:21 UTC (permalink / raw)
  To: Florian Weimer
  Cc: Linux Kernel Developers List,
	linux-crypto-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA, beck-7YlrpqBBQ3VAfugRpC6u6w

On Fri, Jul 18, 2014 at 11:39:17AM +0200, Florian Weimer wrote:
> On 07/17/2014 11:38 PM, Theodore Ts'o wrote:
> >	If the GRND_RANDOM flags bit is set, then draw from the
> >	/dev/random pool instead of the /dev/urandom pool.  The
> >	/dev/random pool is limited based on the entropy that can be
> >	obtained from environmental noise, so if there is insufficient
> >	entropy, the requested number of bytes may not be returned.
> >	If there is no entropy available at all, getrandom(2) will
> >	either block, or return an error with errno set to EAGAIN if
> >	the GRND_NONBLOCK bit is set in flags.
> 
> Can we get a GRND_INIT flag or something like that which means "block/return
> EAGAIN until the kernel pool is initialized"?  Thanks.

This is a mandatory, non-optional feature of getrandom(2).

It will always block or return EAGAIN until it has sufficient entropy.
This is true both for the GRND_RANDOM or !GRND_RANDOM modes.

There are already people whining about how they can't use this
interface to get best efforts randomness for srand().  I'm not
planning meeting their request; non-crypto code which wants to use
random() or rand() can either use the standard getpid()/time()
mechanisms to initialize their PRNG, or they can try to open
/dev/urandom and do things the old fashioned way.  Cry me a river.....

Cheers,

					- Ted

P.S.  Because the ARM architecture does not guarantee a cycle counter
(and apparently using the cycle counter when it is not present cause a
crash, and there's apparently no way to determine whether the cycle
counter is present), entropy collection on ARM is a problem, and so
this new behaviour may be problematic on some architectures,
especially if some part of the system like systemd wants to use
getrandom(2) in very early boot.

However, this is a new interface, so if it causes problems on ARM and
other broken architectures, tough noogies.  Hopefully this will
gradually increase pressure on the ARM folks to fix their broken
CPU architectuure specification...

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

* Re: [PATCH, RFC -v2] random: introduce getrandom(2) system call
@ 2014-07-18 10:21         ` Theodore Ts'o
  0 siblings, 0 replies; 9+ messages in thread
From: Theodore Ts'o @ 2014-07-18 10:21 UTC (permalink / raw)
  To: Florian Weimer
  Cc: Linux Kernel Developers List, linux-crypto, linux-api, beck

On Fri, Jul 18, 2014 at 11:39:17AM +0200, Florian Weimer wrote:
> On 07/17/2014 11:38 PM, Theodore Ts'o wrote:
> >	If the GRND_RANDOM flags bit is set, then draw from the
> >	/dev/random pool instead of the /dev/urandom pool.  The
> >	/dev/random pool is limited based on the entropy that can be
> >	obtained from environmental noise, so if there is insufficient
> >	entropy, the requested number of bytes may not be returned.
> >	If there is no entropy available at all, getrandom(2) will
> >	either block, or return an error with errno set to EAGAIN if
> >	the GRND_NONBLOCK bit is set in flags.
> 
> Can we get a GRND_INIT flag or something like that which means "block/return
> EAGAIN until the kernel pool is initialized"?  Thanks.

This is a mandatory, non-optional feature of getrandom(2).

It will always block or return EAGAIN until it has sufficient entropy.
This is true both for the GRND_RANDOM or !GRND_RANDOM modes.

There are already people whining about how they can't use this
interface to get best efforts randomness for srand().  I'm not
planning meeting their request; non-crypto code which wants to use
random() or rand() can either use the standard getpid()/time()
mechanisms to initialize their PRNG, or they can try to open
/dev/urandom and do things the old fashioned way.  Cry me a river.....

Cheers,

					- Ted

P.S.  Because the ARM architecture does not guarantee a cycle counter
(and apparently using the cycle counter when it is not present cause a
crash, and there's apparently no way to determine whether the cycle
counter is present), entropy collection on ARM is a problem, and so
this new behaviour may be problematic on some architectures,
especially if some part of the system like systemd wants to use
getrandom(2) in very early boot.

However, this is a new interface, so if it causes problems on ARM and
other broken architectures, tough noogies.  Hopefully this will
gradually increase pressure on the ARM folks to fix their broken
CPU architectuure specification...

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

end of thread, other threads:[~2014-07-18 10:22 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-17 21:38 [PATCH, RFC -v2] random: introduce getrandom(2) system call Theodore Ts'o
     [not found] ` <1405633100-4889-1-git-send-email-tytso-3s7WtUTddSA@public.gmane.org>
2014-07-17 21:57   ` Zach Brown
2014-07-17 21:57     ` Zach Brown
2014-07-17 23:22   ` Theodore Ts'o
2014-07-17 23:22     ` Theodore Ts'o
2014-07-18  9:39   ` Florian Weimer
2014-07-18  9:39     ` Florian Weimer
     [not found]     ` <53C8EB45.20304-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2014-07-18 10:21       ` Theodore Ts'o
2014-07-18 10:21         ` Theodore Ts'o

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.