TEST(sys_random, getentropy) {
#if defined(HAVE_SYS_RANDOM)
  char buf1[64];
  char buf2[64];

  ASSERT_EQ(0, getentropy(buf1, sizeof(buf1)));
  ASSERT_EQ(0, getentropy(buf2, sizeof(buf2)));
  ASSERT_TRUE(memcmp(buf1, buf2, sizeof(buf1)) != 0);
#else
  GTEST_SKIP() << "<sys/random.h> not available";
#endif
}
Beispiel #2
0
TEST(sys_random, getentropy) {
#if defined(HAVE_SYS_RANDOM)
  char buf1[64];
  char buf2[64];

  ASSERT_EQ(0, getentropy(buf1, sizeof(buf1)));
  ASSERT_EQ(0, getentropy(buf2, sizeof(buf2)));
  ASSERT_TRUE(memcmp(buf1, buf2, sizeof(buf1)) != 0);
#else
  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
#endif
}
static int osrandom_rand_bytes(unsigned char *buffer, int size) {
    int len;
    int res;

    switch(getentropy_works) {
#if defined(__APPLE__)
    case CRYPTOGRAPHY_OSRANDOM_GETENTROPY_FALLBACK:
        return dev_urandom_read(buffer, size);
#endif
    case CRYPTOGRAPHY_OSRANDOM_GETENTROPY_WORKS:
        while (size > 0) {
            /* OpenBSD and macOS restrict maximum buffer size to 256. */
            len = size > 256 ? 256 : size;
            res = getentropy(buffer, (size_t)len);
            if (res < 0) {
                ERR_Cryptography_OSRandom_error(
                    CRYPTOGRAPHY_OSRANDOM_F_RAND_BYTES,
                    CRYPTOGRAPHY_OSRANDOM_R_GETENTROPY_FAILED,
                    __FILE__, __LINE__
                );
                return 0;
            }
            buffer += len;
            size -= len;
        }
        return 1;
    }
    __builtin_unreachable();
}
Beispiel #4
0
static int li_getentropy (void *buf, size_t buflen)
{
  #ifdef HAVE_GETENTROPY
    return getentropy(buf, buflen);
  #else
    /*(see NOTES section in 'man getrandom' on Linux)*/
   #if defined(HAVE_GETRANDOM) || defined(SYS_getrandom)
    if (buflen <= 256) {
      #ifdef HAVE_GETRANDOM /*(not implemented in glibc yet)*/
        int num = getrandom(buf, buflen, 0);
      #elif defined(SYS_getrandom)
        /* https://lwn.net/Articles/605828/ */
        /* https://bbs.archlinux.org/viewtopic.php?id=200039 */
        int num = (int)syscall(SYS_getrandom, buf, buflen, 0);
      #endif
        if (num == (int)buflen) return 0;
        if (num < 0)            return num; /* -1 */
    }
   #else
    UNUSED(buf);
    UNUSED(buflen);
   #endif
    errno = EIO;
    return -1;
  #endif
}
Beispiel #5
0
static void
_rs_stir(void)
{
	u_char rnd[KEYSZ + IVSZ];

	if (getentropy(rnd, sizeof rnd) == -1) {
#ifdef SIGKILL
		raise(SIGKILL);
#else
		exit(9); /* windows */
#endif
	}

	if (!rs)
		_rs_init(rnd, sizeof(rnd));
	else
		_rs_rekey(rnd, sizeof(rnd));
	explicit_bzero(rnd, sizeof(rnd));	/* discard source seed */

	/* invalidate rs_buf */
	rs->rs_have = 0;
	memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));

	rs->rs_count = 1600000;
}
static int get(struct RandomSeed* randomSeed, uint64_t output[8])
{
    if (getentropy(output, 64) < 0) {
        return -1;
    } else {
        return 0;
    }
}
TEST(sys_random, getentropy_EFAULT) {
#if defined(HAVE_SYS_RANDOM)
  errno = 0;
  ASSERT_EQ(-1, getentropy(nullptr, 1));
  ASSERT_EQ(EFAULT, errno);
#else
  GTEST_SKIP() << "<sys/random.h> not available";
#endif
}
Beispiel #8
0
TEST(sys_random, getentropy_EFAULT) {
#if defined(HAVE_SYS_RANDOM)
  errno = 0;
  ASSERT_EQ(-1, getentropy(nullptr, 1));
  ASSERT_EQ(EFAULT, errno);
#else
  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
#endif
}
Beispiel #9
0
/*
 * syscall_random(): Try to get random data using a system call
 * returns the number of bytes returned in buf, or < 0 on error.
 */
static ssize_t syscall_random(void *buf, size_t buflen)
{
    /*
     * Note: 'buflen' equals the size of the buffer which is used by the
     * get_entropy() callback of the RAND_DRBG. It is roughly bounded by
     *
     *   2 * RAND_POOL_FACTOR * (RAND_DRBG_STRENGTH / 8) = 2^14
     *
     * which is way below the OSSL_SSIZE_MAX limit. Therefore sign conversion
     * between size_t and ssize_t is safe even without a range check.
     */

    /*
     * Do runtime detection to find getentropy().
     *
     * Known OSs that should support this:
     * - Darwin since 16 (OSX 10.12, IOS 10.0).
     * - Solaris since 11.3
     * - OpenBSD since 5.6
     * - Linux since 3.17 with glibc 2.25
     * - FreeBSD since 12.0 (1200061)
     */
#  if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) && !defined(__hpux)
    extern int getentropy(void *buffer, size_t length) __attribute__((weak));

    if (getentropy != NULL)
        return getentropy(buf, buflen) == 0 ? (ssize_t)buflen : -1;
#  else
    union {
        void *p;
        int (*f)(void *buffer, size_t length);
    } p_getentropy;

    /*
     * We could cache the result of the lookup, but we normally don't
     * call this function often.
     */
    ERR_set_mark();
    p_getentropy.p = DSO_global_lookup("getentropy");
    ERR_pop_to_mark();
    if (p_getentropy.p != NULL)
        return p_getentropy.f(buf, buflen) == 0 ? (ssize_t)buflen : -1;
#  endif

    /* Linux supports this since version 3.17 */
#  if defined(__linux) && defined(SYS_getrandom)
    return syscall(SYS_getrandom, buf, buflen, 0);
#  elif (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(KERN_ARND)
    return sysctl_random(buf, buflen);
#  else
    errno = ENOSYS;
    return -1;
#  endif
}
TEST(sys_random, getentropy_EIO) {
#if defined(HAVE_SYS_RANDOM)
  char buf[BUFSIZ];
  static_assert(BUFSIZ > 256, "BUFSIZ <= 256!");

  errno = 0;
  ASSERT_EQ(-1, getentropy(buf, sizeof(buf)));
  ASSERT_EQ(EIO, errno);
#else
  GTEST_SKIP() << "<sys/random.h> not available";
#endif
}
Beispiel #11
0
TEST(sys_random, getentropy_EIO) {
#if defined(HAVE_SYS_RANDOM)
  char buf[BUFSIZ];
  static_assert(BUFSIZ > 256, "BUFSIZ <= 256!");

  errno = 0;
  ASSERT_EQ(-1, getentropy(buf, sizeof(buf)));
  ASSERT_EQ(EIO, errno);
#else
  GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
#endif
}
Beispiel #12
0
/** Generates a random vector of AUTH_VECTOR_LEN octets
 *
 * @param vector a buffer with at least %AUTH_VECTOR_LEN bytes.
 */
static void rc_random_vector (unsigned char *vector)
{
	int             randno;
	int             i;
#if defined(HAVE_GETENTROPY)
	if (getentropy(vector, AUTH_VECTOR_LEN) >= 0) {
		return;
	} /* else fall through */
#elif defined(HAVE_DEV_URANDOM)
	int		fd;

/* well, I added this to increase the security for user passwords.
   we use /dev/urandom here, as /dev/random might block and we don't
   need that much randomness. BTW, great idea, Ted!     -lf, 03/18/95	*/

	if ((fd = open(_PATH_DEV_URANDOM, O_RDONLY)) >= 0)
	{
		unsigned char *pos;
		int readcount;

		i = AUTH_VECTOR_LEN;
		pos = vector;
		while (i > 0)
		{
			readcount = read(fd, (char *)pos, i);
			if (readcount >= 0) {
				pos += readcount;
				i -= readcount;
			} else {
				if (errno != EINTR && errno != EAGAIN)
					goto fallback;
			}
		}

		close(fd);
		return;
	} /* else fall through */
#endif
 fallback:
	for (i = 0; i < AUTH_VECTOR_LEN;)
	{
		randno = random ();
		memcpy ((char *) vector, (char *) &randno, sizeof (int));
		vector += sizeof (int);
		i += sizeof (int);
	}

	return;
}
Beispiel #13
0
/*
 * syscall_random(): Try to get random data using a system call
 * returns the number of bytes returned in buf, or <= 0 on error.
 */
int syscall_random(void *buf, size_t buflen)
{
    /*
     * Do runtime detection to find getentropy().
     *
     * Known OSs that should support this:
     * - Darwin since 16 (OSX 10.12, IOS 10.0).
     * - Solaris since 11.3
     * - OpenBSD since 5.6
     * - Linux since 3.17 with glibc 2.25
     * - FreeBSD since 12.0 (1200061)
     */
#  if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) && !defined(__hpux)
    extern int getentropy(void *bufer, size_t length) __attribute__((weak));

    if (getentropy != NULL)
        return getentropy(buf, buflen) == 0 ? buflen : 0;
#  else
    union {
        void *p;
        int (*f)(void *buffer, size_t length);
    } p_getentropy;

    /*
     * We could cache the result of the lookup, but we normally don't
     * call this function often.
     */
    ERR_set_mark();
    p_getentropy.p = DSO_global_lookup("getentropy");
    ERR_pop_to_mark();
    if (p_getentropy.p != NULL)
        return p_getentropy.f(buf, buflen) == 0 ? buflen : 0;
#  endif

    /* Linux supports this since version 3.17 */
#  if defined(__linux) && defined(SYS_getrandom)
    return (int)syscall(SYS_getrandom, buf, buflen, 0);
#  endif

#  if (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(KERN_ARND)
    return (int)sysctl_random(buf, buflen);
#  endif

    return -1;
}
Beispiel #14
0
/* Fill buffer with size pseudo-random bytes generated by getentropy().
   Return 0 on success, or raise an exception and return -1 on error.

   If fatal is nonzero, call Py_FatalError() instead of raising an exception
   on error. */
static int
py_getentropy(unsigned char *buffer, Py_ssize_t size, int fatal)
{
    while (size > 0) {
        Py_ssize_t len = Py_MIN(size, 256);
        int res;

        if (!fatal) {
            Py_BEGIN_ALLOW_THREADS
            res = getentropy(buffer, len);
            Py_END_ALLOW_THREADS

            if (res < 0) {
                PyErr_SetFromErrno(PyExc_OSError);
                return -1;
            }
        }
        else {
Beispiel #15
0
static void
_rs_stir(void)
{
	u_char rnd[KEYSZ + IVSZ];

	if (getentropy(rnd, sizeof rnd) == -1)
		_getentropy_fail();

	if (!rs)
		_rs_init(rnd, sizeof(rnd));
	else
		_rs_rekey(rnd, sizeof(rnd));
	explicit_bzero(rnd, sizeof(rnd));	/* discard source seed */

	/* invalidate rs_buf */
	rs->rs_have = 0;
	memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));

	rs->rs_count = 1600000;
}
Beispiel #16
0
/* Generate pseudorandom data to stdout. Long parameter is kilobytes */
int prandom (long quantity)
{
    char entropy[1024];
    char pdata[1024];
    int x,y;
    int xlim = 1024;
    long kb_rem = quantity;

    while(kb_rem > 0) {
        getentropy(entropy);
        if (kb_rem < 1024) {
            xlim = kb_rem;
        }
        for(x=0; x<xlim; x++) {
            for(y=0; y<1024; y++) {
                pdata[y] = entropy[x] ^ entropy[y];
            }
            write(1, pdata, 1024);
        }
        kb_rem = kb_rem - 1024;
    }

    return 0;
}
Beispiel #17
0
    while (size > 0) {
        Py_ssize_t len = Py_MIN(size, 256);
        int res;

        if (!fatal) {
            Py_BEGIN_ALLOW_THREADS
            res = getentropy(buffer, len);
            Py_END_ALLOW_THREADS

            if (res < 0) {
                PyErr_SetFromErrno(PyExc_OSError);
                return -1;
            }
        }
        else {
            res = getentropy(buffer, len);
            if (res < 0)
                Py_FatalError("getentropy() failed");
        }

        buffer += len;
        size -= len;
    }
    return 0;
}

#else

/* Issue #25003: Don' use getentropy() on Solaris (available since
 * Solaris 11.3), it is blocking whereas os.urandom() should not block. */
#if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
Beispiel #18
0
int my_getentropy(void *buf, size_t buflen){
    return getentropy(buf, buflen);
}
Beispiel #19
0
/** Generate 128 bits of random noise for seeding RNGs. Attempts to
 * use various OS-specific sources of random bits, with a fallback
 * based on time and pid. */
void
generate_seed(uint64_t seeds[])
{
  bool seed_generated = false;
  static int stream_count = 0;
  int len = sizeof(uint64_t) * 2;

#ifdef HAVE_GETENTROPY
  /* On OpenBSD and up to date Linux, use getentropy() to avoid the
     open/read/close sequence with /dev/urandom */
  if (!seed_generated && getentropy(seeds, len) == 0) {
    fprintf(stderr, "Seeded RNG with getentropy()\n");
    seed_generated = true;
  }
#endif

#ifdef HAVE_ARC4RANDOM_BUF
  /* Most (all?) of the BSDs have this seeder. Use it for the reasons
     above. Also available on Linux with libbsd, but we don't check
     for that. */
  if (!seed_generated) {
    arc4random_buf(seeds, len);
    fprintf(stderr, "Seeded RNG with arc4random\n");
    seed_generated = true;
  }
#endif

#ifdef WIN32
  if (!seed_generated) {
    /* Use the Win32 bcrypto RNG interface */
    if (BCryptGenRandom(NULL, (PUCHAR) seeds, len,
                        BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS) {
      fprintf(stderr, "Seeding RNG with BCryptGenRandom()\n");
      seed_generated = true;
    }
  }
#endif

#ifdef HAVE_DEV_URANDOM
  if (!seed_generated) {
    /* Seed from /dev/urandom if available */
    int fd;

    fd = open("/dev/urandom", O_RDONLY);
    if (fd >= 0) {
      int r = read(fd, (void *) seeds, len);
      close(fd);
      if (r != len) {
        fprintf(stderr, "Couldn't read from /dev/urandom! Resorting to normal "
                        "seeding method.\n");
      } else {
        fprintf(stderr, "Seeding RNG with /dev/urandom\n");
        seed_generated = true;
      }
    } else {
      fprintf(stderr, "Couldn't open /dev/urandom to seed random number "
                      "generator. Resorting to normal seeding method.\n");
    }
  }
#endif

  if (!seed_generated) {
    /* Default seeder. Pick a seed that's slightly random */
#ifdef WIN32
    seeds[0] = (uint64_t) time(NULL);
    seeds[1] = (uint64_t) GetCurrentProcessId() + stream_count;
#else
    seeds[0] = (uint64_t) time(NULL);
    seeds[1] = (uint64_t) getpid() + stream_count;
#endif
    stream_count += 1;
  }
}