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

Collapse All | Expand All

(-)crypto/heimdal/lib/roken/rand.c (-1 lines)
Lines 37-43 void ROKEN_LIB_FUNCTION Link Here
37
rk_random_init(void)
37
rk_random_init(void)
38
{
38
{
39
#if defined(HAVE_ARC4RANDOM)
39
#if defined(HAVE_ARC4RANDOM)
40
    arc4random_stir();
41
#elif defined(HAVE_SRANDOMDEV)
40
#elif defined(HAVE_SRANDOMDEV)
42
    srandomdev();
41
    srandomdev();
43
#elif defined(HAVE_RANDOM)
42
#elif defined(HAVE_RANDOM)
(-)crypto/openssh/config.h (-1 / +1 lines)
Lines 191-197 Link Here
191
#define HAVE_ARC4RANDOM_BUF 1
191
#define HAVE_ARC4RANDOM_BUF 1
192
192
193
/* Define to 1 if you have the `arc4random_stir' function. */
193
/* Define to 1 if you have the `arc4random_stir' function. */
194
#define HAVE_ARC4RANDOM_STIR 1
194
/* #undef HAVE_ARC4RANDOM_STIR */
195
195
196
/* Define to 1 if you have the `arc4random_uniform' function. */
196
/* Define to 1 if you have the `arc4random_uniform' function. */
197
#define HAVE_ARC4RANDOM_UNIFORM 1
197
#define HAVE_ARC4RANDOM_UNIFORM 1
(-)include/stdlib.h (-2 / +7 lines)
Lines 250-260 extern void (*malloc_message)(void *, const char * Link Here
250
void	 abort2(const char *, int, void **) __dead2;
250
void	 abort2(const char *, int, void **) __dead2;
251
__uint32_t
251
__uint32_t
252
	 arc4random(void);
252
	 arc4random(void);
253
void	 arc4random_addrandom(unsigned char *, int);
254
void	 arc4random_buf(void *, size_t);
253
void	 arc4random_buf(void *, size_t);
255
void	 arc4random_stir(void);
256
__uint32_t 
254
__uint32_t 
257
	 arc4random_uniform(__uint32_t);
255
	 arc4random_uniform(__uint32_t);
256
257
#if !defined(BURN_BRIDGES)
258
/* Deprecated arc4random() functions */
259
#define arc4random_stir()
260
#define arc4random_addrandom(a,b)
261
#endif
262
258
#ifdef __BLOCKS__
263
#ifdef __BLOCKS__
259
int	 atexit_b(void (^ _Nonnull)(void));
264
int	 atexit_b(void (^ _Nonnull)(void));
260
void	*bsearch_b(const void *, const void *, size_t,
265
void	*bsearch_b(const void *, const void *, size_t,
(-)lib/libc/gen/Makefile.inc (+2 lines)
Lines 16-21 SRCS+= __getosreldate.c \ Link Here
16
	_thread_init.c \
16
	_thread_init.c \
17
	alarm.c \
17
	alarm.c \
18
	arc4random.c \
18
	arc4random.c \
19
	arc4random-compat.c \
20
	arc4random_uniform.c \
19
	assert.c \
21
	assert.c \
20
	auxv.c \
22
	auxv.c \
21
	basename.c \
23
	basename.c \
(-)lib/libc/gen/Symbol.map (-2 lines)
Lines 65-72 FBSD_1.0 { Link Here
65
	pthread_testcancel;
65
	pthread_testcancel;
66
	alarm;
66
	alarm;
67
	arc4random;
67
	arc4random;
68
	arc4random_addrandom;
69
	arc4random_stir;
70
	__assert;
68
	__assert;
71
	check_utility_compat;
69
	check_utility_compat;
72
	clock;
70
	clock;
(-)lib/libc/gen/arc4random-compat.c (+74 lines)
Line 0 Link Here
1
/*-
2
 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3
 *
4
 * Copyright (c) 2018 Google LLC
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
 * SUCH DAMAGE.
27
 *
28
 * $FreeBSD$
29
 */
30
31
#include <sys/cdefs.h>
32
__FBSDID("$FreeBSD$");
33
34
#include <sys/types.h>
35
#include <stdbool.h>
36
#include <syslog.h>
37
38
/*
39
 * The following functions were removed from OpenBSD for good reasons:
40
 *
41
 *  - arc4random_stir()
42
 *  - arc4random_addrandom()
43
 *
44
 * On FreeBSD, for backward ABI compatibility, we provide two wrapper which
45
 * logs this event and returns.
46
 */
47
48
void __arc4random_stir_fbsd11(void);
49
void __arc4random_addrandom_fbsd11(u_char *, int);
50
51
static bool warned = false;
52
53
void
54
__arc4random_stir_fbsd11(void)
55
{
56
57
	if (!warned)
58
		syslog(LOG_NOTICE, "Deprecated function arc4random_stir() called");
59
	warned = true;
60
	return;
61
}
62
63
void
64
__arc4random_addrandom_fbsd11(u_char * dummy1 __unused, int dummy2 __unused)
65
{
66
67
	if (!warned)
68
		syslog(LOG_NOTICE, "Deprecated function arc4random_addrandom() called");
69
	warned = true;
70
	return;
71
}
72
73
__sym_compat(arc4random_stir, __arc4random_stir_fbsd11, FBSD_1.0);
74
__sym_compat(arc4random_addrandom, __arc4random_addrandom_fbsd11, FBSD_1.0);
(-)lib/libc/gen/arc4random.3 (-47 / +55 lines)
Lines 1-4 Link Here
1
.\" $OpenBSD: arc4random.3,v 1.2 1997/04/27 22:40:25 angelos Exp $
1
.\" $OpenBSD: arc4random.3,v 1.35 2014/11/25 16:45:24 millert Exp $
2
.\"
2
.\" Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
3
.\" Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
3
.\" All rights reserved.
4
.\" All rights reserved.
4
.\"
5
.\"
Lines 30-45 Link Here
30
.\" Manual page, using -mandoc macros
31
.\" Manual page, using -mandoc macros
31
.\" $FreeBSD$
32
.\" $FreeBSD$
32
.\"
33
.\"
33
.Dd April 15, 1997
34
.Dd July 19, 2014
34
.Dt ARC4RANDOM 3
35
.Dt ARC4RANDOM 3
35
.Os
36
.Os
36
.Sh NAME
37
.Sh NAME
37
.Nm arc4random ,
38
.Nm arc4random ,
38
.Nm arc4random_buf ,
39
.Nm arc4random_buf ,
39
.Nm arc4random_uniform ,
40
.Nm arc4random_uniform
40
.Nm arc4random_stir ,
41
.Nd random number generator
41
.Nm arc4random_addrandom
42
.Nd arc4 random number generator
43
.Sh LIBRARY
42
.Sh LIBRARY
44
.Lb libc
43
.Lb libc
45
.Sh SYNOPSIS
44
.Sh SYNOPSIS
Lines 50-69 Link Here
50
.Fn arc4random_buf "void *buf" "size_t nbytes"
49
.Fn arc4random_buf "void *buf" "size_t nbytes"
51
.Ft uint32_t
50
.Ft uint32_t
52
.Fn arc4random_uniform "uint32_t upper_bound"
51
.Fn arc4random_uniform "uint32_t upper_bound"
53
.Ft void
54
.Fn arc4random_stir "void"
55
.Ft void
56
.Fn arc4random_addrandom "unsigned char *dat" "int datlen"
57
.Sh DESCRIPTION
52
.Sh DESCRIPTION
53
This family of functions provides higher quality data than those
54
described in
55
.Xr rand 3 ,
56
.Xr random 3 ,
57
and
58
.Xr rand48 3 .
59
.Pp
60
Use of these functions is encouraged for almost all random number
61
consumption because the other interfaces are deficient in either
62
quality, portability, standardization, or availability.
63
These functions can be called in almost all coding environments,
64
including
65
.Xr pthreads 3
66
and
67
.Xr chroot 2 .
68
.Pp
69
High quality 32-bit pseudo-random numbers are generated very quickly.
70
On each call, a cryptographic pseudo-random number generator is used
71
to generate a new result.
72
One data pool is used for all consumers in a process, so that consumption
73
under program flow can act as additional stirring.
74
The subsystem is re-seeded from the kernel random number subsystem using
75
.Xr getentropy 2
76
on a regular basis, and also upon
77
.Xr fork 2 .
78
.Pp
58
The
79
The
59
.Fn arc4random
80
.Fn arc4random
60
function uses the key stream generator employed by the
81
function returns a single 32-bit value.
61
arc4 cipher, which uses 8*8 8 bit S-Boxes.
62
The S-Boxes
63
can be in about
64
.if t 2\u\s71700\s10\d
65
.if n (2**1700)
66
states.
67
The
82
The
68
.Fn arc4random
83
.Fn arc4random
69
function returns pseudo-random numbers in the range of 0 to
84
function returns pseudo-random numbers in the range of 0 to
Lines 75-107 and Link Here
75
.Xr random 3 .
90
.Xr random 3 .
76
.Pp
91
.Pp
77
.Fn arc4random_buf
92
.Fn arc4random_buf
78
function fills the region
93
fills the region
79
.Fa buf
94
.Fa buf
80
of length
95
of length
81
.Fa nbytes
96
.Fa nbytes
82
with ARC4-derived random data.
97
with random data.
83
.Pp
98
.Pp
84
.Fn arc4random_uniform
99
.Fn arc4random_uniform
85
will return a uniformly distributed random number less than
100
will return a single 32-bit value, uniformly distributed but less than
86
.Fa upper_bound .
101
.Fa upper_bound .
87
.Fn arc4random_uniform
102
This is recommended over constructions like
88
is recommended over constructions like
89
.Dq Li arc4random() % upper_bound
103
.Dq Li arc4random() % upper_bound
90
as it avoids "modulo bias" when the upper bound is not a power of two.
104
as it avoids "modulo bias" when the upper bound is not a power of two.
91
.Pp
105
In the worst case, this function may consume multiple iterations
92
The
106
to ensure uniformity; see the source code to understand the problem
93
.Fn arc4random_stir
107
and solution.
94
function reads data from
108
.Sh RETURN VALUES
95
.Pa /dev/urandom
109
These functions are always successful, and no return value is
96
and uses it to permute the S-Boxes via
110
reserved to indicate an error.
97
.Fn arc4random_addrandom .
98
.Pp
99
There is no need to call
100
.Fn arc4random_stir
101
before using
102
.Fn arc4random
103
functions family, since
104
they automatically initialize themselves.
105
.Sh EXAMPLES
111
.Sh EXAMPLES
106
The following produces a drop-in replacement for the traditional
112
The following produces a drop-in replacement for the traditional
107
.Fn rand
113
.Fn rand
Lines 113-127 functions using Link Here
113
.Dl "#define foo4random() (arc4random() % ((unsigned)RAND_MAX + 1))"
119
.Dl "#define foo4random() (arc4random() % ((unsigned)RAND_MAX + 1))"
114
.Sh SEE ALSO
120
.Sh SEE ALSO
115
.Xr rand 3 ,
121
.Xr rand 3 ,
116
.Xr random 3 ,
122
.Xr rand48 3 ,
117
.Xr srandomdev 3
123
.Xr random 3
118
.Sh HISTORY
124
.Sh HISTORY
119
.Pa RC4
125
These functions first appeared in
120
has been designed by RSA Data Security, Inc.
126
.Ox 2.1 .
121
It was posted anonymously
127
.Pp
122
to the USENET and was confirmed to be equivalent by several sources who
128
The original version of this random number generator used the
123
had access to the original cipher.
129
RC4 (also known as ARC4) algorithm.
124
Since
130
In
125
.Pa RC4
131
.Ox 5.5
126
used to be a trade secret, the cipher is now referred to as
132
it was replaced with the ChaCha20 cipher, and it may be replaced
127
.Pa ARC4 .
133
again in the future as cryptographic techniques advance.
134
A good mnemonic is
135
.Dq A Replacement Call for Random .
(-)lib/libc/gen/arc4random.c (-220 / +123 lines)
Lines 1-8 Link Here
1
/*	$OpenBSD: arc4random.c,v 1.24 2013/06/11 16:59:50 deraadt Exp $	*/
1
/*	$OpenBSD: arc4random.c,v 1.54 2015/09/13 08:31:47 guenther Exp $	*/
2
2
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>
7
 * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
6
 *
8
 *
7
 * Permission to use, copy, modify, and distribute this software for any
9
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
10
 * purpose with or without fee is hereby granted, provided that the above
Lines 18-32 Link Here
18
 */
20
 */
19
21
20
/*
22
/*
21
 * Arc4 random number generator for OpenBSD.
23
 * 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
 */
24
 */
31
25
32
#include <sys/cdefs.h>
26
#include <sys/cdefs.h>
Lines 35-301 __FBSDID("$FreeBSD$"); Link Here
35
#include "namespace.h"
29
#include "namespace.h"
36
#include <fcntl.h>
30
#include <fcntl.h>
37
#include <limits.h>
31
#include <limits.h>
32
#include <pthread.h>
33
#include <signal.h>
34
#include <stdint.h>
38
#include <stdlib.h>
35
#include <stdlib.h>
36
#include <string.h>
39
#include <unistd.h>
37
#include <unistd.h>
40
#include <sys/param.h>
38
#include <sys/types.h>
41
#include <sys/sysctl.h>
42
#include <sys/time.h>
39
#include <sys/time.h>
43
#include <pthread.h>
40
 
44
45
#include "libc_private.h"
41
#include "libc_private.h"
46
#include "un-namespace.h"
42
#include "un-namespace.h"
47
43
48
#ifdef __GNUC__
44
#define KEYSTREAM_ONLY
45
#include "chacha_private.h"
46
47
#define minimum(a, b) ((a) < (b) ? (a) : (b))
48
49
#if defined(__GNUC__) || defined(_MSC_VER)
49
#define inline __inline
50
#define inline __inline
50
#else				/* !__GNUC__ */
51
#else				/* __GNUC__ || _MSC_VER */
51
#define inline
52
#define inline
52
#endif				/* !__GNUC__ */
53
#endif				/* !__GNUC__ && !_MSC_VER */
53
54
54
struct arc4_stream {
55
#define KEYSZ	32
55
	u_int8_t i;
56
#define IVSZ	8
56
	u_int8_t j;
57
#define BLOCKSZ	64
57
	u_int8_t s[256];
58
#define RSBUFSZ	(16*BLOCKSZ)
58
};
59
59
60
static pthread_mutex_t	arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
60
/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */
61
static struct _rs {
62
	size_t		rs_have;	/* valid bytes at end of rs_buf */
63
	size_t		rs_count;	/* bytes till reseed */
64
} *rs;
61
65
62
#define	KEYSIZE		128
66
/* Maybe be preserved in fork children, if _rs_allocate() decides. */
63
#define	_ARC4_LOCK()						\
67
static struct _rsx {
64
	do {							\
68
	chacha_ctx	rs_chacha;	/* chacha context for random keystream */
65
		if (__isthreaded)				\
69
	u_char		rs_buf[RSBUFSZ];	/* keystream blocks */
66
			_pthread_mutex_lock(&arc4random_mtx);	\
70
} *rsx;
67
	} while (0)
68
71
69
#define	_ARC4_UNLOCK()						\
72
static inline int _rs_allocate(struct _rs **, struct _rsx **);
70
	do {							\
73
static inline void _rs_forkdetect(void);
71
		if (__isthreaded)				\
74
#include "arc4random.h"
72
			_pthread_mutex_unlock(&arc4random_mtx);	\
73
	} while (0)
74
75
75
static int rs_initialized;
76
static inline void _rs_rekey(u_char *dat, size_t datlen);
76
static struct arc4_stream rs;
77
static pid_t arc4_stir_pid;
78
static int arc4_count;
79
77
80
extern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
81
    void *newp, size_t newlen);
82
83
static inline u_int8_t arc4_getbyte(void);
84
static void arc4_stir(void);
85
86
static inline void
78
static inline void
87
arc4_init(void)
79
_rs_init(u_char *buf, size_t n)
88
{
80
{
89
	int     n;
81
	if (n < KEYSZ + IVSZ)
82
		return;
90
83
91
	for (n = 0; n < 256; n++)
84
	if (rs == NULL) {
92
		rs.s[n] = n;
85
		if (_rs_allocate(&rs, &rsx) == -1)
93
	rs.i = 0;
86
			abort();
94
	rs.j = 0;
87
	}
88
89
	chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8, 0);
90
	chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ);
95
}
91
}
96
92
97
static inline void
93
static void
98
arc4_addrandom(u_char *dat, int datlen)
94
_rs_stir(void)
99
{
95
{
100
	int     n;
96
	u_char rnd[KEYSZ + IVSZ];
101
	u_int8_t si;
102
97
103
	rs.i--;
98
	if (getentropy(rnd, sizeof rnd) == -1)
104
	for (n = 0; n < 256; n++) {
99
		_getentropy_fail();
105
		rs.i = (rs.i + 1);
106
		si = rs.s[rs.i];
107
		rs.j = (rs.j + si + dat[n % datlen]);
108
		rs.s[rs.i] = rs.s[rs.j];
109
		rs.s[rs.j] = si;
110
	}
111
	rs.j = rs.i;
112
}
113
100
114
size_t
101
	if (!rs)
115
__arc4_sysctl(u_char *buf, size_t size)
102
		_rs_init(rnd, sizeof(rnd));
116
{
103
	else
117
	int mib[2];
104
		_rs_rekey(rnd, sizeof(rnd));
118
	size_t len, done;
105
	explicit_bzero(rnd, sizeof(rnd));	/* discard source seed */
119
106
120
	mib[0] = CTL_KERN;
107
	/* invalidate rs_buf */
121
	mib[1] = KERN_ARND;
108
	rs->rs_have = 0;
122
	done = 0;
109
	memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
123
110
124
	do {
111
	rs->rs_count = 1600000;
125
		len = size;
126
		if (__sysctl(mib, 2, buf, &len, NULL, 0) == -1)
127
			return (done);
128
		done += len;
129
		buf += len;
130
		size -= len;
131
	} while (size > 0);
132
133
	return (done);
134
}
112
}
135
113
136
static void
114
static inline void
137
arc4_stir(void)
115
_rs_stir_if_needed(size_t len)
138
{
116
{
139
	u_char rdat[KEYSIZE];
117
	_rs_forkdetect();
140
	int i;
118
	if (!rs || rs->rs_count <= len)
141
119
		_rs_stir();
142
	if (!rs_initialized) {
120
	if (rs->rs_count <= len)
143
		arc4_init();
121
		rs->rs_count = 0;
144
		rs_initialized = 1;
122
	else
145
	}
123
		rs->rs_count -= len;
146
	if (__arc4_sysctl(rdat, KEYSIZE) != KEYSIZE) {
147
		/*
148
		 * The sysctl cannot fail. If it does fail on some FreeBSD
149
		 * derivative or after some future change, just abort so that
150
		 * the problem will be found and fixed. abort is not normally
151
		 * suitable for a library but makes sense here.
152
		 */
153
		abort();
154
	}
155
156
	arc4_addrandom(rdat, KEYSIZE);
157
158
	/*
159
	 * Discard early keystream, as per recommendations in:
160
	 * "(Not So) Random Shuffles of RC4" by Ilya Mironov.
161
	 */
162
	for (i = 0; i < 3072; i++)
163
		(void)arc4_getbyte();
164
	arc4_count = 1600000;
165
}
124
}
166
125
167
static void
126
static inline void
168
arc4_stir_if_needed(void)
127
_rs_rekey(u_char *dat, size_t datlen)
169
{
128
{
170
	pid_t pid = getpid();
129
#ifndef KEYSTREAM_ONLY
130
	memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
131
#endif
132
	/* fill rs_buf with the keystream */
133
	chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf,
134
	    rsx->rs_buf, sizeof(rsx->rs_buf));
135
	/* mix in optional user provided data */
136
	if (dat) {
137
		size_t i, m;
171
138
172
	if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != pid) {
139
		m = minimum(datlen, KEYSZ + IVSZ);
173
		arc4_stir_pid = pid;
140
		for (i = 0; i < m; i++)
174
		arc4_stir();
141
			rsx->rs_buf[i] ^= dat[i];
175
	}
142
	}
143
	/* immediately reinit for backtracking resistance */
144
	_rs_init(rsx->rs_buf, KEYSZ + IVSZ);
145
	memset(rsx->rs_buf, 0, KEYSZ + IVSZ);
146
	rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ;
176
}
147
}
177
148
178
static inline u_int8_t
149
static inline void
179
arc4_getbyte(void)
150
_rs_random_buf(void *_buf, size_t n)
180
{
151
{
181
	u_int8_t si, sj;
152
	u_char *buf = (u_char *)_buf;
153
	u_char *keystream;
154
	size_t m;
182
155
183
	rs.i = (rs.i + 1);
156
	_rs_stir_if_needed(n);
184
	si = rs.s[rs.i];
157
	while (n > 0) {
185
	rs.j = (rs.j + si);
158
		if (rs->rs_have > 0) {
186
	sj = rs.s[rs.j];
159
			m = minimum(n, rs->rs_have);
187
	rs.s[rs.i] = sj;
160
			keystream = rsx->rs_buf + sizeof(rsx->rs_buf)
188
	rs.s[rs.j] = si;
161
			    - rs->rs_have;
189
	return (rs.s[(si + sj) & 0xff]);
162
			memcpy(buf, keystream, m);
163
			memset(keystream, 0, m);
164
			buf += m;
165
			n -= m;
166
			rs->rs_have -= m;
167
		}
168
		if (rs->rs_have == 0)
169
			_rs_rekey(NULL, 0);
170
	}
190
}
171
}
191
172
192
static inline u_int32_t
173
static inline void
193
arc4_getword(void)
174
_rs_random_u32(uint32_t *val)
194
{
175
{
195
	u_int32_t val;
176
	u_char *keystream;
196
	val = arc4_getbyte() << 24;
197
	val |= arc4_getbyte() << 16;
198
	val |= arc4_getbyte() << 8;
199
	val |= arc4_getbyte();
200
	return val;
201
}
202
177
203
void
178
	_rs_stir_if_needed(sizeof(*val));
204
arc4random_stir(void)
179
	if (rs->rs_have < sizeof(*val))
205
{
180
		_rs_rekey(NULL, 0);
206
	_ARC4_LOCK();
181
	keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have;
207
	arc4_stir();
182
	memcpy(val, keystream, sizeof(*val));
208
	_ARC4_UNLOCK();
183
	memset(keystream, 0, sizeof(*val));
184
	rs->rs_have -= sizeof(*val);
209
}
185
}
210
186
211
void
187
uint32_t
212
arc4random_addrandom(u_char *dat, int datlen)
188
arc4random(void)
213
{
189
{
214
	_ARC4_LOCK();
190
	uint32_t val;
215
	if (!rs_initialized)
216
		arc4_stir();
217
	arc4_addrandom(dat, datlen);
218
	_ARC4_UNLOCK();
219
}
220
191
221
u_int32_t
222
arc4random(void)
223
{
224
	u_int32_t val;
225
	_ARC4_LOCK();
192
	_ARC4_LOCK();
226
	arc4_count -= 4;
193
	_rs_random_u32(&val);
227
	arc4_stir_if_needed();
228
	val = arc4_getword();
229
	_ARC4_UNLOCK();
194
	_ARC4_UNLOCK();
230
	return val;
195
	return val;
231
}
196
}
232
197
233
void
198
void
234
arc4random_buf(void *_buf, size_t n)
199
arc4random_buf(void *buf, size_t n)
235
{
200
{
236
	u_char *buf = (u_char *)_buf;
237
	_ARC4_LOCK();
201
	_ARC4_LOCK();
238
	arc4_stir_if_needed();
202
	_rs_random_buf(buf, n);
239
	while (n--) {
240
		if (--arc4_count <= 0)
241
			arc4_stir();
242
		buf[n] = arc4_getbyte();
243
	}
244
	_ARC4_UNLOCK();
203
	_ARC4_UNLOCK();
245
}
204
}
246
247
/*
248
 * Calculate a uniformly distributed random number less than upper_bound
249
 * avoiding "modulo bias".
250
 *
251
 * Uniformity is achieved by generating new random numbers until the one
252
 * returned is outside the range [0, 2**32 % upper_bound).  This
253
 * guarantees the selected random number will be inside
254
 * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
255
 * after reduction modulo upper_bound.
256
 */
257
u_int32_t
258
arc4random_uniform(u_int32_t upper_bound)
259
{
260
	u_int32_t r, min;
261
262
	if (upper_bound < 2)
263
		return 0;
264
265
	/* 2**32 % x == (2**32 - x) % x */
266
	min = -upper_bound % upper_bound;
267
	/*
268
	 * This could theoretically loop forever but each retry has
269
	 * p > 0.5 (worst case, usually far better) of selecting a
270
	 * number inside the range we need, so it should rarely need
271
	 * to re-roll.
272
	 */
273
	for (;;) {
274
		r = arc4random();
275
		if (r >= min)
276
			break;
277
	}
278
279
	return r % upper_bound;
280
}
281
282
#if 0
283
/*-------- Test code for i386 --------*/
284
#include <stdio.h>
285
#include <machine/pctr.h>
286
int
287
main(int argc, char **argv)
288
{
289
	const int iter = 1000000;
290
	int     i;
291
	pctrval v;
292
293
	v = rdtsc();
294
	for (i = 0; i < iter; i++)
295
		arc4random();
296
	v = rdtsc() - v;
297
	v /= iter;
298
299
	printf("%qd cycles\n", v);
300
}
301
#endif
(-)lib/libc/gen/arc4random.h (+74 lines)
Line 0 Link Here
1
/*	$OpenBSD: arc4random.h,v 1.4 2015/01/15 06:57:18 deraadt Exp $	*/
2
3
/*
4
 * Copyright (c) 1996, David Mazieres <dm@uun.org>
5
 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
6
 * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
7
 * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
8
 *
9
 * Permission to use, copy, modify, and distribute this software for any
10
 * purpose with or without fee is hereby granted, provided that the above
11
 * copyright notice and this permission notice appear in all copies.
12
 *
13
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20
 *
21
 * $FreeBSD$
22
 */
23
24
/*
25
 * Stub functions for portability.
26
 */
27
#include <sys/mman.h>
28
29
#include <signal.h>
30
31
static pthread_mutex_t	arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
32
#define	_ARC4_LOCK()						\
33
	do {							\
34
		if (__isthreaded)				\
35
			_pthread_mutex_lock(&arc4random_mtx);	\
36
	} while (0)
37
38
#define	_ARC4_UNLOCK()						\
39
	do {							\
40
		if (__isthreaded)				\
41
			_pthread_mutex_unlock(&arc4random_mtx);	\
42
	} while (0)
43
44
static inline void
45
_getentropy_fail(void)
46
{
47
	raise(SIGKILL);
48
}
49
50
static inline int
51
_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
52
{
53
	struct {
54
		struct _rs rs;
55
		struct _rsx rsx;
56
	} *p;
57
58
	if ((p = mmap(NULL, sizeof(*p), PROT_READ|PROT_WRITE,
59
	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
60
		return (-1);
61
	if (minherit(p, sizeof(*p), INHERIT_ZERO) == -1) {
62
		munmap(p, sizeof(*p));
63
		return (-1);
64
	}
65
66
	*rsp = &p->rs;
67
	*rsxp = &p->rsx;
68
	return (0);
69
}
70
71
static inline void
72
_rs_forkdetect(void)
73
{
74
}
(-)lib/libc/gen/arc4random_uniform.c (-250 / +7 lines)
Lines 1-7 Link Here
1
/*	$OpenBSD: arc4random.c,v 1.24 2013/06/11 16:59:50 deraadt Exp $	*/
1
/*	$OpenBSD: arc4random_uniform.c,v 1.2 2015/09/13 08:31:47 guenther Exp $	*/
2
2
3
/*
3
/*
4
 * Copyright (c) 1996, David Mazieres <dm@uun.org>
5
 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
4
 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
6
 *
5
 *
7
 * Permission to use, copy, modify, and distribute this software for any
6
 * Permission to use, copy, modify, and distribute this software for any
Lines 15-249 Link Here
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
/*
21
 * Arc4 random number generator for OpenBSD.
22
 *
17
 *
23
 * This code is derived from section 17.1 of Applied Cryptography,
18
 * $FreeBSD$
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
 */
19
 */
31
20
32
#include <sys/cdefs.h>
21
#include <sys/types.h>
33
__FBSDID("$FreeBSD$");
34
35
#include "namespace.h"
36
#include <fcntl.h>
37
#include <limits.h>
38
#include <stdlib.h>
22
#include <stdlib.h>
39
#include <unistd.h>
40
#include <sys/param.h>
41
#include <sys/sysctl.h>
42
#include <sys/time.h>
43
#include <pthread.h>
44
23
45
#include "libc_private.h"
46
#include "un-namespace.h"
47
48
#ifdef __GNUC__
49
#define inline __inline
50
#else				/* !__GNUC__ */
51
#define inline
52
#endif				/* !__GNUC__ */
53
54
struct arc4_stream {
55
	u_int8_t i;
56
	u_int8_t j;
57
	u_int8_t s[256];
58
};
59
60
static pthread_mutex_t	arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
61
62
#define	KEYSIZE		128
63
#define	_ARC4_LOCK()						\
64
	do {							\
65
		if (__isthreaded)				\
66
			_pthread_mutex_lock(&arc4random_mtx);	\
67
	} while (0)
68
69
#define	_ARC4_UNLOCK()						\
70
	do {							\
71
		if (__isthreaded)				\
72
			_pthread_mutex_unlock(&arc4random_mtx);	\
73
	} while (0)
74
75
static int rs_initialized;
76
static struct arc4_stream rs;
77
static pid_t arc4_stir_pid;
78
static int arc4_count;
79
80
extern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
81
    void *newp, size_t newlen);
82
83
static inline u_int8_t arc4_getbyte(void);
84
static void arc4_stir(void);
85
86
static inline void
87
arc4_init(void)
88
{
89
	int     n;
90
91
	for (n = 0; n < 256; n++)
92
		rs.s[n] = n;
93
	rs.i = 0;
94
	rs.j = 0;
95
}
96
97
static inline void
98
arc4_addrandom(u_char *dat, int datlen)
99
{
100
	int     n;
101
	u_int8_t si;
102
103
	rs.i--;
104
	for (n = 0; n < 256; n++) {
105
		rs.i = (rs.i + 1);
106
		si = rs.s[rs.i];
107
		rs.j = (rs.j + si + dat[n % datlen]);
108
		rs.s[rs.i] = rs.s[rs.j];
109
		rs.s[rs.j] = si;
110
	}
111
	rs.j = rs.i;
112
}
113
114
size_t
115
__arc4_sysctl(u_char *buf, size_t size)
116
{
117
	int mib[2];
118
	size_t len, done;
119
120
	mib[0] = CTL_KERN;
121
	mib[1] = KERN_ARND;
122
	done = 0;
123
124
	do {
125
		len = size;
126
		if (__sysctl(mib, 2, buf, &len, NULL, 0) == -1)
127
			return (done);
128
		done += len;
129
		buf += len;
130
		size -= len;
131
	} while (size > 0);
132
133
	return (done);
134
}
135
136
static void
137
arc4_stir(void)
138
{
139
	u_char rdat[KEYSIZE];
140
	int i;
141
142
	if (!rs_initialized) {
143
		arc4_init();
144
		rs_initialized = 1;
145
	}
146
	if (__arc4_sysctl(rdat, KEYSIZE) != KEYSIZE) {
147
		/*
148
		 * The sysctl cannot fail. If it does fail on some FreeBSD
149
		 * derivative or after some future change, just abort so that
150
		 * the problem will be found and fixed. abort is not normally
151
		 * suitable for a library but makes sense here.
152
		 */
153
		abort();
154
	}
155
156
	arc4_addrandom(rdat, KEYSIZE);
157
158
	/*
159
	 * Discard early keystream, as per recommendations in:
160
	 * "(Not So) Random Shuffles of RC4" by Ilya Mironov.
161
	 */
162
	for (i = 0; i < 3072; i++)
163
		(void)arc4_getbyte();
164
	arc4_count = 1600000;
165
}
166
167
static void
168
arc4_stir_if_needed(void)
169
{
170
	pid_t pid = getpid();
171
172
	if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != pid) {
173
		arc4_stir_pid = pid;
174
		arc4_stir();
175
	}
176
}
177
178
static inline u_int8_t
179
arc4_getbyte(void)
180
{
181
	u_int8_t si, sj;
182
183
	rs.i = (rs.i + 1);
184
	si = rs.s[rs.i];
185
	rs.j = (rs.j + si);
186
	sj = rs.s[rs.j];
187
	rs.s[rs.i] = sj;
188
	rs.s[rs.j] = si;
189
	return (rs.s[(si + sj) & 0xff]);
190
}
191
192
static inline u_int32_t
193
arc4_getword(void)
194
{
195
	u_int32_t val;
196
	val = arc4_getbyte() << 24;
197
	val |= arc4_getbyte() << 16;
198
	val |= arc4_getbyte() << 8;
199
	val |= arc4_getbyte();
200
	return val;
201
}
202
203
void
204
arc4random_stir(void)
205
{
206
	_ARC4_LOCK();
207
	arc4_stir();
208
	_ARC4_UNLOCK();
209
}
210
211
void
212
arc4random_addrandom(u_char *dat, int datlen)
213
{
214
	_ARC4_LOCK();
215
	if (!rs_initialized)
216
		arc4_stir();
217
	arc4_addrandom(dat, datlen);
218
	_ARC4_UNLOCK();
219
}
220
221
u_int32_t
222
arc4random(void)
223
{
224
	u_int32_t val;
225
	_ARC4_LOCK();
226
	arc4_count -= 4;
227
	arc4_stir_if_needed();
228
	val = arc4_getword();
229
	_ARC4_UNLOCK();
230
	return val;
231
}
232
233
void
234
arc4random_buf(void *_buf, size_t n)
235
{
236
	u_char *buf = (u_char *)_buf;
237
	_ARC4_LOCK();
238
	arc4_stir_if_needed();
239
	while (n--) {
240
		if (--arc4_count <= 0)
241
			arc4_stir();
242
		buf[n] = arc4_getbyte();
243
	}
244
	_ARC4_UNLOCK();
245
}
246
247
/*
24
/*
248
 * Calculate a uniformly distributed random number less than upper_bound
25
 * Calculate a uniformly distributed random number less than upper_bound
249
 * avoiding "modulo bias".
26
 * avoiding "modulo bias".
Lines 254-263 Link Here
254
 * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
31
 * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
255
 * after reduction modulo upper_bound.
32
 * after reduction modulo upper_bound.
256
 */
33
 */
257
u_int32_t
34
uint32_t
258
arc4random_uniform(u_int32_t upper_bound)
35
arc4random_uniform(uint32_t upper_bound)
259
{
36
{
260
	u_int32_t r, min;
37
	uint32_t r, min;
261
38
262
	if (upper_bound < 2)
39
	if (upper_bound < 2)
263
		return 0;
40
		return 0;
Lines 264-269 Link Here
264
41
265
	/* 2**32 % x == (2**32 - x) % x */
42
	/* 2**32 % x == (2**32 - x) % x */
266
	min = -upper_bound % upper_bound;
43
	min = -upper_bound % upper_bound;
44
267
	/*
45
	/*
268
	 * This could theoretically loop forever but each retry has
46
	 * This could theoretically loop forever but each retry has
269
	 * p > 0.5 (worst case, usually far better) of selecting a
47
	 * p > 0.5 (worst case, usually far better) of selecting a
Lines 278-301 Link Here
278
56
279
	return r % upper_bound;
57
	return r % upper_bound;
280
}
58
}
281
282
#if 0
283
/*-------- Test code for i386 --------*/
284
#include <stdio.h>
285
#include <machine/pctr.h>
286
int
287
main(int argc, char **argv)
288
{
289
	const int iter = 1000000;
290
	int     i;
291
	pctrval v;
292
293
	v = rdtsc();
294
	for (i = 0; i < iter; i++)
295
		arc4random();
296
	v = rdtsc() - v;
297
	v /= iter;
298
299
	printf("%qd cycles\n", v);
300
}
301
#endif
(-)lib/libc/gen/chacha_private.h (+223 lines)
Line 0 Link Here
1
/*
2
chacha-merged.c version 20080118
3
D. J. Bernstein
4
Public domain.
5
*/
6
/* $FreeBSD$ */
7
8
/* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */
9
10
typedef unsigned char u8;
11
typedef unsigned int u32;
12
13
typedef struct
14
{
15
  u32 input[16]; /* could be compressed */
16
} chacha_ctx;
17
18
#define U8C(v) (v##U)
19
#define U32C(v) (v##U)
20
21
#define U8V(v) ((u8)(v) & U8C(0xFF))
22
#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
23
24
#define ROTL32(v, n) \
25
  (U32V((v) << (n)) | ((v) >> (32 - (n))))
26
27
#define U8TO32_LITTLE(p) \
28
  (((u32)((p)[0])      ) | \
29
   ((u32)((p)[1]) <<  8) | \
30
   ((u32)((p)[2]) << 16) | \
31
   ((u32)((p)[3]) << 24))
32
33
#define U32TO8_LITTLE(p, v) \
34
  do { \
35
    (p)[0] = U8V((v)      ); \
36
    (p)[1] = U8V((v) >>  8); \
37
    (p)[2] = U8V((v) >> 16); \
38
    (p)[3] = U8V((v) >> 24); \
39
  } while (0)
40
41
#define ROTATE(v,c) (ROTL32(v,c))
42
#define XOR(v,w) ((v) ^ (w))
43
#define PLUS(v,w) (U32V((v) + (w)))
44
#define PLUSONE(v) (PLUS((v),1))
45
46
#define QUARTERROUND(a,b,c,d) \
47
  a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
48
  c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
49
  a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
50
  c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
51
52
static const char sigma[16] = "expand 32-byte k";
53
static const char tau[16] = "expand 16-byte k";
54
55
static void
56
chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ivbits)
57
{
58
  const char *constants;
59
60
  x->input[4] = U8TO32_LITTLE(k + 0);
61
  x->input[5] = U8TO32_LITTLE(k + 4);
62
  x->input[6] = U8TO32_LITTLE(k + 8);
63
  x->input[7] = U8TO32_LITTLE(k + 12);
64
  if (kbits == 256) { /* recommended */
65
    k += 16;
66
    constants = sigma;
67
  } else { /* kbits == 128 */
68
    constants = tau;
69
  }
70
  x->input[8] = U8TO32_LITTLE(k + 0);
71
  x->input[9] = U8TO32_LITTLE(k + 4);
72
  x->input[10] = U8TO32_LITTLE(k + 8);
73
  x->input[11] = U8TO32_LITTLE(k + 12);
74
  x->input[0] = U8TO32_LITTLE(constants + 0);
75
  x->input[1] = U8TO32_LITTLE(constants + 4);
76
  x->input[2] = U8TO32_LITTLE(constants + 8);
77
  x->input[3] = U8TO32_LITTLE(constants + 12);
78
}
79
80
static void
81
chacha_ivsetup(chacha_ctx *x,const u8 *iv)
82
{
83
  x->input[12] = 0;
84
  x->input[13] = 0;
85
  x->input[14] = U8TO32_LITTLE(iv + 0);
86
  x->input[15] = U8TO32_LITTLE(iv + 4);
87
}
88
89
static void
90
chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
91
{
92
  u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
93
  u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
94
  u8 *ctarget = NULL;
95
  u8 tmp[64];
96
  u_int i;
97
98
  if (!bytes) return;
99
100
  j0 = x->input[0];
101
  j1 = x->input[1];
102
  j2 = x->input[2];
103
  j3 = x->input[3];
104
  j4 = x->input[4];
105
  j5 = x->input[5];
106
  j6 = x->input[6];
107
  j7 = x->input[7];
108
  j8 = x->input[8];
109
  j9 = x->input[9];
110
  j10 = x->input[10];
111
  j11 = x->input[11];
112
  j12 = x->input[12];
113
  j13 = x->input[13];
114
  j14 = x->input[14];
115
  j15 = x->input[15];
116
117
  for (;;) {
118
    if (bytes < 64) {
119
      for (i = 0;i < bytes;++i) tmp[i] = m[i];
120
      m = tmp;
121
      ctarget = c;
122
      c = tmp;
123
    }
124
    x0 = j0;
125
    x1 = j1;
126
    x2 = j2;
127
    x3 = j3;
128
    x4 = j4;
129
    x5 = j5;
130
    x6 = j6;
131
    x7 = j7;
132
    x8 = j8;
133
    x9 = j9;
134
    x10 = j10;
135
    x11 = j11;
136
    x12 = j12;
137
    x13 = j13;
138
    x14 = j14;
139
    x15 = j15;
140
    for (i = 20;i > 0;i -= 2) {
141
      QUARTERROUND( x0, x4, x8,x12)
142
      QUARTERROUND( x1, x5, x9,x13)
143
      QUARTERROUND( x2, x6,x10,x14)
144
      QUARTERROUND( x3, x7,x11,x15)
145
      QUARTERROUND( x0, x5,x10,x15)
146
      QUARTERROUND( x1, x6,x11,x12)
147
      QUARTERROUND( x2, x7, x8,x13)
148
      QUARTERROUND( x3, x4, x9,x14)
149
    }
150
    x0 = PLUS(x0,j0);
151
    x1 = PLUS(x1,j1);
152
    x2 = PLUS(x2,j2);
153
    x3 = PLUS(x3,j3);
154
    x4 = PLUS(x4,j4);
155
    x5 = PLUS(x5,j5);
156
    x6 = PLUS(x6,j6);
157
    x7 = PLUS(x7,j7);
158
    x8 = PLUS(x8,j8);
159
    x9 = PLUS(x9,j9);
160
    x10 = PLUS(x10,j10);
161
    x11 = PLUS(x11,j11);
162
    x12 = PLUS(x12,j12);
163
    x13 = PLUS(x13,j13);
164
    x14 = PLUS(x14,j14);
165
    x15 = PLUS(x15,j15);
166
167
#ifndef KEYSTREAM_ONLY
168
    x0 = XOR(x0,U8TO32_LITTLE(m + 0));
169
    x1 = XOR(x1,U8TO32_LITTLE(m + 4));
170
    x2 = XOR(x2,U8TO32_LITTLE(m + 8));
171
    x3 = XOR(x3,U8TO32_LITTLE(m + 12));
172
    x4 = XOR(x4,U8TO32_LITTLE(m + 16));
173
    x5 = XOR(x5,U8TO32_LITTLE(m + 20));
174
    x6 = XOR(x6,U8TO32_LITTLE(m + 24));
175
    x7 = XOR(x7,U8TO32_LITTLE(m + 28));
176
    x8 = XOR(x8,U8TO32_LITTLE(m + 32));
177
    x9 = XOR(x9,U8TO32_LITTLE(m + 36));
178
    x10 = XOR(x10,U8TO32_LITTLE(m + 40));
179
    x11 = XOR(x11,U8TO32_LITTLE(m + 44));
180
    x12 = XOR(x12,U8TO32_LITTLE(m + 48));
181
    x13 = XOR(x13,U8TO32_LITTLE(m + 52));
182
    x14 = XOR(x14,U8TO32_LITTLE(m + 56));
183
    x15 = XOR(x15,U8TO32_LITTLE(m + 60));
184
#endif
185
186
    j12 = PLUSONE(j12);
187
    if (!j12) {
188
      j13 = PLUSONE(j13);
189
      /* stopping at 2^70 bytes per nonce is user's responsibility */
190
    }
191
192
    U32TO8_LITTLE(c + 0,x0);
193
    U32TO8_LITTLE(c + 4,x1);
194
    U32TO8_LITTLE(c + 8,x2);
195
    U32TO8_LITTLE(c + 12,x3);
196
    U32TO8_LITTLE(c + 16,x4);
197
    U32TO8_LITTLE(c + 20,x5);
198
    U32TO8_LITTLE(c + 24,x6);
199
    U32TO8_LITTLE(c + 28,x7);
200
    U32TO8_LITTLE(c + 32,x8);
201
    U32TO8_LITTLE(c + 36,x9);
202
    U32TO8_LITTLE(c + 40,x10);
203
    U32TO8_LITTLE(c + 44,x11);
204
    U32TO8_LITTLE(c + 48,x12);
205
    U32TO8_LITTLE(c + 52,x13);
206
    U32TO8_LITTLE(c + 56,x14);
207
    U32TO8_LITTLE(c + 60,x15);
208
209
    if (bytes <= 64) {
210
      if (bytes < 64) {
211
        for (i = 0;i < bytes;++i) ctarget[i] = c[i];
212
      }
213
      x->input[12] = j12;
214
      x->input[13] = j13;
215
      return;
216
    }
217
    bytes -= 64;
218
    c += 64;
219
#ifndef KEYSTREAM_ONLY
220
    m += 64;
221
#endif
222
  }
223
}
(-)lib/libc/gen/getentropy.c (-1 / +26 lines)
Lines 31-36 __FBSDID("$FreeBSD$"); Link Here
31
31
32
#include <sys/param.h>
32
#include <sys/param.h>
33
#include <sys/random.h>
33
#include <sys/random.h>
34
#include <sys/sysctl.h>
34
35
35
#include <errno.h>
36
#include <errno.h>
36
#include <stdlib.h>
37
#include <stdlib.h>
Lines 37-42 __FBSDID("$FreeBSD$"); Link Here
37
38
38
#include "libc_private.h"
39
#include "libc_private.h"
39
40
41
extern int __sysctl(int *, u_int, void *, size_t *, void *, size_t);
42
43
static size_t
44
arnd_sysctl(u_char *buf, size_t size)
45
{
46
	int mib[2];
47
	size_t len, done;
48
49
	mib[0] = CTL_KERN;
50
	mib[1] = KERN_ARND;
51
	done = 0;
52
53
	do {
54
		len = size;
55
		if (__sysctl(mib, 2, buf, &len, NULL, 0) == -1)
56
			return (done);
57
		done += len;
58
		buf += len;
59
		size -= len;
60
	} while (size > 0);
61
62
	return (done);
63
}
64
40
/*
65
/*
41
 * If a newer libc is accidentally installed on an older kernel, provide high
66
 * If a newer libc is accidentally installed on an older kernel, provide high
42
 * quality random data anyway.  The sysctl interface is not as fast and does
67
 * quality random data anyway.  The sysctl interface is not as fast and does
Lines 54-60 getentropy_fallback(void *buf, size_t buflen) Link Here
54
		errno = EFAULT;
79
		errno = EFAULT;
55
		return (-1);
80
		return (-1);
56
	}
81
	}
57
	if (__arc4_sysctl(buf, buflen) != buflen) {
82
	if (arnd_sysctl(buf, buflen) != buflen) {
58
		if (errno == EFAULT)
83
		if (errno == EFAULT)
59
			return (-1);
84
			return (-1);
60
		/*
85
		/*
(-)lib/libc/include/libc_private.h (-2 lines)
Lines 405-412 int __sys_futimens(int fd, const struct timespec Link Here
405
int		__sys_utimensat(int fd, const char *path,
405
int		__sys_utimensat(int fd, const char *path,
406
		    const struct timespec *times, int flag) __hidden;
406
		    const struct timespec *times, int flag) __hidden;
407
407
408
__size_t __arc4_sysctl(unsigned char *, __size_t);
409
410
/* execve() with PATH processing to implement posix_spawnp() */
408
/* execve() with PATH processing to implement posix_spawnp() */
411
int _execvpe(const char *, char * const *, char * const *);
409
int _execvpe(const char *, char * const *, char * const *);
412
410

Return to bug 182610