/* Copyright (c) 2014, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#if !defined(_GNU_SOURCE)
#define _GNU_SOURCE  // needed for syscall() on Linux.
#endif

#include <openssl/rand.h>

#if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_FUCHSIA) && \
    !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) && !defined(OPENSSL_TRUSTY)

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#if defined(OPENSSL_LINUX)
#include <linux/random.h>
#include <sys/ioctl.h>
#include <sys/syscall.h>
#endif

#include <openssl/thread.h>
#include <openssl/mem.h>

#include "internal.h"
#include "../delocate.h"
#include "../../internal.h"


#if defined(OPENSSL_LINUX)

#if defined(OPENSSL_X86_64)
#define EXPECTED_NR_getrandom 318
#elif defined(OPENSSL_X86)
#define EXPECTED_NR_getrandom 355
#elif defined(OPENSSL_AARCH64)
#define EXPECTED_NR_getrandom 278
#elif defined(OPENSSL_ARM)
#define EXPECTED_NR_getrandom 384
#elif defined(OPENSSL_PPC64LE)
#define EXPECTED_NR_getrandom 359
#endif

#if defined(EXPECTED_NR_getrandom)
#define USE_NR_getrandom

#if defined(__NR_getrandom)

#if __NR_getrandom != EXPECTED_NR_getrandom
#error "system call number for getrandom is not the expected value"
#endif

#else  // __NR_getrandom

#define __NR_getrandom EXPECTED_NR_getrandom

#endif  // __NR_getrandom

#endif  // EXPECTED_NR_getrandom

#if !defined(GRND_NONBLOCK)
#define GRND_NONBLOCK 1
#endif

#endif  // OPENSSL_LINUX

// rand_lock is used to protect the |*_requested| variables.
DEFINE_STATIC_MUTEX(rand_lock);

// The following constants are magic values of |urandom_fd|.
static const int kUnset = 0;
static const int kHaveGetrandom = -3;

// urandom_fd_requested is set by |RAND_set_urandom_fd|. It's protected by
// |rand_lock|.
DEFINE_BSS_GET(int, urandom_fd_requested);

// urandom_fd is a file descriptor to /dev/urandom. It's protected by |once|.
DEFINE_BSS_GET(int, urandom_fd);

DEFINE_STATIC_ONCE(rand_once);

#if defined(USE_NR_getrandom) || defined(BORINGSSL_FIPS)
// message writes |msg| to stderr. We use this because referencing |stderr|
// with |fprintf| generates relocations, which is a problem inside the FIPS
// module.
static void message(const char *msg) {
  ssize_t r;
  do {
    r = write(2, msg, strlen(msg));
  } while (r == -1 && errno == EINTR);
}
#endif

// init_once initializes the state of this module to values previously
// requested. This is the only function that modifies |urandom_fd| and
// |urandom_buffering|, whose values may be read safely after calling the
// once.
static void init_once(void) {
  CRYPTO_STATIC_MUTEX_lock_read(rand_lock_bss_get());
  int fd = *urandom_fd_requested_bss_get();
  CRYPTO_STATIC_MUTEX_unlock_read(rand_lock_bss_get());

#if defined(USE_NR_getrandom)
  uint8_t dummy;
  long getrandom_ret =
      syscall(__NR_getrandom, &dummy, sizeof(dummy), GRND_NONBLOCK);

  if (getrandom_ret == 1) {
    *urandom_fd_bss_get() = kHaveGetrandom;
    return;
  } else if (getrandom_ret == -1 && errno == EAGAIN) {
    message(
        "getrandom indicates that the entropy pool has not been initialized. "
        "Rather than continue with poor entropy, this process will block until "
        "entropy is available.\n");

    do {
      getrandom_ret =
          syscall(__NR_getrandom, &dummy, sizeof(dummy), 0 /* no flags */);
    } while (getrandom_ret == -1 && errno == EINTR);

    if (getrandom_ret == 1) {
      *urandom_fd_bss_get() = kHaveGetrandom;
      return;
    }
  }
#endif  // USE_NR_getrandom

  if (fd == kUnset) {
    do {
      fd = open("/dev/urandom", O_RDONLY);
    } while (fd == -1 && errno == EINTR);
  }

  if (fd < 0) {
    abort();
  }

  assert(kUnset == 0);
  if (fd == kUnset) {
    // Because we want to keep |urandom_fd| in the BSS, we have to initialise
    // it to zero. But zero is a valid file descriptor too. Thus if open
    // returns zero for /dev/urandom, we dup it to get a non-zero number.
    fd = dup(fd);
    close(kUnset);

    if (fd <= 0) {
      abort();
    }
  }

#if defined(BORINGSSL_FIPS)
  // In FIPS mode we ensure that the kernel has sufficient entropy before
  // continuing. This is automatically handled by getrandom, which requires
  // that the entropy pool has been initialised, but for urandom we have to
  // poll.
  for (;;) {
    int entropy_bits;
    if (ioctl(fd, RNDGETENTCNT, &entropy_bits)) {
      message(
          "RNDGETENTCNT on /dev/urandom failed. We cannot continue in this "
          "case when in FIPS mode.\n");
      abort();
    }

    static const int kBitsNeeded = 256;
    if (entropy_bits >= kBitsNeeded) {
      break;
    }

    usleep(250000);
  }
#endif

  int flags = fcntl(fd, F_GETFD);
  if (flags == -1) {
    // Native Client doesn't implement |fcntl|.
    if (errno != ENOSYS) {
      abort();
    }
  } else {
    flags |= FD_CLOEXEC;
    if (fcntl(fd, F_SETFD, flags) == -1) {
      abort();
    }
  }
  *urandom_fd_bss_get() = fd;
}

void RAND_set_urandom_fd(int fd) {
  fd = dup(fd);
  if (fd < 0) {
    abort();
  }

  assert(kUnset == 0);
  if (fd == kUnset) {
    // Because we want to keep |urandom_fd| in the BSS, we have to initialise
    // it to zero. But zero is a valid file descriptor too. Thus if dup
    // returned zero we dup it again to get a non-zero number.
    fd = dup(fd);
    close(kUnset);

    if (fd <= 0) {
      abort();
    }
  }

  CRYPTO_STATIC_MUTEX_lock_write(rand_lock_bss_get());
  *urandom_fd_requested_bss_get() = fd;
  CRYPTO_STATIC_MUTEX_unlock_write(rand_lock_bss_get());

  CRYPTO_once(rand_once_bss_get(), init_once);
  if (*urandom_fd_bss_get() == kHaveGetrandom) {
    close(fd);
  } else if (*urandom_fd_bss_get() != fd) {
    abort();  // Already initialized.
  }
}

#if defined(USE_NR_getrandom) && defined(OPENSSL_MSAN)
void __msan_unpoison(void *, size_t);
#endif

// fill_with_entropy writes |len| bytes of entropy into |out|. It returns one
// on success and zero on error.
static char fill_with_entropy(uint8_t *out, size_t len) {
  while (len > 0) {
    ssize_t r;

    if (*urandom_fd_bss_get() == kHaveGetrandom) {
#if defined(USE_NR_getrandom)
      do {
        r = syscall(__NR_getrandom, out, len, 0 /* no flags */);
      } while (r == -1 && errno == EINTR);

#if defined(OPENSSL_MSAN)
      if (r > 0) {
        // MSAN doesn't recognise |syscall| and thus doesn't notice that we
        // have initialised the output buffer.
        __msan_unpoison(out, r);
      }
#endif  // OPENSSL_MSAN

#else  // USE_NR_getrandom
      abort();
#endif
    } else {
      do {
        r = read(*urandom_fd_bss_get(), out, len);
      } while (r == -1 && errno == EINTR);
    }

    if (r <= 0) {
      return 0;
    }
    out += r;
    len -= r;
  }

  return 1;
}

// CRYPTO_sysrand puts |requested| random bytes into |out|.
void CRYPTO_sysrand(uint8_t *out, size_t requested) {
  if (requested == 0) {
    return;
  }

  CRYPTO_once(rand_once_bss_get(), init_once);

  if (!fill_with_entropy(out, requested)) {
    abort();
  }

#if defined(BORINGSSL_FIPS_BREAK_CRNG)
  // This breaks the "continuous random number generator test" defined in FIPS
  // 140-2, section 4.9.2, and implemented in rand_get_seed().
  OPENSSL_memset(out, 0, requested);
#endif
}

#endif /* !OPENSSL_WINDOWS && !defined(OPENSSL_FUCHSIA) && \
          !BORINGSSL_UNSAFE_DETERMINISTIC_MODE && !OPENSSL_TRUSTY */
