On Thu, 25 Mar 2021 at 11:38, Jonathan Wakely wrote: > On 25/03/21 08:00 -0300, Alexandre Oliva wrote: > >On Mar 24, 2021, Jonathan Wakely <jwak...@redhat.com> wrote: > > > >> Does vxworks provide any platform-specific source of randomness, like > >> Linux getrandom(2) or BSD arc4random(3) or Windows rand_s? If yes, we > >> should add support for that (in the next stage 1). > > > >There appears to be a randNumGenCtl syscall that appears to be relevant > >to that end, and randAdd to seed and randBytes to obtain random bytes in > >vxRandLib. I couldn't find documentation on how to use it, but there > >seems to be some code using it in openssl. Sorry, I don't know a lot > >about vxworks. > > Thanks! We could look into that in stage 1. >
Maybe something like this, completely untested and not ready to commit.
diff --git a/libstdc++-v3/src/c++11/random.cc b/libstdc++-v3/src/c++11/random.cc index 70fd520077a..eb092cd0950 100644 --- a/libstdc++-v3/src/c++11/random.cc +++ b/libstdc++-v3/src/c++11/random.cc @@ -75,6 +75,14 @@ # include <unistd.h> #endif +#if __has_include(<_vxworks-versions.h>) +# include <_vxworks-versions.h> +# if _VXWORKS_MAJOR_GE(7) && __has_include(<randomNumGen.h>) +# include <randomNumGen.h> +# define USE_RANDBYTES 1 +# endif +#endif + #if defined _GLIBCXX_USE_CRT_RAND_S || defined _GLIBCXX_USE_DEV_RANDOM \ || _GLIBCXX_HAVE_GETENTROPY // The OS provides a source of randomness we can use. @@ -221,6 +229,29 @@ namespace std _GLIBCXX_VISIBILITY(default) } #endif +#if USE_RANDBYTES + unsigned int + __vx_randBytes(void*) + { + int retries = 10; + unsigned int val; + auto bytes = reinterpret_cast<unsigned char*>(&val); + while (retries-- > 0) + { + RANDOM_NUM_GEN_STATUS status = randStatus(); + if (status == RANDOM_NUM_GEN_ENOUGH_ENTROPY + || status == RANDOM_NUM_GEN_MAX_ENTROPY) + { + if (randBytes(bytes, sizeof(val)) == OK) + return val; + } + else + taskDelay(5); + } + std::__throw_runtime_error(__N("random_device: randBytes failed")); + } +#endif + #ifdef USE_LCG // TODO: use this to seed std::mt19937 engine too. unsigned @@ -271,6 +302,7 @@ namespace std _GLIBCXX_VISIBILITY(default) enum Which : unsigned { device_file = 1, prng = 2, rand_s = 4, getentropy = 8, arc4random = 16, rdseed = 64, rdrand = 128, darn = 256, rndr = 512, + randBytes = 1024, any = 0xffff }; @@ -326,6 +358,11 @@ namespace std _GLIBCXX_VISIBILITY(default) return getentropy; #endif +#if USE_RANDBYTES + if (func == __vx_randBytes) + return randBytes; +#endif + #ifdef USE_LCG if (func == &__lcg) return prng; @@ -506,6 +543,14 @@ namespace std _GLIBCXX_VISIBILITY(default) } #endif // _GLIBCXX_HAVE_GETENTROPY +#if USE_RANDBYTES + if (which & randBytes) + { + _M_func = __vx_randBytes; + return; + } +#endif + #ifdef _GLIBCXX_USE_DEV_RANDOM if (which & device_file) { @@ -666,6 +711,8 @@ namespace std _GLIBCXX_VISIBILITY(default) case rand_s: case prng: return 0.0; + case randBytes: // XXX is this a real source of entropy or PRNG? + return 0.0; case device_file: // handled below break;