Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F167652958
D1956.id3936.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D1956.id3936.diff
View Options
Index: sys/dev/random/randomdev.c
===================================================================
--- sys/dev/random/randomdev.c
+++ sys/dev/random/randomdev.c
@@ -214,7 +214,7 @@
*/
/* Hold the address of the routine which is actually called */
-static void (*read_func)(uint8_t *, u_int) = dummy_random_read_phony;
+static void (*read_func)(uint8_t *, u_int);
/* Initialise the reader when/if it is loaded */
void
@@ -229,7 +229,7 @@
randomdev_deinit_reader(void)
{
- read_func = dummy_random_read_phony;
+ read_func = NULL;
}
/* Kernel API version of read_random().
@@ -237,10 +237,10 @@
* the entropy device.
*/
int
-read_random(void *buf, int count)
+priv_read_random(void *buf, int count)
{
- if (count < 0)
+ if (count <= 0 || read_func == NULL)
return 0;
read_func(buf, count);
Index: sys/dev/random/yarrow.c
===================================================================
--- sys/dev/random/yarrow.c
+++ sys/dev/random/yarrow.c
@@ -147,7 +147,7 @@
/* Set up the lock for the reseed/gate state */
#ifdef _KERNEL
- mtx_init(&random_reseed_mtx, "reseed mutex", NULL, MTX_DEF);
+ mtx_init(&random_reseed_mtx, "reseed mutex", NULL, MTX_SPIN);
#else /* !_KERNEL */
mtx_init(&random_reseed_mtx, mtx_plain);
#endif /* _KERNEL */
@@ -265,7 +265,7 @@
{
u_int pl;
- mtx_lock(&random_reseed_mtx);
+ mtx_lock_spin(&random_reseed_mtx);
/* Accumulate the event into the appropriate pool
* where each event carries the destination information.
@@ -278,7 +278,7 @@
random_yarrow_post_insert();
- mtx_unlock(&random_reseed_mtx);
+ mtx_unlock_spin(&random_reseed_mtx);
}
/* Process a block of data suspected to be slightly stochastic */
@@ -440,7 +440,7 @@
return;
/* The reseed task must not be jumped on */
- mtx_lock(&random_reseed_mtx);
+ mtx_lock_spin(&random_reseed_mtx);
blockcount = (bytecount + BLOCKSIZE - 1)/BLOCKSIZE;
for (i = 0; i < blockcount; i++) {
@@ -461,7 +461,7 @@
}
}
- mtx_unlock(&random_reseed_mtx);
+ mtx_unlock_spin(&random_reseed_mtx);
}
/* Internal function to hand external entropy to the PRNG */
@@ -471,7 +471,7 @@
uintmax_t timestamp;
/* We must be locked for all this as plenty of state gets messed with */
- mtx_lock(&random_reseed_mtx);
+ mtx_lock_spin(&random_reseed_mtx);
timestamp = get_cyclecount();
randomdev_hash_iterate(&yarrow_state.start_cache.hash, ×tamp, sizeof(timestamp));
@@ -495,7 +495,7 @@
random_yarrow_process_buffer(yarrow_state.start_cache.junk, KEYSIZE);
memset(yarrow_state.start_cache.junk, 0, KEYSIZE);
- mtx_unlock(&random_reseed_mtx);
+ mtx_unlock_spin(&random_reseed_mtx);
}
static void
@@ -517,9 +517,9 @@
random_yarrow_reseed(void)
{
- mtx_lock(&random_reseed_mtx);
+ mtx_lock_spin(&random_reseed_mtx);
reseed(SLOW);
- mtx_unlock(&random_reseed_mtx);
+ mtx_unlock_spin(&random_reseed_mtx);
}
int
Index: sys/libkern/arc4random.c
===================================================================
--- sys/libkern/arc4random.c
+++ sys/libkern/arc4random.c
@@ -14,12 +14,17 @@
#include <sys/types.h>
#include <sys/param.h>
#include <sys/kernel.h>
+#include <sys/endian.h>
#include <sys/random.h>
#include <sys/libkern.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/time.h>
+#include <machine/cpu.h>
+
+#include <crypto/sha2/sha256.h>
+
#define ARC4_RESEED_BYTES 65536
#define ARC4_RESEED_SECONDS 300
#define ARC4_KEYBYTES (256 / 8)
@@ -44,6 +49,28 @@
*b = c;
}
+static int
+get_best_seed(uint8_t *key, int cnt)
+{
+ struct timespec ts;
+ uint8_t buf[8 + sizeof ts];
+ int pos;
+
+ pos = 0;
+
+ be64enc(&buf[pos], get_cyclecount());
+ pos += 8;
+
+ nanotime(&ts);
+ memcpy(&buf[pos], &ts, sizeof ts);
+ pos += sizeof ts;
+
+ KASSERT(cnt >= 32, ("not enough space for sha256 digest"));
+ SHA256_Data(&buf[0], pos, key);
+
+ return 32;
+}
+
/*
* Stir our S-box.
*/
@@ -58,15 +85,19 @@
* XXX read_random() returns unsafe numbers if the entropy
* device is not loaded -- MarkM.
*/
- r = read_random(key, ARC4_KEYBYTES);
+ r = priv_read_random(key, ARC4_KEYBYTES);
getmicrouptime(&tv_now);
- mtx_lock(&arc4_mtx);
+ mtx_lock_spin(&arc4_mtx);
/* If r == 0 || -1, just use what was on the stack. */
- if (r > 0) {
- for (n = r; n < sizeof(key); n++)
- key[n] = key[n % r];
+ if (r <= 0) {
+ r = get_best_seed(key, sizeof key);
+
+ /* XXX - we should always reseed till random(4) is ready */
}
+ for (n = r; n < sizeof(key); n++)
+ key[n] = key[n % r];
+
for (n = 0; n < 256; n++) {
arc4_j = (arc4_j + arc4_sbox[n] + key[n]) % 256;
arc4_swap(&arc4_sbox[n], &arc4_sbox[arc4_j]);
@@ -84,7 +115,7 @@
*/
for (n = 0; n < 256*4; n++)
arc4_randbyte();
- mtx_unlock(&arc4_mtx);
+ mtx_unlock_spin(&arc4_mtx);
}
/*
@@ -95,7 +126,7 @@
{
int n;
- mtx_init(&arc4_mtx, "arc4_mtx", NULL, MTX_DEF);
+ mtx_init(&arc4_mtx, "arc4_mtx", NULL, MTX_SPIN);
arc4_i = arc4_j = 0;
for (n = 0; n < 256; n++)
arc4_sbox[n] = (u_int8_t) n;
@@ -138,12 +169,12 @@
(tv.tv_sec > arc4_t_reseed))
arc4_randomstir();
- mtx_lock(&arc4_mtx);
+ mtx_lock_spin(&arc4_mtx);
arc4_numruns += len;
p = ptr;
while (len--)
*p++ = arc4_randbyte();
- mtx_unlock(&arc4_mtx);
+ mtx_unlock_spin(&arc4_mtx);
}
uint32_t
Index: sys/libkern/random.c
===================================================================
--- sys/libkern/random.c
+++ sys/libkern/random.c
@@ -34,45 +34,33 @@
#include <sys/libkern.h>
-#define NSHUFF 50 /* to drop some "seed -> 1st value" linearity */
-
-static u_long randseed = 937186357; /* after srandom(1), NSHUFF counted */
-
void
-srandom(seed)
- u_long seed;
+srandom(u_long seed __unused)
{
- int i;
-
- randseed = seed;
- for (i = 0; i < NSHUFF; i++)
- (void)random();
}
/*
- * Pseudo-random number generator for randomizing the profiling clock,
- * and whatever else we might use it for. The result is uniform on
- * [0, 2^31 - 1].
+ * Return a uniformly random value over [0, top).
+ *
+ * Use the simple algorithm that if random value v is in the range
+ * [0, n * top) where n is an integer, return v % top. If v is
+ * equal to or larger than n * top, it would not be uniform, so pick a
+ * new v and try again.
*/
-u_long
-random()
+uint64_t
+random_uniform(uint64_t top)
{
- register long x, hi, lo, t;
+ uint64_t r;
+ uint64_t max;
+
+ /* XXX - should be 2^64 */
+ max = UINT64_MAX / top * top;
+
+ for (;;) {
+ r = random64();
+ if (r >= max)
+ continue;
- /*
- * Compute x[n + 1] = (7^5 * x[n]) mod (2^31 - 1).
- * From "Random number generators: good ones are hard to find",
- * Park and Miller, Communications of the ACM, vol. 31, no. 10,
- * October 1988, p. 1195.
- */
- /* Can't be initialized with 0, so use another value. */
- if ((x = randseed) == 0)
- x = 123459876;
- hi = x / 127773;
- lo = x % 127773;
- t = 16807 * lo - 2836 * hi;
- if (t < 0)
- t += 0x7fffffff;
- randseed = t;
- return (t);
+ return r % top;
+ }
}
Index: sys/sys/libkern.h
===================================================================
--- sys/sys/libkern.h
+++ sys/sys/libkern.h
@@ -75,10 +75,43 @@
#define ARC4_ENTR_SEED 2 /* Reseeding. */
extern int arc4rand_iniseed_state;
-/* Prototypes for non-quad routines. */
-struct malloc_type;
+/* Deprecated random functions */
uint32_t arc4random(void);
void arc4rand(void *ptr, u_int len, int reseed);
+void srandom(u_long);
+
+/* Random functions */
+static __inline uint32_t
+random()
+{
+ uint32_t r;
+
+ arc4rand((uint8_t *)&r, sizeof r, 0);
+
+ return r;
+}
+
+static __inline uint64_t
+random64()
+{
+ uint64_t r;
+
+ arc4rand((uint8_t *)&r, sizeof r, 0);
+
+ return r;
+}
+
+static __inline void
+random_buf(uint8_t *buf, size_t cnt)
+{
+
+ arc4rand(buf, cnt, 0);
+}
+
+uint64_t random_uniform(uint64_t);
+
+/* Prototypes for non-quad routines. */
+struct malloc_type;
int bcmp(const void *, const void *, size_t);
int timingsafe_bcmp(const void *, const void *, size_t);
void *bsearch(const void *, const void *, size_t,
@@ -109,9 +142,7 @@
int (*compar)(const void *, const void *));
void qsort_r(void *base, size_t nmemb, size_t size, void *thunk,
int (*compar)(void *, const void *, const void *));
-u_long random(void);
int scanc(u_int, const u_char *, const u_char *, int);
-void srandom(u_long);
int strcasecmp(const char *, const char *);
char *strcat(char * __restrict, const char * __restrict);
char *strchr(const char *, int);
Index: sys/sys/random.h
===================================================================
--- sys/sys/random.h
+++ sys/sys/random.h
@@ -31,7 +31,20 @@
#ifdef _KERNEL
-int read_random(void *, int);
+#include <sys/libkern.h>
+
+/* Deprecated */
+static __inline int
+read_random(void *buf, int cnt)
+{
+
+ arc4rand(buf, cnt, 0);
+
+ return cnt;
+}
+
+/* Temporary internal interface to random adaptors */
+int priv_read_random(void *, int);
/*
* Note: if you add or remove members of random_entropy_source, remember to also update the
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Aug 24, 1:16 PM (16 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37185147
Default Alt Text
D1956.id3936.diff (8 KB)
Attached To
Mode
D1956: Unify kernel randomness API
Attached
Detach File
Event Timeline
Log In to Comment