]>
jfr.im git - irc/quakenet/snircd.git/blob - ircd/random.c
2 * IRC - Internet Relay Chat, ircd/random.c
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 1, or (at your option)
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 * @brief 32-bit pseudo-random number generator implementation.
20 * @version $Id: random.c,v 1.8 2004/10/06 00:22:09 entrope Exp $
28 #include "ircd_reply.h"
34 /** Pseudo-random number generator state. */
35 static struct MD5Context localkey
;
36 /** Next byte position in #localkey to insert at. */
37 static unsigned int localkey_pos
;
39 /** Add bytes to #localkey.
40 * This should be fairly resistant to adding non-random bytes, but the
41 * more random the bytes are, the harder it is for an attacker to
42 * guess the internal state.
43 * @param[in] buf Buffer of bytes to add.
44 * @param[in] count Number of bytes to add.
47 random_add_entropy(const char *buf
, unsigned int count
)
50 localkey
.in
[localkey_pos
++] ^= *buf
++;
51 if (localkey_pos
>= sizeof(localkey
.in
))
56 /** Seed the PRNG with a string.
57 * @param[in] from Client setting the seed (may be NULL).
58 * @param[in] fields Input arguments (fields[0] is used).
59 * @param[in] count Number of input arguments.
60 * @return Non-zero on success, zero on error.
63 random_seed_set(struct Client
* from
, const char* const* fields
, int count
)
66 if (from
) /* send an error */
67 return need_more_params(from
, "SET");
69 log_write(LS_CONFIG
, L_ERROR
, 0, "Not enough fields in F line");
74 random_add_entropy(fields
[0], strlen(fields
[0]));
78 /** Generate a pseudo-random number.
79 * This uses the #localkey structure plus current time as input to
80 * MD5, feeding most of the MD5 output back to #localkey and using one
81 * output words as the pseudo-random output.
82 * @return A 32-bit pseudo-random number.
84 unsigned int ircrandom(void)
89 /* Add some randomness to the pool. */
92 usec
[1] = tv
.tv_usec
>> 8;
93 usec
[2] = tv
.tv_usec
>> 16;
94 random_add_entropy(usec
, 3);
96 /* Perform MD5 step. */
97 localkey
.buf
[0] = 0x67452301;
98 localkey
.buf
[1] = 0xefcdab89;
99 localkey
.buf
[2] = 0x98badcfe;
100 localkey
.buf
[3] = 0x10325476;
101 MD5Transform(localkey
.buf
, (uint32
*)localkey
.in
);
103 /* Feed back 12 bytes of hash value into randomness pool. */
104 random_add_entropy((char*)localkey
.buf
, 12);
106 /* Return the final word of hash, which should not provide any
107 * useful insight into current pool contents. */
108 return localkey
.buf
[3];