|
1 | | -/* $NetBSD: arc4random.c,v 1.16 2012/08/18 15:04:53 dsl Exp $ */ |
| 1 | +/* $NetBSD: arc4random.c,v 1.17 2012/08/18 15:55:07 dsl Exp $ */ |
2 | 2 | /* $OpenBSD: arc4random.c,v 1.6 2001/06/05 05:05:38 pvalchev Exp $ */ |
3 | 3 |
|
4 | 4 | /* |
|
27 | 27 |
|
28 | 28 | #include <sys/cdefs.h> |
29 | 29 | #if defined(LIBC_SCCS) && !defined(lint) |
30 | | -__RCSID("$NetBSD: arc4random.c,v 1.16 2012/08/18 15:04:53 dsl Exp $"); |
| 30 | +__RCSID("$NetBSD: arc4random.c,v 1.17 2012/08/18 15:55:07 dsl Exp $"); |
31 | 31 | #endif /* LIBC_SCCS and not lint */ |
32 | 32 |
|
33 | 33 | #include "namespace.h" |
@@ -150,20 +150,26 @@ arc4_stir(struct arc4_stream *as) |
150 | 150 | arc4_getbyte(as); |
151 | 151 | } |
152 | 152 |
|
153 | | -static inline uint8_t |
154 | | -arc4_getbyte(struct arc4_stream *as) |
| 153 | +static __always_inline uint8_t |
| 154 | +arc4_getbyte_ij(struct arc4_stream *as, uint8_t *i, uint8_t *j) |
155 | 155 | { |
156 | 156 | uint8_t si, sj; |
157 | 157 |
|
158 | | - as->i = (as->i + 1); |
159 | | - si = as->s[as->i]; |
160 | | - as->j = (as->j + si); |
161 | | - sj = as->s[as->j]; |
162 | | - as->s[as->i] = sj; |
163 | | - as->s[as->j] = si; |
| 158 | + *i = *i + 1; |
| 159 | + si = as->s[*i]; |
| 160 | + *j = *j + si; |
| 161 | + sj = as->s[*j]; |
| 162 | + as->s[*i] = sj; |
| 163 | + as->s[*j] = si; |
164 | 164 | return (as->s[(si + sj) & 0xff]); |
165 | 165 | } |
166 | 166 |
|
| 167 | +static inline uint8_t |
| 168 | +arc4_getbyte(struct arc4_stream *as) |
| 169 | +{ |
| 170 | + return arc4_getbyte_ij(as, &as->i, &as->j); |
| 171 | +} |
| 172 | + |
167 | 173 | static inline uint32_t |
168 | 174 | arc4_getword(struct arc4_stream *as) |
169 | 175 | { |
@@ -210,17 +216,25 @@ arc4random_buf(void *buf, size_t len) |
210 | 216 | { |
211 | 217 | uint8_t *bp = buf; |
212 | 218 | uint8_t *ep = bp + len; |
| 219 | + uint8_t i, j; |
213 | 220 | int skip; |
214 | 221 |
|
215 | 222 | LOCK(&rs); |
216 | 223 | arc4_check_init(&rs); |
217 | 224 |
|
218 | | - skip = arc4_getbyte(&rs) % 3; |
| 225 | + /* cache i and j - compiler can't know 'buf' doesn't alias them */ |
| 226 | + i = rs.i; |
| 227 | + j = rs.j; |
| 228 | + |
| 229 | + skip = arc4_getbyte_ij(&rs, &i, &j) % 3; |
219 | 230 | while (skip--) |
220 | | - (void)arc4_getbyte(&rs); |
| 231 | + (void)arc4_getbyte_ij(&rs, &i, &j); |
221 | 232 |
|
222 | 233 | while (bp < ep) |
223 | | - *bp++ = arc4_getbyte(&rs); |
| 234 | + *bp++ = arc4_getbyte_ij(&rs, &i, &j); |
| 235 | + rs.i = i; |
| 236 | + rs.j = j; |
| 237 | + |
224 | 238 | UNLOCK(&rs); |
225 | 239 | } |
226 | 240 |
|
|
0 commit comments