// 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 <ctype.h>
#include <lib/boot-options/boot-options.h>
#include <lib/crypto/entropy/collector.h>
#include <lib/crypto/entropy/hw_rng_collector.h>
#include <lib/crypto/entropy/jitterentropy_collector.h>
#include <lib/crypto/entropy/quality_test.h>
#include <lib/crypto/global_prng.h>
#include <lib/crypto/prng.h>
#include <string.h>
#include <trace.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include <explicit-memory/bytes.h>
#include <fbl/algorithm.h>
#include <kernel/auto_lock.h>
#include <kernel/mutex.h>
#include <kernel/thread.h>
#include <ktl/algorithm.h>
#include <ktl/byte.h>
#include <ktl/move.h>
#include <ktl/span.h>
#include <ktl/string_view.h>
#include <lk/init.h>
#include <openssl/sha.h>
#include <phys/handoff.h>

#include <ktl/enforce.h>

#define LOCAL_TRACE 0

namespace crypto {
namespace global_prng {
namespace {

Prng* g_prng_instance = nullptr;

// Returns true on success, false on failure.
bool SeedFrom(entropy::Collector* collector) {
  uint8_t buf[Prng::kMinEntropy] = {0};
  size_t remaining = collector->BytesNeeded(8 * Prng::kMinEntropy);
#if LOCAL_TRACE
  {
    char name[ZX_MAX_NAME_LEN];
    collector->get_name(name, sizeof(name));
    LTRACEF("About to collect %zu bytes of entropy from '%s'.\n", remaining, name);
  }
#endif
  while (remaining > 0) {
    size_t result = collector->DrawEntropy(buf, ktl::min(sizeof(buf), remaining));
    if (result == 0) {
      LTRACEF(
          "Collected 0 bytes; aborting. "
          "There were %zu bytes remaining to collect.\n",
          remaining);
      return false;
    }

    g_prng_instance->AddEntropy(buf, result);
    mandatory_memset(buf, 0, sizeof(buf));
    remaining -= result;
  }
  LTRACEF("Successfully collected entropy.\n");
  return true;
}

// Instantiates the global PRNG (in non-thread-safe mode) and seeds it.
void EarlyBootSeed(uint level) {
  ASSERT(g_prng_instance == nullptr);

  // Before doing anything else, test our entropy collector. This is
  // explicitly called here rather than in another init hook to ensure
  // ordering (at level LK_INIT_LEVEL_PLATFORM_EARLY + 1, but before the rest
  // of EarlyBootSeed).
  entropy::EarlyBootTest();

  // Statically allocate an array of bytes to put the PRNG into.  We do this
  // to control when the PRNG constructor is called.
  // TODO(security): This causes the PRNG state to be in a fairly predictable
  // place.  Some aspects of KASLR will help with this, but we may
  // additionally want to remap where this is later.
  alignas(alignof(Prng)) static uint8_t prng_space[sizeof(Prng)];

  // number of successful entropy sources
  unsigned int successful = 0;

  g_prng_instance = new (&prng_space) Prng(nullptr, 0, crypto::Prng::NonThreadSafeTag{});

  // All validation from zbi item and commandline item is performed on phys, so
  // this instance of entropy pool, is guaranteed to meet the minimum requirements
  // for the current boot options, or we would have panic'd already.
  ZX_ASSERT(!gBootOptions->cprng_seed_require_cmdline || gPhysHandoff->entropy_pool.has_value());
  if (gPhysHandoff->entropy_pool) {
    // |pool|'s destructor will wipe the stack.
    auto pool = ktl::move(gPhysHandoff->entropy_pool.value());
    g_prng_instance->AddEntropy(pool.contents().data(), pool.contents().size());
    successful++;
  }
  entropy::Collector* collector = nullptr;
  if (!gBootOptions->cprng_disable_hw_rng &&
      entropy::HwRngCollector::GetInstance(&collector) == ZX_OK && SeedFrom(collector)) {
    successful++;
  } else if (gBootOptions->cprng_seed_require_hw_rng) {
    panic("Failed to seed PRNG from required entropy source: hw-rng\n");
  }
  if (!gBootOptions->cprng_disable_jitterentropy &&
      entropy::JitterentropyCollector::GetInstance(&collector) == ZX_OK && SeedFrom(collector)) {
    successful++;
  } else if (gBootOptions->cprng_seed_require_jitterentropy) {
    panic("Failed to seed PRNG from required entropy source: jitterentropy\n");
  }

  if (successful == 0) {
    printf(
        "WARNING: System has insufficient randomness.  It is completely "
        "unsafe to use this system for any cryptographic applications."
        "\n");
    // TODO(security): *CRITICAL* This is a fallback for systems without RNG
    // hardware that we should remove and attempt to do better.  If this
    // fallback is used, it breaks all cryptography used on the system.
    // *CRITICAL*
    uint8_t buf[Prng::kMinEntropy] = {0};
    g_prng_instance->AddEntropy(buf, sizeof(buf));
    return;
  } else {
    LTRACEF("Successfully collected entropy from %u sources.\n", successful);
  }
}

// Migrate the global PRNG to enter thread-safe mode.
void BecomeThreadSafe(uint level) { GetInstance()->BecomeThreadSafe(); }

// Collect entropy and add it to the cprng.
void ReseedPRNG() {
  unsigned int successful = 0;  // number of successful entropy sources
  entropy::Collector* collector = nullptr;
  // Reseed using HW RNG and jitterentropy;
  if (!gBootOptions->cprng_disable_hw_rng &&
      entropy::HwRngCollector::GetInstance(&collector) == ZX_OK && SeedFrom(collector)) {
    successful++;
  } else if (gBootOptions->cprng_reseed_require_hw_rng) {
    panic("Failed to reseed PRNG from required entropy source: hw-rng\n");
  }
  if (!gBootOptions->cprng_disable_jitterentropy &&
      entropy::JitterentropyCollector::GetInstance(&collector) == ZX_OK && SeedFrom(collector)) {
    successful++;
  } else if (gBootOptions->cprng_reseed_require_jitterentropy) {
    panic("Failed to reseed PRNG from required entropy source: jitterentropy\n");
  }

  if (successful == 0) {
    g_prng_instance->SelfReseed();
    LTRACEF("Reseed PRNG with no new entropy source\n");
  } else {
    LTRACEF("Successfully reseed PRNG from %u sources.\n", successful);
  }
}

int ReseedLoop(void* arg) {
  for (;;) {
    Thread::Current::SleepRelative(ZX_SEC(30));
    ReseedPRNG();
  }
  return 0;
}

// Start a thread to reseed PRNG.
void StartReseedThread(uint level) {
  // Force a reseed before returning from the init hook.
  // We have no guarantees when the thread will be scheduled and run.
  // TODO(fxbug.dev/82810): Make this synchronous reseed faster by removing
  // JitterEntropy reseed, as we already seeded from it in EarlyBoot.
  ReseedPRNG();
  Thread* t = Thread::Create("prng-reseed", ReseedLoop, nullptr, HIGHEST_PRIORITY);
  t->DetachAndResume();
}

}  // namespace

Prng* GetInstance() {
  ASSERT(g_prng_instance);
  return g_prng_instance;
}

}  // namespace global_prng
}  // namespace crypto

// intel hw_rng init hook is at PLATFORM_EARLY+1
// make sure we start after that so we can use it for the early seed.
LK_INIT_HOOK(global_prng_seed, crypto::global_prng::EarlyBootSeed, LK_INIT_LEVEL_PLATFORM_EARLY + 2)

LK_INIT_HOOK(global_prng_thread_safe, crypto::global_prng::BecomeThreadSafe,
             LK_INIT_LEVEL_THREADING - 1)

// Reseed the CPRNG right before entering userspace.
LK_INIT_HOOK(global_prng_reseed, crypto::global_prng::StartReseedThread, LK_INIT_LEVEL_USER - 1)
