View | Details | Raw Unified | Return to bug 182610 | Differences between
and this patch

Collapse All | Expand All

(-)b/lib/libc/gen/arc4random.c (-121 / +164 lines)
Lines 3-8 Link Here
3
/*
3
/*
4
 * Copyright (c) 1996, David Mazieres <dm@uun.org>
4
 * Copyright (c) 1996, David Mazieres <dm@uun.org>
5
 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
5
 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
6
 * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
6
 *
7
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * purpose with or without fee is hereby granted, provided that the above
Lines 18-32 Link Here
18
 */
19
 */
19
20
20
/*
21
/*
21
 * Arc4 random number generator for OpenBSD.
22
 * ChaCha based random number generator for OpenBSD.
22
 *
23
 * This code is derived from section 17.1 of Applied Cryptography,
24
 * second edition, which describes a stream cipher allegedly
25
 * compatible with RSA Labs "RC4" cipher (the actual description of
26
 * which is a trade secret).  The same algorithm is used as a stream
27
 * cipher called "arcfour" in Tatu Ylonen's ssh package.
28
 *
29
 * RC4 is a registered trademark of RSA Laboratories.
30
 */
23
 */
31
24
32
#include <sys/cdefs.h>
25
#include <sys/cdefs.h>
Lines 37-67 __FBSDID("$FreeBSD$"); Link Here
37
#include <limits.h>
30
#include <limits.h>
38
#include <stdlib.h>
31
#include <stdlib.h>
39
#include <unistd.h>
32
#include <unistd.h>
33
#include <string.h>
40
#include <sys/types.h>
34
#include <sys/types.h>
41
#include <sys/param.h>
35
#include <sys/param.h>
42
#include <sys/sysctl.h>
36
#include <sys/sysctl.h>
43
#include <sys/time.h>
37
#include <sys/time.h>
38
#include <sys/mman.h>
44
#include <pthread.h>
39
#include <pthread.h>
45
40
46
#include "libc_private.h"
41
#include "libc_private.h"
47
#include "un-namespace.h"
42
#include "un-namespace.h"
48
43
44
#define KEYSTREAM_ONLY
45
#include "chacha_private.h"
46
49
#ifdef __GNUC__
47
#ifdef __GNUC__
50
#define inline __inline
48
#define inline __inline
51
#else				/* !__GNUC__ */
49
#else				/* !__GNUC__ */
52
#define inline
50
#define inline
53
#endif				/* !__GNUC__ */
51
#endif				/* !__GNUC__ */
54
52
55
struct arc4_stream {
56
	u_int8_t i;
57
	u_int8_t j;
58
	u_int8_t s[256];
59
};
60
61
static pthread_mutex_t	arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
53
static pthread_mutex_t	arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
62
54
63
#define	RANDOMDEV	"/dev/random"
55
#define	RANDOMDEV	"/dev/random"
64
#define	KEYSIZE		128
56
#define	KEYSZ		32
57
#define	IVSZ		8
58
#define	BLOCKSZ		64
59
#define	RSBUFSZ		(16 * BLOCKSZ)
65
#define	_ARC4_LOCK()						\
60
#define	_ARC4_LOCK()						\
66
	do {							\
61
	do {							\
67
		if (__isthreaded)				\
62
		if (__isthreaded)				\
Lines 74-120 static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; Link Here
74
			_pthread_mutex_unlock(&arc4random_mtx);	\
69
			_pthread_mutex_unlock(&arc4random_mtx);	\
75
	} while (0)
70
	} while (0)
76
71
77
static int rs_initialized;
72
/* Marked INHERIT_ZERO, so zero'd out in fork children. */
78
static struct arc4_stream rs;
73
static struct {
79
static pid_t arc4_stir_pid;
74
	/* valid bytes at end of rs_buf */
80
static int arc4_count;
75
	size_t		rs_have;
76
	/* bytes till reseed */
77
	size_t		rs_count;
78
} *rs;
79
80
/* Preserved in fork children */
81
static struct {
82
	/* chacha context for random keystream */
83
	chacha_ctx	ctx;		
84
	/* keystream blocks */	
85
	u_char		rs_buf[RSBUFSZ];
86
} *rsx;
81
87
82
extern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
88
extern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
83
    void *newp, size_t newlen);
89
    void *newp, size_t newlen);
84
90
85
static inline u_int8_t arc4_getbyte(void);
91
static inline void _rs_rekey(u_char *dat, size_t datlen);
86
static void arc4_stir(void);
87
92
88
static inline void
93
static inline void
89
arc4_init(void)
94
_rs_init(u_char *buf, size_t n)
90
{
95
{
91
	int     n;
96
	if (n < (KEYSZ+ IVSZ))
97
		return;
92
98
93
	for (n = 0; n < 256; n++)
99
	if (rs == NULL) {
94
		rs.s[n] = n;
100
		if ((rs = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE,
95
	rs.i = 0;
101
			MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
96
	rs.j = 0;
102
			abort();
97
}
98
103
99
static inline void
104
		if (minherit(rs, sizeof(*rs), INHERIT_ZERO) == -1) {
100
arc4_addrandom(u_char *dat, int datlen)
105
			munmap(rs, sizeof(*rs));
101
{
106
			abort();
102
	int     n;
107
		}
103
	u_int8_t si;
108
104
109
		if ((rsx = mmap(NULL, sizeof(*rsx), PROT_READ|PROT_WRITE,
105
	rs.i--;
110
			MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
106
	for (n = 0; n < 256; n++) {
111
			munmap(rs, sizeof(*rs));
107
		rs.i = (rs.i + 1);
112
			abort();
108
		si = rs.s[rs.i];
113
		}
109
		rs.j = (rs.j + si + dat[n % datlen]);
114
110
		rs.s[rs.i] = rs.s[rs.j];
115
		if (minherit(rsx, sizeof(*rsx), INHERIT_ZERO) == -1) {
111
		rs.s[rs.j] = si;
116
			munmap(rsx, sizeof(*rsx));
117
			munmap(rs, sizeof(*rs));
118
			abort();
119
		}
112
	}
120
	}
113
	rs.j = rs.i;
121
122
	chacha_keysetup(&rsx->ctx, buf, KEYSZ * 8, 0);
123
	chacha_ivsetup(&rsx->ctx, buf + KEYSZ);
114
}
124
}
115
125
116
static size_t
126
static size_t
117
arc4_sysctl(u_char *buf, size_t size)
127
_rs_sysctl(u_char *buf, size_t size)
118
{
128
{
119
	int mib[2];
129
	int mib[2];
120
	size_t len, done;
130
	size_t len, done;
Lines 135-233 arc4_sysctl(u_char *buf, size_t size) Link Here
135
	return (done);
145
	return (done);
136
}
146
}
137
147
148
static size_t
149
arc4_sysctl(u_char *buf, size_t size)
150
{
151
	return (_rs_sysctl(buf, size));
152
}
153
138
static void
154
static void
139
arc4_stir(void)
155
_rs_stir(void)
140
{
156
{
141
	int done, fd, i;
142
	struct {
157
	struct {
143
		struct timeval	tv;
158
		struct timeval	tv;
144
		pid_t		pid;
159
		u_char		rnd[KEYSZ + IVSZ];
145
		u_char	 	rnd[KEYSIZE];
146
	} rdat;
160
	} rdat;
161
	int done, fd;
147
162
148
	if (!rs_initialized) {
149
		arc4_init();
150
		rs_initialized = 1;
151
	}
152
	done = 0;
163
	done = 0;
153
	if (arc4_sysctl((u_char *)&rdat, KEYSIZE) == KEYSIZE)
164
	if (_rs_sysctl((u_char *)&rdat, KEYSZ + IVSZ) == (KEYSZ + IVSZ))
154
		done = 1;
165
		done = 1;
166
155
	if (!done) {
167
	if (!done) {
156
		fd = _open(RANDOMDEV, O_RDONLY | O_CLOEXEC, 0);
168
		fd = _open(RANDOMDEV, O_RDONLY | O_CLOEXEC, 0);
157
		if (fd >= 0) {
169
		if (fd >= 0) {
158
			if (_read(fd, &rdat, KEYSIZE) == KEYSIZE)
170
			if (_read(fd, &rdat, (KEYSZ + IVSZ)) == (KEYSZ + IVSZ))
159
				done = 1;
171
				done = 1;
160
			(void)_close(fd);
172
			(void)_close(fd);
161
		}
173
		}
162
	}
174
	}
175
163
	if (!done) {
176
	if (!done) {
164
		(void)gettimeofday(&rdat.tv, NULL);
177
		(void)gettimeofday(&rdat.tv, NULL);
165
		rdat.pid = getpid();
166
		/* We'll just take whatever was on the stack too... */
178
		/* We'll just take whatever was on the stack too... */
167
	}
179
	}
168
180
169
	arc4_addrandom((u_char *)&rdat, KEYSIZE);
181
	if (!rs) {
182
		_rs_init((u_char *)&rdat, KEYSZ + IVSZ);
183
	} else {
184
		_rs_rekey((u_char *)&rdat, KEYSZ + IVSZ);
185
	}
170
186
171
	/*
187
	memset((u_char *)&rdat, 0, sizeof(rdat));
172
	 * Discard early keystream, as per recommendations in:
188
173
	 * "(Not So) Random Shuffles of RC4" by Ilya Mironov.
189
	/* invalidate rs_buf */
174
	 */
190
	rs->rs_have = 0;
175
	for (i = 0; i < 1024; i++)
191
	memset(rsx->rs_buf, 0, RSBUFSZ);
176
		(void)arc4_getbyte();
192
177
	arc4_count = 1600000;
193
	rs->rs_count = 1600000;
178
}
194
}
179
195
180
static void
196
static inline void
181
arc4_stir_if_needed(void)
197
_rs_stir_if_needed(size_t len)
182
{
198
{
183
	pid_t pid = getpid();
199
	if (!rs || rs->rs_count <= len)
184
200
		_rs_stir();
185
	if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != pid) {
201
	else	
186
		arc4_stir_pid = pid;
202
		rs->rs_count -= len;
187
		arc4_stir();
188
	}
189
}
203
}
190
204
191
static inline u_int8_t
205
static inline void
192
arc4_getbyte(void)
206
_rs_rekey(u_char *dat, size_t datlen)
193
{
207
{
194
	u_int8_t si, sj;
208
#ifndef KEYSTREAM_ONLY
195
209
	memset(rsx->rs_buf, 0, RSBUFSZ);
196
	rs.i = (rs.i + 1);
210
#endif
197
	si = rs.s[rs.i];
211
198
	rs.j = (rs.j + si);
212
	/* fill rs_buf with the keystream */
199
	sj = rs.s[rs.j];
213
	chacha_encrypt_bytes(&rsx->ctx, rsx->rs_buf, rsx->rs_buf, RSBUFSZ);
200
	rs.s[rs.i] = sj;
214
	/* mix in optional user provided data */
201
	rs.s[rs.j] = si;
215
	if (dat) {
202
	return (rs.s[(si + sj) & 0xff]);
216
		size_t i, m;
217
218
		m = MIN(datlen, (KEYSZ + IVSZ));
219
		for (i = 0; i < m; i++)
220
			rsx->rs_buf[i] ^= dat[i];
221
	}
222
	/* immediatly reinit for backtracking resistance */
223
	_rs_init(rsx->rs_buf, (KEYSZ + IVSZ));
224
	memset(rsx->rs_buf, 0, (KEYSZ + IVSZ));
225
	rs->rs_have = (RSBUFSZ - KEYSZ - IVSZ);
203
}
226
}
204
227
205
static inline u_int32_t
228
static inline void
206
arc4_getword(void)
229
_rs_random_buf(void *_buf, size_t n)
207
{
230
{
208
	u_int32_t val;
231
	u_char *buf = (u_char *)_buf;
209
	val = arc4_getbyte() << 24;
232
	u_char *keystream;
210
	val |= arc4_getbyte() << 16;
233
	size_t m;
211
	val |= arc4_getbyte() << 8;
234
212
	val |= arc4_getbyte();
235
	_rs_stir_if_needed(n);
213
	return val;
236
	while (n > 0) {
237
		if (rs->rs_have > 0) {
238
			m = MIN(n, rs->rs_have);
239
			keystream = (rsx->rs_buf + RSBUFSZ - rs->rs_have);
240
			memcpy(buf, keystream, m);
241
			memset(keystream, 0, m);
242
			buf += m;
243
			n -= m;
244
			rs->rs_have -= m;
245
		}
246
247
		if (rs->rs_have == 0)
248
			_rs_rekey(NULL, 0);
249
	}
214
}
250
}
215
251
216
void
252
static inline void
217
arc4random_stir(void)
253
_rs_random_u32(u_int32_t *val)
218
{
254
{
219
	_ARC4_LOCK();
255
	u_char *keystream;
220
	arc4_stir();
256
221
	_ARC4_UNLOCK();
257
	_rs_stir_if_needed(sizeof(*val));
258
	if (rs->rs_have < sizeof(*val))
259
		_rs_rekey(NULL, 0);
260
	keystream = (rsx->rs_buf + RSBUFSZ - rs->rs_have);
261
	memcpy(val, keystream, sizeof(*val));
262
	memset(keystream, 0, sizeof(*val));
263
	rs->rs_have -= sizeof(*val);
222
}
264
}
223
265
224
void
266
void
225
arc4random_addrandom(u_char *dat, int datlen)
267
arc4random_addrandom(u_char *dat, int datlen)
226
{
268
{
269
	int m;
270
227
	_ARC4_LOCK();
271
	_ARC4_LOCK();
228
	if (!rs_initialized)
272
	if (!rs)
229
		arc4_stir();
273
		_rs_stir();
230
	arc4_addrandom(dat, datlen);
274
275
	while (datlen > 0) {
276
		m = MIN(datlen, (KEYSZ + IVSZ));
277
		_rs_rekey(dat, m);
278
		dat += m;
279
		datlen -= m;
280
	}
231
	_ARC4_UNLOCK();
281
	_ARC4_UNLOCK();
232
}
282
}
233
283
Lines 235-244 u_int32_t Link Here
235
arc4random(void)
285
arc4random(void)
236
{
286
{
237
	u_int32_t val;
287
	u_int32_t val;
288
238
	_ARC4_LOCK();
289
	_ARC4_LOCK();
239
	arc4_count -= 4;
290
	_rs_random_u32(&val);
240
	arc4_stir_if_needed();
241
	val = arc4_getword();
242
	_ARC4_UNLOCK();
291
	_ARC4_UNLOCK();
243
	return val;
292
	return val;
244
}
293
}
Lines 246-295 arc4random(void) Link Here
246
void
295
void
247
arc4random_buf(void *_buf, size_t n)
296
arc4random_buf(void *_buf, size_t n)
248
{
297
{
249
	u_char *buf = (u_char *)_buf;
250
	_ARC4_LOCK();
298
	_ARC4_LOCK();
251
	arc4_stir_if_needed();
299
	_rs_random_buf(_buf, n);
252
	while (n--) {
300
	_ARC4_UNLOCK();
253
		if (--arc4_count <= 0)
301
}
254
			arc4_stir();
302
255
		buf[n] = arc4_getbyte();
303
void
256
	}
304
arc4random_stir(void)
305
{
306
	_ARC4_LOCK();
307
	_rs_stir();
257
	_ARC4_UNLOCK();
308
	_ARC4_UNLOCK();
258
}
309
}
259
310
260
/*
261
 * Calculate a uniformly distributed random number less than upper_bound
262
 * avoiding "modulo bias".
263
 *
264
 * Uniformity is achieved by generating new random numbers until the one
265
 * returned is outside the range [0, 2**32 % upper_bound).  This
266
 * guarantees the selected random number will be inside
267
 * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
268
 * after reduction modulo upper_bound.
269
 */
270
u_int32_t
311
u_int32_t
271
arc4random_uniform(u_int32_t upper_bound)
312
arc4random_uniform(u_int32_t upper_bound)
272
{
313
{
273
	u_int32_t r, min;
314
	u_int32_t r, min;
274
315
275
	if (upper_bound < 2)
316
	if (upper_bound < 2)
276
		return 0;
317
		return (0);
277
318
278
	/* 2**32 % x == (2**32 - x) % x */
319
	/* 2**32 % x == (2**32 - x) % x */
279
	min = -upper_bound % upper_bound;
320
	min = -upper_bound % upper_bound;
321
280
	/*
322
	/*
281
	 * This could theoretically loop forever but each retry has
323
	 * This could theorically loop forever but each retry has
282
	 * p > 0.5 (worst case, usually far better) of selecting a
324
	 * p > 0.5 (worst case, usually far better) of selecting a
283
	 * number inside the range we need, so it should rarely need
325
	 * number inside the range we need, so it should rarely need
284
	 * to re-roll.
326
	 * to re-roll.
285
	 */
327
	 */
328
286
	for (;;) {
329
	for (;;) {
287
		r = arc4random();
330
		r = arc4random();
288
		if (r >= min)
331
		if (r >= min)
289
			break;
332
			break;
290
	}
333
	}
291
334
292
	return r % upper_bound;
335
	return (r % upper_bound);
293
}
336
}
294
337
295
#if 0
338
#if 0
(-)b/lib/libc/gen/chacha_private.h (+233 lines)
Added Link Here
1
/*
2
chacha-merged.c version 20080118
3
D.J. Bernstein
4
Public domain.
5
*/
6
7
/* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */
8
9
typedef unsigned char u8;
10
typedef unsigned int u32;
11
12
typedef struct
13
{
14
	u32 input[16];	/* could be compressed */
15
} chacha_ctx;
16
17
#define	U8C(v)	(v##U)
18
#define	U32C(v)	(v##U)
19
20
#define U8V(v)	((u8)(v) & U8C(0xFF))
21
#define	U32V(v)	((u32)(v) & U32C(0xFFFFFFFF))
22
23
#define	ROTL32(v, n)							\
24
	(U32V((v) << (n)) | ((v) >> (32 - (n))))
25
26
#define	U8TO32_LITTLE(p)						\
27
	(((u32)((p)[0]))	|					\
28
	((u32)((p)[1]) << 8)	|					\
29
	((u32)((p)[2]) << 16)	|					\
30
	((u32)((p)[3]) << 24))
31
32
#define	U32TO8_LITTLE(p, v)						\
33
	do {								\
34
		(p)[0] = U8V((v));					\
35
		(p)[1] = U8V((v) >> 8);					\
36
		(p)[2] = U8V((v) >> 16);				\
37
		(p)[3] = U8V((v) >> 24);				\
38
	} while (0)
39
40
#define	ROTATE(v, c)	(ROTL32(v, c))
41
#define	XOR(v, w)		((v) ^ (w))
42
#define	PLUS(v, w)		(U32V((v) + (w)))
43
#define	PLUSONE(v)		(PLUS((v), 1))
44
45
#define	QUARTERROUND(a, b, c, d)					\
46
	a = PLUS(a, b); d = ROTATE(XOR(d, a), 16);			\
47
	c = PLUS(c, d); b = ROTATE(XOR(b, c), 12);			\
48
	a = PLUS(a, b); d = ROTATE(XOR(d, a), 8);			\
49
	c = PLUS(c, d); b = ROTATE(XOR(b, c), 7);
50
51
static const char sigma[16] = "expand 32-byte k";
52
static const char tau[16] = "expand 16-byte k";
53
54
static void
55
chacha_keysetup(chacha_ctx *x, const u8 *k, u32 kbits, u32 ivbits)
56
{
57
	const char *constants;
58
59
	x->input[4] = U8TO32_LITTLE(k + 0);
60
	x->input[5] = U8TO32_LITTLE(k + 4);
61
	x->input[6] = U8TO32_LITTLE(k + 8);
62
	x->input[7] = U8TO32_LITTLE(k + 12);
63
64
	if (kbits == 256) {	/* recommended */
65
		k += 16;
66
		constants = sigma;
67
	} else {			/* kbits == 128 */
68
		constants = tau;
69
	}
70
71
	x->input[8] = U8TO32_LITTLE(k + 0);
72
	x->input[9] = U8TO32_LITTLE(k + 4);
73
	x->input[10] = U8TO32_LITTLE(k + 8);
74
	x->input[11] = U8TO32_LITTLE(k + 12);
75
	x->input[0] = U8TO32_LITTLE(constants + 0);
76
	x->input[1] = U8TO32_LITTLE(constants + 4);
77
	x->input[2] = U8TO32_LITTLE(constants + 8);
78
	x->input[3] = U8TO32_LITTLE(constants + 12);
79
}
80
81
static void
82
chacha_ivsetup(chacha_ctx *x, const u8 *iv)
83
{
84
	x->input[12] = 0;
85
	x->input[13] = 0;
86
	x->input[14] = U8TO32_LITTLE(iv + 0);
87
	x->input[15] = U8TO32_LITTLE(iv + 4);
88
}
89
90
static void
91
chacha_encrypt_bytes(chacha_ctx *x, const u8 *m, u8 *c, u32 bytes)
92
{
93
	u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
94
	u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
95
	u8 *ctarget = NULL;
96
	u8 tmp[64];
97
	u_int i;
98
99
	if (!bytes)
100
		return;
101
102
	j0 = x->input[0];
103
	j1 = x->input[1];
104
	j2 = x->input[2];
105
	j3 = x->input[3];
106
	j4 = x->input[4];
107
	j5 = x->input[5];
108
	j6 = x->input[6];
109
	j7 = x->input[7];
110
	j8 = x->input[8];
111
	j9 = x->input[9];
112
	j10 = x->input[10];
113
	j11 = x->input[11];
114
	j12 = x->input[12];
115
	j13 = x->input[13];
116
	j14 = x->input[14];
117
	j15 = x->input[15];
118
119
	for (;;) {
120
		if (bytes < 64) {
121
			for (i = 0; i < bytes; ++i)
122
				tmp[i] = m[i];
123
			m = tmp;
124
			ctarget = c;
125
			c = tmp;
126
		}
127
128
		x0 = j0;
129
		x1 = j1;
130
		x2 = j2;
131
		x3 = j3;
132
		x4 = j4;
133
		x5 = j5;
134
		x6 = j6;
135
		x7 = j7;
136
		x8 = j8;
137
		x9 = j9;
138
		x10 = j10;
139
		x11 = j11;
140
		x12 = j12;
141
		x13 = j13;
142
		x14 = j14;
143
		x15 = j15;
144
145
		for (i = 20; i > 0; i -= 2) {
146
			QUARTERROUND(x0, x4, x8, x12)
147
			QUARTERROUND(x1, x5, x9, x13)
148
			QUARTERROUND(x2, x6, x10, x14)
149
			QUARTERROUND(x3, x7, x11, x15)
150
			QUARTERROUND(x0, x5, x10, x15)
151
			QUARTERROUND(x1, x6, x11, x12)
152
			QUARTERROUND(x2, x7, x8, x13)
153
			QUARTERROUND(x3, x4, x9, x14)
154
		}
155
156
		x0 = PLUS(x0, j0);
157
		x1 = PLUS(x1, j1);
158
		x2 = PLUS(x2, j2);
159
		x3 = PLUS(x3, j3);
160
		x4 = PLUS(x4, j4);
161
		x5 = PLUS(x5, j5);
162
		x6 = PLUS(x6, j6);
163
		x7 = PLUS(x7, j7);
164
		x8 = PLUS(x8, j8);
165
		x9 = PLUS(x9, j9);
166
		x10 = PLUS(x10, j10);
167
		x11 = PLUS(x11, j11);
168
		x12 = PLUS(x12, j12);
169
		x13 = PLUS(x13, j13);
170
		x14 = PLUS(x14, j14);
171
		x15 = PLUS(x15, j15);
172
173
#ifndef	KEYSTREAM_ONLY
174
		x0 = XOR(x0, U8TO32_LITTLE(m + 0));
175
		x1 = XOR(x1, U8TO32_LITTLE(m + 4));
176
		x2 = XOR(x2, U8TO32_LITTLE(m + 8));
177
		x3 = XOR(x3, U8TO32_LITTLE(m + 12));
178
		x4 = XOR(x4, U8TO32_LITTLE(m + 16));
179
		x5 = XOR(x5, U8TO32_LITTLE(m + 20));
180
		x6 = XOR(x6, U8TO32_LITTLE(m + 24));
181
		x7 = XOR(x7, U8TO32_LITTLE(m + 28));
182
		x8 = XOR(x8, U8TO32_LITTLE(m + 32));
183
		x9 = XOR(x9, U8TO32_LITTLE(m + 36));
184
		x10 = XOR(x10, U8TO32_LITTLE(m + 40));
185
		x11 = XOR(x11, U8TO32_LITTLE(m + 44));
186
		x12 = XOR(x12, U8TO32_LITTLE(m + 48));
187
		x13 = XOR(x13, U8TO32_LITTLE(m + 52));
188
		x14 = XOR(x14, U8TO32_LITTLE(m + 56));
189
		x15 = XOR(x15, U8TO32_LITTLE(m + 60));
190
#endif
191
192
		j12 = PLUSONE(j12);
193
194
		if (!j12) {
195
			j13 = PLUSONE(j13);
196
			/* stopping at 2^70 bytes per nonce is user responsability */
197
		}
198
199
		U32TO8_LITTLE(c + 0, x0);
200
		U32TO8_LITTLE(c + 4, x1);
201
		U32TO8_LITTLE(c + 8, x2);
202
		U32TO8_LITTLE(c + 12, x3);
203
		U32TO8_LITTLE(c + 16, x4);
204
		U32TO8_LITTLE(c + 20, x5);
205
		U32TO8_LITTLE(c + 24, x6);
206
		U32TO8_LITTLE(c + 28, x7);
207
		U32TO8_LITTLE(c + 32, x8);
208
		U32TO8_LITTLE(c + 36, x9);
209
		U32TO8_LITTLE(c + 40, x10);
210
		U32TO8_LITTLE(c + 44, x11);
211
		U32TO8_LITTLE(c + 48, x12);
212
		U32TO8_LITTLE(c + 52, x13);
213
		U32TO8_LITTLE(c + 56, x14);
214
		U32TO8_LITTLE(c + 60, x15);
215
216
		if (bytes <= 64) {
217
			if (bytes < 64) {
218
				for (i = 0; i < bytes; ++i)
219
					ctarget[i] = c[i];
220
			}
221
222
			x->input[12] = j12;
223
			x->input[13] = j13;
224
			return;
225
		}
226
227
		bytes -= 64;
228
		c += 64;
229
#ifndef	KEYSTREAM_ONLY
230
		m += 64;
231
#endif
232
	}
233
}
(-)b/lib/libc/sys/minherit.2 (+3 lines)
Lines 91-96 it will no longer be shared in the parent Link Here
91
after the parent forks and there is no way to get the previous
91
after the parent forks and there is no way to get the previous
92
shared-backing-store mapping without unmapping and remapping the address
92
shared-backing-store mapping without unmapping and remapping the address
93
space in the parent.
93
space in the parent.
94
.It Dv INHERIT_ZERO
95
This option guarantees that a fork has
96
zero'd memory mapping.
94
.El
97
.El
95
.Sh RETURN VALUES
98
.Sh RETURN VALUES
96
.Rv -std minherit
99
.Rv -std minherit
(-)b/sys/crypto/chacha_private.h (+233 lines)
Added Link Here
1
/*
2
chacha-merged.c version 20080118
3
D.J. Bernstein
4
Public domain.
5
*/
6
7
/* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */
8
9
typedef unsigned char u8;
10
typedef unsigned int u32;
11
12
typedef struct
13
{
14
	u32 input[16];	/* could be compressed */
15
} chacha_ctx;
16
17
#define	U8C(v)	(v##U)
18
#define	U32C(v)	(v##U)
19
20
#define U8V(v)	((u8)(v) & U8C(0xFF))
21
#define	U32V(v)	((u32)(v) & U32C(0xFFFFFFFF))
22
23
#define	ROTL32(v, n)							\
24
	(U32V((v) << (n)) | ((v) >> (32 - (n))))
25
26
#define	U8TO32_LITTLE(p)						\
27
	(((u32)((p)[0]))	|					\
28
	((u32)((p)[1]) << 8)	|					\
29
	((u32)((p)[2]) << 16)	|					\
30
	((u32)((p)[3]) << 24))
31
32
#define	U32TO8_LITTLE(p, v)						\
33
	do {								\
34
		(p)[0] = U8V((v));					\
35
		(p)[1] = U8V((v) >> 8);					\
36
		(p)[2] = U8V((v) >> 16);				\
37
		(p)[3] = U8V((v) >> 24);				\
38
	} while (0)
39
40
#define	ROTATE(v, c)	(ROTL32(v, c))
41
#define	XOR(v, w)		((v) ^ (w))
42
#define	PLUS(v, w)		(U32V((v) + (w)))
43
#define	PLUSONE(v)		(PLUS((v), 1))
44
45
#define	QUARTERROUND(a, b, c, d)					\
46
	a = PLUS(a, b); d = ROTATE(XOR(d, a), 16);			\
47
	c = PLUS(c, d); b = ROTATE(XOR(b, c), 12);			\
48
	a = PLUS(a, b); d = ROTATE(XOR(d, a), 8);			\
49
	c = PLUS(c, d); b = ROTATE(XOR(b, c), 7);
50
51
static const char sigma[16] = "expand 32-byte k";
52
static const char tau[16] = "expand 16-byte k";
53
54
static void
55
chacha_keysetup(chacha_ctx *x, const u8 *k, u32 kbits, u32 ivbits)
56
{
57
	const char *constants;
58
59
	x->input[4] = U8TO32_LITTLE(k + 0);
60
	x->input[5] = U8TO32_LITTLE(k + 4);
61
	x->input[6] = U8TO32_LITTLE(k + 8);
62
	x->input[7] = U8TO32_LITTLE(k + 12);
63
64
	if (kbits == 256) {	/* recommended */
65
		k += 16;
66
		constants = sigma;
67
	} else {			/* kbits == 128 */
68
		constants = tau;
69
	}
70
71
	x->input[8] = U8TO32_LITTLE(k + 0);
72
	x->input[9] = U8TO32_LITTLE(k + 4);
73
	x->input[10] = U8TO32_LITTLE(k + 8);
74
	x->input[11] = U8TO32_LITTLE(k + 12);
75
	x->input[0] = U8TO32_LITTLE(constants + 0);
76
	x->input[1] = U8TO32_LITTLE(constants + 4);
77
	x->input[2] = U8TO32_LITTLE(constants + 8);
78
	x->input[3] = U8TO32_LITTLE(constants + 12);
79
}
80
81
static void
82
chacha_ivsetup(chacha_ctx *x, const u8 *iv)
83
{
84
	x->input[12] = 0;
85
	x->input[13] = 0;
86
	x->input[14] = U8TO32_LITTLE(iv + 0);
87
	x->input[15] = U8TO32_LITTLE(iv + 4);
88
}
89
90
static void
91
chacha_encrypt_bytes(chacha_ctx *x, const u8 *m, u8 *c, u32 bytes)
92
{
93
	u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
94
	u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
95
	u8 *ctarget = NULL;
96
	u8 tmp[64];
97
	u_int i;
98
99
	if (!bytes)
100
		return;
101
102
	j0 = x->input[0];
103
	j1 = x->input[1];
104
	j2 = x->input[2];
105
	j3 = x->input[3];
106
	j4 = x->input[4];
107
	j5 = x->input[5];
108
	j6 = x->input[6];
109
	j7 = x->input[7];
110
	j8 = x->input[8];
111
	j9 = x->input[9];
112
	j10 = x->input[10];
113
	j11 = x->input[11];
114
	j12 = x->input[12];
115
	j13 = x->input[13];
116
	j14 = x->input[14];
117
	j15 = x->input[15];
118
119
	for (;;) {
120
		if (bytes < 64) {
121
			for (i = 0; i < bytes; ++i)
122
				tmp[i] = m[i];
123
			m = tmp;
124
			ctarget = c;
125
			c = tmp;
126
		}
127
128
		x0 = j0;
129
		x1 = j1;
130
		x2 = j2;
131
		x3 = j3;
132
		x4 = j4;
133
		x5 = j5;
134
		x6 = j6;
135
		x7 = j7;
136
		x8 = j8;
137
		x9 = j9;
138
		x10 = j10;
139
		x11 = j11;
140
		x12 = j12;
141
		x13 = j13;
142
		x14 = j14;
143
		x15 = j15;
144
145
		for (i = 20; i > 0; i -= 2) {
146
			QUARTERROUND(x0, x4, x8, x12)
147
			QUARTERROUND(x1, x5, x9, x13)
148
			QUARTERROUND(x2, x6, x10, x14)
149
			QUARTERROUND(x3, x7, x11, x15)
150
			QUARTERROUND(x0, x5, x10, x15)
151
			QUARTERROUND(x1, x6, x11, x12)
152
			QUARTERROUND(x2, x7, x8, x13)
153
			QUARTERROUND(x3, x4, x9, x14)
154
		}
155
156
		x0 = PLUS(x0, j0);
157
		x1 = PLUS(x1, j1);
158
		x2 = PLUS(x2, j2);
159
		x3 = PLUS(x3, j3);
160
		x4 = PLUS(x4, j4);
161
		x5 = PLUS(x5, j5);
162
		x6 = PLUS(x6, j6);
163
		x7 = PLUS(x7, j7);
164
		x8 = PLUS(x8, j8);
165
		x9 = PLUS(x9, j9);
166
		x10 = PLUS(x10, j10);
167
		x11 = PLUS(x11, j11);
168
		x12 = PLUS(x12, j12);
169
		x13 = PLUS(x13, j13);
170
		x14 = PLUS(x14, j14);
171
		x15 = PLUS(x15, j15);
172
173
#ifndef	KEYSTREAM_ONLY
174
		x0 = XOR(x0, U8TO32_LITTLE(m + 0));
175
		x1 = XOR(x1, U8TO32_LITTLE(m + 4));
176
		x2 = XOR(x2, U8TO32_LITTLE(m + 8));
177
		x3 = XOR(x3, U8TO32_LITTLE(m + 12));
178
		x4 = XOR(x4, U8TO32_LITTLE(m + 16));
179
		x5 = XOR(x5, U8TO32_LITTLE(m + 20));
180
		x6 = XOR(x6, U8TO32_LITTLE(m + 24));
181
		x7 = XOR(x7, U8TO32_LITTLE(m + 28));
182
		x8 = XOR(x8, U8TO32_LITTLE(m + 32));
183
		x9 = XOR(x9, U8TO32_LITTLE(m + 36));
184
		x10 = XOR(x10, U8TO32_LITTLE(m + 40));
185
		x11 = XOR(x11, U8TO32_LITTLE(m + 44));
186
		x12 = XOR(x12, U8TO32_LITTLE(m + 48));
187
		x13 = XOR(x13, U8TO32_LITTLE(m + 52));
188
		x14 = XOR(x14, U8TO32_LITTLE(m + 56));
189
		x15 = XOR(x15, U8TO32_LITTLE(m + 60));
190
#endif
191
192
		j12 = PLUSONE(j12);
193
194
		if (!j12) {
195
			j13 = PLUSONE(j13);
196
			/* stopping at 2^70 bytes per nonce is user responsability */
197
		}
198
199
		U32TO8_LITTLE(c + 0, x0);
200
		U32TO8_LITTLE(c + 4, x1);
201
		U32TO8_LITTLE(c + 8, x2);
202
		U32TO8_LITTLE(c + 12, x3);
203
		U32TO8_LITTLE(c + 16, x4);
204
		U32TO8_LITTLE(c + 20, x5);
205
		U32TO8_LITTLE(c + 24, x6);
206
		U32TO8_LITTLE(c + 28, x7);
207
		U32TO8_LITTLE(c + 32, x8);
208
		U32TO8_LITTLE(c + 36, x9);
209
		U32TO8_LITTLE(c + 40, x10);
210
		U32TO8_LITTLE(c + 44, x11);
211
		U32TO8_LITTLE(c + 48, x12);
212
		U32TO8_LITTLE(c + 52, x13);
213
		U32TO8_LITTLE(c + 56, x14);
214
		U32TO8_LITTLE(c + 60, x15);
215
216
		if (bytes <= 64) {
217
			if (bytes < 64) {
218
				for (i = 0; i < bytes; ++i)
219
					ctarget[i] = c[i];
220
			}
221
222
			x->input[12] = j12;
223
			x->input[13] = j13;
224
			return;
225
		}
226
227
		bytes -= 64;
228
		c += 64;
229
#ifndef	KEYSTREAM_ONLY
230
		m += 64;
231
#endif
232
	}
233
}
(-)b/sys/libkern/arc4random.c (-62 / +148 lines)
Lines 19-24 __FBSDID("$FreeBSD$"); Link Here
19
#include <sys/lock.h>
19
#include <sys/lock.h>
20
#include <sys/mutex.h>
20
#include <sys/mutex.h>
21
#include <sys/time.h>
21
#include <sys/time.h>
22
#include <sys/systm.h>
23
24
#define KEYSTREAM_ONLY
25
#include <crypto/chacha_private.h>
22
26
23
#define	ARC4_RESEED_BYTES 65536
27
#define	ARC4_RESEED_BYTES 65536
24
#define	ARC4_RESEED_SECONDS 300
28
#define	ARC4_RESEED_SECONDS 300
Lines 26-90 __FBSDID("$FreeBSD$"); Link Here
26
30
27
int arc4rand_iniseed_state = ARC4_ENTR_NONE;
31
int arc4rand_iniseed_state = ARC4_ENTR_NONE;
28
32
29
static u_int8_t arc4_i, arc4_j;
30
static int arc4_numruns = 0;
33
static int arc4_numruns = 0;
31
static u_int8_t arc4_sbox[256];
32
static time_t arc4_t_reseed;
34
static time_t arc4_t_reseed;
33
static struct mtx arc4_mtx;
35
static struct mtx arc4_mtx;
34
36
37
#define	KEYSZ		32
38
#define	IVSZ		8
39
#define	BLOCKSZ		64
40
#define	RSBUFSZ		(16*BLOCKSZ)
41
42
static int rs_initialized;
43
static chacha_ctx rs;		/* chacha context for random keystream */
44
/* keystream blocks */
45
static u_char rs_buf[RSBUFSZ];
46
static size_t rs_have;		/* valid bytes at end of rs_buf */
47
static size_t rs_count;		/* bytes till reseed */
48
35
static u_int8_t arc4_randbyte(void);
49
static u_int8_t arc4_randbyte(void);
36
50
51
static __inline void _rs_rekey(u_char *dat, size_t datlen);
52
static __inline void _rs_stir(int);
53
54
static __inline void
55
_rs_init(u_char *buf, size_t n)
56
{
57
	KASSERT(n >= (KEYSZ + IVSZ), ("_rs_init size too small"));
58
59
	chacha_keysetup(&rs, buf, (KEYSZ * 8), 0);
60
	chacha_ivsetup(&rs, (buf + KEYSZ));
61
}
62
63
static void
64
_rs_seed(u_char *buf, size_t n)
65
{
66
	_rs_rekey(buf, n);
67
68
	/* reset rs_buf */
69
	rs_have = 0;
70
	memset(rs_buf, 0, sizeof(rs_buf));
71
72
	rs_count = 1600000;
73
}
74
75
static __inline void
76
_rs_stir_if_needed(size_t len)
77
{
78
	if (!rs_initialized) {
79
		_rs_init(rs_buf, (KEYSZ + IVSZ));
80
		rs_count = 1024 * 1024 * 1024;
81
		rs_initialized = 1;
82
	} else if (rs_count <= len) {
83
		_rs_stir(0);
84
	} else {
85
		rs_count -= len;
86
	}
87
}
88
37
static __inline void
89
static __inline void
38
arc4_swap(u_int8_t *a, u_int8_t *b)
90
_rs_rekey(u_char *dat, size_t datlen)
39
{
91
{
40
	u_int8_t c;
92
	size_t n, r;
93
#ifndef	KEYSTREAM_ONLY
94
	memset(rs_buf, 0, RSBUFSZ);
95
#endif
96
97
	chacha_encrypt_bytes(&rs, rs_buf, rs_buf, RSBUFSZ);
98
	/* with user provided data, we fill a bit more */
99
	if (dat) {
100
		r = MIN(datlen, (KEYSZ + IVSZ));
101
		for (n = 0; n < r; n++)
102
			rs_buf[n] ^= dat[n];
103
	}
104
	
105
	/* backtracking resistance, we force the reinitialization */
106
	_rs_init(rs_buf, (KEYSZ + IVSZ));
107
	memset(rs_buf, 0, (KEYSZ + IVSZ));
108
	rs_have = (RSBUFSZ - KEYSZ - IVSZ);
109
}
110
111
static __inline void
112
_rs_random_buf(void *_buf, size_t n)
113
{
114
	u_char *buf = (u_char *)_buf;
115
	u_char *keystream;
116
	size_t m;
117
118
	_rs_stir_if_needed(n);
119
	while (n > 0) {
120
		if (rs_have > 0) {
121
			m = MIN(n, rs_have);
122
			keystream = (rs_buf + RSBUFSZ - rs_have);
123
			memcpy(buf, keystream, m);
124
			memset(keystream, 0, m);
125
			buf += m;
126
			n -= m;
127
			rs_have -= m;
128
		}
129
130
		if (rs_have == 0)
131
			_rs_rekey(NULL, 0);
132
	}
133
}
41
134
42
	c = *a;
135
static __inline void
43
	*a = *b;
136
_rs_random_u32(u_int32_t *val)
44
	*b = c;
137
{
45
}	
138
	u_char *keystream;
139
140
	_rs_stir_if_needed(sizeof(*val));
141
	if (rs_have < sizeof(*val))
142
		_rs_rekey(NULL, 0);
143
	keystream = (rs_buf + RSBUFSZ - rs_have);
144
	memcpy(val, keystream, sizeof(*val));
145
	memset(keystream, 0, sizeof(*val));
146
	rs_have -= sizeof(*val);
147
	return;
148
}
46
149
47
/*
150
/*
48
 * Stir our S-box.
151
 * Stir our S-box.
49
 */
152
 */
50
static void
153
static void
51
arc4_randomstir (void)
154
_rs_stir(int lock)
52
{
155
{
53
	u_int8_t key[256];
156
	u_int8_t key[KEYSZ + IVSZ], *p;
54
	int r, n;
157
	int r, n;
55
	struct timeval tv_now;
158
	struct timespec ts_now;
56
159
57
	/*
160
	/*
58
	 * XXX read_random() returns unsafe numbers if the entropy
161
	 * XXX read_random() returns unsafe numbers if the entropy
59
	 * device is not loaded -- MarkM.
162
	 * device is not loaded -- MarkM.
60
	 */
163
	 */
61
	r = read_random(key, ARC4_KEYBYTES);
164
	r = read_random(key, ARC4_KEYBYTES);
62
	getmicrouptime(&tv_now);
165
	nanotime(&ts_now);
63
	mtx_lock(&arc4_mtx);
166
167
	if (lock)
168
		mtx_lock(&arc4_mtx);
169
170
	_rs_random_buf(key, sizeof(key));
64
	/* If r == 0 || -1, just use what was on the stack. */
171
	/* If r == 0 || -1, just use what was on the stack. */
65
	if (r > 0) {
172
	if (r > 0) {
66
		for (n = r; n < sizeof(key); n++)
173
		for (n = r; n < sizeof(key); n++)
67
			key[n] = key[n % r];
174
			key[n] = key[n % r];
68
	}
175
	}
69
176
70
	for (n = 0; n < 256; n++) {
177
	/* 
71
		arc4_j = (arc4_j + arc4_sbox[n] + key[n]) % 256;
178
	 * Even if read_random does not provide some bytes
72
		arc4_swap(&arc4_sbox[n], &arc4_sbox[arc4_j]);
179
	 * we have at least the possibility to fill with some time value
73
	}
180
	 */
74
	arc4_i = arc4_j = 0;
181
	for (p = (u_int8_t *)&ts_now, n = 0; n < sizeof(ts_now); n++)
182
		key[n] ^= p[n];
183
184
	_rs_seed(key, sizeof(key));
75
185
76
	/* Reset for next reseed cycle. */
186
	arc4_t_reseed = ts_now.tv_sec + ARC4_RESEED_SECONDS;
77
	arc4_t_reseed = tv_now.tv_sec + ARC4_RESEED_SECONDS;
78
	arc4_numruns = 0;
187
	arc4_numruns = 0;
79
188
80
	/*
189
	if (lock)
81
	 * Throw away the first N words of output, as suggested in the
190
		mtx_unlock(&arc4_mtx);
82
	 * paper "Weaknesses in the Key Scheduling Algorithm of RC4"
191
83
	 * by Fluher, Mantin, and Shamir.  (N = 256 in our case.)
192
	explicit_bzero(key, sizeof(key));
84
	 */
85
	for (n = 0; n < 256*4; n++)
86
		arc4_randbyte();
87
	mtx_unlock(&arc4_mtx);
88
}
193
}
89
194
90
/*
195
/*
Lines 93-104 arc4_randomstir (void) Link Here
93
static void
198
static void
94
arc4_init(void)
199
arc4_init(void)
95
{
200
{
96
	int n;
97
98
	mtx_init(&arc4_mtx, "arc4_mtx", NULL, MTX_DEF);
201
	mtx_init(&arc4_mtx, "arc4_mtx", NULL, MTX_DEF);
99
	arc4_i = arc4_j = 0;
202
	_rs_stir(1);
100
	for (n = 0; n < 256; n++)
101
		arc4_sbox[n] = (u_int8_t) n;
102
203
103
	arc4_t_reseed = 0;
204
	arc4_t_reseed = 0;
104
}
205
}
Lines 106-148 arc4_init(void) Link Here
106
SYSINIT(arc4_init, SI_SUB_LOCK, SI_ORDER_ANY, arc4_init, NULL);
207
SYSINIT(arc4_init, SI_SUB_LOCK, SI_ORDER_ANY, arc4_init, NULL);
107
208
108
/*
209
/*
109
 * Generate a random byte.
110
 */
111
static u_int8_t
112
arc4_randbyte(void)
113
{
114
	u_int8_t arc4_t;
115
116
	arc4_i = (arc4_i + 1) % 256;
117
	arc4_j = (arc4_j + arc4_sbox[arc4_i]) % 256;
118
119
	arc4_swap(&arc4_sbox[arc4_i], &arc4_sbox[arc4_j]);
120
121
	arc4_t = (arc4_sbox[arc4_i] + arc4_sbox[arc4_j]) % 256;
122
	return arc4_sbox[arc4_t];
123
}
124
125
/*
126
 * MPSAFE
210
 * MPSAFE
127
 */
211
 */
128
void
212
void
129
arc4rand(void *ptr, u_int len, int reseed)
213
arc4rand(void *ptr, u_int len, int reseed)
130
{
214
{
131
	u_char *p;
215
	struct timespec ts;
132
	struct timeval tv;
133
216
134
	getmicrouptime(&tv);
217
	nanotime(&ts);
135
	if (atomic_cmpset_int(&arc4rand_iniseed_state, ARC4_ENTR_HAVE,
218
	if (atomic_cmpset_int(&arc4rand_iniseed_state, ARC4_ENTR_HAVE,
136
	    ARC4_ENTR_SEED) || reseed ||
219
		ARC4_ENTR_SEED) || reseed ||
137
	   (arc4_numruns > ARC4_RESEED_BYTES) ||
220
		(arc4_numruns > ARC4_RESEED_BYTES) ||
138
	   (tv.tv_sec > arc4_t_reseed))
221
		(ts.tv_sec > arc4_t_reseed))
139
		arc4_randomstir();
222
		_rs_stir(0);
140
223
141
	mtx_lock(&arc4_mtx);
224
	mtx_lock(&arc4_mtx);
142
	arc4_numruns += len;
225
	arc4_numruns += len;
143
	p = ptr;
226
144
	while (len--)
227
	_rs_random_buf(ptr, len);
145
		*p++ = arc4_randbyte();
228
	
146
	mtx_unlock(&arc4_mtx);
229
	mtx_unlock(&arc4_mtx);
147
}
230
}
148
231
Lines 150-156 uint32_t Link Here
150
arc4random(void)
233
arc4random(void)
151
{
234
{
152
	uint32_t ret;
235
	uint32_t ret;
236
	
237
	mtx_lock(&arc4_mtx);
238
	_rs_random_u32(&ret);
239
	mtx_unlock(&arc4_mtx);
153
240
154
	arc4rand(&ret, sizeof ret, 0);
241
	return (ret);
155
	return ret;
156
}
242
}
(-)b/sys/sys/mman.h (+1 lines)
Lines 43-48 Link Here
43
#define INHERIT_SHARE	0
43
#define INHERIT_SHARE	0
44
#define INHERIT_COPY	1
44
#define INHERIT_COPY	1
45
#define INHERIT_NONE	2
45
#define INHERIT_NONE	2
46
#define INHERIT_ZERO	3
46
#endif
47
#endif
47
48
48
/*
49
/*
(-)b/sys/vm/vm.h (+1 lines)
Lines 68-73 typedef char vm_inherit_t; /* inheritance codes */ Link Here
68
#define	VM_INHERIT_SHARE	((vm_inherit_t) 0)
68
#define	VM_INHERIT_SHARE	((vm_inherit_t) 0)
69
#define	VM_INHERIT_COPY		((vm_inherit_t) 1)
69
#define	VM_INHERIT_COPY		((vm_inherit_t) 1)
70
#define	VM_INHERIT_NONE		((vm_inherit_t) 2)
70
#define	VM_INHERIT_NONE		((vm_inherit_t) 2)
71
#define	VM_INHERIT_ZERO		((vm_inherit_t) 3)
71
#define	VM_INHERIT_DEFAULT	VM_INHERIT_COPY
72
#define	VM_INHERIT_DEFAULT	VM_INHERIT_COPY
72
73
73
typedef u_char vm_prot_t;	/* protection codes */
74
typedef u_char vm_prot_t;	/* protection codes */
(-)b/sys/vm/vm_map.c (-2 / +5 lines)
Lines 2258-2263 vm_map_inherit(vm_map_t map, vm_offset_t start, vm_offset_t end, Link Here
2258
	case VM_INHERIT_NONE:
2258
	case VM_INHERIT_NONE:
2259
	case VM_INHERIT_COPY:
2259
	case VM_INHERIT_COPY:
2260
	case VM_INHERIT_SHARE:
2260
	case VM_INHERIT_SHARE:
2261
	case VM_INHERIT_ZERO:
2261
		break;
2262
		break;
2262
	default:
2263
	default:
2263
		return (KERN_INVALID_ARGUMENT);
2264
		return (KERN_INVALID_ARGUMENT);
Lines 3390-3395 vmspace_fork(struct vmspace *vm1, vm_ooffset_t *fork_charge) Link Here
3390
			break;
3391
			break;
3391
3392
3392
		case VM_INHERIT_COPY:
3393
		case VM_INHERIT_COPY:
3394
		case VM_INHERIT_ZERO:
3393
			/*
3395
			/*
3394
			 * Clone the entry and link into the map.
3396
			 * Clone the entry and link into the map.
3395
			 */
3397
			 */
Lines 3407-3414 vmspace_fork(struct vmspace *vm1, vm_ooffset_t *fork_charge) Link Here
3407
			vm_map_entry_link(new_map, new_map->header.prev,
3409
			vm_map_entry_link(new_map, new_map->header.prev,
3408
			    new_entry);
3410
			    new_entry);
3409
			vmspace_map_entry_forked(vm1, vm2, new_entry);
3411
			vmspace_map_entry_forked(vm1, vm2, new_entry);
3410
			vm_map_copy_entry(old_map, new_map, old_entry,
3412
			if (old_entry->inheritance == VM_INHERIT_COPY)
3411
			    new_entry, fork_charge);
3413
				vm_map_copy_entry(old_map, new_map, old_entry,
3414
			    		new_entry, fork_charge);
3412
			break;
3415
			break;
3413
		}
3416
		}
3414
		old_entry = old_entry->next;
3417
		old_entry = old_entry->next;

Return to bug 182610