linux-crypto.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Tan Swee Heng" <thesweeheng@gmail.com>
To: "Linux Crypto" <linux-crypto@vger.kernel.org>
Subject: Re: [PATCH 2/3] [eSTREAM] stream: Wrapper for eSTREAM ciphers
Date: Tue, 13 Nov 2007 04:02:30 +0800	[thread overview]
Message-ID: <fd3e431c0711121202p2cf9890dna4a940c9072f275b@mail.gmail.com> (raw)
In-Reply-To: <fd3e431c0711121159p4eec500fw5a3caec76f07295d@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 509 bytes --]

Sorry I omitted the patch. Here it is.

On Nov 13, 2007 3:59 AM, Tan Swee Heng <thesweeheng@gmail.com> wrote:
> This patch implements a template that wraps around an eSTREAM cipher
> algorithm and its ivsize.
>
> For example, an eSTREAM cipher with the name CIPHERNAME and ivsize
> IVSIZE will be instantiated as "stream(CIPHERNAME,IVSIZE)" in
> cryptomgr. It uses blkcipher to walk over the memory it
> encrypts/decrypts. It has been modified to use the crypto_estream_*
> type instead of crypto_cipher_*.
>

[-- Attachment #2: patch2-stream.txt --]
[-- Type: text/plain, Size: 7773 bytes --]

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 4ad25fd..27a802f 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -211,6 +211,16 @@ config CRYPTO_CTR
 	  CTR: Counter mode
 	  This block cipher algorithm is required for IPSec.
 
+config CRYPTO_STREAM
+	tristate "STREAM: Wrapper for eSTREAM ciphers (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	select CRYPTO_BLKCIPHER
+	select CRYPTO_MANAGER
+	select CRYPTO_ESTREAM
+	help
+	  STREAM: Wrapper for eSTREAM ciphers
+	  This wrapper is used by stream ciphers submitted to eSTREAM.
+
 config CRYPTO_CRYPTD
 	tristate "Software async crypto daemon"
 	select CRYPTO_ABLKCIPHER
diff --git a/crypto/Makefile b/crypto/Makefile
index 14afa34..f95206b 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_CRYPTO_PCBC) += pcbc.o
 obj-$(CONFIG_CRYPTO_LRW) += lrw.o
 obj-$(CONFIG_CRYPTO_XTS) += xts.o
 obj-$(CONFIG_CRYPTO_CTR) += ctr.o
+obj-$(CONFIG_CRYPTO_STREAM) += stream.o
 obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o
 obj-$(CONFIG_CRYPTO_DES) += des_generic.o
 obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o
diff --git a/crypto/stream.c b/crypto/stream.c
new file mode 100644
index 0000000..0c2ffc7
--- /dev/null
+++ b/crypto/stream.c
@@ -0,0 +1,241 @@
+/*
+ * STREAM: Wrapper for eSTREAM ciphers
+ *
+ * Copyright (c) 2007 Tan Swee Heng <thesweeheng@gmail.com>
+ *
+ * Derived from
+ * - cbc.c: Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
+ * - ctr.c: Copyright (c) IBM Corp. 2007 Joy Latten <latten@us.ibm.com>
+ *
+ * Stream ciphers submitted to eSTREAM, the ECRYPT Stream Cipher Project,
+ * requires both key size and IV size in the key setup. This is different
+ * from standard block ciphers. This wrapper provides the necessary glue
+ * tp work with such eSTREAM 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/algapi.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+
+struct stream_instance_ctx {
+	struct crypto_spawn alg;
+	unsigned int ivsize;
+};
+
+struct crypto_stream_ctx {
+	struct crypto_estream *child;
+};
+
+static int crypto_stream_setkey(struct crypto_tfm *parent, const u8 *key,
+				unsigned int keysize)
+{
+	struct crypto_stream_ctx *ctx = crypto_tfm_ctx(parent);
+	struct crypto_estream *child = ctx->child;
+	struct stream_instance_ctx *ictx =
+		crypto_instance_ctx(crypto_tfm_alg_instance(parent));
+	int err;
+
+	crypto_estream_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+	crypto_estream_set_flags(child, crypto_tfm_get_flags(parent) &
+				 CRYPTO_TFM_REQ_MASK);
+	err = crypto_estream_setkey(child, key, keysize, ictx->ivsize);
+	crypto_tfm_set_flags(parent, crypto_estream_get_flags(child) &
+			     CRYPTO_TFM_RES_MASK);
+	return err;
+}
+
+static int crypto_stream_crypt_walk(struct blkcipher_walk *walk,
+				    struct crypto_estream *tfm)
+{
+	unsigned int bsize = crypto_estream_blocksize(tfm);
+	unsigned int nbytes = walk->nbytes;
+	u8 *src = walk->src.virt.addr;
+	u8 *dst = walk->dst.virt.addr;
+	u8 *iv = walk->iv;
+	u8 *ks;
+
+	crypto_estream_setiv(tfm, iv);
+	while (nbytes >= bsize) {
+		crypto_estream_encrypt_block(tfm, dst, src);
+		dst += bsize;
+		src += bsize;
+		nbytes -= bsize;
+	}
+	if (nbytes > 0) {
+		ks = kzalloc(bsize, GFP_KERNEL);
+		memcpy(ks, src, nbytes);
+		crypto_estream_encrypt_block(tfm, ks, ks);
+		memcpy(dst, ks, nbytes);
+		kfree(ks);
+	}
+
+	return 0;
+}
+
+static int crypto_stream_crypt(struct blkcipher_desc *desc,
+			       struct scatterlist *dst,
+			       struct scatterlist *src,
+			       unsigned int nbytes)
+{
+	struct blkcipher_walk walk;
+	struct crypto_blkcipher *tfm = desc->tfm;
+	struct crypto_stream_ctx *ctx = crypto_blkcipher_ctx(tfm);
+	struct crypto_estream *child = ctx->child;
+	int err;
+
+	blkcipher_walk_init(&walk, dst, src, nbytes);
+	err = blkcipher_walk_virt(desc, &walk);
+
+	while (walk.nbytes) {
+		nbytes = crypto_stream_crypt_walk(&walk, child);
+		err = blkcipher_walk_done(desc, &walk, nbytes);
+	}
+
+	return err;
+}
+
+
+static int crypto_stream_init_tfm(struct crypto_tfm *tfm)
+{
+	struct crypto_instance *inst = (void *)tfm->__crt_alg;
+	struct stream_instance_ctx *ictx = crypto_instance_ctx(inst);
+	struct crypto_stream_ctx *ctx = crypto_tfm_ctx(tfm);
+	struct crypto_estream *estream;
+
+	estream = crypto_spawn_estream(&ictx->alg);
+	if (IS_ERR(estream))
+		return PTR_ERR(estream);
+
+	ctx->child = estream;
+	return 0;
+}
+
+static void crypto_stream_exit_tfm(struct crypto_tfm *tfm)
+{
+	struct crypto_stream_ctx *ctx = crypto_tfm_ctx(tfm);
+	crypto_free_estream(ctx->child);
+}
+
+static struct crypto_instance *crypto_stream_alloc(struct rtattr **tb)
+{
+	struct crypto_instance *inst;
+	struct crypto_alg *alg;
+	struct stream_instance_ctx *ictx;
+	unsigned int ivsize;
+	int err;
+
+	err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER);
+	if (err)
+		return ERR_PTR(err);
+
+	alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_ESTREAM,
+			      CRYPTO_ALG_TYPE_MASK);
+	if (IS_ERR(alg))
+		return ERR_PTR(PTR_ERR(alg));
+
+	err = crypto_attr_u32(tb[2], &ivsize);
+	if (err)
+		goto out_put_alg;
+
+	err = -EINVAL;
+	if ((ivsize < alg->cra_estream.min_ivsize) ||
+		(ivsize > alg->cra_estream.max_ivsize))
+		goto out_put_alg;
+
+	inst = kzalloc(sizeof(*inst) + sizeof(*ictx), GFP_KERNEL);
+	err = -ENOMEM;
+	if (!inst)
+		goto out_put_alg;
+
+	err = -	ENAMETOOLONG;
+	if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME,
+		     "stream(%s,%u)", alg->cra_name,
+		     ivsize) >=  CRYPTO_MAX_ALG_NAME) {
+		goto err_free_inst;
+	}
+
+	if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
+		     "stream(%s,%u)", alg->cra_driver_name,
+		     ivsize) >=  CRYPTO_MAX_ALG_NAME) {
+		goto err_free_inst;
+	}
+
+	ictx = crypto_instance_ctx(inst);
+	ictx->ivsize = ivsize;
+
+	err = crypto_init_spawn(&ictx->alg, alg, inst,
+				CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
+	if (err)
+		goto err_free_inst;
+
+	err = 0;
+	inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER;
+	inst->alg.cra_priority = alg->cra_priority;
+	inst->alg.cra_blocksize = 1;
+	inst->alg.cra_alignmask = alg->cra_alignmask;
+	inst->alg.cra_type = &crypto_blkcipher_type;
+
+	inst->alg.cra_blkcipher.ivsize = ivsize;
+	inst->alg.cra_blkcipher.min_keysize = alg->cra_estream.min_keysize;
+	inst->alg.cra_blkcipher.max_keysize = alg->cra_estream.max_keysize;
+
+	inst->alg.cra_ctxsize = sizeof(struct crypto_stream_ctx);
+
+	inst->alg.cra_init = crypto_stream_init_tfm;
+	inst->alg.cra_exit = crypto_stream_exit_tfm;
+
+	inst->alg.cra_blkcipher.setkey = crypto_stream_setkey;
+	inst->alg.cra_blkcipher.encrypt = crypto_stream_crypt;
+	inst->alg.cra_blkcipher.decrypt = crypto_stream_crypt;
+
+err_free_inst:
+	if (err)
+		kfree(inst);
+
+out_put_alg:
+	crypto_mod_put(alg);
+
+	if(err)
+		inst = ERR_PTR(err);
+
+	return inst;
+}
+
+static void crypto_stream_free(struct crypto_instance *inst)
+{
+	crypto_drop_spawn(crypto_instance_ctx(inst));
+	kfree(inst);
+}
+
+static struct crypto_template crypto_stream_tmpl = {
+	.name = "stream",
+	.alloc = crypto_stream_alloc,
+	.free = crypto_stream_free,
+	.module = THIS_MODULE,
+};
+
+static int __init crypto_stream_module_init(void)
+{
+	return crypto_register_template(&crypto_stream_tmpl);
+}
+
+static void __exit crypto_stream_module_exit(void)
+{
+	crypto_unregister_template(&crypto_stream_tmpl);
+}
+
+module_init(crypto_stream_module_init);
+module_exit(crypto_stream_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Wrapper for eSTREAM ciphers");

  reply	other threads:[~2007-11-12 20:02 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-12 19:59 [PATCH 2/3] [eSTREAM] stream: Wrapper for eSTREAM ciphers Tan Swee Heng
2007-11-12 20:02 ` Tan Swee Heng [this message]
2007-11-13  1:43 ` Herbert Xu
2007-11-13 17:25   ` Tan Swee Heng
2007-11-14  3:07     ` Herbert Xu
2007-11-15  1:14       ` Tan Swee Heng
2007-11-15  1:18         ` Herbert Xu
2007-11-16 17:48           ` Tan Swee Heng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fd3e431c0711121202p2cf9890dna4a940c9072f275b@mail.gmail.com \
    --to=thesweeheng@gmail.com \
    --cc=linux-crypto@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).