~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/char/i810_rng.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2 
  3         Hardware driver for Intel i810 Random Number Generator (RNG)
  4         Copyright 2000 Jeff Garzik <jgarzik@mandrakesoft.com>
  5         Copyright 2000 Philipp Rumpf <prumpf@tux.org>
  6 
  7         Driver Web site:  http://gtf.org/garzik/drivers/i810_rng/
  8 
  9 
 10 
 11         Based on:
 12         Intel 82802AB/82802AC Firmware Hub (FWH) Datasheet
 13                 May 1999 Order Number: 290658-002 R
 14 
 15         Intel 82802 Firmware Hub: Random Number Generator
 16         Programmer's Reference Manual
 17                 December 1999 Order Number: 298029-001 R
 18 
 19         Intel 82802 Firmware HUB Random Number Generator Driver
 20         Copyright (c) 2000 Matt Sottek <msottek@quiknet.com>
 21 
 22         Special thanks to Matt Sottek.  I did the "guts", he
 23         did the "brains" and all the testing.  (Anybody wanna send
 24         me an i810 or i820?)
 25 
 26         ----------------------------------------------------------
 27 
 28         This software may be used and distributed according to the terms
 29         of the GNU Public License, incorporated herein by reference.
 30 
 31         ----------------------------------------------------------
 32 
 33         From the firmware hub datasheet:
 34 
 35         The Firmware Hub integrates a Random Number Generator (RNG)
 36         using thermal noise generated from inherently random quantum
 37         mechanical properties of silicon. When not generating new random
 38         bits the RNG circuitry will enter a low power state. Intel will
 39         provide a binary software driver to give third party software
 40         access to our RNG for use as a security feature. At this time,
 41         the RNG is only to be used with a system in an OS-present state.
 42 
 43         ----------------------------------------------------------
 44 
 45         Theory of operation:
 46 
 47         This driver has TWO modes of operation:
 48 
 49         Mode 1
 50         ------
 51         Character driver.  Using the standard open()
 52         and read() system calls, you can read random data from
 53         the i810 RNG device.  This data is NOT CHECKED by any
 54         fitness tests, and could potentially be bogus (if the
 55         hardware is faulty or has been tampered with).
 56 
 57         /dev/intel_rng is char device major 10, minor 183.
 58 
 59 
 60         Mode 2
 61         ------
 62         Injection of entropy into the kernel entropy pool via a
 63         timer function.
 64 
 65         A timer is run at rng_timer_len intervals, reading 8 bits
 66         of data from the RNG.  If the RNG has previously passed a
 67         FIPS test, then the data will be added to the /dev/random
 68         entropy pool.  Then, those 8 bits are added to an internal
 69         test data pool.  When that pool is full, a FIPS test is
 70         run to verify that the last N bytes read are decently random.
 71 
 72         Thus, the RNG will never be enabled until it passes a
 73         FIPS test.  And, data will stop flowing into the system
 74         entropy pool if the data is determined to be non-random.
 75 
 76         Finally, note that the timer defaults to OFF.  This ensures
 77         that the system entropy pool will not be polluted with
 78         RNG-originated data unless a conscious decision is made
 79         by the user.
 80 
 81         HOWEVER NOTE THAT UP TO 2499 BYTES OF DATA CAN BE BOGUS
 82         BEFORE THE SYSTEM WILL NOTICE VIA THE FIPS TEST.
 83 
 84         ----------------------------------------------------------
 85 
 86         Driver notes:
 87 
 88         * You may enable and disable the RNG timer via sysctl:
 89 
 90                 # disable RNG
 91                 echo 0 > /proc/sys/dev/i810_rng_timer
 92 
 93                 # enable RNG
 94                 echo 1 > /proc/sys/dev/i810_rng_timer
 95 
 96         * The default number of entropy bits added by default is
 97         the full 8 bits.  If you wish to reduce this value for
 98         paranoia's sake, you can do so via sysctl as well:
 99 
100                 # Add only 4 bits of entropy to /dev/random
101                 echo 4 > /proc/sys/dev/i810_rng_entropy
102 
103         * The default number of entropy bits can also be set via
104         a module parameter "rng_entropy" at module load time.
105 
106         * When the RNG timer is enabled, the driver reads 1 byte
107         from the hardware RNG every N jiffies.  By default, every
108         half-second.  If you would like to change the timer interval,
109         do so via another sysctl:
110 
111                 echo 200 > /proc/sys/dev/i810_rng_interval
112 
113         NOTE THIS VALUE IS IN JIFFIES, NOT SECONDS OR MILLISECONDS.
114         Minimum interval is 1 jiffy, maximum interval is 24 hours.
115 
116         * In order to unload the i810_rng module, you must first
117         disable the hardware via sysctl i810_hw_enabled, as shown above,
118         and make sure all users of the character device have closed
119 
120         * The timer and the character device may be used simultaneously,
121         if desired.
122 
123         * FIXME: support poll()
124 
125         * FIXME: should we be crazy and support mmap()?
126 
127         * FIXME: It is possible for the timer function to read,
128         and shove into the kernel entropy pool, 2499 bytes of data
129         before the internal FIPS test notices that the data is bad.
130         The kernel should handle this (I think???), but we should use a
131         2500-byte array, and re-run the FIPS test for every byte read.
132         This will slow things down but guarantee that bad data is
133         never passed upstream.
134 
135         * FIXME: module unload is racy.  To fix this, struct ctl_table
136         needs an owner member a la struct file_operations.
137 
138         * Since the RNG is accessed from a timer as well as normal
139         kernel code, but not from interrupts, we use spin_lock_bh
140         in regular code, and spin_lock in the timer function, to
141         serialize access to the RNG hardware area.
142 
143         ----------------------------------------------------------
144 
145         Change history:
146 
147         Version 0.6.2:
148         * Clean up spinlocks.  Since we don't have any interrupts
149           to worry about, but we do have a timer to worry about,
150           we use spin_lock_bh everywhere except the timer function
151           itself.
152         * Fix module load/unload.
153         * Fix timer function and h/w enable/disable logic
154         * New timer interval sysctl
155         * Clean up sysctl names
156 
157         Version 0.9.0:
158         * Don't register a pci_driver, because we are really
159           using PCI bridge vendor/device ids, and someone
160           may want to register a driver for the bridge. (bug fix)
161         * Don't let the usage count go negative (bug fix)
162         * Clean up spinlocks (bug fix)
163         * Enable PCI device, if necessary (bug fix)
164         * iounmap on module unload (bug fix)
165         * If RNG chrdev is already in use when open(2) is called,
166           sleep until it is available.
167         * Remove redundant globals rng_allocated, rng_use_count
168         * Convert numeric globals to unsigned
169         * Module unload cleanup
170 
171         Version 0.9.1:
172         * Support i815 chipsets too (Matt Sottek)
173         * Fix reference counting when statically compiled (prumpf)
174         * Rewrite rng_dev_read (prumpf)
175         * Make module races less likely (prumpf)
176         * Small miscellaneous bug fixes (prumpf)
177         * Use pci table for PCI id list
178 
179         Version 0.9.2:
180         * Simplify open blocking logic
181 
182  */
183 
184 
185 #include <linux/module.h>
186 #include <linux/kernel.h>
187 #include <linux/fs.h>
188 #include <linux/init.h>
189 #include <linux/pci.h>
190 #include <linux/interrupt.h>
191 #include <linux/spinlock.h>
192 #include <linux/random.h>
193 #include <linux/sysctl.h>
194 #include <linux/miscdevice.h>
195 #include <linux/smp_lock.h>
196 #include <linux/mm.h>
197 
198 #include <asm/io.h>
199 #include <asm/uaccess.h>
200 
201 
202 /*
203  * core module and version information
204  */
205 #define RNG_VERSION "0.9.2"
206 #define RNG_MODULE_NAME "i810_rng"
207 #define RNG_DRIVER_NAME   RNG_MODULE_NAME " hardware driver " RNG_VERSION
208 #define PFX RNG_MODULE_NAME ": "
209 
210 
211 /*
212  * debugging macros
213  */
214 #undef RNG_DEBUG /* define to 1 to enable copious debugging info */
215 
216 #ifdef RNG_DEBUG
217 /* note: prints function name for you */
218 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
219 #else
220 #define DPRINTK(fmt, args...)
221 #endif
222 
223 #define RNG_NDEBUG 0        /* define to 1 to disable lightweight runtime checks */
224 #if RNG_NDEBUG
225 #define assert(expr)
226 #else
227 #define assert(expr) \
228         if(!(expr)) {                                   \
229         printk( "Assertion failed! %s,%s,%s,line=%d\n", \
230         #expr,__FILE__,__FUNCTION__,__LINE__);          \
231         }
232 #endif
233 
234 
235 /*
236  * prototypes
237  */
238 static void rng_fips_test_store (int rng_data);
239 static void rng_run_fips_test (void);
240 
241 
242 /*
243  * RNG registers (offsets from rng_mem)
244  */
245 #define RNG_HW_STATUS                   0
246 #define         RNG_PRESENT             0x40
247 #define         RNG_ENABLED             0x01
248 #define RNG_STATUS                      1
249 #define         RNG_DATA_PRESENT        0x01
250 #define RNG_DATA                        2
251 
252 #define RNG_ADDR                        0xFFBC015F
253 #define RNG_ADDR_LEN                    3
254 
255 #define RNG_MAX_ENTROPY                 8 /* max entropy h/w is capable of */
256 
257 #define RNG_MISCDEV_MINOR               183 /* official */
258 
259 
260 /*
261  * Frequency that data is added to kernel entropy pool
262  * HZ>>1 == every half-second
263  */
264 #define RNG_DEF_TIMER_LEN               (HZ >> 1)
265 
266 
267 /*
268  * number of bytes required for a FIPS test.
269  * do not alter unless you really, I mean
270  * REALLY know what you are doing.
271  */
272 #define RNG_FIPS_TEST_THRESHOLD 2500
273 
274 
275 /*
276  * various RNG status variables.  they are globals
277  * as we only support a single RNG device
278  */
279 static int rng_hw_enabled;              /* is the RNG h/w enabled? */
280 static int rng_timer_enabled;           /* is the RNG timer enabled? */
281 static int rng_trusted;                 /* does FIPS trust out data? */
282 static int rng_enabled_sysctl;          /* sysctl for enabling/disabling RNG */
283 static unsigned int rng_entropy = 8;    /* number of entropy bits we submit to /dev/random */
284 static unsigned int rng_entropy_sysctl; /* sysctl for changing entropy bits */
285 static unsigned int rng_interval_sysctl; /* sysctl for changing timer interval */
286 static int rng_have_mem_region;         /* did we grab RNG region via request_mem_region? */
287 static unsigned int rng_fips_counter;   /* size of internal FIPS test data pool */
288 static unsigned int rng_timer_len = RNG_DEF_TIMER_LEN; /* timer interval, in jiffies */
289 static void *rng_mem;                   /* token to our ioremap'd RNG register area */
290 static spinlock_t rng_lock = SPIN_LOCK_UNLOCKED; /* hardware lock */
291 static struct timer_list rng_timer;     /* kernel timer for RNG hardware reads and tests */
292 static struct pci_dev *rng_pdev;        /* Firmware Hub PCI device found during PCI probe */
293 static struct semaphore rng_open_sem;   /* Semaphore for serializing rng_open/release */
294 
295 
296 /*
297  * inlined helper functions for accessing RNG registers
298  */
299 static inline u8 rng_hwstatus (void)
300 {
301         assert (rng_mem != NULL);
302         return readb (rng_mem + RNG_HW_STATUS);
303 }
304 
305 
306 static inline void rng_hwstatus_set (u8 hw_status)
307 {
308         assert (rng_mem != NULL);
309         writeb (hw_status, rng_mem + RNG_HW_STATUS);
310 }
311 
312 
313 static inline int rng_data_present (void)
314 {
315         assert (rng_mem != NULL);
316         assert (rng_hw_enabled == 1);
317 
318         return (readb (rng_mem + RNG_STATUS) & RNG_DATA_PRESENT) ? 1 : 0;
319 }
320 
321 
322 static inline int rng_data_read (void)
323 {
324         assert (rng_mem != NULL);
325         assert (rng_hw_enabled == 1);
326 
327         return readb (rng_mem + RNG_DATA);
328 }
329 
330 
331 /*
332  * rng_timer_ticker - executes every rng_timer_len jiffies,
333  *                    adds a single byte to system entropy
334  *                    and internal FIPS test pools
335  */
336 static void rng_timer_tick (unsigned long data)
337 {
338         int rng_data;
339 
340         spin_lock (&rng_lock);
341 
342         if (rng_data_present ()) {
343                 /* gimme some thermal noise, baby */
344                 rng_data = rng_data_read ();
345 
346                 spin_unlock (&rng_lock);
347 
348                 /*
349                  * if RNG has been verified in the past, add
350                  * data just read to the /dev/random pool,
351                  * with the entropy specified by the user
352                  * via sysctl (defaults to 8 bits)
353                  */
354                 if (rng_trusted)
355                         batch_entropy_store (rng_data, jiffies, rng_entropy);
356 
357                 /* fitness testing via FIPS, if we have enough data */
358                 rng_fips_test_store (rng_data);
359                 if (rng_fips_counter > RNG_FIPS_TEST_THRESHOLD)
360                         rng_run_fips_test ();
361         } else {
362                 spin_unlock (&rng_lock);
363         }
364 
365         /* run the timer again, if enabled */
366         if (rng_timer_enabled) {
367                 rng_timer.expires = jiffies + rng_timer_len;
368                 add_timer (&rng_timer);
369         }
370 }
371 
372 
373 /*
374  * rng_enable - enable or disable the RNG hardware
375  */
376 static int rng_enable (int enable)
377 {
378         int rc = 0, action = 0;
379         u8 hw_status, new_status;
380 
381         DPRINTK ("ENTER\n");
382 
383         spin_lock_bh (&rng_lock);
384 
385         hw_status = rng_hwstatus ();
386 
387         if (enable) {
388                 rng_hw_enabled++;
389                 MOD_INC_USE_COUNT;
390         } else {
391                 if (rng_hw_enabled) {
392                         rng_hw_enabled--;
393                         MOD_DEC_USE_COUNT;
394                 }
395         }
396 
397         if (rng_hw_enabled && ((hw_status & RNG_ENABLED) == 0)) {
398                 rng_hwstatus_set (hw_status | RNG_ENABLED);
399                 action = 1;
400         }
401 
402         else if (!rng_hw_enabled && (hw_status & RNG_ENABLED)) {
403                 rng_hwstatus_set (hw_status & ~RNG_ENABLED);
404                 action = 2;
405         }
406 
407         new_status = rng_hwstatus ();
408 
409         spin_unlock_bh (&rng_lock);
410 
411         if (action == 1)
412                 printk (KERN_INFO PFX "RNG h/w enabled\n");
413         else if (action == 2)
414                 printk (KERN_INFO PFX "RNG h/w disabled\n");
415 
416         /* too bad C doesn't have ^^ */
417         if ((!enable) != (!(new_status & RNG_ENABLED))) {
418                 printk (KERN_ERR PFX "Unable to %sable the RNG\n",
419                         enable ? "en" : "dis");
420                 rc = -EIO;
421         }
422 
423         DPRINTK ("EXIT, returning %d\n", rc);
424         return rc;
425 }
426 
427 
428 /*
429  * rng_handle_sysctl_enable - handle a read or write of our enable/disable sysctl
430  */
431 
432 static int rng_handle_sysctl_enable (ctl_table * table, int write, struct file *filp,
433                                      void *buffer, size_t * lenp)
434 {
435         int enabled_save, rc;
436 
437         DPRINTK ("ENTER\n");
438 
439         MOD_INC_USE_COUNT;
440         spin_lock_bh (&rng_lock);
441         rng_enabled_sysctl = enabled_save = rng_timer_enabled;
442         spin_unlock_bh (&rng_lock);
443 
444         rc = proc_dointvec (table, write, filp, buffer, lenp);
445         if (rc)
446                 return rc;
447 
448         spin_lock_bh (&rng_lock);
449         if (enabled_save != rng_enabled_sysctl) {
450                 rng_timer_enabled = rng_enabled_sysctl;
451                 spin_unlock_bh (&rng_lock);
452 
453                 /* enable/disable hardware */
454                 rng_enable (rng_enabled_sysctl);
455 
456                 /* enable/disable timer */
457                 if (rng_enabled_sysctl) {
458                         rng_timer.expires = jiffies + rng_timer_len;
459                         add_timer (&rng_timer);
460                 } else {
461                         del_timer_sync (&rng_timer);
462                 }
463         } else {
464                 spin_unlock_bh (&rng_lock);
465         }
466 
467         /* This needs to be in a higher layer */
468         MOD_DEC_USE_COUNT;
469 
470         DPRINTK ("EXIT, returning 0\n");
471         return 0;
472 }
473 
474 
475 /*
476  * rng_handle_sysctl_entropy - handle a read or write of our entropy bits sysctl
477  */
478 
479 static int rng_handle_sysctl_entropy (ctl_table * table, int write, struct file *filp,
480                                       void *buffer, size_t * lenp)
481 {
482         int entropy_bits_save, rc;
483 
484         DPRINTK ("ENTER\n");
485 
486         spin_lock_bh (&rng_lock);
487         rng_entropy_sysctl = entropy_bits_save = rng_entropy;
488         spin_unlock_bh (&rng_lock);
489 
490         rc = proc_dointvec (table, write, filp, buffer, lenp);
491         if (rc)
492                 return rc;
493 
494         if (entropy_bits_save == rng_entropy_sysctl)
495                 goto out;
496 
497         if ((rng_entropy_sysctl >= 0) &&
498             (rng_entropy_sysctl <= 8)) {
499                 spin_lock_bh (&rng_lock);
500                 rng_entropy = rng_entropy_sysctl;
501                 spin_unlock_bh (&rng_lock);
502 
503                 printk (KERN_INFO PFX "entropy bits now %d\n", rng_entropy_sysctl);
504         } else {
505                 printk (KERN_INFO PFX "ignoring invalid entropy setting (%d)\n",
506                         rng_entropy_sysctl);
507         }
508 
509 out:
510         DPRINTK ("EXIT, returning 0\n");
511         return 0;
512 }
513 
514 /*
515  * rng_handle_sysctl_interval - handle a read or write of our timer interval len sysctl
516  */
517 
518 static int rng_handle_sysctl_interval (ctl_table * table, int write, struct file *filp,
519                                       void *buffer, size_t * lenp)
520 {
521         int timer_len_save, rc;
522 
523         DPRINTK ("ENTER\n");
524 
525         spin_lock_bh (&rng_lock);
526         rng_interval_sysctl = timer_len_save = rng_timer_len;
527         spin_unlock_bh (&rng_lock);
528 
529         rc = proc_dointvec (table, write, filp, buffer, lenp);
530         if (rc)
531                 return rc;
532 
533         if (timer_len_save == rng_interval_sysctl)
534                 goto out;
535 
536         if ((rng_interval_sysctl > 0) &&
537             (rng_interval_sysctl < (HZ*86400))) {
538                 spin_lock_bh (&rng_lock);
539                 rng_timer_len = rng_interval_sysctl;
540                 spin_unlock_bh (&rng_lock);
541 
542                 printk (KERN_INFO PFX "timer interval now %d\n", rng_interval_sysctl);
543         } else {
544                 printk (KERN_INFO PFX "ignoring invalid timer interval (%d)\n",
545                         rng_interval_sysctl);
546         }
547 
548 out:
549         DPRINTK ("EXIT, returning 0\n");
550         return 0;
551 }
552 
553 
554 /*
555  * rng_sysctl - add or remove the rng sysctl
556  */
557 static void rng_sysctl (int add)
558 {
559 #define DEV_I810_TIMER          1
560 #define DEV_I810_ENTROPY        2
561 #define DEV_I810_INTERVAL       3
562 
563         /* Definition of the sysctl */
564         /* FIXME: use new field:value style of struct initialization */
565         static ctl_table rng_sysctls[] = {
566                 {DEV_I810_TIMER,                /* ID */
567                  RNG_MODULE_NAME "_timer",      /* name in /proc */
568                  &rng_enabled_sysctl,
569                  sizeof (rng_enabled_sysctl),   /* data ptr, data size */
570                  0644,                          /* mode */
571                  0,                             /* child */
572                  rng_handle_sysctl_enable,      /* proc handler */
573                  0,                             /* strategy */
574                  0,                             /* proc control block */
575                  0, 0}
576                 ,
577                 {DEV_I810_ENTROPY,              /* ID */
578                  RNG_MODULE_NAME "_entropy",    /* name in /proc */
579                  &rng_entropy_sysctl,
580                  sizeof (rng_entropy_sysctl),   /* data ptr, data size */
581                  0644,                          /* mode */
582                  0,                             /* child */
583                  rng_handle_sysctl_entropy,     /* proc handler */
584                  0,                             /* strategy */
585                  0,                             /* proc control block */
586                  0, 0}
587                 ,
588                 {DEV_I810_INTERVAL,             /* ID */
589                  RNG_MODULE_NAME "_interval",   /* name in /proc */
590                  &rng_interval_sysctl,
591                  sizeof (rng_interval_sysctl),  /* data ptr, data size */
592                  0644,                          /* mode */
593                  0,                             /* child */
594                  rng_handle_sysctl_interval,    /* proc handler */
595                  0,                             /* strategy */
596                  0,                             /* proc control block */
597                  0, 0}
598                 ,
599                 {0}
600         };
601 
602         /* Define the parent file : /proc/sys/dev */
603         static ctl_table sysctls_root[] = {
604                 {CTL_DEV,
605                  "dev",
606                  NULL, 0,
607                  0555,
608                  rng_sysctls},
609                 {0}
610         };
611         static struct ctl_table_header *sysctls_root_header = NULL;
612 
613         if (add) {
614                 if (!sysctls_root_header)
615                         sysctls_root_header = register_sysctl_table (sysctls_root, 0);
616         } else if (sysctls_root_header) {
617                 unregister_sysctl_table (sysctls_root_header);
618                 sysctls_root_header = NULL;
619         }
620 }
621 
622 
623 static int rng_dev_open (struct inode *inode, struct file *filp)
624 {
625         int rc = -EINVAL;
626 
627         if ((filp->f_mode & FMODE_READ) == 0)
628                 return rc;
629         if (filp->f_mode & FMODE_WRITE)
630                 return rc;
631 
632         /* wait for device to become free */
633         if (filp->f_flags & O_NONBLOCK) {
634                 if (down_trylock (&rng_open_sem))
635                         return -EAGAIN;
636         } else {
637                 if (down_interruptible (&rng_open_sem))
638                         return -ERESTARTSYS;
639         }
640 
641         if (rng_enable (1)) {
642                 rc = -EIO;
643                 goto err_out;
644         }
645 
646         return 0;
647 
648 err_out:
649         up (&rng_open_sem);
650         return rc;
651 }
652 
653 
654 static int rng_dev_release (struct inode *inode, struct file *filp)
655 {
656         rng_enable(0);
657         up (&rng_open_sem);
658         return 0;
659 }
660 
661 
662 static ssize_t rng_dev_read (struct file *filp, char *buf, size_t size,
663                              loff_t * offp)
664 {
665         int have_data;
666         u8 data = 0;
667         ssize_t ret = 0;
668 
669         while (size) {
670                 spin_lock_bh (&rng_lock);
671 
672                 have_data = 0;
673                 if (rng_data_present ()) {
674                         data = rng_data_read ();
675                         have_data = 1;
676                 }
677 
678                 spin_unlock_bh (&rng_lock);
679 
680                 if (have_data) {
681                         if (put_user (data, buf++)) {
682                                 ret = ret ? : -EFAULT;
683                                 break;
684                         }
685                         size--;
686                         ret++;
687                 }
688 
689                 if (current->need_resched)
690                         schedule ();
691 
692                 if (signal_pending (current))
693                         return ret ? : -ERESTARTSYS;
694 
695                 if (filp->f_flags & O_NONBLOCK)
696                         return ret ? : -EAGAIN;
697         }
698 
699         return ret;
700 }
701 
702 
703 /*
704  * rng_init_one - look for and attempt to init a single RNG
705  */
706 static int __init rng_init_one (struct pci_dev *dev)
707 {
708         int rc;
709         u8 hw_status;
710 
711         DPRINTK ("ENTER\n");
712 
713         if (pci_enable_device (dev))
714                 return -EIO;
715 
716         /* XXX currently fails, investigate who has our mem region */
717         if (request_mem_region (RNG_ADDR, RNG_ADDR_LEN, RNG_MODULE_NAME))
718                 rng_have_mem_region = 1;
719 
720         rng_mem = ioremap (RNG_ADDR, RNG_ADDR_LEN);
721         if (rng_mem == NULL) {
722                 printk (KERN_ERR PFX "cannot ioremap RNG Memory\n");
723                 DPRINTK ("EXIT, returning -EBUSY\n");
724                 rc = -EBUSY;
725                 goto err_out_free_res;
726         }
727 
728         /* Check for Intel 82802 */
729         hw_status = rng_hwstatus ();
730         if ((hw_status & RNG_PRESENT) == 0) {
731                 printk (KERN_ERR PFX "RNG not detected\n");
732                 DPRINTK ("EXIT, returning -ENODEV\n");
733                 rc = -ENODEV;
734                 goto err_out_free_map;
735         }
736 
737         if (rng_entropy < 0 || rng_entropy > RNG_MAX_ENTROPY)
738                 rng_entropy = RNG_MAX_ENTROPY;
739 
740         /* init core RNG timer, but do not add it */
741         init_timer (&rng_timer);
742         rng_timer.function = rng_timer_tick;
743 
744         /* turn RNG h/w off, if it's on */
745         rc = rng_enable (0);
746         if (rc) {
747                 printk (KERN_ERR PFX "cannot disable RNG, aborting\n");
748                 goto err_out_free_map;
749         }
750 
751         /* add sysctls */
752         rng_sysctl (1);
753 
754         DPRINTK ("EXIT, returning 0\n");
755         return 0;
756 
757 err_out_free_map:
758         iounmap (rng_mem);
759 err_out_free_res:
760         if (rng_have_mem_region)
761                 release_mem_region (RNG_ADDR, RNG_ADDR_LEN);
762         return rc;
763 }
764 
765 
766 /*
767  * Data for PCI driver interface
768  *
769  * This data only exists for exporting the supported
770  * PCI ids via MODULE_DEVICE_TABLE.  We do not actually
771  * register a pci_driver, because someone else might one day
772  * want to register another driver on the same PCI id.
773  */
774 const static struct pci_device_id rng_pci_tbl[] __initdata = {
775         { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, },
776         { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, },
777         { 0x8086, 0x1130, PCI_ANY_ID, PCI_ANY_ID, },
778         { 0, },
779 };
780 MODULE_DEVICE_TABLE (pci, rng_pci_tbl);
781 
782 
783 MODULE_AUTHOR("Jeff Garzik, Matt Sottek");
784 MODULE_DESCRIPTION("Intel i8xx chipset Random Number Generator (RNG) driver");
785 MODULE_PARM(rng_entropy, "1i");
786 MODULE_PARM_DESC(rng_entropy, "Bits of entropy to add to random pool per RNG byte (range: 0-8, default 8)");
787 
788 
789 static struct file_operations rng_chrdev_ops = {
790         owner:          THIS_MODULE,
791         open:           rng_dev_open,
792         release:        rng_dev_release,
793         read:           rng_dev_read,
794 };
795 
796 
797 static struct miscdevice rng_miscdev = {
798         RNG_MISCDEV_MINOR,
799         RNG_MODULE_NAME,
800         &rng_chrdev_ops,
801 };
802 
803 
804 /*
805  * rng_init - initialize RNG module
806  */
807 static int __init rng_init (void)
808 {
809         int rc;
810         struct pci_dev *pdev;
811 
812         DPRINTK ("ENTER\n");
813 
814         init_MUTEX (&rng_open_sem);
815 
816         pci_for_each_dev(pdev) {
817                 if (pci_match_device (rng_pci_tbl, pdev) != NULL)
818                         goto match;
819         }
820 
821         DPRINTK ("EXIT, returning -ENODEV\n");
822         return -ENODEV;
823 
824 match:
825         rc = rng_init_one (pdev);
826         if (rc)
827                 return rc;
828 
829         rc = misc_register (&rng_miscdev);
830         if (rc) {
831                 iounmap (rng_mem);
832                 if (rng_have_mem_region)
833                         release_mem_region (RNG_ADDR, RNG_ADDR_LEN);
834                 DPRINTK ("EXIT, returning %d\n", rc);
835                 return rc;
836         }
837 
838         printk (KERN_INFO RNG_DRIVER_NAME " loaded\n");
839 
840         rng_pdev = pdev;
841 
842         DPRINTK ("EXIT, returning 0\n");
843         return 0;
844 }
845 
846 
847 /*
848  * rng_init - shutdown RNG module
849  */
850 static void __exit rng_cleanup (void)
851 {
852         DPRINTK ("ENTER\n");
853 
854         assert (rng_timer_enabled == 0);
855         assert (rng_hw_enabled == 0);
856 
857         misc_deregister (&rng_miscdev);
858 
859         rng_sysctl (0);
860 
861         iounmap (rng_mem);
862         if (rng_have_mem_region)
863                 release_mem_region (RNG_ADDR, RNG_ADDR_LEN);
864 
865         DPRINTK ("EXIT\n");
866 }
867 
868 
869 module_init (rng_init);
870 module_exit (rng_cleanup);
871 
872 
873 
874 
875 /* These are the startup tests suggested by the FIPS 140-1 spec section
876 *  4.11.1 (http://csrc.nist.gov/fips/fips1401.htm)
877 *  The Monobit, Poker, Runs, and Long Runs tests are implemented below.
878 *  This test is run at periodic intervals to verify
879 *  data is sufficiently random. If the tests are failed the RNG module
880 *  will no longer submit data to the entropy pool, but the tests will
881 *  continue to run at the given interval. If at a later time the RNG
882 *  passes all tests it will be re-enabled for the next period.
883 *   The reason for this is that it is not unlikely that at some time
884 *  during normal operation one of the tests will fail. This does not
885 *  necessarily mean the RNG is not operating properly, it is just a
886 *  statistically rare event. In that case we don't want to forever
887 *  disable the RNG, we will just leave it disabled for the period of
888 *  time until the tests are rerun and passed.
889 *
890 *  For argument sake I tested /dev/urandom with these tests and it
891 *  took 142,095 tries before I got a failure, and urandom isn't as
892 *  random as random :)
893 */
894 
895 static int poker[16] = { 0, }, runs[12] = { 0, };
896 static int ones = 0, rlength = -1, current_bit = 0, rng_test = 0;
897 
898 
899 /*
900  * rng_fips_test_store - store 8 bits of entropy in FIPS
901  *                       internal test data pool
902  */
903 static void rng_fips_test_store (int rng_data)
904 {
905         int j;
906         static int last_bit = 0;
907 
908         DPRINTK ("ENTER, rng_data = %d\n", rng_data);
909 
910         poker[rng_data >> 4]++;
911         poker[rng_data & 15]++;
912 
913         /* Note in the loop below rlength is always one less than the actual
914            run length. This makes things easier. */
915         last_bit = (rng_data & 128) >> 7;
916         for (j = 7; j >= 0; j--) {
917                 ones += current_bit = (rng_data & 1 << j) >> j;
918                 if (current_bit != last_bit) {
919                         /* If runlength is 1-6 count it in correct bucket. 0's go in
920                            runs[0-5] 1's go in runs[6-11] hence the 6*current_bit below */
921                         if (rlength < 5) {
922                                 runs[rlength +
923                                      (6 * current_bit)]++;
924                         } else {
925                                 runs[5 + (6 * current_bit)]++;
926                         }
927 
928                         /* Check if we just failed longrun test */
929                         if (rlength >= 33)
930                                 rng_test &= 8;
931                         rlength = 0;
932                         /* flip the current run type */
933                         last_bit = current_bit;
934                 } else {
935                         rlength++;
936                 }
937         }
938 
939         DPRINTK ("EXIT\n");
940 }
941 
942 
943 /*
944  * now that we have some data, run a FIPS test
945  */
946 static void rng_run_fips_test (void)
947 {
948         int j, i;
949 
950         DPRINTK ("ENTER\n");
951 
952         /* add in the last (possibly incomplete) run */
953         if (rlength < 5)
954                 runs[rlength + (6 * current_bit)]++;
955         else {
956                 runs[5 + (6 * current_bit)]++;
957                 if (rlength >= 33)
958                         rng_test &= 8;
959         }
960         /* Ones test */
961         if ((ones >= 10346) || (ones <= 9654))
962                 rng_test &= 1;
963         /* Poker calcs */
964         for (i = 0, j = 0; i < 16; i++)
965                 j += poker[i] * poker[i];
966         if ((j >= 1580457) || (j <= 1562821))
967                 rng_test &= 2;
968         if ((runs[0] < 2267) || (runs[0] > 2733) ||
969             (runs[1] < 1079) || (runs[1] > 1421) ||
970             (runs[2] < 502) || (runs[2] > 748) ||
971             (runs[3] < 223) || (runs[3] > 402) ||
972             (runs[4] < 90) || (runs[4] > 223) ||
973             (runs[5] < 90) || (runs[5] > 223) ||
974             (runs[6] < 2267) || (runs[6] > 2733) ||
975             (runs[7] < 1079) || (runs[7] > 1421) ||
976             (runs[8] < 502) || (runs[8] > 748) ||
977             (runs[9] < 223) || (runs[9] > 402) ||
978             (runs[10] < 90) || (runs[10] > 223) ||
979             (runs[11] < 90) || (runs[11] > 223)) {
980                 rng_test &= 4;
981         }
982 
983         rng_test = !rng_test;
984         DPRINTK ("FIPS test %sed\n", rng_test ? "pass" : "fail");
985 
986         /* enable/disable RNG with results of the tests */
987         if (rng_test && !rng_trusted)
988                 printk (KERN_WARNING PFX "FIPS test passed, enabling RNG\n");
989         else if (!rng_test && rng_trusted)
990                 printk (KERN_WARNING PFX "FIPS test failed, disabling RNG\n");
991 
992         rng_trusted = rng_test;
993 
994         /* finally, clear out FIPS variables for start of next run */
995         memset (poker, 0, sizeof (poker));
996         memset (runs, 0, sizeof (runs));
997         ones = 0;
998         rlength = -1;
999         current_bit = 0;
1000         rng_test = 0;
1001 
1002         DPRINTK ("EXIT\n");
1003 }
1004 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.