[PATCH 4/4] crypto: algif_skcipher - User-space interface for skcipher operations

2010-11-26 Thread Herbert Xu
crypto: algif_skcipher - User-space interface for skcipher operations

This patch adds the af_alg plugin for symmetric key ciphers,
corresponding to the ablkcipher kernel operation type.

Keys can optionally be set through the setsockopt interface.

Once a sendmsg call occurs without MSG_MORE no further writes
may be made to the socket until all previous data has been read.

IVs and and whether encryption/decryption is performed can be
set through the setsockopt interface or as a control message
to sendmsg.

The interface is completely synchronous, all operations are
carried out in recvmsg(2) and will complete prior to the system
call returning.

The splice(2) interface support reading the user-space data directly
without copying (except that the Crypto API itself may copy the data
if alignment is off).

The recvmsg(2) interface supports directly writing to user-space
without additional copying, i.e., the kernel crypto interface will
receive the user-space address as its output SG list.

Thakns to Miloslav Trmac for reviewing this and contributing
fixes and improvements.

Signed-off-by: Herbert Xu 
Acked-by: David S. Miller 
---

 crypto/Kconfig  |8 
 crypto/Makefile |1 
 crypto/algif_skcipher.c |  640 
 3 files changed, 649 insertions(+)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 6db27d7..69437e2 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -852,6 +852,14 @@ config CRYPTO_USER_API_HASH
  This option enables the user-spaces interface for hash
  algorithms.
 
+config CRYPTO_USER_API_SKCIPHER
+   tristate "User-space interface for symmetric key cipher algorithms"
+   select CRYPTO_BLKCIPHER
+   select CRYPTO_USER_API
+   help
+ This option enables the user-spaces interface for symmetric
+ key cipher algorithms.
+
 source "drivers/crypto/Kconfig"
 
 endif  # if CRYPTO
diff --git a/crypto/Makefile b/crypto/Makefile
index 14ab405..efc0f18 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -87,6 +87,7 @@ obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
 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
 
 #
 # generic algorithms and the async_tx api
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
new file mode 100644
index 000..211c956
--- /dev/null
+++ b/crypto/algif_skcipher.c
@@ -0,0 +1,640 @@
+/*
+ * algif_skcipher: User-space interface for skcipher algorithms
+ *
+ * This file provides the user-space API for symmetric key ciphers.
+ *
+ * Copyright (c) 2010 Herbert Xu 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct skcipher_sg_list {
+   struct list_head list;
+
+   int cur;
+
+   struct scatterlist sg[0];
+};
+
+struct skcipher_ctx {
+   struct list_head tsgl;
+   struct af_alg_sgl rsgl;
+
+   void *iv;
+
+   struct af_alg_completion completion;
+
+   unsigned used;
+
+   unsigned int len;
+   bool more;
+   bool merge;
+   bool enc;
+
+   struct ablkcipher_request req;
+};
+
+#define MAX_SGL_ENTS ((PAGE_SIZE - sizeof(struct skcipher_sg_list)) / \
+ sizeof(struct scatterlist) - 1)
+
+static inline bool skcipher_writable(struct sock *sk)
+{
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask->private;
+
+   return ctx->used + PAGE_SIZE <= max_t(int, sk->sk_sndbuf, PAGE_SIZE);
+}
+
+static int skcipher_alloc_sgl(struct sock *sk)
+{
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask->private;
+   struct skcipher_sg_list *sgl;
+   struct scatterlist *sg = NULL;
+
+   sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
+   if (!list_empty(&ctx->tsgl))
+   sg = sgl->sg;
+
+   if (!sg || sgl->cur >= MAX_SGL_ENTS) {
+   sgl = sock_kmalloc(sk, sizeof(*sgl) +
+  sizeof(sgl->sg[0]) * (MAX_SGL_ENTS + 1),
+  GFP_KERNEL);
+   if (!sgl)
+   return -ENOMEM;
+
+   sg_init_table(sgl->sg, MAX_SGL_ENTS + 1);
+   sgl->cur = 0;
+
+   if (sg)
+   scatterwalk_sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg);
+
+   list_add_tail(&sgl->list, &ctx->tsgl);
+   }
+
+   return 0;
+}
+
+static void skcipher_pull_sgl(struct sock *sk, int used)
+{
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask->private;
+   struct sk

Re: [PATCH 4/4] crypto: algif_skcipher - User-space interface for skcipher operations

2010-11-26 Thread Herbert Xu
On Fri, Nov 19, 2010 at 05:51:36PM +0800, Herbert Xu wrote:
> 
> Miroslave found quite a few more problems with the patch-set
> so here is another revision with those problems resolved:

OK two more bugs found and fixed so here is one more revision:

* If recvmsg leaves bytes behind in the last SG entry it gets
  freed incorrectly.
* sendmsg's SG loop did not apply the socket limit, causing
  crashes with large sends.

Thanks,
-- 
Email: Herbert Xu 
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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/4] crypto: algif_skcipher - User-space interface for skcipher operations

2010-11-19 Thread Herbert Xu
crypto: algif_skcipher - User-space interface for skcipher operations

This patch adds the af_alg plugin for symmetric key ciphers,
corresponding to the ablkcipher kernel operation type.

Keys can optionally be set through the setsockopt interface.

Once a sendmsg call occurs without MSG_MORE no further writes
may be made to the socket until all previous data has been read.

IVs and and whether encryption/decryption is performed can be
set through the setsockopt interface or as a control message
to sendmsg.

The interface is completely synchronous, all operations are
carried out in recvmsg(2) and will complete prior to the system
call returning.

The splice(2) interface support reading the user-space data directly
without copying (except that the Crypto API itself may copy the data
if alignment is off).

The recvmsg(2) interface supports directly writing to user-space
without additional copying, i.e., the kernel crypto interface will
receive the user-space address as its output SG list.

Thakns to Miloslav Trmac for reviewing this and contributing
fixes and improvements.

Signed-off-by: Herbert Xu 
Acked-by: David S. Miller 
---

 crypto/Kconfig  |8 
 crypto/Makefile |1 
 crypto/algif_skcipher.c |  642 
 3 files changed, 651 insertions(+)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 6db27d7..69437e2 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -852,6 +852,14 @@ config CRYPTO_USER_API_HASH
  This option enables the user-spaces interface for hash
  algorithms.
 
+config CRYPTO_USER_API_SKCIPHER
+   tristate "User-space interface for symmetric key cipher algorithms"
+   select CRYPTO_BLKCIPHER
+   select CRYPTO_USER_API
+   help
+ This option enables the user-spaces interface for symmetric
+ key cipher algorithms.
+
 source "drivers/crypto/Kconfig"
 
 endif  # if CRYPTO
diff --git a/crypto/Makefile b/crypto/Makefile
index 14ab405..efc0f18 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -87,6 +87,7 @@ obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
 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
 
 #
 # generic algorithms and the async_tx api
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
new file mode 100644
index 000..d8d3ddf
--- /dev/null
+++ b/crypto/algif_skcipher.c
@@ -0,0 +1,642 @@
+/*
+ * algif_skcipher: User-space interface for skcipher algorithms
+ *
+ * This file provides the user-space API for symmetric key ciphers.
+ *
+ * Copyright (c) 2010 Herbert Xu 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct skcipher_sg_list {
+   struct list_head list;
+
+   int cur;
+
+   struct scatterlist sg[0];
+};
+
+struct skcipher_ctx {
+   struct list_head tsgl;
+   struct af_alg_sgl rsgl;
+
+   void *iv;
+
+   struct af_alg_completion completion;
+
+   unsigned used;
+
+   unsigned int len;
+   bool more;
+   bool merge;
+   bool enc;
+
+   struct ablkcipher_request req;
+};
+
+#define MAX_SGL_ENTS ((PAGE_SIZE - sizeof(struct skcipher_sg_list)) / \
+ sizeof(struct scatterlist) - 1)
+
+static inline bool skcipher_writable(struct sock *sk)
+{
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask->private;
+
+   return ctx->used + PAGE_SIZE <= max_t(int, sk->sk_sndbuf, PAGE_SIZE);
+}
+
+static int skcipher_alloc_sgl(struct sock *sk)
+{
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask->private;
+   struct skcipher_sg_list *sgl;
+   struct scatterlist *sg = NULL;
+
+   sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
+   if (!list_empty(&ctx->tsgl))
+   sg = sgl->sg;
+
+   if (!sg || sgl->cur >= MAX_SGL_ENTS) {
+   sgl = sock_kmalloc(sk, sizeof(*sgl) +
+  sizeof(sgl->sg[0]) * (MAX_SGL_ENTS + 1),
+  GFP_KERNEL);
+   if (!sgl)
+   return -ENOMEM;
+
+   sg_init_table(sgl->sg, MAX_SGL_ENTS + 1);
+   sgl->cur = 0;
+
+   if (sg)
+   scatterwalk_sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg);
+
+   list_add_tail(&sgl->list, &ctx->tsgl);
+   }
+
+   return 0;
+}
+
+static void skcipher_pull_sgl(struct sock *sk, int used)
+{
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask->private;
+   struct sk

Re: [PATCH 4/4] crypto: algif_skcipher - User-space interface for skcipher operations

2010-11-19 Thread Herbert Xu
On Mon, Nov 15, 2010 at 03:55:49PM +0100, Martin Willi wrote:
> 
> > This patch adds the af_alg plugin for symmetric key ciphers,
> > corresponding to the ablkcipher kernel operation type.
> 
> I can confirm that the newest patch fixes the page leak.
> 
> Tested-by: Martin Willi 

Thanks Martin!

Miroslave found quite a few more problems with the patch-set
so here is another revision with those problems resolved:

* cmsg_len check fixed.
* Added missing locking to af_alg setsockopt/accept.
* Error path memory leak in alg_setkey.
* Bogus module aliases deleted.
* Bogus semilcon after if in skcipher_data_wakeup.
* Fixed broken wait logic in algif_skcipher.
* Fixed a couple of bugs with the SG merging in algif_skcipher.

Cheers,
-- 
Email: Herbert Xu 
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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/4] crypto: algif_skcipher - User-space interface for skcipher operations

2010-11-15 Thread Martin Willi

> This patch adds the af_alg plugin for symmetric key ciphers,
> corresponding to the ablkcipher kernel operation type.

I can confirm that the newest patch fixes the page leak.

Tested-by: Martin Willi 

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/4] crypto: algif_skcipher - User-space interface for skcipher operations

2010-11-15 Thread Herbert Xu
crypto: algif_skcipher - User-space interface for skcipher operations

This patch adds the af_alg plugin for symmetric key ciphers,
corresponding to the ablkcipher kernel operation type.

Keys can optionally be set through the setsockopt interface.

Once a sendmsg call occurs without MSG_MORE no further writes
may be made to the socket until all previous data has been read.

IVs and and whether encryption/decryption is performed can be
set through the setsockopt interface or as a control message
to sendmsg.

The interface is completely synchronous, all operations are
carried out in recvmsg(2) and will complete prior to the system
call returning.

The splice(2) interface support reading the user-space data directly
without copying (except that the Crypto API itself may copy the data
if alignment is off).

The recvmsg(2) interface supports directly writing to user-space
without additional copying, i.e., the kernel crypto interface will
receive the user-space address as its output SG list.

Thakns to Miloslav Trmac for reviewing this and contributing
fixes and improvements.

Signed-off-by: Herbert Xu 
Acked-by: David S. Miller 
---

 crypto/Kconfig  |8 
 crypto/Makefile |1 
 crypto/algif_skcipher.c |  642 
 3 files changed, 651 insertions(+)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 6db27d7..69437e2 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -852,6 +852,14 @@ config CRYPTO_USER_API_HASH
  This option enables the user-spaces interface for hash
  algorithms.
 
+config CRYPTO_USER_API_SKCIPHER
+   tristate "User-space interface for symmetric key cipher algorithms"
+   select CRYPTO_BLKCIPHER
+   select CRYPTO_USER_API
+   help
+ This option enables the user-spaces interface for symmetric
+ key cipher algorithms.
+
 source "drivers/crypto/Kconfig"
 
 endif  # if CRYPTO
diff --git a/crypto/Makefile b/crypto/Makefile
index 14ab405..efc0f18 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -87,6 +87,7 @@ obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
 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
 
 #
 # generic algorithms and the async_tx api
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
new file mode 100644
index 000..0c67612
--- /dev/null
+++ b/crypto/algif_skcipher.c
@@ -0,0 +1,642 @@
+/*
+ * algif_skcipher: User-space interface for skcipher algorithms
+ *
+ * This file provides the user-space API for symmetric key ciphers.
+ *
+ * Copyright (c) 2010 Herbert Xu 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct skcipher_sg_list {
+   struct list_head list;
+
+   int cur;
+
+   struct scatterlist sg[0];
+};
+
+struct skcipher_ctx {
+   struct list_head tsgl;
+   struct af_alg_sgl rsgl;
+
+   void *iv;
+
+   struct af_alg_completion completion;
+
+   unsigned used;
+
+   unsigned int len;
+   bool more;
+   bool merge;
+   bool enc;
+
+   struct ablkcipher_request req;
+};
+
+#define MAX_SGL_ENTS ((PAGE_SIZE - sizeof(struct skcipher_sg_list)) / \
+ sizeof(struct scatterlist) - 1)
+
+static inline bool skcipher_writable(struct sock *sk)
+{
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask->private;
+
+   return ctx->used + PAGE_SIZE <= max_t(int, sk->sk_sndbuf, PAGE_SIZE);
+}
+
+static int skcipher_alloc_sgl(struct sock *sk)
+{
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask->private;
+   struct skcipher_sg_list *sgl;
+   struct scatterlist *sg = NULL;
+
+   sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
+   if (!list_empty(&ctx->tsgl))
+   sg = sgl->sg;
+
+   if (!sg || sgl->cur >= MAX_SGL_ENTS) {
+   sgl = sock_kmalloc(sk, sizeof(*sgl) +
+  sizeof(sgl->sg[0]) * (MAX_SGL_ENTS + 1),
+  GFP_KERNEL);
+   if (!sgl)
+   return -ENOMEM;
+
+   sg_init_table(sgl->sg, MAX_SGL_ENTS + 1);
+   sgl->cur = 0;
+
+   if (sg)
+   scatterwalk_sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg);
+
+   list_add_tail(&sgl->list, &ctx->tsgl);
+   }
+
+   return 0;
+}
+
+static void skcipher_pull_sgl(struct sock *sk, int used)
+{
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask->private;
+   struct sk

Re: [PATCH 4/4] crypto: algif_skcipher - User-space interface for skcipher operations

2010-11-15 Thread Herbert Xu
On Mon, Nov 08, 2010 at 10:10:20AM +0100, Martin Willi wrote:
> 
> The test program below runs 1000 encryptions:
> 
> # grep nr_free /proc/vmstat 
> nr_free_pages 11031
> # ./test

Thanks, Miroslav identified a bogosity where if we're not doing
a whole page then the last sgl pointer is off by one which triggers
the leak.

With his fix I cannot reproduce this problem anymore.

Other major problems identified by him include inadequage checks
with respect to ALG_MAX_PAGES, and the use of generic SG chaining
instead of crypto SG chaining.

So here is a respin of the patches which I hope will be the last :)

Cheers,
-- 
Email: Herbert Xu 
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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/4] crypto: algif_skcipher - User-space interface for skcipher operations

2010-11-08 Thread Martin Willi

> Hmm, can you show me your test program and how you determined
> that it was leaking pages?

The test program below runs 1000 encryptions:

# grep nr_free /proc/vmstat 
nr_free_pages 11031
# ./test
...
# grep nr_free /proc/vmstat 
nr_free_pages 10026
# ./test
...
# grep nr_free /proc/vmstat 
nr_free_pages 9027
# ./test
...
# grep nr_free /proc/vmstat 
nr_free_pages 8025

Regards
Martin

--
#include 
#include 
#include 
#include 
#include 
#include 

int main()
{
int tfm, i;
char key[16];

struct sockaddr_alg sa = {
.salg_family = AF_ALG,
.salg_type = "skcipher",
.salg_name = "cbc(aes)",
};

tfm = socket(AF_ALG, SOCK_SEQPACKET, 0);
if (tfm == -1 ||
bind(tfm, (struct sockaddr*)&sa, sizeof(sa)) == -1)
{
return 1;
}
memset(key, 0x34, sizeof(key));
if (setsockopt(tfm, SOL_ALG, ALG_SET_KEY,
key, sizeof(key)) == -1)
{
return 1;
}

for (i = 0; i < 1000; i++)
{
struct msghdr msg = {};
struct cmsghdr *cmsg;
struct af_alg_iv *ivm;
u_int32_t type;
struct iovec iov;
char buf[CMSG_SPACE(sizeof(type)) +
 CMSG_SPACE(offsetof(struct af_alg_iv, iv)+16)];
char data[64];
ssize_t len;
int op;

op = accept(tfm, NULL, 0);
if (op == -1)
{
return 1;
}

type = ALG_OP_ENCRYPT;
memset(data, 0x12, sizeof(data));
memset(buf, 0, sizeof(buf));

msg.msg_control = buf;
msg.msg_controllen = sizeof(buf);

cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_ALG;
cmsg->cmsg_type = ALG_SET_OP;
cmsg->cmsg_len = CMSG_LEN(sizeof(type));
*(u_int32_t*)CMSG_DATA(cmsg) = type;

cmsg = CMSG_NXTHDR(&msg, cmsg);
cmsg->cmsg_level = SOL_ALG;
cmsg->cmsg_type = ALG_SET_IV;
cmsg->cmsg_len = CMSG_LEN(
offsetof(struct af_alg_iv, iv) + 16);
ivm = (void*)CMSG_DATA(cmsg);
ivm->ivlen = 16;
memset(ivm->iv, 0x23, 16);

msg.msg_iov = &iov;
msg.msg_iovlen = 1;

iov.iov_base = data;
iov.iov_len = sizeof(data);

len = sendmsg(op, &msg, 0);
if (len != sizeof(data))
{
return 1;
}
if (read(op, data, len) != len)
{
return 1;
}
printf(".");
fflush(stdout);
close(op);
}
close(tfm);
printf("\n");
return 0;
}

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/4] crypto: algif_skcipher - User-space interface for skcipher operations

2010-11-06 Thread Herbert Xu
Martin Willi  wrote:
> Hi Herbert,
> 
> I did a proof-of-concept implementation for our crypto library, the
> interface looks good so far. All our hash, hmac, xcbc and cipher test
> vectors matched.
> 
>> + sg_assign_page(sg + i, alloc_page(GFP_KERNEL));
> 
> Every skcipher operation leaks memory on my box (this page?). Should be
> reproducible by doing encryption with any cipher.

Hmm, can you show me your test program and how you determined
that it was leaking pages?

Thanks!
-- 
Email: Herbert Xu 
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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/4] crypto: algif_skcipher - User-space interface for skcipher operations

2010-11-06 Thread Martin Willi
Hi Herbert,

I did a proof-of-concept implementation for our crypto library, the
interface looks good so far. All our hash, hmac, xcbc and cipher test
vectors matched.

> + sg_assign_page(sg + i, alloc_page(GFP_KERNEL));

Every skcipher operation leaks memory on my box (this page?). Should be
reproducible by doing encryption with any cipher.

Regards
Martin

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/4] crypto: algif_skcipher - User-space interface for skcipher operations

2010-11-04 Thread David Miller
From: Herbert Xu 
Date: Thu, 04 Nov 2010 12:36:20 -0500

> crypto: algif_skcipher - User-space interface for skcipher operations
> 
> This patch adds the af_alg plugin for symmetric key ciphers,
> corresponding to the ablkcipher kernel operation type.
> 
> Keys can optionally be set through the setsockopt interface.
> 
> Once a sendmsg call occurs without MSG_MORE no further writes
> may be made to the socket until all previous data has been read.
> 
> IVs and and whether encryption/decryption is performed can be
> set through the setsockopt interface or as a control message
> to sendmsg.
> 
> The interface is completely synchronous, all operations are
> carried out in recvmsg(2) and will complete prior to the system
> call returning.
> 
> The splice(2) interface support reading the user-space data directly
> without copying (except that the Crypto API itself may copy the data
> if alignment is off).
> 
> The recvmsg(2) interface supports directly writing to user-space
> without additional copying, i.e., the kernel crypto interface will
> receive the user-space address as its output SG list.
> 
> Thakns to Miloslav Trmac for reviewing this and contributing
> fixes and improvements.
> 
> Signed-off-by: Herbert Xu 

Acked-by: David S. Miller 
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/4] crypto: algif_skcipher - User-space interface for skcipher operations

2010-11-04 Thread Herbert Xu
crypto: algif_skcipher - User-space interface for skcipher operations

This patch adds the af_alg plugin for symmetric key ciphers,
corresponding to the ablkcipher kernel operation type.

Keys can optionally be set through the setsockopt interface.

Once a sendmsg call occurs without MSG_MORE no further writes
may be made to the socket until all previous data has been read.

IVs and and whether encryption/decryption is performed can be
set through the setsockopt interface or as a control message
to sendmsg.

The interface is completely synchronous, all operations are
carried out in recvmsg(2) and will complete prior to the system
call returning.

The splice(2) interface support reading the user-space data directly
without copying (except that the Crypto API itself may copy the data
if alignment is off).

The recvmsg(2) interface supports directly writing to user-space
without additional copying, i.e., the kernel crypto interface will
receive the user-space address as its output SG list.

Thakns to Miloslav Trmac for reviewing this and contributing
fixes and improvements.

Signed-off-by: Herbert Xu 
---

 crypto/Kconfig  |8 
 crypto/Makefile |1 
 crypto/algif_skcipher.c |  647 
 3 files changed, 656 insertions(+)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 6db27d7..69437e2 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -852,6 +852,14 @@ config CRYPTO_USER_API_HASH
  This option enables the user-spaces interface for hash
  algorithms.
 
+config CRYPTO_USER_API_SKCIPHER
+   tristate "User-space interface for symmetric key cipher algorithms"
+   select CRYPTO_BLKCIPHER
+   select CRYPTO_USER_API
+   help
+ This option enables the user-spaces interface for symmetric
+ key cipher algorithms.
+
 source "drivers/crypto/Kconfig"
 
 endif  # if CRYPTO
diff --git a/crypto/Makefile b/crypto/Makefile
index 14ab405..efc0f18 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -87,6 +87,7 @@ obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
 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
 
 #
 # generic algorithms and the async_tx api
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
new file mode 100644
index 000..abc15b2
--- /dev/null
+++ b/crypto/algif_skcipher.c
@@ -0,0 +1,647 @@
+/*
+ * algif_skcipher: User-space interface for skcipher algorithms
+ *
+ * This file provides the user-space API for symmetric key ciphers.
+ *
+ * Copyright (c) 2010 Herbert Xu 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct skcipher_sg_list {
+   struct list_head list;
+
+   int cur;
+
+   struct scatterlist sg[0];
+};
+
+struct skcipher_ctx {
+   struct list_head tsgl;
+   struct af_alg_sgl rsgl;
+
+   void *iv;
+
+   struct af_alg_completion completion;
+
+   unsigned used;
+
+   unsigned int len;
+   bool more;
+   bool merge;
+   bool enc;
+
+   struct ablkcipher_request req;
+};
+
+#define MAX_SGL_ENTS ((PAGE_SIZE - sizeof(struct skcipher_sg_list)) / \
+ sizeof(struct scatterlist) - 1)
+
+static inline bool skcipher_writable(struct sock *sk)
+{
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask->private;
+
+   return ctx->used + PAGE_SIZE <= max_t(int, sk->sk_sndbuf, PAGE_SIZE);
+}
+
+static int skcipher_alloc_sgl(struct sock *sk, int size)
+{
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask->private;
+   struct skcipher_sg_list *sgl;
+   struct scatterlist *sg = NULL;
+
+   sgl = list_first_entry(&ctx->tsgl, struct skcipher_sg_list, list);
+   if (!list_empty(&ctx->tsgl))
+   sg = sgl->sg;
+
+   if (!sg || sgl->cur >= MAX_SGL_ENTS) {
+   sgl = sock_kmalloc(sk, sizeof(*sgl) +
+  sizeof(sgl->sg[0]) * (MAX_SGL_ENTS + 1),
+  GFP_KERNEL);
+   if (!sgl)
+   return -ENOMEM;
+
+   sg_init_table(sgl->sg, MAX_SGL_ENTS + 1);
+   sgl->cur = 0;
+
+   if (sg)
+   sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg);
+
+   list_add_tail(&sgl->list, &ctx->tsgl);
+   }
+
+   return 0;
+}
+
+static void skcipher_pull_sgl(struct sock *sk, int used)
+{
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask->private;
+   struct skcipher_sg_list *sgl;
+   struct sc

[PATCH 4/4] crypto: algif_skcipher - User-space interface for skcipher operations

2010-10-19 Thread Herbert Xu
crypto: algif_skcipher - User-space interface for skcipher operations

This patch adds the af_alg plugin for symmetric key ciphers,
corresponding to the ablkcipher kernel operation type.

Keys can optionally be set through the setsockopt interface.

Once a sendmsg call occurs without MSG_MORE no further writes
may be made to the socket until all previous data has been read.

IVs and and whether encryption/decryption is performed can be
set through the setsockopt interface or as a control message
to sendmsg.

The interface is completely synchronous, all operations are
carried out in recvmsg(2) and will complete prior to the system
call returning.

The splice(2) interface support reading the user-space data directly
without copying (except that the Crypto API itself may copy the data
if alignment is off).

The recvmsg(2) interface supports directly writing to user-space
without additional copying, i.e., the kernel crypto interface will
receive the user-space address as its output SG list.

Signed-off-by: Herbert Xu 
---

 crypto/Kconfig  |8 
 crypto/Makefile |1 
 crypto/algif_skcipher.c |  664 
 3 files changed, 673 insertions(+)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 6db27d7..69437e2 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -852,6 +852,14 @@ config CRYPTO_USER_API_HASH
  This option enables the user-spaces interface for hash
  algorithms.
 
+config CRYPTO_USER_API_SKCIPHER
+   tristate "User-space interface for symmetric key cipher algorithms"
+   select CRYPTO_BLKCIPHER
+   select CRYPTO_USER_API
+   help
+ This option enables the user-spaces interface for symmetric
+ key cipher algorithms.
+
 source "drivers/crypto/Kconfig"
 
 endif  # if CRYPTO
diff --git a/crypto/Makefile b/crypto/Makefile
index 14ab405..efc0f18 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -87,6 +87,7 @@ obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
 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
 
 #
 # generic algorithms and the async_tx api
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
new file mode 100644
index 000..af26040
--- /dev/null
+++ b/crypto/algif_skcipher.c
@@ -0,0 +1,664 @@
+/*
+ * algif_skcipher: User-space interface for skcipher algorithms
+ *
+ * This file provides the user-space API for symmetric key ciphers.
+ *
+ * Copyright (c) 2010 Herbert Xu 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct skcipher_sg_list {
+   struct list_head list;
+
+   int cur;
+
+   struct scatterlist sg[0];
+};
+
+struct skcipher_ctx {
+   struct list_head tsgl;
+   struct af_alg_sgl rsgl;
+
+   struct completion completion;
+
+   void *iv;
+
+   unsigned used;
+
+   unsigned int len;
+   int err;
+   bool more;
+   bool merge;
+   bool enc;
+
+   struct ablkcipher_request req;
+};
+
+#define MAX_SGL_ENTS ((PAGE_SIZE - sizeof(struct skcipher_sg_list)) / \
+ sizeof(struct scatterlist) - 1)
+
+static inline bool skcipher_writable(struct sock *sk)
+{
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask->private;
+
+   return ctx->used + PAGE_SIZE <= max_t(int, sk->sk_sndbuf, PAGE_SIZE);
+}
+
+static void skcipher_done(struct crypto_async_request *req, int err)
+{
+   struct sock *sk = req->data;
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask->private;
+
+   ctx->err = err;
+   complete(&ctx->completion);
+}
+
+static int skcipher_alloc_sgl(struct sock *sk, int size)
+{
+   struct alg_sock *ask = alg_sk(sk);
+   struct skcipher_ctx *ctx = ask->private;
+   struct skcipher_sg_list *sgl;
+   struct scatterlist *sg = NULL;
+
+   sgl = list_first_entry(&ctx->tsgl, struct skcipher_sg_list, list);
+   if (!list_empty(&ctx->tsgl))
+   sg = sgl->sg;
+
+   if (!sg || sgl->cur >= MAX_SGL_ENTS) {
+   sgl = sock_kmalloc(sk, sizeof(*sgl) +
+  sizeof(sgl->sg[0]) * (MAX_SGL_ENTS + 1),
+  GFP_KERNEL);
+   if (!sgl)
+   return -ENOMEM;
+
+   sg_init_table(sgl->sg, MAX_SGL_ENTS + 1);
+   sgl->cur = 0;
+
+   if (sg)
+   sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg);
+
+   list_add_tail(&sgl->list, &ctx->tsgl);
+   }
+
+   return 0;
+}
+
+sta