// Copyright 2016 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <assert.h>
#include <lib/crypto/entropy_pool.h>
#include <lib/crypto/prng.h>
#include <lib/fit/defer.h>
#include <pow2.h>
#include <string.h>
#include <zircon/compiler.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include <explicit-memory/bytes.h>
#include <kernel/mutex.h>
#include <ktl/atomic.h>
#include <ktl/move.h>
#include <openssl/chacha.h>
#include <openssl/sha.h>

#include <ktl/enforce.h>

namespace crypto {
namespace {

const uint128_t kNonceOverflow = ((uint128_t)1ULL) << 96;

static_assert(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__, "must be LE");

}  // namespace

Prng::Prng(const void* data, size_t size) : Prng(data, size, NonThreadSafeTag()) {
  BecomeThreadSafe();
}

Prng::Prng(const void* data, size_t size, NonThreadSafeTag tag) : nonce_(0), accumulated_(0) {
  AddEntropy(data, size);
}

Prng::~Prng() {
  Guard<SpinLock, IrqSave> spinlock_guard(&pool_lock_);
  nonce_ = 0;
}

void Prng::AddEntropy(const void* data, size_t size) {
  DEBUG_ASSERT(data || size == 0);
  ASSERT(size <= kMaxEntropy);

  // Concurrent calls to |AddEntropy| must run sequentially.
  Guard<Mutex> add_entropy_guard(&add_entropy_lock_);
  EntropyPool pool;
  {
    Guard<SpinLock, IrqSave> pool_guard(&pool_lock_);
    pool = pool_.Clone();
  }

  pool.Add(ktl::span<const uint8_t>(reinterpret_cast<const uint8_t*>(data), size));

  {
    Guard<SpinLock, IrqSave> pool_guard(&pool_lock_);
    pool_ = ktl::move(pool);
  }

  // Increment how much entropy has been added, and signal if we have enough.
  size_t total_entropy = accumulated_.fetch_add(size) + size;
  if (is_thread_safe() && total_entropy >= kMinEntropy) {
    ready_->Signal();
  }
}

// AddEntropy() with NULL input effectively reseeds with hash of current key.
void Prng::SelfReseed() { AddEntropy(nullptr, 0); }

void Prng::Draw(void* out, size_t size) {
  DEBUG_ASSERT(out || size == 0);
  ASSERT(size <= kMaxDrawLen);
  // Wait if other threads should add entropy.
  if (is_thread_safe() && accumulated_.load() < kMinEntropy) {
    ready_->Wait();
  }
  // Save these on the stack, but guarantee we clean them up
  EntropyPool pool;
  uint128_t nonce;
  auto cleanup = fit::defer([&] { mandatory_memset(&nonce, 0, sizeof(nonce)); });
  {
    Guard<SpinLock, IrqSave> pool_guard(&pool_lock_);
    nonce = ++nonce_;
    pool = pool_.Clone();
  }
  ASSERT(nonce < kNonceOverflow);
  uint8_t* nonce_u8 = reinterpret_cast<uint8_t*>(&nonce);
  uint8_t* buf = reinterpret_cast<uint8_t*>(out);

  // We randomize |buf| by encrypting it with a key that is never exposed to
  // the caller, and a 96-bit nonce that changes on each call.  We don't zero
  // |buf| because the encrypted output meets the criteria of the PRNG
  // regardless of its original contents.  We reset the counter to 0 on each
  // request; it can't overflow because of the limit on the overall size.
  CRYPTO_chacha_20(buf, buf, size, pool.contents().data(), nonce_u8, 0);
}

uint64_t Prng::RandInt(uint64_t exclusive_upper_bound) {
  ASSERT(exclusive_upper_bound != 0);

  const uint log2 = static_cast<uint>(log2_ceil<uint64_t>(exclusive_upper_bound));
  const size_t mask =
      (log2 != sizeof(uint64_t) * CHAR_BIT) ? (uint64_t(1) << log2) - 1 : UINT64_MAX;
  DEBUG_ASSERT(exclusive_upper_bound - 1 <= mask);

  // This loop should terminate very fast, since the probability that the
  // drawn value is >= exclusive_upper_bound is less than 0.5.  This is the
  // classic discard out-of-range values approach.
  while (true) {
    uint64_t v;
    Draw(reinterpret_cast<uint8_t*>(&v), sizeof(uint64_t) / sizeof(uint8_t));
    v &= mask;
    if (v < exclusive_upper_bound) {
      return v;
    }
  }
}

// It is safe to call this function from PRNG's constructor provided
// |ready_| and |accumulated_| initialized.
void Prng::BecomeThreadSafe() {
  ASSERT(!is_thread_safe());
  ready_.Initialize(accumulated_.load() >= kMinEntropy);
  is_thread_safe_ = true;
}

bool Prng::is_thread_safe() const {
  // Safe to read |is_thread_safe_|; it is read-only in a threaded context.
  return is_thread_safe_;
}

}  // namespace crypto
