crypto: algif_compression - User-space interface for compression
This patch adds af_alg plugin for compression algorithms of type scomp/acomp
registered to the kernel crypto layer.
The user needs to set operation (compression/decompression) as a control
message to sendmsg, identical to selecting the cipher operation type in case of
ciphers. Once a sendmsg call occurs, no further writes can be made to the
socket until all previous data has been processed and read. Therefore the
interface only supports one request at a time.
The interface is completely synchronous; all operations are carried out in
recvmsg and will complete prior to the system call returning.
The sendmsg and recvmsg interface supports directly reading/writing to
user-space without additional copying, i.e., the kernel crypto interface will
receive the user-space address as its input/output SG list. The scomp interface
or crypto drivers may copy the data as required.
Signed-off-by: Abed Kamaluddin <akam...@cavium.com>
Signed-off-by: Mahipal Challa <mahipal.cha...@cavium.com>
---
crypto/Kconfig | 11 ++
crypto/Makefile | 1 +
crypto/algif_compression.c | 272
include/uapi/linux/if_alg.h | 2 +
4 files changed, 286 insertions(+)
diff --git a/crypto/Kconfig b/crypto/Kconfig
index f37e9cc..13b03ba 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -1741,6 +1741,17 @@ config CRYPTO_USER_API_AEAD
This option enables the user-spaces interface for AEAD
cipher algorithms.
+config CRYPTO_USER_API_COMPRESSION
+ tristate "User-space interface for compression algorithms"
+ depends on NET
+ select CRYPTO_ACOMP
+ select CRYPTO_USER_API
+ help
+ This option enables the user-space interface for compression
+ algorithms. Enable this option for access to compression algorithms
+ of type scomp/acomp exported by the kernel crypto layer through
+ AF_ALG interface.
+
config CRYPTO_HASH_INFO
bool
diff --git a/crypto/Makefile b/crypto/Makefile
index 8a44057..1469e06 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -134,6 +134,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_COMPRESSION) += algif_compression.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
diff --git a/crypto/algif_compression.c b/crypto/algif_compression.c
new file mode 100644
index 000..0ba6d1e
--- /dev/null
+++ b/crypto/algif_compression.c
@@ -0,0 +1,272 @@
+/*
+ * algif_compression: User-space interface for COMPRESSION algorithms
+ *
+ * This file provides user-space API support for compression algorithms
+ * registered through the kernel crypto layer.
+ *
+ * Copyright (C) 2017 Cavium, Inc.
+ *
+ * Original Authors: Abed Kamaluddin <akamalud...@cavium.com>
+ *
+ * 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
+
+/* scomp scratch is currently 128KB */
+#define COMP_BUFFER_SIZE 65535
+
+struct comp_ctx {
+ struct af_alg_sgl tsgl;
+ struct af_alg_sgl rsgl;
+ struct af_alg_completion completion;
+ unsigned int clen;
+ unsigned int slen;
+ unsigned int dlen;
+ bool comp;
+ bool used;
+ struct acomp_req *acomp_req;
+};
+
+struct comp_tfm {
+ struct crypto_acomp *acomp;
+};
+
+static int comp_sendmsg(struct socket *sock, struct msghdr *msg,
+ size_t ignored)
+{
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ struct comp_ctx *ctx = ask->private;
+ struct af_alg_control con = {};
+ int limit = COMP_BUFFER_SIZE;
+ int len;
+ int err = -EINVAL;
+
+ if (msg->msg_controllen) {
+ err = af_alg_cmsg_send(msg, );
+ if (err)
+ return err;
+
+ switch (con.op) {
+ case ALG_OP_COMPRESS:
+ ctx->comp = 1;
+ break;
+
+ case ALG_OP_DECOMPRESS:
+ ctx->comp = 0;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ }
+
+ lock_sock(sk);
+
+ /* One request at a time supported, data submitted for comp/decomp will
+* be processed at subsequent recvmsg
+*/
+ if (ctx->used) {
+