@@ -102,6 +102,28 @@ static void RandAddSeedPerfmon()
102
102
#endif
103
103
}
104
104
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
+
105
127
/* * Get 32 bytes of system entropy. */
106
128
void GetOSRand (unsigned char *ent32)
107
129
{
@@ -122,8 +144,17 @@ void GetOSRand(unsigned char *ent32)
122
144
* will always return as many bytes as requested and will not be
123
145
* interrupted by signals."
124
146
*/
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
+ }
127
158
}
128
159
#elif defined(HAVE_GETENTROPY)
129
160
/* On OpenBSD this can return up to 256 bytes of entropy, will return an
@@ -150,19 +181,7 @@ void GetOSRand(unsigned char *ent32)
150
181
/* Fall back to /dev/urandom if there is no specific method implemented to
151
182
* get system entropy for this OS.
152
183
*/
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);
166
185
#endif
167
186
}
168
187
0 commit comments