From: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
To: linux-kernel@vger.kernel.org
Cc: Fruhwirth Clemens <clemens@endorphin.org>,
Herbert Xu <herbert@gondor.apana.org.au>,
cryptoapi@lists.logix.cz, James Morris <jmorris@redhat.com>,
David Miller <davem@davemloft.net>, Andrew Morton <akpm@osdl.org>,
Evgeniy Polyakov <johnpol@2ka.mipt.ru>
Subject: [4/many] acrypto: async_provider.c
Date: Mon, 7 Mar 2005 23:37:33 +0300 [thread overview]
Message-ID: <11102278533364@2ka.mipt.ru> (raw)
In-Reply-To: <11102278533380@2ka.mipt.ru>
--- /tmp/empty/async_provider.c 1970-01-01 03:00:00.000000000 +0300
+++ ./acrypto/async_provider.c 2005-03-07 21:19:10.000000000 +0300
@@ -0,0 +1,322 @@
+/*
+ * async_provider.c
+ *
+ * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
+ *
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/err.h>
+#include <linux/crypto.h>
+#include <linux/mm.h>
+#include <linux/blkdev.h>
+
+#include "acrypto.h"
+#include "crypto_stat.h"
+#include "crypto_def.h"
+#include "crypto_route.h"
+#include "crypto_user.h"
+
+static unsigned int trnum = 1;
+module_param(trnum, uint, 0);
+
+static void prov_data_ready(struct crypto_device *);
+
+static struct crypto_capability prov_caps[] = {
+ {CRYPTO_OP_ENCRYPT, CRYPTO_TYPE_AES_128, CRYPTO_MODE_ECB, 100},
+ {CRYPTO_OP_DECRYPT, CRYPTO_TYPE_AES_128, CRYPTO_MODE_ECB, 100},
+
+ {CRYPTO_OP_ENCRYPT, CRYPTO_TYPE_AES_128, CRYPTO_MODE_CBC, 100},
+ {CRYPTO_OP_DECRYPT, CRYPTO_TYPE_AES_128, CRYPTO_MODE_CBC, 100},
+};
+static int prov_cap_number = sizeof(prov_caps)/sizeof(prov_caps[0]);
+
+static int need_exit;
+static char async_algo[] = "aes";
+static char async_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static struct crypto_device pdev = {
+ .name = "async_provider",
+ .data_ready = prov_data_ready,
+ .cap = &prov_caps[0],
+};
+
+static struct async_provider
+{
+ int num;
+ struct crypto_tfm *tfm;
+ wait_queue_head_t async_wait_queue;
+ struct completion thread_exited;
+ struct crypto_device pdev;
+} *aprov;
+
+static void prov_data_ready(struct crypto_device *dev)
+{
+ struct async_provider *p;
+
+ p = (struct async_provider *)dev->priv;
+
+ if (p)
+ wake_up_interruptible(&p->async_wait_queue);
+}
+
+static int async_thread(void *data)
+{
+ struct async_provider *p = (struct async_provider *)data;
+ struct crypto_device *dev = &p->pdev;
+ struct crypto_session *s, *n;
+ int i, err, keylen, ivlen;
+ u8 *key, *iv;
+ int zero_pnum_cnt = 0;
+
+ daemonize("%s", dev->name);
+ allow_signal(SIGTERM);
+
+ while (!need_exit) {
+ int num, pnum;
+
+ if (need_exit)
+ break;
+
+ num = pnum = 0;
+ list_for_each_entry_safe(s, n, &dev->session_list, dev_queue_entry) {
+ num++;
+
+ if (session_completed(s))
+ continue;
+
+ pnum++;
+
+ start_process_session(s);
+
+ if (s->data.sg_src_num != s->data.sg_dst_num) {
+ dprintk("Broken session: sg_src_num [%d] != sg_dst_num [%d].\n",
+ s->data.sg_src_num, s->data.sg_dst_num);
+ broke_session(s);
+ goto out;
+ }
+
+ /*
+ * Simple case - key is small(it's size is less than PAGE_SIZE).
+ * Assymetric crypto will require proper key sg handling.
+ */
+ key = kmap(s->data.sg_key[0].page) + s->data.sg_key[0].offset;
+ keylen = s->data.sg_key[0].length;
+
+ err = crypto_cipher_setkey(p->tfm, key, keylen);
+ if (err) {
+ dprintk(KERN_ERR "Failed to set key [keylen=%d]: err=%d.\n", keylen, err);
+ broke_session(s);
+ goto out;
+ }
+
+ if (s->ci.mode != CRYPTO_MODE_ECB) {
+ if (!s->data.sg_iv || !s->data.sg_iv_num) {
+ dprintk("Crypto mode %d requires IV.\n", s->ci.mode);
+ broke_session(s);
+ goto out;
+ }
+
+ iv = kmap(s->data.sg_iv[0].page) + s->data.sg_iv[0].offset;
+ ivlen = s->data.sg_iv[0].length;
+
+ if (!iv || !ivlen) {
+ dprintk("Crypto mode %d requires IV, whic is broken: iv=%p, ivlen=%d.\n",
+ s->ci.mode, iv, ivlen);
+ broke_session(s);
+ goto out;
+ }
+
+ crypto_cipher_set_iv(p->tfm, iv, ivlen);
+ } else {
+ iv = NULL;
+ ivlen = 0;
+ }
+
+ for (i=0; i<s->data.sg_src_num; ++i) {
+ u8 *dst, *src;
+ int len;
+
+ dst = kmap_atomic(s->data.sg_dst[i].page, KM_USER0) + s->data.sg_dst[i].offset;
+ src = kmap_atomic(s->data.sg_src[i].page, KM_USER1) + s->data.sg_src[i].offset;
+ len = s->data.sg_src[i].length;
+
+ if (s->ci.operation == CRYPTO_OP_ENCRYPT)
+ err = crypto_cipher_encrypt(p->tfm, &s->data.sg_dst[i], &s->data.sg_src[i], s->data.sg_src[i].length);
+ else
+ err = crypto_cipher_decrypt(p->tfm, &s->data.sg_dst[i], &s->data.sg_src[i], s->data.sg_src[i].length);
+
+ kunmap_atomic(src, KM_USER1);
+ kunmap_atomic(dst, KM_USER0);
+
+ s->data.sg_dst[i].length = s->data.sg_src[i].length;
+ s->data.sg_dst[i].offset = s->data.sg_src[i].offset;
+
+ if (err < 0) {
+ broke_session(s);
+ printk("operation=%02x, size=%u, err=%d.\n", s->ci.operation, s->data.sg_src[i].length, err);
+ }
+ }
+
+ kunmap(s->data.sg_key[0].page);
+
+ if (iv)
+ kunmap(s->data.sg_iv[0].page);
+
+ dprintk("%lu: Completing session %llu [%llu] in %s.\n",
+ jiffies, s->ci.id, s->ci.dev_id, pdev.name);
+out:
+ crypto_stat_complete_inc(s);
+ crypto_session_dequeue_route(s);
+ complete_session(s);
+ stop_process_session(s);
+ }
+
+ if (!pnum)
+ zero_pnum_cnt++;
+ else
+ zero_pnum_cnt = 0;
+
+ if (unlikely(zero_pnum_cnt == 1000)) {
+ zero_pnum_cnt = 0;
+ interruptible_sleep_on_timeout(&p->async_wait_queue, 10);
+ }
+ }
+
+ complete_and_exit(&p->thread_exited, 0);
+}
+
+static int prov_init_one(struct async_provider *p)
+{
+ int pid, err;
+
+ init_waitqueue_head(&p->async_wait_queue);
+
+ p->tfm = crypto_alloc_tfm(async_algo, CRYPTO_TFM_MODE_CBC);
+ if (!p->tfm) {
+ dprintk(KERN_ERR "Failed to allocate %d's %s tfm.\n", p->num, async_algo);
+ return -EINVAL;
+ }
+
+ err = crypto_cipher_setkey(p->tfm, async_key, sizeof(async_key));
+ if (err) {
+ dprintk("Failed to set key [keylen=%d]: err=%d.\n",
+ sizeof(async_key), err);
+ goto err_out_free_tfm;
+ }
+
+ init_completion(&p->thread_exited);
+ pid = kernel_thread(async_thread, p, CLONE_FS | CLONE_FILES);
+ if (IS_ERR((void *)pid)) {
+ err = -EINVAL;
+ dprintk(KERN_ERR "Failed to create kernel load balancing thread.\n");
+ goto err_out_free_tfm;
+ }
+
+ memcpy(&p->pdev, &pdev, sizeof(pdev));
+ snprintf(p->pdev.name, sizeof(p->pdev.name), "async_provider%d", p->num);
+
+ p->pdev.cap_number = prov_cap_number;
+ p->pdev.priv = p;
+
+ err = crypto_device_add(&p->pdev);
+ if (err)
+ goto err_out_remove_thread;
+
+ return 0;
+
+err_out_remove_thread:
+ need_exit = 1;
+ wake_up(&p->async_wait_queue);
+ wait_for_completion(&p->thread_exited);
+err_out_free_tfm:
+ crypto_free_tfm(p->tfm);
+
+ return err;
+}
+
+static void prov_fini_one(struct async_provider *p)
+{
+ crypto_device_remove(&p->pdev);
+ need_exit = 1;
+ wake_up(&p->async_wait_queue);
+ wait_for_completion(&p->thread_exited);
+
+ crypto_free_tfm(p->tfm);
+}
+
+int prov_init(void)
+{
+ int err, i;
+
+ aprov = kmalloc(trnum * sizeof(struct async_provider), GFP_KERNEL);
+ if (!aprov) {
+ dprintk(KERN_ERR "Failed to allocate %d async_provider pointers.\n", trnum);
+ return -ENOMEM;
+ }
+
+ memset(aprov, 0, trnum * sizeof(struct async_provider));
+
+ for (i=0; i<trnum; ++i) {
+ aprov[i].num = i;
+
+ err = prov_init_one(&aprov[i]);
+ if (err)
+ goto err_out_fini_one;
+ }
+
+ dprintk(KERN_INFO "Test crypto provider module %s is loaded for %d processors.\n",
+ pdev.name, trnum);
+
+ return 0;
+
+err_out_fini_one:
+ i--;
+ while (i >= 0)
+ prov_fini_one(&aprov[i]);
+
+ kfree(aprov);
+
+ return err;
+}
+
+void prov_fini(void)
+{
+ int i;
+
+ for (i=0; i<trnum; ++i)
+ prov_fini_one(&aprov[i]);
+
+ kfree(aprov);
+
+ dprintk(KERN_INFO "Test crypto provider module %s is unloaded.\n", pdev.name);
+}
+
+module_init(prov_init);
+module_exit(prov_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
+MODULE_DESCRIPTION("Test crypto module provider.");
next prev parent reply other threads:[~2005-03-07 20:52 UTC|newest]
Thread overview: 84+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-03-07 20:37 [0/many] Acrypto - asynchronous crypto layer for linux kernel 2.6 Evgeniy Polyakov
2005-03-07 20:37 ` [??/many] list of files to be sent in a next couple of e-mails with small description Evgeniy Polyakov
2005-03-07 20:37 ` [??/many] acrypto benchmarks vs cryptoloop vs dm_crypt Evgeniy Polyakov
2005-03-07 20:37 ` [??/many] iok.c - simple example of the userspace acrypto usage [IOCTL] Evgeniy Polyakov
2005-03-07 20:37 ` [??/many] ucon_crypto.c - simple example of the userspace acrypto usage [DIRECT ACCESS] Evgeniy Polyakov
2005-03-07 20:37 ` [1/many] acrypto: Kconfig Evgeniy Polyakov
2005-03-07 20:37 ` [2/many] acrypto: Makefile Evgeniy Polyakov
2005-03-07 20:37 ` [3/many] acrypto: acrypto.h Evgeniy Polyakov
2005-03-07 20:37 ` Evgeniy Polyakov [this message]
2005-03-07 20:37 ` [5/many] acrypto: crypto_conn.c Evgeniy Polyakov
2005-03-07 20:37 ` [6/many] acrypto: crypto_conn.h Evgeniy Polyakov
2005-03-07 20:37 ` [7/many] acrypto: crypto_def.h Evgeniy Polyakov
2005-03-07 20:37 ` [8/many] acrypto: crypto_dev.c Evgeniy Polyakov
2005-03-07 20:37 ` [9/many] acrypto: crypto_lb.c Evgeniy Polyakov
2005-03-07 20:37 ` [10/many] acrypto: crypto_lb.h Evgeniy Polyakov
2005-03-07 20:37 ` [11/many] acrypto: crypto_main.c Evgeniy Polyakov
2005-03-07 20:37 ` [12/many] acrypto: crypto_route.h Evgeniy Polyakov
2005-03-07 20:37 ` [13/many] acrypto: crypto_stat.c Evgeniy Polyakov
2005-03-07 20:37 ` [14/many] acrypto: crypto_stat.h Evgeniy Polyakov
2005-03-07 20:37 ` [15/many] acrypto: crypto_user.c Evgeniy Polyakov
2005-03-07 20:37 ` [16/many] acrypto: crypto_user.h Evgeniy Polyakov
2005-03-07 20:37 ` [17/many] acrypto: crypto_user_direct.c Evgeniy Polyakov
2005-03-07 20:37 ` [18/many] acrypto: crypto_user_direct.h Evgeniy Polyakov
2005-03-07 20:37 ` [19/many] acrypto: crypto_user_ioctl.c Evgeniy Polyakov
2005-03-07 20:37 ` [20/many] acrypto: crypto_user_ioctl.h Evgeniy Polyakov
2005-03-07 20:37 ` [21/many] acrypto: simple_lb.c Evgeniy Polyakov
2005-03-07 20:37 ` [22/many] arch: alpha config Evgeniy Polyakov
2005-03-07 20:37 ` [23/many] arch: arm config Evgeniy Polyakov
2005-03-07 20:37 ` [24/many] arch: arm26 config Evgeniy Polyakov
2005-03-07 20:37 ` [25/many] arch: cris config Evgeniy Polyakov
2005-03-07 20:37 ` [26/many] arch: frv config Evgeniy Polyakov
2005-03-07 20:37 ` [27/many] arch: h8300 config Evgeniy Polyakov
2005-03-07 20:37 ` [28/many] arch: i386 config Evgeniy Polyakov
2005-03-07 20:37 ` [29/many] arch: ia64 config Evgeniy Polyakov
2005-03-07 20:37 ` [30/many] arch: m32r config Evgeniy Polyakov
2005-03-07 20:37 ` [31/many] arch: m68k config Evgeniy Polyakov
2005-03-07 20:37 ` [32/many] arch: m68knommu config Evgeniy Polyakov
2005-03-07 20:37 ` [33/many] arch: mips config Evgeniy Polyakov
2005-03-07 20:37 ` [34/many] arch: parisc config Evgeniy Polyakov
2005-03-07 20:37 ` [35/many] arch: ppc config Evgeniy Polyakov
2005-03-07 20:37 ` [36/many] arch: ppc64 config Evgeniy Polyakov
2005-03-07 20:37 ` [37/many] arch: s390 config Evgeniy Polyakov
2005-03-07 20:37 ` [38/many] arch: sh config Evgeniy Polyakov
2005-03-07 20:37 ` [39/many] arch: sh64 config Evgeniy Polyakov
2005-03-07 20:37 ` [40/many] arch: sparc config Evgeniy Polyakov
2005-03-07 20:37 ` [41/many] arch: sparc64 config Evgeniy Polyakov
2005-03-07 20:37 ` [42/many] arch: um config Evgeniy Polyakov
2005-03-07 20:37 ` [43/many] arch: v850 config Evgeniy Polyakov
2005-03-07 20:37 ` [44/many] arch: x86_64 config Evgeniy Polyakov
2005-03-07 20:37 ` [1/5] bd: Asynchronous block device Evgeniy Polyakov
2005-03-07 20:37 ` [2/5] bd: userspace utility to control asynchronous " Evgeniy Polyakov
2005-03-07 20:37 ` [4/5] bd: script for binding file and acrypto filters Evgeniy Polyakov
2005-03-07 20:37 ` [5/5] bd: script for unbinding any filters Evgeniy Polyakov
2005-03-08 15:16 ` [1/5] bd: Asynchronous block device Evgeniy Polyakov
2005-03-15 17:27 ` [16/many] acrypto: crypto_user.h Randy.Dunlap
2005-03-15 16:24 ` [11/many] acrypto: crypto_main.c Randy.Dunlap
2005-03-16 4:58 ` Evgeniy Polyakov
2005-03-08 18:02 ` [UPDATE PATCH 9/many] acrypto: crypto_lb.c Nishanth Aravamudan
2005-03-08 18:33 ` Evgeniy Polyakov
2005-03-10 19:18 ` [9/many] " Randy.Dunlap
2005-03-07 22:40 ` [8/many] acrypto: crypto_dev.c Nish Aravamudan
2005-03-07 23:14 ` Evgeniy Polyakov
2005-03-07 22:51 ` Nish Aravamudan
2005-03-07 23:27 ` Evgeniy Polyakov
2005-03-08 1:46 ` [UPDATE PATCH 8/many] " Nishanth Aravamudan
2005-03-08 9:40 ` Evgeniy Polyakov
2005-03-07 23:37 ` [8/many] " Randy.Dunlap
2005-03-08 0:05 ` Evgeniy Polyakov
2005-03-07 23:50 ` [3/many] acrypto: acrypto.h Randy.Dunlap
2005-03-08 0:34 ` Evgeniy Polyakov
2005-03-07 23:33 ` [1/many] acrypto: Kconfig Randy.Dunlap
2005-03-08 0:03 ` Evgeniy Polyakov
2005-03-07 21:13 ` [0/many] Acrypto - asynchronous crypto layer for linux kernel 2.6 Fruhwirth Clemens
2005-03-07 21:49 ` Evgeniy Polyakov
2005-03-08 13:24 ` Joshua Jackson
2005-03-10 10:27 ` Evgeniy Polyakov
2005-03-08 5:08 ` Kyle Moffett
2005-03-08 9:37 ` Evgeniy Polyakov
2005-03-08 12:22 ` Kyle Moffett
2005-03-08 13:07 ` Evgeniy Polyakov
2005-03-08 14:46 ` Kyle Moffett
2005-03-08 15:24 ` Evgeniy Polyakov
2005-03-10 12:42 ` Christophe Saout
2005-03-08 10:30 ` Herbert Xu
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=11102278533364@2ka.mipt.ru \
--to=johnpol@2ka.mipt.ru \
--cc=akpm@osdl.org \
--cc=clemens@endorphin.org \
--cc=cryptoapi@lists.logix.cz \
--cc=davem@davemloft.net \
--cc=herbert@gondor.apana.org.au \
--cc=jmorris@redhat.com \
--cc=linux-kernel@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.