diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc index 4e30df5aaabc..5e459fc67ffe 100644 --- a/lib/libc/gen/Makefile.inc +++ b/lib/libc/gen/Makefile.inc @@ -3,6 +3,7 @@ # machine-independent gen sources .PATH: ${LIBC_SRCTOP}/${LIBC_ARCH}/gen ${LIBC_SRCTOP}/gen +.PATH: ${SRCTOP}/sys/libkern CONFS= shells diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 863a1135f5a6..7a7154dae6d3 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -1668,6 +1668,8 @@ MLINKS+=psignal.9 gsignal.9 \ psignal.9 tdsignal.9 MLINKS+=random.9 arc4rand.9 \ random.9 arc4random.9 \ + random.9 arc4random_buf.9 \ + random.9 arc4random_uniform.9 \ random.9 is_random_seeded.9 \ random.9 read_random.9 \ random.9 read_random_uio.9 \ diff --git a/share/man/man9/random.9 b/share/man/man9/random.9 index 97218dcab39c..1537e28dd356 100644 --- a/share/man/man9/random.9 +++ b/share/man/man9/random.9 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" " -.Dd April 16, 2019 +.Dd April 19, 2019 .Dt RANDOM 9 .Os .Sh NAME @@ -45,6 +45,8 @@ .Fn arc4random "void" .Ft void .Fn arc4random_buf "void *ptr" "size_t len" +.Ft uint32_t +.Fn arc4random_uniform "uint32_t upper_bound" .Ft void .Fn arc4rand "void *ptr" "u_int length" "int reseed" .Pp @@ -80,6 +82,15 @@ with .Fa len bytes of random data. .Pp +.Fn arc4random_uniform +will return a single 32-bit value, uniformly distributed but less than +.Fa upper_bound . +This is recommended over constructions like +.Dq Li arc4random() % upper_bound +as it avoids "modulo bias" when the upper bound is not a power of two. +In the worst case, this function may consume multiple iterations +to ensure uniformity. +.Pp The .Fn arc4rand CSPRNG diff --git a/sys/conf/files b/sys/conf/files index 90057c557cb5..9f2f00382c19 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -3985,6 +3985,7 @@ kgssapi/gsstest.c optional kgssapi_debug # the file should be moved to conf/files. from here. # libkern/arc4random.c standard +libkern/arc4random_uniform.c standard crypto/chacha20/chacha.c standard libkern/asprintf.c standard libkern/bcd.c standard diff --git a/lib/libc/gen/arc4random_uniform.c b/sys/libkern/arc4random_uniform.c similarity index 97% rename from lib/libc/gen/arc4random_uniform.c rename to sys/libkern/arc4random_uniform.c index 0136c66e3289..26f91e6532f9 100644 --- a/lib/libc/gen/arc4random_uniform.c +++ b/sys/libkern/arc4random_uniform.c @@ -19,7 +19,11 @@ */ #include +#ifdef _KERNEL +#include +#else #include +#endif /* * Calculate a uniformly distributed random number less than upper_bound diff --git a/sys/sys/libkern.h b/sys/sys/libkern.h index 123f6eeda3f3..1d7dcc369f0f 100644 --- a/sys/sys/libkern.h +++ b/sys/sys/libkern.h @@ -128,6 +128,7 @@ struct malloc_type; uint32_t arc4random(void); void arc4random_buf(void *, size_t); void arc4rand(void *, u_int, int); +uint32_t arc4random_uniform(uint32_t); int timingsafe_bcmp(const void *, const void *, size_t); void *bsearch(const void *, const void *, size_t, size_t, int (*)(const void *, const void *));