- return 0;
- }
-
- if (r < 0) {
- if (errno == ENOSYS)
- /* we lack the syscall, continue with
- * reading from /dev/urandom */
- have_syscall = false;
- else if (errno == EAGAIN)
- /* not enough entropy for now. Let's
- * remember to use the syscall the
- * next time, again, but also read
- * from /dev/urandom for now, which
- * doesn't care about the current
- * amount of entropy. */
- have_syscall = true;
- else
- return -errno;
+ if (r == n)
+ return 0;
+ if (!high_quality_required) {
+ /* Fill in the remaing bytes using pseudorandom values */
+ pseudorandom_bytes((uint8_t*) p + r, n - r);
+ return 0;
+ }
+
+ already_done = r;
+ } else if (errno == ENOSYS)
+ /* We lack the syscall, continue with reading from /dev/urandom. */
+ have_syscall = false;
+ else if (errno == EAGAIN) {
+ /* The kernel has no entropy whatsoever. Let's remember to
+ * use the syscall the next time again though.
+ *
+ * If high_quality_required is false, return an error so that
+ * random_bytes() can produce some pseudorandom
+ * bytes. Otherwise, fall back to /dev/urandom, which we know
+ * is empty, but the kernel will produce some bytes for us on
+ * a best-effort basis. */
+ have_syscall = true;
+
+ if (!high_quality_required)
+ return -ENODATA;