2010-12-13 17:12:26

by Neil Horman

[permalink] [raw]
Subject: [PATCH] Add RNG support to AF_ALG

This patch enhances the AF_ALG protocol family to include support for random
number generator algorithms. With this enhancment, users of the AF_ALG protocol
can now bind sockets to instances of the various RNG algorithms available to the
kernel. For those RNG's that support it, instances can be reseeded using the
SETKEY socket option within the AF_ALG socket family. Like with hashes and
ciphers, only the intially created socket allows seeding, and only child sockets
retured via accept may return random data. Sending data on RNG instances is
prohibited, only receiving RNG data is possible.

Tested successfully using NIST provided RNG vectors by myself:
Signed-off-by: Neil Horman <[email protected]>
CC: Herbert Xu <[email protected]>
CC: "David S. Miller" <[email protected]>
---
crypto/Kconfig | 9 +++
crypto/Makefile | 1 +
crypto/algif_rng.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 207 insertions(+), 0 deletions(-)
create mode 100644 crypto/algif_rng.c

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 96b0e55..ea448ca 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -864,6 +864,15 @@ config CRYPTO_USER_API_SKCIPHER
This option enables the user-spaces interface for symmetric
key cipher algorithms.

+config CRYPTO_USER_API_RNG
+ tristate "User-space interface for Random Number Generator algorithms"
+ depends on NET
+ select CRYPTO_ANSI_CPRNG
+ select CRYPTO_USER_API
+ help
+ This option enables the user-space interface for random number
+ generation algorithms.
+
source "drivers/crypto/Kconfig"

endif # if CRYPTO
diff --git a/crypto/Makefile b/crypto/Makefile
index e9a399c..8868555 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -88,6 +88,7 @@ obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o
obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o
obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o
obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o
+obj-$(CONFIG_CRYPTO_USER_API_RNG) += algif_rng.o

#
# generic algorithms and the async_tx api
diff --git a/crypto/algif_rng.c b/crypto/algif_rng.c
new file mode 100644
index 0000000..b660a2a
--- /dev/null
+++ b/crypto/algif_rng.c
@@ -0,0 +1,197 @@
+/*
+ * algif_rng: User-space interface for rng algorithms
+ *
+ * This file provides the user-space API for rng algorithms.
+ *
+ * Copyright (c) 2010 Neil Horman <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include <crypto/rng.h>
+#include <crypto/if_alg.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/net.h>
+#include <net/sock.h>
+
+struct rng_ctx {
+ struct crypto_rng *ctx;
+ u8 *seed;
+ size_t seedlen;
+ char *name;
+ u32 type;
+ u32 mask;
+};
+
+static int rng_recvmsg(struct kiocb *unused, struct socket *sock,
+ struct msghdr *msg, size_t len, int flags)
+{
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ struct rng_ctx *ctx = ask->private;
+ int rc, i;
+ u8 *data = kzalloc(len, GFP_KERNEL);
+
+ if (!data)
+ return -ENOMEM;
+ rc = crypto_rng_get_bytes(ctx->ctx, data, len);
+ if (rc < 0)
+ goto out;
+
+ rc = memcpy_toiovec(msg->msg_iov, data, len);
+out:
+ kfree(data);
+ return rc ?: len;
+}
+
+
+static const struct proto_ops algif_rng_ops = {
+ .family = PF_ALG,
+
+ .connect = sock_no_connect,
+ .socketpair = sock_no_socketpair,
+ .getname = sock_no_getname,
+ .ioctl = sock_no_ioctl,
+ .listen = sock_no_listen,
+ .shutdown = sock_no_shutdown,
+ .getsockopt = sock_no_getsockopt,
+ .mmap = sock_no_mmap,
+ .bind = sock_no_bind,
+ .setsockopt = sock_no_setsockopt,
+ .poll = sock_no_poll,
+
+ .release = af_alg_release,
+ .sendmsg = sock_no_sendmsg,
+ .sendpage = sock_no_sendpage,
+ .recvmsg = rng_recvmsg,
+ .accept = sock_no_accept,
+};
+
+static void *rng_bind(const char *name, u32 type, u32 mask)
+{
+ struct rng_ctx *new = kzalloc(sizeof(struct rng_ctx), GFP_KERNEL);
+
+ if (!new)
+ goto out;
+
+ new->name = kmemdup(name, strnlen(name, 63)+1, GFP_KERNEL);
+ new->type = type;
+ new->mask = mask;
+out:
+ return new;
+}
+
+static void rng_release(void *private)
+{
+ struct rng_ctx *ctx = private;
+ crypto_free_rng(ctx->ctx);
+ kfree(ctx->seed);
+ kfree(ctx->name);
+ kfree(ctx);
+}
+
+static int rng_setkey(void *private, const u8 *key, unsigned int keylen)
+{
+ struct rng_ctx *ctx = private;
+ u8 *oldseed = ctx->seed;
+
+ ctx->seed = kmemdup(key, keylen, GFP_KERNEL);
+
+ if (!ctx->seed)
+ return -ENOMEM;
+
+ kfree(oldseed);
+ ctx->seedlen = keylen;
+
+ return 0;
+}
+
+static void rng_sock_destruct(struct sock *sk)
+{
+ struct alg_sock *ask = alg_sk(sk);
+ struct rng_ctx *ctx = ask->private;
+
+ crypto_free_rng(ctx->ctx);
+ kfree(ctx->seed);
+ sock_kfree_s(sk, ctx, sizeof(struct rng_ctx));
+ af_alg_release_parent(sk);
+}
+
+static int rng_accept_parent(void *private, struct sock *sk)
+{
+ struct rng_ctx *parent = private;
+ struct rng_ctx *child;
+ struct alg_sock *ask = alg_sk(sk);
+ int rc = -EINVAL;
+
+ if (!parent->seed)
+ goto out;
+
+ rc = -ENOMEM;
+ child = sock_kmalloc(sk, sizeof(struct rng_ctx), GFP_KERNEL);
+
+ if (!child)
+ goto out;
+
+ rc = -ENOENT;
+ child->ctx = crypto_alloc_rng(parent->name,
+ parent->type, parent->mask);
+ if (IS_ERR(child->ctx))
+ goto out_child;
+ child->seed = kmemdup(parent->seed, parent->seedlen, GFP_KERNEL);
+ if (!child->seed)
+ goto out_ctx;
+
+ child->seedlen = parent->seedlen;
+
+ rc = -EBUSY;
+ if (crypto_rng_reset(child->ctx, child->seed, child->seedlen))
+ goto out_seed;
+
+ ask->private = child;
+
+ sk->sk_destruct = rng_sock_destruct;
+
+
+ return 0;
+
+out_seed:
+ kfree(child->seed);
+out_ctx:
+ crypto_free_rng(child->ctx);
+out_child:
+ kfree(child);
+out:
+ return rc;
+}
+
+static const struct af_alg_type algif_type_rng = {
+ .bind = rng_bind,
+ .release = rng_release,
+ .setkey = rng_setkey,
+ .accept = rng_accept_parent,
+ .ops = &algif_rng_ops,
+ .name = "rng",
+ .owner = THIS_MODULE
+};
+
+static int __init algif_rng_init(void)
+{
+ return af_alg_register_type(&algif_type_rng);
+}
+
+static void __exit algif_rng_exit(void)
+{
+ int err = af_alg_unregister_type(&algif_type_rng);
+ BUG_ON(err);
+}
+
+module_init(algif_rng_init);
+module_exit(algif_rng_exit);
+MODULE_LICENSE("GPL");
--
1.7.2.3


2010-12-13 17:24:46

by Miloslav Trmac

[permalink] [raw]
Subject: Re: [PATCH] Add RNG support to AF_ALG

----- "Neil Horman" <[email protected]> wrote:
> +static int rng_recvmsg(struct kiocb *unused, struct socket *sock,
> + struct msghdr *msg, size_t len, int flags)
> +{
> + struct sock *sk = sock->sk;
> + struct alg_sock *ask = alg_sk(sk);
> + struct rng_ctx *ctx = ask->private;
> + int rc, i;
> + u8 *data = kzalloc(len, GFP_KERNEL);
There probably should be an upper limit on the allocation - perhaps just always allocate a single page.

> +static void rng_release(void *private)
> +{
> + struct rng_ctx *ctx = private;
> + crypto_free_rng(ctx->ctx);
> + kfree(ctx->seed);
Is a seed secret enough that it should be zeroed before freeing? (Same in setkey, accept_parent).

Mirek

2010-12-13 17:47:45

by Neil Horman

[permalink] [raw]
Subject: Re: [PATCH] Add RNG support to AF_ALG

On Mon, Dec 13, 2010 at 12:24:34PM -0500, Miloslav Trmac wrote:
> ----- "Neil Horman" <[email protected]> wrote:
> > +static int rng_recvmsg(struct kiocb *unused, struct socket *sock,
> > + struct msghdr *msg, size_t len, int flags)
> > +{
> > + struct sock *sk = sock->sk;
> > + struct alg_sock *ask = alg_sk(sk);
> > + struct rng_ctx *ctx = ask->private;
> > + int rc, i;
> > + u8 *data = kzalloc(len, GFP_KERNEL);
> There probably should be an upper limit on the allocation - perhaps just always allocate a single page.
>
I'd rather allocate the explicit amount needed, just to avoid added memory
pressure allocating memory that we won't use, but yes, I can definately add an
upper limit to how much data can be requested in a single call.

> > +static void rng_release(void *private)
> > +{
> > + struct rng_ctx *ctx = private;
> > + crypto_free_rng(ctx->ctx);
> > + kfree(ctx->seed);
> Is a seed secret enough that it should be zeroed before freeing? (Same in setkey, accept_parent).
>
I don't think that nececcecary, strictly speaking, but it couldn't hurt.
Actually looking at it, I don't really need to duplicate the seed at all in
accept_parent. I can probaby shrink that down considerably.

Thanks for the notes Mirek, I'll post an updated version shortly.
Neil

> Mirek
>

2010-12-13 17:50:31

by Miloslav Trmac

[permalink] [raw]
Subject: Re: [PATCH] Add RNG support to AF_ALG

----- "Neil Horman" <[email protected]> wrote:

> On Mon, Dec 13, 2010 at 12:24:34PM -0500, Miloslav Trmac wrote:
> > ----- "Neil Horman" <[email protected]> wrote:
> > > +static int rng_recvmsg(struct kiocb *unused, struct socket
> *sock,
> > > + struct msghdr *msg, size_t len, int flags)
> > > +{
> > > + struct sock *sk = sock->sk;
> > > + struct alg_sock *ask = alg_sk(sk);
> > > + struct rng_ctx *ctx = ask->private;
> > > + int rc, i;
> > > + u8 *data = kzalloc(len, GFP_KERNEL);
> > There probably should be an upper limit on the allocation - perhaps
> just always allocate a single page.
> >
> I'd rather allocate the explicit amount needed, just to avoid added memory
> pressure allocating memory that we won't use, but yes, I can definately add an
> upper limit to how much data can be requested in a single call.
Please allow arbitrarily large requests. rng_recvmsg can easily use a smaller buffer by filling the user-space destination one buffer-size at a time, on the other hand handling an arbitrary upper limit in user-space would be unnecessarily complex.
Mirek

2010-12-13 21:26:03

by Neil Horman

[permalink] [raw]
Subject: [PATCH] Add RNG support to AF_ALG (v2)

Change notes:
Changed rng_rcvmsg to allocate a fixed size maximum temp block to store rng data
when recvmsg is called. This should prevent malicious DoS from user space by
tring to receive obscene amounts of random data in one call. Instead now we
loop using the same block of data and copy it incrementally to the user space
buffer using memcpy_toiovecend

Also changed the accept routine to only allocate a new rng, and not store the
seed value separately, simplifying the code somewhat. also now we memset the
parent sockets seed value to zero on free to hide the seed from intruders.

Summary:
This patch enhances the AF_ALG protocol family to include support for random
number generator algorithms. With this enhancment, users of the AF_ALG protocol
can now bind sockets to instances of the various RNG algorithms available to the
kernel. For those RNG's that support it, instances can be reseeded using the
SETKEY socket option within the AF_ALG socket family. Like with hashes and
ciphers, only the intially created socket allows seeding, and only child sockets
retured via accept may return random data. Sending data on RNG instances is
prohibited, only receiving RNG data is possible.

Tested successfully using NIST provided RNG vectors by myself:
Signed-off-by: Neil Horman <[email protected]>
CC: Herbert Xu <[email protected]>
CC: "David S. Miller" <[email protected]>
---
crypto/Kconfig | 9 ++
crypto/Makefile | 1 +
crypto/algif_rng.c | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 222 insertions(+), 0 deletions(-)
create mode 100644 crypto/algif_rng.c

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 96b0e55..ea448ca 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -864,6 +864,15 @@ config CRYPTO_USER_API_SKCIPHER
This option enables the user-spaces interface for symmetric
key cipher algorithms.

+config CRYPTO_USER_API_RNG
+ tristate "User-space interface for Random Number Generator algorithms"
+ depends on NET
+ select CRYPTO_ANSI_CPRNG
+ select CRYPTO_USER_API
+ help
+ This option enables the user-space interface for random number
+ generation algorithms.
+
source "drivers/crypto/Kconfig"

endif # if CRYPTO
diff --git a/crypto/Makefile b/crypto/Makefile
index e9a399c..8868555 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -88,6 +88,7 @@ obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o
obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o
obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o
obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o
+obj-$(CONFIG_CRYPTO_USER_API_RNG) += algif_rng.o

#
# generic algorithms and the async_tx api
diff --git a/crypto/algif_rng.c b/crypto/algif_rng.c
new file mode 100644
index 0000000..8664793
--- /dev/null
+++ b/crypto/algif_rng.c
@@ -0,0 +1,212 @@
+/*
+ * algif_rng: User-space interface for rng algorithms
+ *
+ * This file provides the user-space API for rng algorithms.
+ *
+ * Copyright (c) 2010 Neil Horman <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include <crypto/rng.h>
+#include <crypto/if_alg.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/net.h>
+#include <net/sock.h>
+
+struct rng_ctx {
+ struct crypto_rng *ctx;
+ u8 *seed;
+ size_t seedlen;
+ char *name;
+ u32 type;
+ u32 mask;
+};
+
+static int rng_recvmsg(struct kiocb *unused, struct socket *sock,
+ struct msghdr *msg, size_t len, int flags)
+{
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ struct crypto_rng *ctx = ask->private;
+ int rc = 0;
+ int rc2;
+ u8 *data;
+ size_t alen, clen;
+
+ /*
+ * Prevent huge memory allocations from user space
+ */
+ alen = (len > PAGE_SIZE) ? PAGE_SIZE : len;
+ data = kzalloc(alen, GFP_KERNEL);
+
+ if (!data)
+ return -ENOMEM;
+
+ clen = 0;
+ while (clen != len) {
+ rc = crypto_rng_get_bytes(ctx, data, alen);
+ if (rc < 0)
+ goto out;
+
+ rc2 = memcpy_toiovecend(msg->msg_iov, data, clen, rc);
+ if (rc2) {
+ rc = rc2;
+ goto out;
+ }
+
+ clen += rc;
+
+ /*
+ * Get the remaining bytes
+ */
+ if ((len-clen) < alen)
+ alen = len-clen;
+ rc = 0;
+ }
+out:
+ kfree(data);
+ return rc ?: len;
+}
+
+
+static struct proto_ops algif_rng_ops = {
+ .family = PF_ALG,
+
+ .connect = sock_no_connect,
+ .socketpair = sock_no_socketpair,
+ .getname = sock_no_getname,
+ .ioctl = sock_no_ioctl,
+ .listen = sock_no_listen,
+ .shutdown = sock_no_shutdown,
+ .getsockopt = sock_no_getsockopt,
+ .mmap = sock_no_mmap,
+ .bind = sock_no_bind,
+ .setsockopt = sock_no_setsockopt,
+ .poll = sock_no_poll,
+
+ .release = af_alg_release,
+ .sendmsg = sock_no_sendmsg,
+ .sendpage = sock_no_sendpage,
+ .recvmsg = rng_recvmsg,
+ .accept = sock_no_accept,
+};
+
+static void *rng_bind(const char *name, u32 type, u32 mask)
+{
+ struct rng_ctx *new = kzalloc(sizeof(struct rng_ctx), GFP_KERNEL);
+
+ if (!new)
+ goto out;
+
+ new->name = kmemdup(name, strnlen(name, 63)+1, GFP_KERNEL);
+ new->type = type;
+ new->mask = mask;
+out:
+ return new;
+}
+
+static void rng_release(void *private)
+{
+ struct rng_ctx *ctx = private;
+ crypto_free_rng(ctx->ctx);
+ if (ctx->seed)
+ memset(ctx->seed, 0, ctx->seedlen);
+ kfree(ctx->seed);
+ kfree(ctx->name);
+ kfree(ctx);
+}
+
+static int rng_setkey(void *private, const u8 *key, unsigned int keylen)
+{
+ struct rng_ctx *ctx = private;
+ u8 *oldseed = ctx->seed;
+ size_t oldlen = ctx->seedlen;
+
+ ctx->seed = kmemdup(key, keylen, GFP_KERNEL);
+
+ if (!ctx->seed)
+ return -ENOMEM;
+
+ ctx->seedlen = keylen;
+
+ if (oldseed) {
+ memset(oldseed, 0, oldlen);
+ kfree(oldseed);
+ }
+
+ return 0;
+}
+
+static void rng_sock_destruct(struct sock *sk)
+{
+ struct alg_sock *ask = alg_sk(sk);
+ struct crypto_rng *ctx = ask->private;
+
+ crypto_free_rng(ctx);
+ af_alg_release_parent(sk);
+}
+
+static int rng_accept_parent(void *private, struct sock *sk)
+{
+ struct rng_ctx *parent = private;
+ struct crypto_rng *child;
+ struct alg_sock *ask = alg_sk(sk);
+ int rc = -EINVAL;
+
+ if (!parent->seed)
+ goto out;
+
+ rc = -ENOENT;
+ child = crypto_alloc_rng(parent->name,
+ parent->type, parent->mask);
+ if (IS_ERR(child))
+ goto out;
+
+ rc = -EBUSY;
+ if (crypto_rng_reset(child, parent->seed, parent->seedlen))
+ goto out_ctx;
+
+ ask->private = child;
+
+ sk->sk_destruct = rng_sock_destruct;
+
+
+ return 0;
+
+out_ctx:
+ crypto_free_rng(child);
+out:
+ return rc;
+}
+
+static const struct af_alg_type algif_type_rng = {
+ .bind = rng_bind,
+ .release = rng_release,
+ .setkey = rng_setkey,
+ .accept = rng_accept_parent,
+ .ops = &algif_rng_ops,
+ .name = "rng",
+ .owner = THIS_MODULE
+};
+
+static int __init algif_rng_init(void)
+{
+ return af_alg_register_type(&algif_type_rng);
+}
+
+static void __exit algif_rng_exit(void)
+{
+ int err = af_alg_unregister_type(&algif_type_rng);
+ BUG_ON(err);
+}
+
+module_init(algif_rng_init);
+module_exit(algif_rng_exit);
+MODULE_LICENSE("GPL");
--
1.7.2.3

2011-01-20 23:34:52

by Neil Horman

[permalink] [raw]
Subject: Re: [PATCH] Add RNG support to AF_ALG (v2)

On Mon, Dec 13, 2010 at 04:25:14PM -0500, Neil Horman wrote:
> Change notes:
> Changed rng_rcvmsg to allocate a fixed size maximum temp block to store rng data
> when recvmsg is called. This should prevent malicious DoS from user space by
> tring to receive obscene amounts of random data in one call. Instead now we
> loop using the same block of data and copy it incrementally to the user space
> buffer using memcpy_toiovecend
>
> Also changed the accept routine to only allocate a new rng, and not store the
> seed value separately, simplifying the code somewhat. also now we memset the
> parent sockets seed value to zero on free to hide the seed from intruders.
>
> Summary:
> This patch enhances the AF_ALG protocol family to include support for random
> number generator algorithms. With this enhancment, users of the AF_ALG protocol
> can now bind sockets to instances of the various RNG algorithms available to the
> kernel. For those RNG's that support it, instances can be reseeded using the
> SETKEY socket option within the AF_ALG socket family. Like with hashes and
> ciphers, only the intially created socket allows seeding, and only child sockets
> retured via accept may return random data. Sending data on RNG instances is
> prohibited, only receiving RNG data is possible.
>
> Tested successfully using NIST provided RNG vectors by myself:
> Signed-off-by: Neil Horman <[email protected]>
> CC: Herbert Xu <[email protected]>
> CC: "David S. Miller" <[email protected]>
Herbert, Sorry to bug you about this, but are you still planning on pulling this
now that Linus has the infrastructure scheduled for 2.6.38?

Neil

2011-01-21 06:00:10

by Herbert Xu

[permalink] [raw]
Subject: Re: [PATCH] Add RNG support to AF_ALG (v2)

On Thu, Jan 20, 2011 at 06:34:40PM -0500, Neil Horman wrote:
>
> Herbert, Sorry to bug you about this, but are you still planning on pulling this
> now that Linus has the infrastructure scheduled for 2.6.38?

I think it's best if we leave this out for now, unless we can
come up with some way of merging this with the hardware RNG
interface so that we are not duplicating an existing user interface.

Could we perhaps merge this with the HWRNG interface somehow?
Or maybe we should just expose ansi_cprng (I presume you only
need that) through the hwrng interface?

Thanks,
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

2011-01-21 12:09:59

by Neil Horman

[permalink] [raw]
Subject: Re: [PATCH] Add RNG support to AF_ALG (v2)

On Fri, Jan 21, 2011 at 05:00:05PM +1100, Herbert Xu wrote:
> On Thu, Jan 20, 2011 at 06:34:40PM -0500, Neil Horman wrote:
> >
> > Herbert, Sorry to bug you about this, but are you still planning on pulling this
> > now that Linus has the infrastructure scheduled for 2.6.38?
>
> I think it's best if we leave this out for now, unless we can
> come up with some way of merging this with the hardware RNG
> interface so that we are not duplicating an existing user interface.
>
I take your point, but I'm not certain I agree that we are duplicating an
existing user interface. A cursory glance would say that we are, but
/dev/random and /dev/urandom really just provide access to the kernels entropy
pools, whereas the AF_ALG provides access to instances of any RNG the kernel has
to offer as well as the key management services that AF_ALG has, which I think
is adventageous, given that the CPRNG requires keying to work properly.

> Could we perhaps merge this with the HWRNG interface somehow?
We could certainly, add an ioctl to place /dev/[u]random in a cprng mode, and
another to allow key setting/resets/etc, but that seems fairly limiting in that
only one instace of a cprng could be accessed at a time.

> Or maybe we should just expose ansi_cprng (I presume you only
> need that) through the hwrng interface?
>
Again, we could, but that doesn't seem wise if:
1) A user is expecting truly random data
2) A user needs to truly have predicitbility of their random number set (if
they're using the cprng, multiple un-cordinated users breaks the ability to
predict the rng data).

Another alternative (just off the top of my head), might be to eliminate the
hwrng interface in the kernel entirely, and replace it with the AF_ALG based
interface. People requiring access to /dev/random until their applications can
be migrated could still access /dev/[u]random via a user space daemon that opens
2 unix sockets, binds them to /dev/[u]random, and proxies them to two AF_ALG
sockets connected to the blocking and non-blocking entropy pools in the kernel.

Not saying thats a great idea mind, just brainstorming ways we can eliminate
interface duplication without restricting the CPRNG to a character based
interface, when AF_ALG provides it so much more.
Neil

> Thanks,
> --
> Email: Herbert Xu <[email protected]>
> Home Page: http://gondor.apana.org.au/~herbert/
> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
> --
> To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>

2011-01-21 12:35:22

by Herbert Xu

[permalink] [raw]
Subject: Re: [PATCH] Add RNG support to AF_ALG (v2)

On Fri, Jan 21, 2011 at 07:09:50AM -0500, Neil Horman wrote:
>
> I take your point, but I'm not certain I agree that we are duplicating an
> existing user interface. A cursory glance would say that we are, but
> /dev/random and /dev/urandom really just provide access to the kernels entropy
> pools, whereas the AF_ALG provides access to instances of any RNG the kernel has
> to offer as well as the key management services that AF_ALG has, which I think
> is adventageous, given that the CPRNG requires keying to work properly.

I'm not talking about /dev/random, I'm talking the hwrng interface
in drivers/char/hwrng.

Cheers,
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

2011-01-21 13:24:23

by Neil Horman

[permalink] [raw]
Subject: Re: [PATCH] Add RNG support to AF_ALG (v2)

On Fri, Jan 21, 2011 at 11:35:17PM +1100, Herbert Xu wrote:
> On Fri, Jan 21, 2011 at 07:09:50AM -0500, Neil Horman wrote:
> >
> > I take your point, but I'm not certain I agree that we are duplicating an
> > existing user interface. A cursory glance would say that we are, but
> > /dev/random and /dev/urandom really just provide access to the kernels entropy
> > pools, whereas the AF_ALG provides access to instances of any RNG the kernel has
> > to offer as well as the key management services that AF_ALG has, which I think
> > is adventageous, given that the CPRNG requires keying to work properly.
>
> I'm not talking about /dev/random, I'm talking the hwrng interface
> in drivers/char/hwrng.
>
Doh! I'm sorry, that was stupid of me. Yes that makes alot more sense. I'll
try another pass, adding the cprng to that interface instead.

Thanks!
Neil

> Cheers,
> --
> Email: Herbert Xu <[email protected]>
> Home Page: http://gondor.apana.org.au/~herbert/
> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
>