Module Name:    src
Committed By:   dsl
Date:           Mon Aug 20 20:27:47 UTC 2012

Modified Files:
        src/lib/libc/gen: arc4random.c

Log Message:
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).


To generate a diff of this commit:
cvs rdiff -u -r1.17 -r1.18 src/lib/libc/gen/arc4random.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/gen/arc4random.c
diff -u src/lib/libc/gen/arc4random.c:1.17 src/lib/libc/gen/arc4random.c:1.18
--- src/lib/libc/gen/arc4random.c:1.17	Sat Aug 18 15:55:07 2012
+++ src/lib/libc/gen/arc4random.c	Mon Aug 20 20:27:46 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: arc4random.c,v 1.17 2012/08/18 15:55:07 dsl Exp $	*/
+/*	$NetBSD: arc4random.c,v 1.18 2012/08/20 20:27:46 dsl Exp $	*/
 /*	$OpenBSD: arc4random.c,v 1.6 2001/06/05 05:05:38 pvalchev Exp $	*/
 
 /*
@@ -27,7 +27,7 @@
 
 #include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: arc4random.c,v 1.17 2012/08/18 15:55:07 dsl Exp $");
+__RCSID("$NetBSD: arc4random.c,v 1.18 2012/08/20 20:27:46 dsl Exp $");
 #endif /* LIBC_SCCS and not lint */
 
 #include "namespace.h"
@@ -44,13 +44,13 @@ __RCSID("$NetBSD: arc4random.c,v 1.17 20
 __weak_alias(arc4random,_arc4random)
 #endif
 
-#define RSIZE 256
 struct arc4_stream {
-	mutex_t mtx;
-	int initialized;
+	uint8_t stirred;
+	uint8_t pad;
 	uint8_t i;
 	uint8_t j;
-	uint8_t s[RSIZE];
+	uint8_t s[(uint8_t)~0u + 1u];	/* 256 to you and me */
+	mutex_t mtx;
 };
 
 #ifdef _REENTRANT
@@ -67,35 +67,33 @@ struct arc4_stream {
 #define UNLOCK(rs)
 #endif
 
-
-/* XXX lint explodes with an internal error if only mtx is initialized! */
-static struct arc4_stream rs = { .i = 0, .mtx = MUTEX_INITIALIZER };
+#define S(n) (n)
+#define S4(n) S(n), S(n + 1), S(n + 2), S(n + 3)
+#define S16(n) S4(n), S4(n + 4), S4(n + 8), S4(n + 12)
+#define S64(n) S16(n), S16(n + 16), S16(n + 32), S16(n + 48)
+#define S256 S64(0), S64(64), S64(128), S64(192)
+
+static struct arc4_stream rs = { .i = 0xff, .j = 0, .s = { S256 },
+		.stirred = 0, .mtx = MUTEX_INITIALIZER };
+
+#undef S
+#undef S4
+#undef S16
+#undef S64
+#undef S256
 
 static inline void arc4_addrandom(struct arc4_stream *, u_char *, int);
-static void arc4_stir(struct arc4_stream *);
+static __noinline void arc4_stir(struct arc4_stream *);
 static inline uint8_t arc4_getbyte(struct arc4_stream *);
 static inline uint32_t arc4_getword(struct arc4_stream *);
 
-static __noinline void
-arc4_init(struct arc4_stream *as)
-{
-	int n;
-	for (n = 0; n < RSIZE; n++)
-		as->s[n] = n;
-	as->i = 0;
-	as->j = 0;
-
-	as->initialized = 1;
-	arc4_stir(as);
-}
-
 static inline int
 arc4_check_init(struct arc4_stream *as)
 {
-	if (__predict_true(rs.initialized))
+	if (__predict_true(rs.stirred))
 		return 0;
 
-	arc4_init(as);
+	arc4_stir(as);
 	return 1;
 }
 
@@ -103,20 +101,18 @@ static inline void
 arc4_addrandom(struct arc4_stream *as, u_char *dat, int datlen)
 {
 	uint8_t si;
-	int n;
+	size_t n;
 
-	as->i--;
-	for (n = 0; n < RSIZE; n++) {
+	for (n = 0; n < __arraycount(as->s); n++) {
 		as->i = (as->i + 1);
 		si = as->s[as->i];
 		as->j = (as->j + si + dat[n % datlen]);
 		as->s[as->i] = as->s[as->j];
 		as->s[as->j] = si;
 	}
-	as->j = as->i;
 }
 
-static void
+static __noinline void
 arc4_stir(struct arc4_stream *as)
 {
 	int rdat[32];
@@ -146,8 +142,10 @@ arc4_stir(struct arc4_stream *as)
 	 * paper "Weaknesses in the Key Scheduling Algorithm of RC4"
 	 * by Fluher, Mantin, and Shamir.  (N = 256 in our case.)
 	 */
-	for (j = 0; j < RSIZE * 4; j++)
+	for (j = 0; j < __arraycount(as->s) * 4; j++)
 		arc4_getbyte(as);
+
+	as->stirred = 1;
 }
 
 static __always_inline uint8_t
@@ -185,8 +183,7 @@ void
 arc4random_stir(void)
 {
 	LOCK(&rs);
-	if (__predict_false(!arc4_check_init(&rs)))	/* init() stirs */
-		arc4_stir(&rs);
+	arc4_stir(&rs);
 	UNLOCK(&rs);
 }
 

Reply via email to