summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/freebl/unix_urandom.c
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@gmail.com>2018-09-04 20:53:31 +0200
committerwolfbeast <mcwerewolf@gmail.com>2018-09-04 20:53:31 +0200
commit580084e9e1d0355c96a54a9641df6c1fee894948 (patch)
tree5aff416b5aed2ca9e326054567d837f28c20ed25 /security/nss/lib/freebl/unix_urandom.c
parentfc61780b35af913801d72086456f493f63197da6 (diff)
parentb28ab55f9675f2e97dda9a4fcac0d4f5267a2bb9 (diff)
downloadUXP-580084e9e1d0355c96a54a9641df6c1fee894948.tar
UXP-580084e9e1d0355c96a54a9641df6c1fee894948.tar.gz
UXP-580084e9e1d0355c96a54a9641df6c1fee894948.tar.lz
UXP-580084e9e1d0355c96a54a9641df6c1fee894948.tar.xz
UXP-580084e9e1d0355c96a54a9641df6c1fee894948.zip
Merge branch 'master' into Basilisk-releasev2018.09.05
Diffstat (limited to 'security/nss/lib/freebl/unix_urandom.c')
-rw-r--r--security/nss/lib/freebl/unix_urandom.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/security/nss/lib/freebl/unix_urandom.c b/security/nss/lib/freebl/unix_urandom.c
index 25e6ad91c..869a5ed8c 100644
--- a/security/nss/lib/freebl/unix_urandom.c
+++ b/security/nss/lib/freebl/unix_urandom.c
@@ -4,10 +4,14 @@
#include <fcntl.h>
#include <unistd.h>
+#include <errno.h>
#include "secerr.h"
#include "secrng.h"
#include "prprf.h"
+/* syscall getentropy() is limited to retrieving 256 bytes */
+#define GETENTROPY_MAX_BYTES 256
+
void
RNG_SystemInfoForRNG(void)
{
@@ -28,6 +32,35 @@ RNG_SystemRNG(void *dest, size_t maxLen)
size_t fileBytes = 0;
unsigned char *buffer = dest;
+#if defined(__OpenBSD__) || (defined(LINUX) && defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 25))))
+ int result;
+
+ while (fileBytes < maxLen) {
+ size_t getBytes = maxLen - fileBytes;
+ if (getBytes > GETENTROPY_MAX_BYTES) {
+ getBytes = GETENTROPY_MAX_BYTES;
+ }
+ result = getentropy(buffer, getBytes);
+ if (result == 0) { /* success */
+ fileBytes += getBytes;
+ buffer += getBytes;
+ } else {
+ break;
+ }
+ }
+ if (fileBytes == maxLen) { /* success */
+ return maxLen;
+ }
+ /* If we failed with an error other than ENOSYS, it means the destination
+ * buffer is not writeable. We don't need to try writing to it again. */
+ if (errno != ENOSYS) {
+ PORT_SetError(SEC_ERROR_NEED_RANDOM);
+ return 0;
+ }
+ /* ENOSYS means the kernel doesn't support getentropy()/getrandom().
+ * Reset the number of bytes to get and fall back to /dev/urandom. */
+ fileBytes = 0;
+#endif
fd = open("/dev/urandom", O_RDONLY);
if (fd < 0) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);