/* 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. */

#include <openssl/rand.h>

#if !defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_UNSAFE_FUZZER_MODE)

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

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

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


/* This file implements a PRNG by reading from /dev/urandom, optionally with a
 * buffer, which is unsafe across |fork|. */

#define BUF_SIZE 4096

/* rand_buffer contains unused, random bytes, some of which may have been
 * consumed already. */
struct rand_buffer {
  size_t used;
  uint8_t rand[BUF_SIZE];
};

/* requested_lock is used to protect the |*_requested| variables. */
static struct CRYPTO_STATIC_MUTEX requested_lock = CRYPTO_STATIC_MUTEX_INIT;

/* urandom_fd_requested is set by |RAND_set_urandom_fd|.  It's protected by
 * |requested_lock|. */
static int urandom_fd_requested = -2;

/* urandom_fd is a file descriptor to /dev/urandom. It's protected by |once|. */
static int urandom_fd = -2;

/* urandom_buffering_requested is set by |RAND_enable_fork_unsafe_buffering|.
 * It's protected by |requested_lock|. */
static int urandom_buffering_requested = 0;

/* urandom_buffering controls whether buffering is enabled (1) or not (0). This
 * is protected by |once|. */
static int urandom_buffering = 0;

static CRYPTO_once_t once = CRYPTO_ONCE_INIT;

/* 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(&requested_lock);
  urandom_buffering = urandom_buffering_requested;
  int fd = urandom_fd_requested;
  CRYPTO_STATIC_MUTEX_unlock_read(&requested_lock);

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

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

  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 = fd;
}

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

  CRYPTO_STATIC_MUTEX_lock_write(&requested_lock);
  urandom_fd_requested = fd;
  CRYPTO_STATIC_MUTEX_unlock_write(&requested_lock);

  CRYPTO_once(&once, init_once);
  if (urandom_fd != fd) {
    abort();  // Already initialized.
  }
}

void RAND_enable_fork_unsafe_buffering(int fd) {
  if (fd >= 0) {
    fd = dup(fd);
    if (fd < 0) {
      abort();
    }
  } else {
    fd = -2;
  }

  CRYPTO_STATIC_MUTEX_lock_write(&requested_lock);
  urandom_buffering_requested = 1;
  urandom_fd_requested = fd;
  CRYPTO_STATIC_MUTEX_unlock_write(&requested_lock);

  CRYPTO_once(&once, init_once);
  if (urandom_buffering != 1 || (fd >= 0 && urandom_fd != fd)) {
    abort();  // Already initialized.
  }
}

static struct rand_buffer *get_thread_local_buffer(void) {
  struct rand_buffer *buf =
      CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_URANDOM_BUF);
  if (buf != NULL) {
    return buf;
  }

  buf = OPENSSL_malloc(sizeof(struct rand_buffer));
  if (buf == NULL) {
    return NULL;
  }
  buf->used = BUF_SIZE;  /* To trigger a |read_full| on first use. */
  if (!CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_URANDOM_BUF, buf,
                               OPENSSL_free)) {
    OPENSSL_free(buf);
    return NULL;
  }

  return buf;
}

/* read_full reads exactly |len| bytes from |fd| into |out| and returns 1. In
 * the case of an error it returns 0. */
static char read_full(int fd, uint8_t *out, size_t len) {
  ssize_t r;

  while (len > 0) {
    do {
      r = read(fd, out, len);
    } while (r == -1 && errno == EINTR);

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

  return 1;
}

/* read_from_buffer reads |requested| random bytes from the buffer into |out|,
 * refilling it if necessary to satisfy the request. */
static void read_from_buffer(struct rand_buffer *buf,
                             uint8_t *out, size_t requested) {
  size_t remaining = BUF_SIZE - buf->used;

  while (requested > remaining) {
    memcpy(out, &buf->rand[buf->used], remaining);
    buf->used += remaining;
    out += remaining;
    requested -= remaining;

    if (!read_full(urandom_fd, buf->rand, BUF_SIZE)) {
      abort();
      return;
    }
    buf->used = 0;
    remaining = BUF_SIZE;
  }

  memcpy(out, &buf->rand[buf->used], requested);
  buf->used += requested;
}

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

  CRYPTO_once(&once, init_once);
  if (urandom_buffering && requested < BUF_SIZE) {
    struct rand_buffer *buf = get_thread_local_buffer();
    if (buf != NULL) {
      read_from_buffer(buf, out, requested);
      return;
    }
  }

  if (!read_full(urandom_fd, out, requested)) {
    abort();
  }
}

#endif  /* !OPENSSL_WINDOWS && !BORINGSSL_UNSAFE_FUZZER_MODE */
