]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blame_incremental - src/patches/linux-2.4.27-frandom-2.patch
Wir kehren zurueck zu Kudzu, da hwinfo noch mehr Aerger macht.
[people/teissler/ipfire-2.x.git] / src / patches / linux-2.4.27-frandom-2.patch
... / ...
CommitLineData
1Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes)
2Date: 2004-11-03
3Initial Package Version: Linux 2.4.27
4Upstream Status: Rejected Upstream
5Origin: http://frandom.sourceforge.net/ - frandom-0.8
6Description: This is usefull for smashing stack protector, wiping
7discs, mktemp, arc4random, and more.
8This source was modified for 2.4.26, and is enabled by default in
9arch/i386/defconfig. A define was added to sysctl.h too.
10
11To get character devices do this:
12mknod /dev/frandom c 235 11
13mknod /dev/erandom c 235 12
14
15Thanks to Eli Billauer
16http://www.billauer.co.il/
17http://frandom.sourceforge.net/
18
19Also see:
20http://www.linuxfromscratch.org/hlfs/
21http://www.linuxfromscratch.org/hints/downloads/files/entropy.txt
22http://www.linuxfromscratch.org/~robert/hlfs/hints/attachments/entropy/\
23 frandom-0.8.tar.gz
24
25diff -Naur linux-2.4.27.orig/Documentation/Configure.help linux-2.4.27.frandom/Documentation/Configure.help
26--- linux-2.4.27.orig/Documentation/Configure.help 2004-08-07 23:26:04.000000000 +0000
27+++ linux-2.4.27.frandom/Documentation/Configure.help 2004-11-04 01:11:24.126837840 +0000
28@@ -18447,6 +18447,17 @@
29 input/output character sets. Say Y here for the UTF-8 encoding of
30 the Unicode/ISO9646 universal character set.
31
32+Fast random data generator suite (/dev/frandom and /dev/erandom)
33+CONFIG_FRANDOM
34+ Fast random data/number generator support in kernel. This random
35+ generator is 10-50 times faster than /dev/urandom, and saves kernel
36+ entropy.
37+
38+ If unsure, say Y unless you're tight on kernel size. This module is
39+ small and harmless otherwise.
40+
41+ If you choose M, the sysctl interface will be disabled.
42+
43 Virtual terminal
44 CONFIG_VT
45 If you say Y here, you will get support for terminal devices with
46diff -Naur linux-2.4.27.orig/arch/i386/defconfig linux-2.4.27.frandom/arch/i386/defconfig
47--- linux-2.4.27.orig/arch/i386/defconfig 2004-08-07 23:26:04.000000000 +0000
48+++ linux-2.4.27.frandom/arch/i386/defconfig 2004-11-04 01:11:24.150834192 +0000
49@@ -579,6 +579,7 @@
50 #
51 CONFIG_VT=y
52 CONFIG_VT_CONSOLE=y
53+CONFIG_FRANDOM=y
54 CONFIG_SERIAL=y
55 # CONFIG_SERIAL_CONSOLE is not set
56 # CONFIG_SERIAL_EXTENDED is not set
57diff -Naur linux-2.4.27.orig/drivers/char/Config.in linux-2.4.27.frandom/drivers/char/Config.in
58--- linux-2.4.27.orig/drivers/char/Config.in 2004-08-07 23:26:04.000000000 +0000
59+++ linux-2.4.27.frandom/drivers/char/Config.in 2004-11-04 01:11:24.201826440 +0000
60@@ -25,6 +25,7 @@
61 tristate ' Dual serial port support' CONFIG_DUALSP_SERIAL
62 fi
63 fi
64+tristate 'Fast random data generator suite (/dev/frandom and /dev/erandom)' CONFIG_FRANDOM
65 dep_mbool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED $CONFIG_SERIAL
66 if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then
67 bool ' Support more than 4 serial ports' CONFIG_SERIAL_MANY_PORTS
68diff -Naur linux-2.4.27.orig/drivers/char/Makefile linux-2.4.27.frandom/drivers/char/Makefile
69--- linux-2.4.27.orig/drivers/char/Makefile 2004-08-07 23:26:04.000000000 +0000
70+++ linux-2.4.27.frandom/drivers/char/Makefile 2004-11-04 01:11:24.209825224 +0000
71@@ -25,7 +25,7 @@
72 misc.o pty.o random.o selection.o serial.o \
73 sonypi.o tty_io.o tty_ioctl.o generic_serial.o \
74 au1000_gpio.o vac-serial.o hp_psaux.o nvram.o \
75- scx200.o fetchop.o
76+ scx200.o fetchop.o frandom.o
77
78 mod-subdirs := joystick ftape drm drm-4.0 pcmcia
79
80@@ -334,6 +334,8 @@
81 obj-y += ipmi/ipmi.o
82 endif
83
84+obj-$(CONFIG_FRANDOM) += frandom.o
85+
86 include $(TOPDIR)/Rules.make
87
88 fastdep:
89diff -Naur linux-2.4.27.orig/drivers/char/frandom.c linux-2.4.27.frandom/drivers/char/frandom.c
90--- linux-2.4.27.orig/drivers/char/frandom.c 1970-01-01 00:00:00.000000000 +0000
91+++ linux-2.4.27.frandom/drivers/char/frandom.c 2004-11-04 01:11:24.213824616 +0000
92@@ -0,0 +1,362 @@
93+/*
94+** frandom.c
95+** Fast pseudo-random generator
96+**
97+** (c) Copyright 2003 Eli Billauer
98+** http://www.billauer.co.il
99+**
100+** This program is free software; you can redistribute it and/or modify
101+** it under the terms of the GNU General Public License as published by
102+** the Free Software Foundation; either version 2 of the License, or
103+** (at your option) any later version.
104+**
105+** Usage: mknod /dev/frandom c 235 11
106+** mknod /dev/erandom c 235 12
107+** insmod frandom
108+**
109+** This code is highly based upon the examples given in the book "Linux
110+** Device Drivers" by Alessandro Rubini and Jonathan Corbet, published
111+** by O'Reilly & Associates.
112+** O'Reilly's release of this book on the web for free is highly
113+** appreciated.
114+**
115+*/
116+
117+#include <linux/version.h>
118+#include <linux/config.h>
119+#include <linux/module.h>
120+
121+#include <linux/kernel.h>
122+#include <linux/init.h>
123+#include <linux/slab.h>
124+#include <linux/fs.h>
125+#include <linux/errno.h>
126+#include <linux/types.h>
127+#include <linux/random.h>
128+
129+#include <asm/uaccess.h>
130+
131+#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,0))
132+#include <linux/moduleparam.h>
133+#endif
134+
135+#define INTERNAL_SEED 0
136+#define EXTERNAL_SEED 1
137+
138+#define FRANDOM_MAJOR 235
139+#define FRANDOM_MINOR 11
140+#define ERANDOM_MINOR 12
141+
142+static struct file_operations frandom_fops; /* Values assigned below */
143+
144+static int erandom_seeded = 0; /* Internal flag */
145+
146+static int frandom_major = FRANDOM_MAJOR;
147+static int frandom_minor = FRANDOM_MINOR;
148+static int erandom_minor = ERANDOM_MINOR;
149+static int frandom_bufsize = 256;
150+static int frandom_chunklimit = 0; /* =0 means unlimited */
151+
152+MODULE_DESCRIPTION("Fast pseudo-random number generator");
153+MODULE_LICENSE("GPL");
154+MODULE_AUTHOR("Eli Billauer");
155+MODULE_PARM(frandom_major,"i");
156+MODULE_PARM_DESC(frandom_major,"Major number of /dev/frandom and /dev/erandom");
157+MODULE_PARM(frandom_minor,"i");
158+MODULE_PARM_DESC(frandom_minor,"Minor number of /dev/frandom");
159+MODULE_PARM(erandom_minor,"i");
160+MODULE_PARM_DESC(erandom_minor,"Minor number of /dev/erandom");
161+MODULE_PARM(frandom_bufsize,"i");
162+MODULE_PARM_DESC(frandom_bufsize,"Internal buffer size in bytes. Default is 256. Must be >= 256");
163+MODULE_PARM(frandom_chunklimit,"i");
164+MODULE_PARM_DESC(frandom_chunklimit,"Limit for read() blocks size. 0 (default) is unlimited, otherwise must be >= 256");
165+
166+struct frandom_state
167+{
168+ struct semaphore sem; /* Semaphore on the state structure */
169+
170+ u8 S[256]; /* The state array */
171+ u8 i;
172+ u8 j;
173+
174+ char *buf;
175+};
176+
177+static struct frandom_state *erandom_state;
178+
179+static inline void swap_byte(u8 *a, u8 *b)
180+{
181+ u8 swapByte;
182+
183+ swapByte = *a;
184+ *a = *b;
185+ *b = swapByte;
186+}
187+
188+static void init_rand_state(struct frandom_state *state, int seedflag);
189+
190+void erandom_get_random_bytes(char *buf, size_t count)
191+{
192+ struct frandom_state *state = erandom_state;
193+ int k;
194+
195+ unsigned int i;
196+ unsigned int j;
197+ u8 *S;
198+
199+ /* If we fail to get the semaphore, we revert to external random data.
200+ Since semaphore blocking is expected to be very rare, and interrupts
201+ during these rare and very short periods of time even less frequent,
202+ we take the better-safe-than-sorry approach, and fill the buffer
203+ some expensive random data, in case the caller wasn't aware of this
204+ possibility, and expects random data anyhow.
205+ */
206+
207+ if (down_interruptible(&state->sem)) {
208+ get_random_bytes(buf, count);
209+ return;
210+ }
211+
212+ /* We seed erandom as late as possible, hoping that the kernel's main
213+ RNG is already restored in the boot sequence (not critical, but
214+ better.
215+ */
216+
217+ if (!erandom_seeded) {
218+ erandom_seeded = 1;
219+ init_rand_state(state, EXTERNAL_SEED);
220+ printk(KERN_INFO "frandom: Seeded global generator now (used by erandom)\n");
221+ }
222+
223+ i = state->i;
224+ j = state->j;
225+ S = state->S;
226+
227+ for (k=0; k<count; k++) {
228+ i = (i + 1) & 0xff;
229+ j = (j + S[i]) & 0xff;
230+ swap_byte(&S[i], &S[j]);
231+ *buf++ = S[(S[i] + S[j]) & 0xff];
232+ }
233+
234+ state->i = i;
235+ state->j = j;
236+
237+ up(&state->sem);
238+}
239+
240+static void init_rand_state(struct frandom_state *state, int seedflag)
241+{
242+ unsigned int i, j, k;
243+ u8 *S;
244+ u8 *seed = state->buf;
245+
246+ if (seedflag == INTERNAL_SEED)
247+ erandom_get_random_bytes(seed, 256);
248+ else
249+ get_random_bytes(seed, 256);
250+
251+ S = state->S;
252+ for (i=0; i<256; i++)
253+ *S++=i;
254+
255+ j=0;
256+ S = state->S;
257+
258+ for (i=0; i<256; i++) {
259+ j = (j + S[i] + *seed++) & 0xff;
260+ swap_byte(&S[i], &S[j]);
261+ }
262+
263+ /* It's considered good practice to discard the first 256 bytes
264+ generated. So we do it:
265+ */
266+
267+ i=0; j=0;
268+ for (k=0; k<256; k++) {
269+ i = (i + 1) & 0xff;
270+ j = (j + S[i]) & 0xff;
271+ swap_byte(&S[i], &S[j]);
272+ }
273+
274+ state->i = i; /* Save state */
275+ state->j = j;
276+}
277+
278+static int frandom_open(struct inode *inode, struct file *filp)
279+{
280+
281+ struct frandom_state *state;
282+
283+ int num =MINOR(inode->i_rdev);
284+ if ((num != frandom_minor) && (num != erandom_minor)) return -ENODEV;
285+
286+ state = kmalloc(sizeof(struct frandom_state), GFP_KERNEL);
287+ if (!state)
288+ return -ENOMEM;
289+
290+ state->buf = kmalloc(frandom_bufsize, GFP_KERNEL);
291+ if (!state->buf) {
292+ kfree(state);
293+ return -ENOMEM;
294+ }
295+
296+ sema_init(&state->sem, 1); /* Init semaphore as a mutex */
297+
298+ if (num == frandom_minor)
299+ init_rand_state(state, EXTERNAL_SEED);
300+ else
301+ init_rand_state(state, INTERNAL_SEED);
302+
303+ filp->private_data = state;
304+
305+#if (LINUX_VERSION_CODE<KERNEL_VERSION(2,4,0))
306+ MOD_INC_USE_COUNT;
307+#endif
308+
309+ return 0; /* Success */
310+}
311+
312+static int frandom_release(struct inode *inode, struct file *filp)
313+{
314+
315+ struct frandom_state *state = filp->private_data;
316+
317+ kfree(state->buf);
318+ kfree(state);
319+
320+#if (LINUX_VERSION_CODE<KERNEL_VERSION(2,4,0))
321+ MOD_DEC_USE_COUNT;
322+#endif
323+
324+ return 0;
325+}
326+
327+static ssize_t frandom_read(struct file *filp, char *buf, size_t count,
328+ loff_t *f_pos)
329+{
330+ struct frandom_state *state = filp->private_data;
331+ ssize_t ret;
332+ int dobytes, k;
333+ char *localbuf;
334+
335+ unsigned int i;
336+ unsigned int j;
337+ u8 *S;
338+
339+ if (down_interruptible(&state->sem))
340+ return -ERESTARTSYS;
341+
342+ if ((frandom_chunklimit > 0) && (count > frandom_chunklimit))
343+ count = frandom_chunklimit;
344+
345+ ret = count; /* It's either everything or an error... */
346+
347+ i = state->i;
348+ j = state->j;
349+ S = state->S;
350+
351+ while (count) {
352+ if (count > frandom_bufsize)
353+ dobytes = frandom_bufsize;
354+ else
355+ dobytes = count;
356+
357+ localbuf = state->buf;
358+
359+ for (k=0; k<dobytes; k++) {
360+ i = (i + 1) & 0xff;
361+ j = (j + S[i]) & 0xff;
362+ swap_byte(&S[i], &S[j]);
363+ *localbuf++ = S[(S[i] + S[j]) & 0xff];
364+ }
365+
366+ if (copy_to_user(buf, state->buf, dobytes)) {
367+ ret = -EFAULT;
368+ goto out;
369+ }
370+
371+ buf += dobytes;
372+ count -= dobytes;
373+ }
374+
375+ out:
376+ state->i = i;
377+ state->j = j;
378+
379+ up(&state->sem);
380+ return ret;
381+}
382+
383+static struct file_operations frandom_fops = {
384+ read: frandom_read,
385+ open: frandom_open,
386+ release: frandom_release,
387+};
388+
389+static void frandom_cleanup_module(void) {
390+ kfree(erandom_state->buf);
391+ kfree(erandom_state);
392+
393+ unregister_chrdev(frandom_major, "frandom");
394+}
395+
396+
397+static int frandom_init_module(void)
398+{
399+ int result;
400+
401+ /* The buffer size MUST be at least 256 bytes, because we assume that
402+ minimal length in init_rand_state().
403+ */
404+ if (frandom_bufsize < 256) {
405+ printk(KERN_ERR "frandom: Refused to load because frandom_bufsize=%d < 256\n",frandom_bufsize);
406+ return -EINVAL;
407+ }
408+ if ((frandom_chunklimit != 0) && (frandom_chunklimit < 256)) {
409+ printk(KERN_ERR "frandom: Refused to load because frandom_chunklimit=%d < 256 and != 0\n",frandom_chunklimit);
410+ return -EINVAL;
411+ }
412+
413+ erandom_state = kmalloc(sizeof(struct frandom_state), GFP_KERNEL);
414+ if (!erandom_state)
415+ return -ENOMEM;
416+
417+ /* This specific buffer is only used for seeding, so we need
418+ 256 bytes exactly */
419+ erandom_state->buf = kmalloc(256, GFP_KERNEL);
420+ if (!erandom_state->buf) {
421+ kfree(erandom_state);
422+ return -ENOMEM;
423+ }
424+
425+ sema_init(&erandom_state->sem, 1); /* Init semaphore as a mutex */
426+
427+ erandom_seeded = 0;
428+
429+#ifdef SET_MODULE_OWNER
430+ SET_MODULE_OWNER(&frandom_fops);
431+#endif
432+ /*
433+ * Register your major, and accept a dynamic number. This is the
434+ * first thing to do, in order to avoid releasing other module's
435+ * fops in frandom_cleanup_module()
436+ */
437+ result = register_chrdev(frandom_major, "frandom", &frandom_fops);
438+ if (result < 0) {
439+ printk(KERN_WARNING "frandom: can't get major %d\n",frandom_major);
440+
441+ kfree(erandom_state->buf);
442+ kfree(erandom_state);
443+
444+ return result;
445+ }
446+ if (frandom_major == 0) frandom_major = result; /* dynamic */
447+
448+ return 0; /* succeed */
449+}
450+
451+module_init(frandom_init_module);
452+module_exit(frandom_cleanup_module);
453+
454+EXPORT_SYMBOL(erandom_get_random_bytes);
455diff -Naur linux-2.4.27.orig/drivers/char/random.c linux-2.4.27.frandom/drivers/char/random.c
456--- linux-2.4.27.orig/drivers/char/random.c 2004-02-18 13:36:31.000000000 +0000
457+++ linux-2.4.27.frandom/drivers/char/random.c 2004-11-04 01:11:24.260817472 +0000
458@@ -1870,6 +1870,60 @@
459 return 1;
460 }
461
462+#ifdef CONFIG_FRANDOM
463+/* We don't really want to create a header file for frandom
464+ at this stage, so here's the prototype: */
465+
466+void erandom_get_random_bytes(char *buf, size_t count);
467+
468+static int proc_do_erandom(ctl_table *table, int write, struct file *filp,
469+ void *buffer, size_t *lenp)
470+{
471+ ctl_table fake_table;
472+ unsigned char buf[64], random[16], *p;
473+ int i;
474+
475+ erandom_get_random_bytes(random, 16);
476+
477+ p=buf;
478+
479+ for (i=0; i<16; i++) {
480+ sprintf(p, "%02x", random[i]);
481+ p+=2;
482+ }
483+
484+ fake_table.data = buf;
485+ fake_table.maxlen = sizeof(buf);
486+
487+ return proc_dostring(&fake_table, write, filp, buffer, lenp);
488+}
489+
490+
491+static int erandom_strategy(ctl_table *table, int *name, int nlen,
492+ void *oldval, size_t *oldlenp,
493+ void *newval, size_t newlen, void **context)
494+{
495+ unsigned char random[16];
496+ unsigned int len;
497+
498+ if (!oldval || !oldlenp)
499+ return 1;
500+
501+ erandom_get_random_bytes(random, 16);
502+
503+ if (get_user(len, oldlenp))
504+ return -EFAULT;
505+ if (len) {
506+ if (len > 16)
507+ len = 16;
508+ if (copy_to_user(oldval, random, len) ||
509+ put_user(len, oldlenp))
510+ return -EFAULT;
511+ }
512+ return 1;
513+}
514+#endif
515+
516 ctl_table random_table[] = {
517 {RANDOM_POOLSIZE, "poolsize",
518 &sysctl_poolsize, sizeof(int), 0644, NULL,
519@@ -1888,6 +1942,11 @@
520 {RANDOM_BOOT_ID, "boot_id",
521 &sysctl_bootid, 16, 0444, NULL,
522 &proc_do_uuid, &uuid_strategy},
523+#ifdef CONFIG_FRANDOM
524+ {RANDOM_ERANDOM, "erandom",
525+ NULL, 16, 0444, NULL,
526+ &proc_do_erandom, &erandom_strategy},
527+#endif
528 {RANDOM_UUID, "uuid",
529 NULL, 16, 0444, NULL,
530 &proc_do_uuid, &uuid_strategy},
531diff -Naur linux-2.4.27.orig/include/linux/sysctl.h linux-2.4.27.frandom/include/linux/sysctl.h
532--- linux-2.4.27.orig/include/linux/sysctl.h 2004-08-07 23:26:06.000000000 +0000
533+++ linux-2.4.27.frandom/include/linux/sysctl.h 2004-11-04 01:13:02.000000000 +0000
534@@ -184,6 +184,7 @@
535 };
536
537 /* /proc/sys/kernel/random */
538+#define SYSCTL_ERANDOM
539 enum
540 {
541 RANDOM_POOLSIZE=1,
542@@ -191,7 +192,8 @@
543 RANDOM_READ_THRESH=3,
544 RANDOM_WRITE_THRESH=4,
545 RANDOM_BOOT_ID=5,
546- RANDOM_UUID=6
547+ RANDOM_UUID=6,
548+ RANDOM_ERANDOM=7
549 };
550
551 /* /proc/sys/bus/isa */