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");
next prev parent 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).