Skip to content

Commit be24195

Browse files
author
dsl
committed
Since 'rs' is statically initialised (not bss) its s[] might as well be
compile-time initialised as well. arc4_init) is the same as arc4_stir(). Initialise rs.i to 0xff (not 0) so that the first key byte is processed with rs.i == 0 without the splurios rs.i-- in arc4_addrandom(). Remove the assignment rs.j = rs.i at the end of arc4_addrandom(), it isn't necessary and I can see no justificationm for it. Replace RSIZE with __arraycount(as->s), however it is manifestly 256 (more correctly the number of values in rs.i and rs.j).
1 parent 66f1772 commit be24195

File tree

1 file changed

+29
-32
lines changed

1 file changed

+29
-32
lines changed

lib/libc/gen/arc4random.c

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $NetBSD: arc4random.c,v 1.17 2012/08/18 15:55:07 dsl Exp $ */
1+
/* $NetBSD: arc4random.c,v 1.18 2012/08/20 20:27:46 dsl Exp $ */
22
/* $OpenBSD: arc4random.c,v 1.6 2001/06/05 05:05:38 pvalchev Exp $ */
33

44
/*
@@ -27,7 +27,7 @@
2727

2828
#include <sys/cdefs.h>
2929
#if defined(LIBC_SCCS) && !defined(lint)
30-
__RCSID("$NetBSD: arc4random.c,v 1.17 2012/08/18 15:55:07 dsl Exp $");
30+
__RCSID("$NetBSD: arc4random.c,v 1.18 2012/08/20 20:27:46 dsl Exp $");
3131
#endif /* LIBC_SCCS and not lint */
3232

3333
#include "namespace.h"
@@ -44,13 +44,13 @@ __RCSID("$NetBSD: arc4random.c,v 1.17 2012/08/18 15:55:07 dsl Exp $");
4444
__weak_alias(arc4random,_arc4random)
4545
#endif
4646

47-
#define RSIZE 256
4847
struct arc4_stream {
49-
mutex_t mtx;
50-
int initialized;
48+
uint8_t stirred;
49+
uint8_t pad;
5150
uint8_t i;
5251
uint8_t j;
53-
uint8_t s[RSIZE];
52+
uint8_t s[(uint8_t)~0u + 1u]; /* 256 to you and me */
53+
mutex_t mtx;
5454
};
5555

5656
#ifdef _REENTRANT
@@ -67,56 +67,52 @@ struct arc4_stream {
6767
#define UNLOCK(rs)
6868
#endif
6969

70+
#define S(n) (n)
71+
#define S4(n) S(n), S(n + 1), S(n + 2), S(n + 3)
72+
#define S16(n) S4(n), S4(n + 4), S4(n + 8), S4(n + 12)
73+
#define S64(n) S16(n), S16(n + 16), S16(n + 32), S16(n + 48)
74+
#define S256 S64(0), S64(64), S64(128), S64(192)
75+
76+
static struct arc4_stream rs = { .i = 0xff, .j = 0, .s = { S256 },
77+
.stirred = 0, .mtx = MUTEX_INITIALIZER };
7078

71-
/* XXX lint explodes with an internal error if only mtx is initialized! */
72-
static struct arc4_stream rs = { .i = 0, .mtx = MUTEX_INITIALIZER };
79+
#undef S
80+
#undef S4
81+
#undef S16
82+
#undef S64
83+
#undef S256
7384

7485
static inline void arc4_addrandom(struct arc4_stream *, u_char *, int);
75-
static void arc4_stir(struct arc4_stream *);
86+
static __noinline void arc4_stir(struct arc4_stream *);
7687
static inline uint8_t arc4_getbyte(struct arc4_stream *);
7788
static inline uint32_t arc4_getword(struct arc4_stream *);
7889

79-
static __noinline void
80-
arc4_init(struct arc4_stream *as)
81-
{
82-
int n;
83-
for (n = 0; n < RSIZE; n++)
84-
as->s[n] = n;
85-
as->i = 0;
86-
as->j = 0;
87-
88-
as->initialized = 1;
89-
arc4_stir(as);
90-
}
91-
9290
static inline int
9391
arc4_check_init(struct arc4_stream *as)
9492
{
95-
if (__predict_true(rs.initialized))
93+
if (__predict_true(rs.stirred))
9694
return 0;
9795

98-
arc4_init(as);
96+
arc4_stir(as);
9997
return 1;
10098
}
10199

102100
static inline void
103101
arc4_addrandom(struct arc4_stream *as, u_char *dat, int datlen)
104102
{
105103
uint8_t si;
106-
int n;
104+
size_t n;
107105

108-
as->i--;
109-
for (n = 0; n < RSIZE; n++) {
106+
for (n = 0; n < __arraycount(as->s); n++) {
110107
as->i = (as->i + 1);
111108
si = as->s[as->i];
112109
as->j = (as->j + si + dat[n % datlen]);
113110
as->s[as->i] = as->s[as->j];
114111
as->s[as->j] = si;
115112
}
116-
as->j = as->i;
117113
}
118114

119-
static void
115+
static __noinline void
120116
arc4_stir(struct arc4_stream *as)
121117
{
122118
int rdat[32];
@@ -146,8 +142,10 @@ arc4_stir(struct arc4_stream *as)
146142
* paper "Weaknesses in the Key Scheduling Algorithm of RC4"
147143
* by Fluher, Mantin, and Shamir. (N = 256 in our case.)
148144
*/
149-
for (j = 0; j < RSIZE * 4; j++)
145+
for (j = 0; j < __arraycount(as->s) * 4; j++)
150146
arc4_getbyte(as);
147+
148+
as->stirred = 1;
151149
}
152150

153151
static __always_inline uint8_t
@@ -185,8 +183,7 @@ void
185183
arc4random_stir(void)
186184
{
187185
LOCK(&rs);
188-
if (__predict_false(!arc4_check_init(&rs))) /* init() stirs */
189-
arc4_stir(&rs);
186+
arc4_stir(&rs);
190187
UNLOCK(&rs);
191188
}
192189

0 commit comments

Comments
 (0)