@@ -102,6 +102,28 @@ static void RandAddSeedPerfmon()
102102#endif
103103}
104104
105+ #ifndef WIN32
106+ /* * Fallback: get 32 bytes of system entropy from /dev/urandom. The most
107+ * compatible way to get cryptographic randomness on UNIX-ish platforms.
108+ */
109+ void GetDevURandom (unsigned char *ent32)
110+ {
111+ int f = open (" /dev/urandom" , O_RDONLY);
112+ if (f == -1 ) {
113+ RandFailure ();
114+ }
115+ int have = 0 ;
116+ do {
117+ ssize_t n = read (f, ent32 + have, NUM_OS_RANDOM_BYTES - have);
118+ if (n <= 0 || n + have > NUM_OS_RANDOM_BYTES) {
119+ RandFailure ();
120+ }
121+ have += n;
122+ } while (have < NUM_OS_RANDOM_BYTES);
123+ close (f);
124+ }
125+ #endif
126+
105127/* * Get 32 bytes of system entropy. */
106128void GetOSRand (unsigned char *ent32)
107129{
@@ -122,8 +144,17 @@ void GetOSRand(unsigned char *ent32)
122144 * will always return as many bytes as requested and will not be
123145 * interrupted by signals."
124146 */
125- if (syscall (SYS_getrandom, ent32, NUM_OS_RANDOM_BYTES, 0 ) != NUM_OS_RANDOM_BYTES) {
126- RandFailure ();
147+ int rv = syscall (SYS_getrandom, ent32, NUM_OS_RANDOM_BYTES, 0 );
148+ if (rv != NUM_OS_RANDOM_BYTES) {
149+ if (rv < 0 && errno == ENOSYS) {
150+ /* Fallback for kernel <3.17: the return value will be -1 and errno
151+ * ENOSYS if the syscall is not available, in that case fall back
152+ * to /dev/urandom.
153+ */
154+ GetDevURandom (ent32);
155+ } else {
156+ RandFailure ();
157+ }
127158 }
128159#elif defined(HAVE_GETENTROPY)
129160 /* On OpenBSD this can return up to 256 bytes of entropy, will return an
@@ -150,19 +181,7 @@ void GetOSRand(unsigned char *ent32)
150181 /* Fall back to /dev/urandom if there is no specific method implemented to
151182 * get system entropy for this OS.
152183 */
153- int f = open (" /dev/urandom" , O_RDONLY);
154- if (f == -1 ) {
155- RandFailure ();
156- }
157- int have = 0 ;
158- do {
159- ssize_t n = read (f, ent32 + have, NUM_OS_RANDOM_BYTES - have);
160- if (n <= 0 || n + have > NUM_OS_RANDOM_BYTES) {
161- RandFailure ();
162- }
163- have += n;
164- } while (have < NUM_OS_RANDOM_BYTES);
165- close (f);
184+ GetDevURandom (ent32);
166185#endif
167186}
168187
0 commit comments