diff options
Diffstat (limited to 'src/lib/libc/crypt/arc4random.c')
-rw-r--r-- | src/lib/libc/crypt/arc4random.c | 204 |
1 files changed, 0 insertions, 204 deletions
diff --git a/src/lib/libc/crypt/arc4random.c b/src/lib/libc/crypt/arc4random.c deleted file mode 100644 index 2da8e010ad..0000000000 --- a/src/lib/libc/crypt/arc4random.c +++ /dev/null | |||
@@ -1,204 +0,0 @@ | |||
1 | /* $OpenBSD: arc4random.c,v 1.58 2022/07/31 13:41:45 tb 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 | |||
22 | /* | ||
23 | * ChaCha based random number generator for OpenBSD. | ||
24 | */ | ||
25 | |||
26 | #include <fcntl.h> | ||
27 | #include <limits.h> | ||
28 | #include <signal.h> | ||
29 | #include <stdint.h> | ||
30 | #include <stdlib.h> | ||
31 | #include <string.h> | ||
32 | #include <unistd.h> | ||
33 | #include <sys/types.h> | ||
34 | #include <sys/time.h> | ||
35 | |||
36 | #define KEYSTREAM_ONLY | ||
37 | #include "chacha_private.h" | ||
38 | |||
39 | #define minimum(a, b) ((a) < (b) ? (a) : (b)) | ||
40 | |||
41 | #if defined(__GNUC__) || defined(_MSC_VER) | ||
42 | #define inline __inline | ||
43 | #else /* __GNUC__ || _MSC_VER */ | ||
44 | #define inline | ||
45 | #endif /* !__GNUC__ && !_MSC_VER */ | ||
46 | |||
47 | #define KEYSZ 32 | ||
48 | #define IVSZ 8 | ||
49 | #define BLOCKSZ 64 | ||
50 | #define RSBUFSZ (16*BLOCKSZ) | ||
51 | |||
52 | #define REKEY_BASE (1024*1024) /* NB. should be a power of 2 */ | ||
53 | |||
54 | /* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */ | ||
55 | static struct _rs { | ||
56 | size_t rs_have; /* valid bytes at end of rs_buf */ | ||
57 | size_t rs_count; /* bytes till reseed */ | ||
58 | } *rs; | ||
59 | |||
60 | /* Maybe be preserved in fork children, if _rs_allocate() decides. */ | ||
61 | static struct _rsx { | ||
62 | chacha_ctx rs_chacha; /* chacha context for random keystream */ | ||
63 | u_char rs_buf[RSBUFSZ]; /* keystream blocks */ | ||
64 | } *rsx; | ||
65 | |||
66 | static inline int _rs_allocate(struct _rs **, struct _rsx **); | ||
67 | static inline void _rs_forkdetect(void); | ||
68 | #include "arc4random.h" | ||
69 | |||
70 | static inline void _rs_rekey(u_char *dat, size_t datlen); | ||
71 | |||
72 | static inline void | ||
73 | _rs_init(u_char *buf, size_t n) | ||
74 | { | ||
75 | if (n < KEYSZ + IVSZ) | ||
76 | return; | ||
77 | |||
78 | if (rs == NULL) { | ||
79 | if (_rs_allocate(&rs, &rsx) == -1) | ||
80 | _exit(1); | ||
81 | } | ||
82 | |||
83 | chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8); | ||
84 | chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ); | ||
85 | } | ||
86 | |||
87 | static void | ||
88 | _rs_stir(void) | ||
89 | { | ||
90 | u_char rnd[KEYSZ + IVSZ]; | ||
91 | uint32_t rekey_fuzz = 0; | ||
92 | |||
93 | if (getentropy(rnd, sizeof rnd) == -1) | ||
94 | _getentropy_fail(); | ||
95 | |||
96 | if (!rs) | ||
97 | _rs_init(rnd, sizeof(rnd)); | ||
98 | else | ||
99 | _rs_rekey(rnd, sizeof(rnd)); | ||
100 | explicit_bzero(rnd, sizeof(rnd)); /* discard source seed */ | ||
101 | |||
102 | /* invalidate rs_buf */ | ||
103 | rs->rs_have = 0; | ||
104 | memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf)); | ||
105 | |||
106 | /* rekey interval should not be predictable */ | ||
107 | chacha_encrypt_bytes(&rsx->rs_chacha, (uint8_t *)&rekey_fuzz, | ||
108 | (uint8_t *)&rekey_fuzz, sizeof(rekey_fuzz)); | ||
109 | rs->rs_count = REKEY_BASE + (rekey_fuzz % REKEY_BASE); | ||
110 | } | ||
111 | |||
112 | static inline void | ||
113 | _rs_stir_if_needed(size_t len) | ||
114 | { | ||
115 | _rs_forkdetect(); | ||
116 | if (!rs || rs->rs_count <= len) | ||
117 | _rs_stir(); | ||
118 | if (rs->rs_count <= len) | ||
119 | rs->rs_count = 0; | ||
120 | else | ||
121 | rs->rs_count -= len; | ||
122 | } | ||
123 | |||
124 | static inline void | ||
125 | _rs_rekey(u_char *dat, size_t datlen) | ||
126 | { | ||
127 | #ifndef KEYSTREAM_ONLY | ||
128 | memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf)); | ||
129 | #endif | ||
130 | /* fill rs_buf with the keystream */ | ||
131 | chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf, | ||
132 | rsx->rs_buf, sizeof(rsx->rs_buf)); | ||
133 | /* mix in optional user provided data */ | ||
134 | if (dat) { | ||
135 | size_t i, m; | ||
136 | |||
137 | m = minimum(datlen, KEYSZ + IVSZ); | ||
138 | for (i = 0; i < m; i++) | ||
139 | rsx->rs_buf[i] ^= dat[i]; | ||
140 | } | ||
141 | /* immediately reinit for backtracking resistance */ | ||
142 | _rs_init(rsx->rs_buf, KEYSZ + IVSZ); | ||
143 | memset(rsx->rs_buf, 0, KEYSZ + IVSZ); | ||
144 | rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ; | ||
145 | } | ||
146 | |||
147 | static inline void | ||
148 | _rs_random_buf(void *_buf, size_t n) | ||
149 | { | ||
150 | u_char *buf = (u_char *)_buf; | ||
151 | u_char *keystream; | ||
152 | size_t m; | ||
153 | |||
154 | _rs_stir_if_needed(n); | ||
155 | while (n > 0) { | ||
156 | if (rs->rs_have > 0) { | ||
157 | m = minimum(n, rs->rs_have); | ||
158 | keystream = rsx->rs_buf + sizeof(rsx->rs_buf) | ||
159 | - rs->rs_have; | ||
160 | memcpy(buf, keystream, m); | ||
161 | memset(keystream, 0, m); | ||
162 | buf += m; | ||
163 | n -= m; | ||
164 | rs->rs_have -= m; | ||
165 | } | ||
166 | if (rs->rs_have == 0) | ||
167 | _rs_rekey(NULL, 0); | ||
168 | } | ||
169 | } | ||
170 | |||
171 | static inline void | ||
172 | _rs_random_u32(uint32_t *val) | ||
173 | { | ||
174 | u_char *keystream; | ||
175 | |||
176 | _rs_stir_if_needed(sizeof(*val)); | ||
177 | if (rs->rs_have < sizeof(*val)) | ||
178 | _rs_rekey(NULL, 0); | ||
179 | keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have; | ||
180 | memcpy(val, keystream, sizeof(*val)); | ||
181 | memset(keystream, 0, sizeof(*val)); | ||
182 | rs->rs_have -= sizeof(*val); | ||
183 | } | ||
184 | |||
185 | uint32_t | ||
186 | arc4random(void) | ||
187 | { | ||
188 | uint32_t val; | ||
189 | |||
190 | _ARC4_LOCK(); | ||
191 | _rs_random_u32(&val); | ||
192 | _ARC4_UNLOCK(); | ||
193 | return val; | ||
194 | } | ||
195 | DEF_WEAK(arc4random); | ||
196 | |||
197 | void | ||
198 | arc4random_buf(void *buf, size_t n) | ||
199 | { | ||
200 | _ARC4_LOCK(); | ||
201 | _rs_random_buf(buf, n); | ||
202 | _ARC4_UNLOCK(); | ||
203 | } | ||
204 | DEF_WEAK(arc4random_buf); | ||