57 #define RANDOMDEV "/dev/urandom"
71 static void _nmsg_random_addrandom(nmsg_random_t, uint8_t *,
size_t);
72 static void _nmsg_random_check_stir(nmsg_random_t r);
73 static void _nmsg_random_stir(nmsg_random_t);
74 static uint8_t _nmsg_random_getbyte(nmsg_random_t r);
75 static uint32_t _nmsg_random_getuint32(nmsg_random_t r);
80 nmsg_random_init(
void) {
81 struct nmsg_random *r;
84 r = calloc(1,
sizeof(*r));
88 for (n = 0; n < 256; n++)
99 nmsg_random_destroy(nmsg_random_t *r) {
105 _nmsg_random_addrandom(nmsg_random_t r, uint8_t *dat,
size_t datlen) {
110 for (n = 0; n < 256; n++) {
113 r->j = (r->j + si + dat[n % datlen]);
114 r->s[r->i] = r->s[r->j];
121 _nmsg_random_check_stir(nmsg_random_t r) {
122 if (r->arc4_count <= 0)
123 _nmsg_random_stir(r);
127 _nmsg_random_stir(nmsg_random_t r) {
132 uint8_t rnd[KEYSIZE];
135 fd = open(RANDOMDEV, O_RDONLY, 0);
138 if (read(fd, &rdat.rnd, KEYSIZE) == KEYSIZE)
141 _nmsg_random_addrandom(r, rdat.rnd,
sizeof(rdat.rnd));
144 (void)gettimeofday(&rdat.tv, NULL);
147 _nmsg_random_addrandom(r, (uint8_t *)&rdat,
sizeof(rdat));
157 for (n = 0; n < 1024; n++)
158 (
void)_nmsg_random_getbyte(r);
159 r->arc4_count = 1600000;
163 _nmsg_random_getbyte(nmsg_random_t r) {
173 return (r->s[(si + sj) & 0xff]);
177 _nmsg_random_getuint32(nmsg_random_t r) {
180 val = _nmsg_random_getbyte(r) << 24;
181 val |= _nmsg_random_getbyte(r) << 16;
182 val |= _nmsg_random_getbyte(r) << 8;
183 val |= _nmsg_random_getbyte(r);
189 nmsg_random_uint32(nmsg_random_t r) {
192 _nmsg_random_check_stir(r);
193 rnd = _nmsg_random_getuint32(r);
200 nmsg_random_buf(nmsg_random_t r, uint8_t *buf,
size_t n) {
202 _nmsg_random_check_stir(r);
203 buf[n] = _nmsg_random_getbyte(r);
219 nmsg_random_uniform(nmsg_random_t r, uint32_t upper_bound) {
225 #if (ULONG_MAX > 0xffffffffUL)
226 min = 0x100000000UL % upper_bound;
229 if (upper_bound > 0x80000000)
230 min = 1 + ~upper_bound;
233 min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound;
244 rnd = nmsg_random_uint32(r);
249 return (rnd % upper_bound);