linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/4] crypto: add algif_akcipher user space API
@ 2015-12-17 23:49 Stephan Mueller
  2015-12-17 23:50 ` [PATCH v3 1/4] crypto: AF_ALG -- add sign/verify API Stephan Mueller
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Stephan Mueller @ 2015-12-17 23:49 UTC (permalink / raw)
  To: herbert
  Cc: tadeusz.struk, marcel, dwmw2, linux-api, linux-crypto, linux-kernel

Hi,

This patch set adds the AF_ALG user space API to externalize the
asymmetric cipher API recently added to the kernel crypto API.

The patch set is tested with the user space library of libkcapi [1].
Use [1] test/test.sh for a full test run. The test covers the
following scenarios:

	* sendmsg of one IOVEC

	* sendmsg of 16 IOVECs with non-linear buffer

	* vmsplice of one IOVEC

	* vmsplice of 15 IOVECs with non-linear buffer

	* invoking multiple separate cipher operations with one
	  open cipher handle

	* encryption with private key (using vector from testmgr.h)

	* encryption with public key (using vector from testmgr.h)

	* decryption with private key (using vector from testmgr.h)

Changes v3:
 * fix hack in alg_setkey and alg_setsockopt by avoding branches for
 setkey and setpubkey as pointed out by Marcel Holtmann
 * removal of patch for fixing SGL handling as this is already included

Changes v2:
 * use updated SGL-based akcipher API
 * allow mix-n-match of sendmsg and vmsplice calls

[1] http://www.chronox.de/libkcapi.html

Stephan Mueller (4):
  crypto: AF_ALG -- add sign/verify API
  crypto: AF_ALG -- add setpubkey setsockopt call
  crypto: AF_ALG -- add asymmetric cipher interface
  crypto: algif_akcipher - enable compilation

 crypto/Kconfig              |   9 +
 crypto/Makefile             |   1 +
 crypto/af_alg.c             |  18 +-
 crypto/algif_akcipher.c     | 542 ++++++++++++++++++++++++++++++++++++++++++++
 include/crypto/if_alg.h     |   1 +
 include/uapi/linux/if_alg.h |   3 +
 6 files changed, 569 insertions(+), 5 deletions(-)
 create mode 100644 crypto/algif_akcipher.c

-- 
2.5.0



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

* [PATCH v3 1/4] crypto: AF_ALG -- add sign/verify API
  2015-12-17 23:49 [PATCH v3 0/4] crypto: add algif_akcipher user space API Stephan Mueller
@ 2015-12-17 23:50 ` Stephan Mueller
  2015-12-17 23:50 ` [PATCH v3 2/4] crypto: AF_ALG -- add setpubkey setsockopt call Stephan Mueller
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Stephan Mueller @ 2015-12-17 23:50 UTC (permalink / raw)
  To: herbert
  Cc: tadeusz.struk, marcel, dwmw2, linux-api, linux-crypto, linux-kernel

Add the flags for handling signature generation and signature
verification.

Also, the patch adds the interface for setting a public key.

Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
 include/uapi/linux/if_alg.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/uapi/linux/if_alg.h b/include/uapi/linux/if_alg.h
index f2acd2f..02e6162 100644
--- a/include/uapi/linux/if_alg.h
+++ b/include/uapi/linux/if_alg.h
@@ -34,9 +34,12 @@ struct af_alg_iv {
 #define ALG_SET_OP			3
 #define ALG_SET_AEAD_ASSOCLEN		4
 #define ALG_SET_AEAD_AUTHSIZE		5
+#define ALG_SET_PUBKEY			6
 
 /* Operations */
 #define ALG_OP_DECRYPT			0
 #define ALG_OP_ENCRYPT			1
+#define ALG_OP_SIGN			2
+#define ALG_OP_VERIFY			3
 
 #endif	/* _LINUX_IF_ALG_H */
-- 
2.5.0



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

* [PATCH v3 2/4] crypto: AF_ALG -- add setpubkey setsockopt call
  2015-12-17 23:49 [PATCH v3 0/4] crypto: add algif_akcipher user space API Stephan Mueller
  2015-12-17 23:50 ` [PATCH v3 1/4] crypto: AF_ALG -- add sign/verify API Stephan Mueller
@ 2015-12-17 23:50 ` Stephan Mueller
  2015-12-17 23:51 ` [PATCH v3 3/4] crypto: AF_ALG -- add asymmetric cipher interface Stephan Mueller
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Stephan Mueller @ 2015-12-17 23:50 UTC (permalink / raw)
  To: herbert
  Cc: tadeusz.struk, marcel, dwmw2, linux-api, linux-crypto, linux-kernel

For supporting asymmetric ciphers, user space must be able to set the
public key. The patch adds a new setsockopt call for setting the public
key.

Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
 crypto/af_alg.c         | 18 +++++++++++++-----
 include/crypto/if_alg.h |  1 +
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index a8e7aa3..767a134 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -173,13 +173,17 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 }
 
 static int alg_setkey(struct sock *sk, char __user *ukey,
-		      unsigned int keylen)
+		      unsigned int keylen,
+		      int (*setkey)(void *private, const u8 *key,
+				    unsigned int keylen))
 {
 	struct alg_sock *ask = alg_sk(sk);
-	const struct af_alg_type *type = ask->type;
 	u8 *key;
 	int err;
 
+	if (!setkey)
+		return -ENOPROTOOPT;
+
 	key = sock_kmalloc(sk, keylen, GFP_KERNEL);
 	if (!key)
 		return -ENOMEM;
@@ -188,7 +192,7 @@ static int alg_setkey(struct sock *sk, char __user *ukey,
 	if (copy_from_user(key, ukey, keylen))
 		goto out;
 
-	err = type->setkey(ask->private, key, keylen);
+	err = setkey(ask->private, key, keylen);
 
 out:
 	sock_kzfree_s(sk, key, keylen);
@@ -214,10 +218,14 @@ static int alg_setsockopt(struct socket *sock, int level, int optname,
 	case ALG_SET_KEY:
 		if (sock->state == SS_CONNECTED)
 			goto unlock;
-		if (!type->setkey)
+
+		err = alg_setkey(sk, optval, optlen, type->setkey);
+		break;
+	case ALG_SET_PUBKEY:
+		if (sock->state == SS_CONNECTED)
 			goto unlock;
 
-		err = alg_setkey(sk, optval, optlen);
+		err = alg_setkey(sk, optval, optlen, type->setpubkey);
 		break;
 	case ALG_SET_AEAD_AUTHSIZE:
 		if (sock->state == SS_CONNECTED)
diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h
index 018afb2..ca4dc72 100644
--- a/include/crypto/if_alg.h
+++ b/include/crypto/if_alg.h
@@ -49,6 +49,7 @@ struct af_alg_type {
 	void *(*bind)(const char *name, u32 type, u32 mask);
 	void (*release)(void *private);
 	int (*setkey)(void *private, const u8 *key, unsigned int keylen);
+	int (*setpubkey)(void *private, const u8 *key, unsigned int keylen);
 	int (*accept)(void *private, struct sock *sk);
 	int (*setauthsize)(void *private, unsigned int authsize);
 
-- 
2.5.0



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

* [PATCH v3 3/4] crypto: AF_ALG -- add asymmetric cipher interface
  2015-12-17 23:49 [PATCH v3 0/4] crypto: add algif_akcipher user space API Stephan Mueller
  2015-12-17 23:50 ` [PATCH v3 1/4] crypto: AF_ALG -- add sign/verify API Stephan Mueller
  2015-12-17 23:50 ` [PATCH v3 2/4] crypto: AF_ALG -- add setpubkey setsockopt call Stephan Mueller
@ 2015-12-17 23:51 ` Stephan Mueller
  2015-12-17 23:51 ` [PATCH v3 4/4] crypto: algif_akcipher - enable compilation Stephan Mueller
  2016-01-25 21:34 ` [PATCH v3 0/4] crypto: add algif_akcipher user space API Stephan Mueller
  4 siblings, 0 replies; 7+ messages in thread
From: Stephan Mueller @ 2015-12-17 23:51 UTC (permalink / raw)
  To: herbert
  Cc: tadeusz.struk, marcel, dwmw2, linux-api, linux-crypto, linux-kernel

This patch adds the user space interface for asymmetric ciphers. The
interface allows the use of sendmsg as well as vmsplice to provide data.

Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
 crypto/algif_akcipher.c | 542 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 542 insertions(+)
 create mode 100644 crypto/algif_akcipher.c

diff --git a/crypto/algif_akcipher.c b/crypto/algif_akcipher.c
new file mode 100644
index 0000000..7c58e9b
--- /dev/null
+++ b/crypto/algif_akcipher.c
@@ -0,0 +1,542 @@
+/*
+ * algif_akcipher: User-space interface for asymmetric cipher algorithms
+ *
+ * Copyright (C) 2015, Stephan Mueller <smueller@chronox.de>
+ *
+ * This file provides the user-space API for asymmetric ciphers.
+ *
+ * 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/akcipher.h>
+#include <crypto/scatterwalk.h>
+#include <crypto/if_alg.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/net.h>
+#include <net/sock.h>
+
+struct akcipher_sg_list {
+	unsigned int cur;
+	struct scatterlist sg[ALG_MAX_PAGES];
+};
+
+struct akcipher_ctx {
+	struct akcipher_sg_list tsgl;
+	struct af_alg_sgl rsgl[ALG_MAX_PAGES];
+
+	struct af_alg_completion completion;
+
+	unsigned long used;
+
+	unsigned int len;
+	bool more;
+	bool merge;
+	int op;
+
+	struct akcipher_request req;
+};
+
+static inline int akcipher_sndbuf(struct sock *sk)
+{
+	struct alg_sock *ask = alg_sk(sk);
+	struct akcipher_ctx *ctx = ask->private;
+
+	return max_t(int, max_t(int, sk->sk_sndbuf & PAGE_MASK, PAGE_SIZE) -
+			  ctx->used, 0);
+}
+
+static inline bool akcipher_writable(struct sock *sk)
+{
+	return PAGE_SIZE <= akcipher_sndbuf(sk);
+}
+
+static inline int akcipher_calcsize(struct akcipher_ctx *ctx)
+{
+	return crypto_akcipher_maxsize(crypto_akcipher_reqtfm(&ctx->req));
+}
+
+static void akcipher_put_sgl(struct sock *sk)
+{
+	struct alg_sock *ask = alg_sk(sk);
+	struct akcipher_ctx *ctx = ask->private;
+	struct akcipher_sg_list *sgl = &ctx->tsgl;
+	struct scatterlist *sg = sgl->sg;
+	unsigned int i;
+
+	for (i = 0; i < sgl->cur; i++) {
+		if (!sg_page(sg + i))
+			continue;
+
+		put_page(sg_page(sg + i));
+		sg_assign_page(sg + i, NULL);
+	}
+	sg_init_table(sg, ALG_MAX_PAGES);
+	sgl->cur = 0;
+	ctx->used = 0;
+	ctx->more = 0;
+	ctx->merge = 0;
+}
+
+static void akcipher_wmem_wakeup(struct sock *sk)
+{
+	struct socket_wq *wq;
+
+	if (!akcipher_writable(sk))
+		return;
+
+	rcu_read_lock();
+	wq = rcu_dereference(sk->sk_wq);
+	if (wq_has_sleeper(wq))
+		wake_up_interruptible_sync_poll(&wq->wait, POLLIN |
+							   POLLRDNORM |
+							   POLLRDBAND);
+	sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
+	rcu_read_unlock();
+}
+
+static int akcipher_wait_for_data(struct sock *sk, unsigned flags)
+{
+	struct alg_sock *ask = alg_sk(sk);
+	struct akcipher_ctx *ctx = ask->private;
+	long timeout;
+	DEFINE_WAIT(wait);
+	int err = -ERESTARTSYS;
+
+	if (flags & MSG_DONTWAIT)
+		return -EAGAIN;
+
+	set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+
+	for (;;) {
+		if (signal_pending(current))
+			break;
+		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
+		timeout = MAX_SCHEDULE_TIMEOUT;
+		if (sk_wait_event(sk, &timeout, !ctx->more)) {
+			err = 0;
+			break;
+		}
+	}
+	finish_wait(sk_sleep(sk), &wait);
+
+	clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+
+	return err;
+}
+
+static void akcipher_data_wakeup(struct sock *sk)
+{
+	struct alg_sock *ask = alg_sk(sk);
+	struct akcipher_ctx *ctx = ask->private;
+	struct socket_wq *wq;
+
+	if (ctx->more)
+		return;
+	if (!ctx->used)
+		return;
+
+	rcu_read_lock();
+	wq = rcu_dereference(sk->sk_wq);
+	if (wq_has_sleeper(wq))
+		wake_up_interruptible_sync_poll(&wq->wait, POLLOUT |
+							   POLLRDNORM |
+							   POLLRDBAND);
+	sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
+	rcu_read_unlock();
+}
+
+static int akcipher_sendmsg(struct socket *sock, struct msghdr *msg,
+			    size_t size)
+{
+	struct sock *sk = sock->sk;
+	struct alg_sock *ask = alg_sk(sk);
+	struct akcipher_ctx *ctx = ask->private;
+	struct akcipher_sg_list *sgl = &ctx->tsgl;
+	struct af_alg_control con = {};
+	long copied = 0;
+	int op = 0;
+	bool init = 0;
+	int err;
+
+	if (msg->msg_controllen) {
+		err = af_alg_cmsg_send(msg, &con);
+		if (err)
+			return err;
+
+		init = 1;
+		switch (con.op) {
+		case ALG_OP_VERIFY:
+		case ALG_OP_SIGN:
+		case ALG_OP_ENCRYPT:
+		case ALG_OP_DECRYPT:
+			op = con.op;
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	lock_sock(sk);
+	if (!ctx->more && ctx->used)
+		goto unlock;
+
+	if (init)
+		ctx->op = op;
+
+	while (size) {
+		unsigned long len = size;
+		struct scatterlist *sg = NULL;
+
+		/* use the existing memory in an allocated page */
+		if (ctx->merge) {
+			sg = sgl->sg + sgl->cur - 1;
+			len = min_t(unsigned long, len,
+				    PAGE_SIZE - sg->offset - sg->length);
+			err = memcpy_from_msg(page_address(sg_page(sg)) +
+					      sg->offset + sg->length,
+					      msg, len);
+			if (err)
+				goto unlock;
+
+			sg->length += len;
+			ctx->merge = (sg->offset + sg->length) &
+				     (PAGE_SIZE - 1);
+
+			ctx->used += len;
+			copied += len;
+			size -= len;
+			continue;
+		}
+
+		if (!akcipher_writable(sk)) {
+			/* user space sent too much data */
+			akcipher_put_sgl(sk);
+			err = -EMSGSIZE;
+			goto unlock;
+		}
+
+		/* allocate a new page */
+		len = min_t(unsigned long, size, akcipher_sndbuf(sk));
+		while (len) {
+			int plen = 0;
+
+			if (sgl->cur >= ALG_MAX_PAGES) {
+				akcipher_put_sgl(sk);
+				err = -E2BIG;
+				goto unlock;
+			}
+
+			sg = sgl->sg + sgl->cur;
+			plen = min_t(int, len, PAGE_SIZE);
+
+			sg_assign_page(sg, alloc_page(GFP_KERNEL));
+			if (!sg_page(sg)) {
+				err = -ENOMEM;
+				goto unlock;
+			}
+
+			err = memcpy_from_msg(page_address(sg_page(sg)),
+					      msg, plen);
+			if (err) {
+				__free_page(sg_page(sg));
+				sg_assign_page(sg, NULL);
+				goto unlock;
+			}
+
+			sg->offset = 0;
+			sg->length = plen;
+			len -= plen;
+			ctx->used += plen;
+			copied += plen;
+			sgl->cur++;
+			size -= plen;
+			ctx->merge = plen & (PAGE_SIZE - 1);
+		}
+	}
+
+	err = 0;
+
+	ctx->more = msg->msg_flags & MSG_MORE;
+
+unlock:
+	akcipher_data_wakeup(sk);
+	release_sock(sk);
+
+	return err ?: copied;
+}
+
+static ssize_t akcipher_sendpage(struct socket *sock, struct page *page,
+				 int offset, size_t size, int flags)
+{
+	struct sock *sk = sock->sk;
+	struct alg_sock *ask = alg_sk(sk);
+	struct akcipher_ctx *ctx = ask->private;
+	struct akcipher_sg_list *sgl = &ctx->tsgl;
+	int err = 0;
+
+	if (flags & MSG_SENDPAGE_NOTLAST)
+		flags |= MSG_MORE;
+
+	if (sgl->cur >= ALG_MAX_PAGES)
+		return -E2BIG;
+
+	lock_sock(sk);
+	if (!ctx->more && ctx->used)
+		goto unlock;
+
+	if (!size)
+		goto done;
+
+	if (!akcipher_writable(sk)) {
+		/* user space sent too much data */
+		akcipher_put_sgl(sk);
+		err = -EMSGSIZE;
+		goto unlock;
+	}
+
+	ctx->merge = 0;
+
+	get_page(page);
+	sg_set_page(sgl->sg + sgl->cur, page, size, offset);
+	sgl->cur++;
+	ctx->used += size;
+
+done:
+	ctx->more = flags & MSG_MORE;
+unlock:
+	akcipher_data_wakeup(sk);
+	release_sock(sk);
+
+	return err ? err : size;
+}
+
+static int akcipher_recvmsg(struct socket *sock, struct msghdr *msg,
+			    size_t ignored, int flags)
+{
+	struct sock *sk = sock->sk;
+	struct alg_sock *ask = alg_sk(sk);
+	struct akcipher_ctx *ctx = ask->private;
+	struct akcipher_sg_list *sgl = &ctx->tsgl;
+	unsigned int i = 0;
+	int err;
+	unsigned long used = 0;
+	size_t usedpages = 0;
+	unsigned int cnt = 0;
+
+	/* Limit number of IOV blocks to be accessed below */
+	if (msg->msg_iter.nr_segs > ALG_MAX_PAGES)
+		return -ENOMSG;
+
+	lock_sock(sk);
+
+	if (ctx->more) {
+		err = akcipher_wait_for_data(sk, flags);
+		if (err)
+			goto unlock;
+	}
+
+	used = ctx->used;
+
+	/* convert iovecs of output buffers into scatterlists */
+	while (iov_iter_count(&msg->msg_iter)) {
+		/* make one iovec available as scatterlist */
+		err = af_alg_make_sg(&ctx->rsgl[cnt], &msg->msg_iter,
+				     iov_iter_count(&msg->msg_iter));
+		if (err < 0)
+			goto unlock;
+		usedpages += err;
+		/* chain the new scatterlist with previous one */
+		if (cnt)
+			af_alg_link_sg(&ctx->rsgl[cnt-1], &ctx->rsgl[cnt]);
+
+		iov_iter_advance(&msg->msg_iter, err);
+		cnt++;
+	}
+
+	/* ensure output buffer is sufficiently large */
+	if (usedpages < akcipher_calcsize(ctx)) {
+		err = -EMSGSIZE;
+		goto unlock;
+	}
+
+	sg_mark_end(sgl->sg + sgl->cur - 1);
+
+	akcipher_request_set_crypt(&ctx->req, sgl->sg, ctx->rsgl[0].sg, used,
+				   usedpages);
+	switch (ctx->op) {
+	case ALG_OP_VERIFY:
+		err = crypto_akcipher_verify(&ctx->req);
+		break;
+	case ALG_OP_SIGN:
+		err = crypto_akcipher_sign(&ctx->req);
+		break;
+	case ALG_OP_ENCRYPT:
+		err = crypto_akcipher_encrypt(&ctx->req);
+		break;
+	case ALG_OP_DECRYPT:
+		err = crypto_akcipher_decrypt(&ctx->req);
+		break;
+	default:
+		err = -EFAULT;
+		goto unlock;
+	}
+
+	err = af_alg_wait_for_completion(err, &ctx->completion);
+
+	if (err) {
+		/* EBADMSG implies a valid cipher operation took place */
+		if (err == -EBADMSG)
+			akcipher_put_sgl(sk);
+		goto unlock;
+	}
+
+	akcipher_put_sgl(sk);
+
+unlock:
+	for (i = 0; i < cnt; i++)
+		af_alg_free_sg(&ctx->rsgl[i]);
+
+	akcipher_wmem_wakeup(sk);
+	release_sock(sk);
+
+	return err ? err : ctx->req.dst_len;
+}
+
+static unsigned int akcipher_poll(struct file *file, struct socket *sock,
+				  poll_table *wait)
+{
+	struct sock *sk = sock->sk;
+	struct alg_sock *ask = alg_sk(sk);
+	struct akcipher_ctx *ctx = ask->private;
+	unsigned int mask = 0;
+
+	sock_poll_wait(file, sk_sleep(sk), wait);
+
+	if (!ctx->more)
+		mask |= POLLIN | POLLRDNORM;
+
+	if (akcipher_writable(sk))
+		mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
+
+	return mask;
+}
+
+static struct proto_ops algif_akcipher_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,
+	.accept		=	sock_no_accept,
+	.setsockopt	=	sock_no_setsockopt,
+
+	.release	=	af_alg_release,
+	.sendmsg	=	akcipher_sendmsg,
+	.sendpage	=	akcipher_sendpage,
+	.recvmsg	=	akcipher_recvmsg,
+	.poll		=	akcipher_poll,
+};
+
+static void *akcipher_bind(const char *name, u32 type, u32 mask)
+{
+	return crypto_alloc_akcipher(name, type, mask);
+}
+
+static void akcipher_release(void *private)
+{
+	crypto_free_akcipher(private);
+}
+
+static int akcipher_setprivkey(void *private, const u8 *key,
+			       unsigned int keylen)
+{
+	return crypto_akcipher_set_priv_key(private, key, keylen);
+}
+
+static int akcipher_setpubkey(void *private, const u8 *key, unsigned int keylen)
+{
+	return crypto_akcipher_set_pub_key(private, key, keylen);
+}
+
+static void akcipher_sock_destruct(struct sock *sk)
+{
+	struct alg_sock *ask = alg_sk(sk);
+	struct akcipher_ctx *ctx = ask->private;
+
+	akcipher_put_sgl(sk);
+	sock_kfree_s(sk, ctx, ctx->len);
+	af_alg_release_parent(sk);
+}
+
+static int akcipher_accept_parent(void *private, struct sock *sk)
+{
+	struct akcipher_ctx *ctx;
+	struct alg_sock *ask = alg_sk(sk);
+	unsigned int len = sizeof(*ctx) + crypto_akcipher_reqsize(private);
+
+	ctx = sock_kmalloc(sk, len, GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+	memset(ctx, 0, len);
+
+	ctx->len = len;
+	ctx->used = 0;
+	ctx->more = 0;
+	ctx->merge = 0;
+	ctx->op = 0;
+	ctx->tsgl.cur = 0;
+	af_alg_init_completion(&ctx->completion);
+	sg_init_table(ctx->tsgl.sg, ALG_MAX_PAGES);
+
+	ask->private = ctx;
+
+	akcipher_request_set_tfm(&ctx->req, private);
+	akcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+				      af_alg_complete, &ctx->completion);
+
+	sk->sk_destruct = akcipher_sock_destruct;
+
+	return 0;
+}
+
+static const struct af_alg_type algif_type_akcipher = {
+	.bind		=	akcipher_bind,
+	.release	=	akcipher_release,
+	.setkey		=	akcipher_setprivkey,
+	.setpubkey	=	akcipher_setpubkey,
+	.setauthsize	=	NULL,
+	.accept		=	akcipher_accept_parent,
+	.ops		=	&algif_akcipher_ops,
+	.name		=	"akcipher",
+	.owner		=	THIS_MODULE
+};
+
+static int __init algif_akcipher_init(void)
+{
+	return af_alg_register_type(&algif_type_akcipher);
+}
+
+static void __exit algif_akcipher_exit(void)
+{
+	int err = af_alg_unregister_type(&algif_type_akcipher);
+	BUG_ON(err);
+}
+
+module_init(algif_akcipher_init);
+module_exit(algif_akcipher_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
+MODULE_DESCRIPTION("Asymmetric kernel crypto API user space interface");
-- 
2.5.0



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

* [PATCH v3 4/4] crypto: algif_akcipher - enable compilation
  2015-12-17 23:49 [PATCH v3 0/4] crypto: add algif_akcipher user space API Stephan Mueller
                   ` (2 preceding siblings ...)
  2015-12-17 23:51 ` [PATCH v3 3/4] crypto: AF_ALG -- add asymmetric cipher interface Stephan Mueller
@ 2015-12-17 23:51 ` Stephan Mueller
  2016-01-25 21:34 ` [PATCH v3 0/4] crypto: add algif_akcipher user space API Stephan Mueller
  4 siblings, 0 replies; 7+ messages in thread
From: Stephan Mueller @ 2015-12-17 23:51 UTC (permalink / raw)
  To: herbert
  Cc: tadeusz.struk, marcel, dwmw2, linux-api, linux-crypto, linux-kernel

Add the Makefile and Kconfig updates to allow algif_akcipher to be
compiled.

Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
 crypto/Kconfig  | 9 +++++++++
 crypto/Makefile | 1 +
 2 files changed, 10 insertions(+)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 7240821..c085c09 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -1639,6 +1639,15 @@ config CRYPTO_USER_API_AEAD
 	  This option enables the user-spaces interface for AEAD
 	  cipher algorithms.
 
+config CRYPTO_USER_API_AKCIPHER
+	tristate "User-space interface for asymmetric key cipher algorithms"
+	depends on NET
+	select CRYPTO_AKCIPHER2
+	select CRYPTO_USER_API
+	help
+	  This option enables the user-spaces interface for asymmetric
+	  key cipher algorithms.
+
 config CRYPTO_HASH_INFO
 	bool
 
diff --git a/crypto/Makefile b/crypto/Makefile
index 2acdbbd..23522fa 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -122,6 +122,7 @@ 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
 obj-$(CONFIG_CRYPTO_USER_API_AEAD) += algif_aead.o
+obj-$(CONFIG_CRYPTO_USER_API_AKCIPHER) += algif_akcipher.o
 
 #
 # generic algorithms and the async_tx api
-- 
2.5.0



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

* Re: [PATCH v3 0/4] crypto: add algif_akcipher user space API
  2015-12-17 23:49 [PATCH v3 0/4] crypto: add algif_akcipher user space API Stephan Mueller
                   ` (3 preceding siblings ...)
  2015-12-17 23:51 ` [PATCH v3 4/4] crypto: algif_akcipher - enable compilation Stephan Mueller
@ 2016-01-25 21:34 ` Stephan Mueller
  2016-01-26 11:12   ` Herbert Xu
  4 siblings, 1 reply; 7+ messages in thread
From: Stephan Mueller @ 2016-01-25 21:34 UTC (permalink / raw)
  To: herbert
  Cc: tadeusz.struk, marcel, dwmw2, linux-api, linux-crypto, linux-kernel

Am Freitag, 18. Dezember 2015, 00:49:57 schrieb Stephan Mueller:

Hi Herbert,

[...]

> Changes v3:
>  * fix hack in alg_setkey and alg_setsockopt by avoding branches for
>  setkey and setpubkey as pointed out by Marcel Holtmann
>  * removal of patch for fixing SGL handling as this is already included

I have ported the code to 4.5. Shall I wait for comments from you for the 
current code or shall I post v4 for the current cryptodev tree?


Ciao
Stephan

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

* Re: [PATCH v3 0/4] crypto: add algif_akcipher user space API
  2016-01-25 21:34 ` [PATCH v3 0/4] crypto: add algif_akcipher user space API Stephan Mueller
@ 2016-01-26 11:12   ` Herbert Xu
  0 siblings, 0 replies; 7+ messages in thread
From: Herbert Xu @ 2016-01-26 11:12 UTC (permalink / raw)
  To: Stephan Mueller
  Cc: tadeusz.struk, marcel, dwmw2, linux-api, linux-crypto, linux-kernel

On Mon, Jan 25, 2016 at 10:34:53PM +0100, Stephan Mueller wrote:
> Am Freitag, 18. Dezember 2015, 00:49:57 schrieb Stephan Mueller:
> 
> Hi Herbert,
> 
> [...]
> 
> > Changes v3:
> >  * fix hack in alg_setkey and alg_setsockopt by avoding branches for
> >  setkey and setpubkey as pointed out by Marcel Holtmann
> >  * removal of patch for fixing SGL handling as this is already included
> 
> I have ported the code to 4.5. Shall I wait for comments from you for the 
> current code or shall I post v4 for the current cryptodev tree?

Until the objections in

http://www.gossamer-threads.com/lists/linux/kernel/2333253

are resolved I'm not taking any patches that export akcipher
via algif.

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

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

end of thread, other threads:[~2016-01-26 11:12 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-17 23:49 [PATCH v3 0/4] crypto: add algif_akcipher user space API Stephan Mueller
2015-12-17 23:50 ` [PATCH v3 1/4] crypto: AF_ALG -- add sign/verify API Stephan Mueller
2015-12-17 23:50 ` [PATCH v3 2/4] crypto: AF_ALG -- add setpubkey setsockopt call Stephan Mueller
2015-12-17 23:51 ` [PATCH v3 3/4] crypto: AF_ALG -- add asymmetric cipher interface Stephan Mueller
2015-12-17 23:51 ` [PATCH v3 4/4] crypto: algif_akcipher - enable compilation Stephan Mueller
2016-01-25 21:34 ` [PATCH v3 0/4] crypto: add algif_akcipher user space API Stephan Mueller
2016-01-26 11:12   ` Herbert Xu

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 NNTP newsgroup(s).