/* * consumer.c * * Copyright (c) 2004 Evgeniy Polyakov * * * 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 #include #include #include #include #include #include #include #include #include #include #include "acrypto.h" #include "crypto_def.h" #include "via-padlock/padlock.h" #define KEY_LENGTH 16 static char ckey[KEY_LENGTH]; static int key_length = sizeof(ckey); static void ctest_callback(struct crypto_session_initializer *ci, struct crypto_data *data); static struct crypto_session_initializer ci = { .operation = CRYPTO_OP_ENCRYPT, .type = CRYPTO_TYPE_AES_128, .mode = CRYPTO_MODE_ECB, .priority = 4, .callback = ctest_callback, }; static struct crypto_data cdata; #define CSESSION_MAX 1000 static struct crypto_session *s; static int watermark; static struct completion callback_completed; static void ctest_callback(struct crypto_session_initializer *ci, struct crypto_data *data) { int i, off, size, ssize; struct scatterlist *sg; unsigned char *ptr; watermark--; dprintk("%s: session %llu [%llu]\n", __func__, ci->id, ci->dev_id); dprintk("src=%s, len=%d.\n", (char *)page_address(data->sg_src.page), data->sg_src.length); sg = &data->sg_key; ptr = (unsigned char *)page_address(sg->page); off = sg->offset; size = sg->length; printk("key[%d]=", size); for (i=0; isg_src; ptr = (unsigned char *)page_address(sg->page); off = sg->offset; ssize = size = sg->length; printk("src[%d]=", size); for (i=0; isg_dst; ptr = (unsigned char *)page_address(sg->page); off = sg->offset; size = sg->length; if (size == 0) { dprintk("size=5, setting to %d.\n", ssize); size = ssize; } printk("dst[%d]=", size); for (i=0; i PAGE_SIZE) size = PAGE_SIZE; ptr = (u8 *)page_address(cdata.sg_src.page); memcpy(ptr, data, size); cdata.sg_src.length = size; ci.operation = op; s = crypto_session_alloc(&ci, &cdata); if (s) watermark++; else dprintk("allocation failed.\n"); return (s)?0:-EINVAL; } static int alloc_sg(struct scatterlist *sg, void *data, int size) { sg->offset = 0; sg->page = alloc_pages(GFP_KERNEL, get_order(size)); if (!sg->page) { printk(KERN_ERR "Failed to allocate page.\n"); return -ENOMEM; } if (data) memcpy(sg->page, data, size); sg->length = size; return 0; } int consumer_init(void) { int err; char str[] = "test message qwerty asdzxc\n"; int size; init_completion(&callback_completed); cdata.sg_src_num = 1; err = alloc_sg(&cdata.sg_src, NULL, PAGE_SIZE); if (err) goto err_out_return; err = alloc_sg(&cdata.sg_dst, NULL, PAGE_SIZE); if (err) goto err_out_src; err = alloc_sg(&cdata.sg_key, ckey, key_length); if (err) goto err_out_dst; err = alloc_sg(&cdata.sg_iv, NULL, PAGE_SIZE); if (err) goto err_out_key; cdata.priv_size = sizeof(struct aes_ctx); size = 32; err = ctimer_func(str, size, CRYPTO_OP_ENCRYPT); if (err) goto err_out_iv; wait_for_completion(&callback_completed); init_completion(&callback_completed); err = ctimer_func(page_address(cdata.sg_dst.page), cdata.sg_dst.length, CRYPTO_OP_DECRYPT); if (err) goto err_out_iv; wait_for_completion(&callback_completed); err_out_iv: __free_pages(cdata.sg_iv.page, get_order(1)); err_out_key: __free_pages(cdata.sg_key.page, get_order(cdata.sg_key.length)); err_out_dst: __free_pages(cdata.sg_dst.page, get_order(1)); err_out_src: __free_pages(cdata.sg_src.page, get_order(1)); err_out_return: return -ENODEV; } void consumer_fini(void) { while(watermark) { set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ); printk(KERN_INFO "Waiting for sessions to be freed: watermark=%d.\n", watermark); } if (!cdata.sg_key.length) printk("BUG: key length is 0 in %s.\n", __func__); __free_pages(cdata.sg_key.page, get_order(key_length)); __free_pages(cdata.sg_dst.page, get_order(1)); __free_pages(cdata.sg_src.page, get_order(1)); printk(KERN_INFO "Test crypto module consumer is unloaded.\n"); } module_init(consumer_init); module_exit(consumer_fini); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Evgeniy Polyakov "); MODULE_DESCRIPTION("Test crypto module consumer.");