On Thu, 2005-03-24 at 14:59 +0300, Evgeniy Polyakov wrote: > For example here is patch to enable acrypto support for hw_random.c > It is very simple and support only upto 4 bytes request, of course it > is not interested for anyone, but it is only 2-minutes example: Full port. --- ./drivers/char/hw_random.c.orig 2005-03-24 13:36:05.000000000 +0300 +++ ./drivers/char/hw_random.c 2005-03-25 08:46:03.841601032 +0300 @@ -34,6 +34,10 @@ #include <linux/smp_lock.h> #include <linux/mm.h> #include <linux/delay.h> +#include <linux/acrypto.h> +#include <linux/crypto_def.h> +#include <linux/crypto_stat.h> +#include <linux/highmem.h> #ifdef __i386__ #include <asm/msr.h> @@ -73,6 +77,8 @@ #endif #define RNG_MISCDEV_MINOR 183 /* official */ + +static DEFINE_SPINLOCK(rng_lock); static int rng_dev_open (struct inode *inode, struct file *filp); static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size, @@ -482,7 +488,6 @@ static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size, loff_t * offp) { - static DEFINE_SPINLOCK(rng_lock); unsigned int have_data; u32 data = 0; ssize_t ret = 0; @@ -526,7 +531,163 @@ return ret; } +#ifdef CONFIG_ACRYPTO +static struct crypto_device *hwr_cdev; +static struct crypto_capability hwr_caps[] = { + {CRYPTO_OP_RNG, 0, 0, 100}, +}; +static int hwr_pid, hwr_need_exit; +static struct completion hwr_thread_exited; +static DECLARE_WAIT_QUEUE_HEAD(hwr_wait); + + +static void hwr_data_ready(struct crypto_device *dev) +{ + wake_up(&hwr_wait); +} + +static int hwr_process(void *data) +{ + struct crypto_device *dev = data; + struct crypto_session *s, *n; + u32 rng_data = 0; + unsigned int have_data, size; + int i; + u8 *ptr; + + daemonize("%s", dev->name); + allow_signal(SIGTERM); + + while (!hwr_need_exit) { + interruptible_sleep_on_timeout(&hwr_wait, 10); + + list_for_each_entry_safe(s, n, &dev->session_list, dev_queue_entry) { + if (!session_completed(s) && !session_is_processed(s)) { + start_process_session(s); + + if (s->data.sg_src_num != s->data.sg_dst_num) { + dprintk("%s: session %llu [%llu]: different src/dst sg numbers: %d %d.\n", + dev->name, s->ci.id, s->ci.dev_id, + s->data.sg_src_num, s->data.sg_dst_num); + broke_session(s); + goto out_complete_session; + } + + for (i=0; i<s->data.sg_src_num; ++i) { + if (s->data.sg_dst[i].length != s->data.sg_src[i].length) { + dprintk("%s: session %llu [%llu]: sg %d different src/dst lengths: %u %u.\n", + dev->name, s->ci.id, s->ci.dev_id, i, + s->data.sg_src[i].length, s->data.sg_dst[i].length); + if (s->data.sg_dst[i].length) + s->data.sg_src[i].length = s->data.sg_dst[i].length; + else + s->data.sg_dst[i].length = s->data.sg_src[i].length; + + } + + size = s->data.sg_dst[i].length; + + while (size) { + spin_lock(&rng_lock); + have_data = 0; + if (rng_ops->data_present()) { + rng_data = rng_ops->data_read(); + have_data = rng_ops->n_bytes; + } + spin_unlock (&rng_lock); + + ptr = kmap_atomic(s->data.sg_dst[i].page, KM_USER0) + s->data.sg_dst[i].offset + + s->data.sg_dst[i].length - size; + + while (size && have_data) { + *ptr = rng_data & 0xff; + size--; + have_data--; + rng_data >>= 8; + } + kunmap_atomic(ptr, KM_USER0); + + if (size) + msleep_interruptible(1); + } + } + + crypto_stat_complete_inc(s); + +out_complete_session: + crypto_session_dequeue_route(s); + complete_session(s); + stop_process_session(s); + } + } + } + + complete_and_exit(&hwr_thread_exited, 0); +} + +static int hwr_acrypto_init(struct rng_operations *ops) +{ + int err; + + hwr_cdev = kmalloc(sizeof(*hwr_cdev), GFP_KERNEL); + if (!hwr_cdev) { + printk(KERN_ERR "Failed to allocate new crypto_device structure.\n"); + return -ENOMEM; + } + + memset(hwr_cdev, 0, sizeof(*hwr_cdev)); + + hwr_cdev->cap = hwr_caps; + hwr_cdev->cap_number = sizeof(hwr_caps)/sizeof(hwr_caps[0]); + hwr_cdev->priv = ops; + hwr_cdev->data_ready = &hwr_data_ready; + snprintf(hwr_cdev->name, sizeof(hwr_cdev->name), "%s", "hwr"); + + init_completion(&hwr_thread_exited); + hwr_pid = kernel_thread(hwr_process, hwr_cdev, CLONE_FS | CLONE_FILES); + if (hwr_pid < 0) { + err = hwr_pid; + goto err_out_free_cdev; + } + err = crypto_device_add(hwr_cdev); + if (err) + goto err_out_remove_thread; + + printk(KERN_INFO "%s acrypto support is turned on.\n", hwr_cdev->name); + +err_out_remove_thread: + hwr_need_exit = 1; + kill_proc(hwr_pid, SIGTERM, 0); + wait_for_completion(&hwr_thread_exited); +err_out_free_cdev: + kfree(hwr_cdev); + hwr_cdev = NULL; + return err; +} + +static void hwr_acrypto_fini(void) +{ + crypto_device_remove(hwr_cdev); + printk(KERN_INFO "%s acrypto support is turned off.\n", hwr_cdev->name); + + hwr_need_exit = 1; + kill_proc(hwr_pid, SIGTERM, 0); + wait_for_completion(&hwr_thread_exited); + + kfree(hwr_cdev); + hwr_cdev = NULL; +} +#else +static int hwr_acrypto_init(struct rng_operations *ops) +{ + return 0; +} + +static void hwr_acrypto_fini(void) +{ +} +#endif /* * rng_init_one - look for and attempt to init a single RNG @@ -549,9 +710,15 @@ goto err_out_cleanup_hw; } + rc = hwr_acrypto_init(rng_ops); + if (rc) + goto err_out_misc_unregister; + DPRINTK ("EXIT, returning 0\n"); return 0; +err_out_misc_unregister: + misc_deregister(&rng_miscdev); err_out_cleanup_hw: rng_ops->cleanup(); err_out: @@ -617,6 +784,8 @@ { DPRINTK ("ENTER\n"); + hwr_acrypto_fini(); + misc_deregister (&rng_miscdev); if (rng_ops->cleanup) -- Evgeniy Polyakov Crash is better than data corruption -- Arthur Grabowski
Attachment:
signature.asc
Description: This is a digitally signed message part
- References:
- [PATCH] API for true Random Number Generators to add entropy (2.6.11)
- From: David McCullough <[email protected]>
- Re: [PATCH] API for true Random Number Generators to add entropy (2.6.11)
- From: Evgeniy Polyakov <[email protected]>
- [PATCH] API for true Random Number Generators to add entropy (2.6.11)
- Prev by Date: Re: [PATCH scsi-misc-2.6 08/08] scsi: fix hot unplug sequence
- Next by Date: Re: [PATCH] API for true Random Number Generators to add entropy (2.6.11)
- Previous by thread: Re: [PATCH] API for true Random Number Generators to add entropy (2.6.11)
- Next by thread: Possible bug: ASYNC IO with RT Signals in threaded application doesnt work
- Index(es):