// Copyright 2025 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// BoringCrypto Jitter Entropy version 20250725.

#include <openssl/base.h>

#if defined(OPENSSL_LINUX) || defined(OPENSSL_MACOS)

#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include <array>
#include <type_traits>
#include <utility>

#include <openssl/mem.h>

#include "internal.h"
#include "sha512.cc.inc"

#if defined(__x86_64__)
#include <x86intrin.h>
#endif


BSSL_NAMESPACE_BEGIN
namespace entropy {
namespace {

#if defined(__x86_64__)
static uint64_t GetTimestamp() { return _rdtsc(); }
#elif defined(__aarch64__)
static uint64_t GetTimestamp() {
  // Ideally this would use __arm_rsr64 from <arm_acle.h>. Clang has supported
  // it Clang 3.7 (2016), but GCC did not add it until GCC 14.1.0 (2024). See
  // https://crbug.com/440670941. When our minimum GCC is past that point,
  // switch this back to __arm_rsr64.
  uint64_t ret;
  __asm__ volatile("mrs %0, cntvct_el0" : "=r"(ret));
  return ret;
}
#else
static uint64_t GetTimestamp() {
  struct timespec ts;
  clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
  return ts.tv_sec * 1000000000ULL + ts.tv_nsec;
}
#endif

class MemoryOffsetLCG {
 public:
  MemoryOffsetLCG() : state(GetTimestamp() & 0xFFFFFFFF) {}
  uint32_t Next() {
    state = state * 1664525 + 1013904223;
    return state;
  }

 private:
  uint32_t state;
};

class MemoryAccessSampler {
 public:
  MemoryAccessSampler(size_t array_size, unsigned num_samples)
      : array_size_(array_size),
        num_samples_(num_samples),
        array_(reinterpret_cast<uint8_t *>(OPENSSL_malloc(array_size_))) {
    if (array_ == nullptr ||         //
        array_size_ == 0 ||          //
        array_size_ > (1u << 26) ||  //
        array_size_ & (array_size_ - 1)) {
      abort();
    }
  }

  ~MemoryAccessSampler() { OPENSSL_free(const_cast<uint8_t *>(array_)); }

  MemoryAccessSampler(const MemoryAccessSampler &) = delete;
  MemoryAccessSampler &operator=(const MemoryAccessSampler &) = delete;

  MemoryAccessSampler(MemoryAccessSampler &&other)
      : array_size_(other.array_size_),
        num_samples_(other.num_samples_),
        lcg_(other.lcg_),
        array_(other.array_) {
    other.array_ = nullptr;
  }

  bool Next(uint64_t *out) {
    // Perform some memory accesses and measure how long it took. The LCG is
    // intended to defeat any CPU predictors and thus expose this code to as
    // much system entropy as possible.
    for (unsigned i = 0; i < num_samples_; i++) {
      // The lower bits of an LCG tend to fall into short cycles and so are
      // discarded here.
      array_[(lcg_.Next() >> 6) & (array_size_ - 1)] += 1;
    }

    *out = GetTimestamp();
    return true;
  }

 private:
  const size_t array_size_;
  const unsigned num_samples_;
  MemoryOffsetLCG lcg_;
  volatile uint8_t *array_;
};

template <typename T>
class DeltaSampler {
 public:
  explicit DeltaSampler(T &&sub_sampler)
      : sub_sampler_(std::forward<T>(sub_sampler)) {}

  // Next function to return the delta between two subsequent samples
  bool Next(uint64_t *out) {
    uint64_t sample;
    if (!sub_sampler_.Next(&sample)) {
      return false;
    }

    if (!initialized_) {
      last_sample_ = sample;
      if (!sub_sampler_.Next(&sample)) {
        return false;
      }
      initialized_ = true;
    }

    *out = sample - last_sample_;
    last_sample_ = sample;
    return true;
  }

 private:
  bool initialized_ = false;
  T sub_sampler_;
  uint64_t last_sample_ = 0;
};

template <typename U>
DeltaSampler(U &&sub_sampler) -> DeltaSampler<std::decay_t<U>>;

template <typename T>
class MaskSampler {
 public:
  explicit MaskSampler(uint8_t mask, T &&sub_sampler)
      : mask_(mask), sub_sampler_(std::forward<T>(sub_sampler)) {}

  bool Next(uint8_t *out) {
    uint64_t sample;
    if (!sub_sampler_.Next(&sample)) {
      return false;
    }

    *out = sample & mask_;
    return true;
  }

 private:
  const uint8_t mask_;
  T sub_sampler_;
};

template <typename U>
MaskSampler(uint8_t mask, U &&sub_sampler) -> MaskSampler<std::decay_t<U>>;

// The estimated entropy per sample from MaskSampler.
constexpr float kH = 0.8;

// kAlphaLog2 is log_2(alpha), where alpha is the standard false-positive
// probability from SP 800-90B.
static constexpr float kAlphaLog2 = -20;
// kAlpha is the variable of the same name from section 4.4.1 of SP 800-90B.
constexpr float kAlpha = 1.0 / (1 << static_cast<unsigned>(-kAlphaLog2));

// Ceil rounds up its non-negative argument to the next integer. (std::ceil
// isn't constexpr until C++23.)
constexpr unsigned Ceil(float val) {
  auto truncated = static_cast<unsigned>(val);
  if (val == static_cast<float>(truncated)) {
    return truncated;
  }
  if (val > 0) {
    return truncated + 1;
  }
  __builtin_unreachable();
}

template <typename T>
class RepetitionCountTest {
 public:
  static constexpr unsigned kThreshold = 1 + Ceil(-kAlphaLog2 / kH);
  static_assert(kThreshold == 26);

  explicit RepetitionCountTest(T &&sub_sampler)
      : sub_sampler_(std::forward<T>(sub_sampler)) {}

  bool Next(uint8_t *out) {
    uint8_t sample;
    if (!sub_sampler_.Next(&sample)) {
      return false;
    }
    if (sample == last_sample_) {
      count_++;
    } else {
      count_ = 1;
      last_sample_ = sample;
    }
    if (count_ >= kThreshold) {
      return false;
    }
    *out = sample;
    return true;
  }

 private:
  T sub_sampler_;
  unsigned count_ = 0;
  uint8_t last_sample_ = 0;
};

template <typename U>
RepetitionCountTest(U &&sub_sampler) -> RepetitionCountTest<std::decay_t<U>>;

constexpr double BinomialPMF(int64_t k, int64_t n, double p) {
  if (k < 0 || k > n) {
    return 0.0;
  }

  double result = 1.0;
  for (int64_t i = 0; i < k; ++i) {
    result *= (n - i);
    result /= (i + 1);
  }

  for (int64_t i = 0; i < k; ++i) {
    result *= p;
  }
  for (int64_t i = 0; i < n - k; ++i) {
    result *= (1 - p);
  }

  return result;
}

// CritBinom implements the Excel function of the same name.
constexpr unsigned CritBinom(unsigned trials, double probability_s,
                             double alpha) {
  if (probability_s < 0.0 || probability_s > 1.0 || alpha < 0.0 ||
      alpha > 1.0) {
    __builtin_unreachable();
  }

  double cumulative = 0.0;
  for (unsigned k = 0; k <= trials; ++k) {
    cumulative += BinomialPMF(k, trials, probability_s);
    if (cumulative >= alpha) {
      return k;
    }
  }

  return trials;
}

// ExpTaylor calculates e^x using the Taylor series: e^x = 1 + x + x²/2! +
// x³/3! + ...
constexpr double ExpTaylor(double x) {
  double sum = 1.0;
  double term = 1.0;

  for (int i = 1; i < 25; ++i) {
    term *= x / i;
    sum += term;
  }

  return sum;
}

// Power2 calculates 2^exp by calculating e^(ln(2) * exp) = e^(ln(2)) ^ exp =
// 2^exp. (std::pow isn't constexpr until C++26.)
constexpr double Power2(double exp) {
  constexpr double ln2 = 0.693147180559945309417232121458;
  return ExpTaylor(exp * ln2);
}

// AdaptiveProportionTestCutoff implements the function from the footnote on
// page 27 of SP 800-90B.
constexpr unsigned AdaptiveProportionTestCutoff(unsigned W, float H,
                                                float alpha) {
  return 1 + CritBinom(W, Power2(-H), 1.0 - alpha);
}

// These are the example values from table 2 of SP 800-90B, to show that
// we're calculating the values correctly.
static_assert(AdaptiveProportionTestCutoff(512, 0.5, kAlpha) == 410);
static_assert(AdaptiveProportionTestCutoff(512, 1, kAlpha) == 311);
static_assert(AdaptiveProportionTestCutoff(512, 2, kAlpha) == 177);
static_assert(AdaptiveProportionTestCutoff(512, 4, kAlpha) == 62);
static_assert(AdaptiveProportionTestCutoff(512, 8, kAlpha) == 13);

template <typename T>
class AdaptiveProportionTest {
 public:
  // The size of the sliding window, representing the number of recent samples
  // to analyze.
  static constexpr unsigned kWindowSize = 512;

  // The maximum number of times any single byte value is allowed to appear
  // within the sliding window.
  static constexpr unsigned kThreshold =
      AdaptiveProportionTestCutoff(kWindowSize, kH, kAlpha);
  static_assert(kThreshold == 348);

  explicit AdaptiveProportionTest(T &&sub_sampler)
      : sub_sampler_(std::forward<T>(sub_sampler)) {
    counts_.fill(0);
  }

  bool Next(uint8_t *out) {
    uint8_t sample;
    if (!sub_sampler_.Next(&sample)) {
      return false;
    }
    *out = sample;

    if (samples_processed_ >= kWindowSize) {
      const uint8_t evicted_sample = buffer_[buffer_idx_];
      counts_[evicted_sample]--;
    }

    buffer_[buffer_idx_] = sample;
    const uint16_t new_count = ++counts_[sample];

    if (new_count > kThreshold) {
      return false;
    }

    buffer_idx_ = (buffer_idx_ + 1) % kWindowSize;
    samples_processed_++;

    return true;
  }

 private:
  T sub_sampler_;

  // A circular buffer to store the most recent `kWindowSize` samples.
  std::array<uint8_t, kWindowSize> buffer_{};

  // An array to store the frequency counts of each possible byte value (0-255)
  // within the current window.
  std::array<uint16_t, 256> counts_{};

  // The current index for writing into the circular buffer.
  size_t buffer_idx_ = 0;

  // The total number of samples processed. Used to determine when the buffer
  // is full and eviction should begin.
  size_t samples_processed_ = 0;
};

template <typename U>
AdaptiveProportionTest(U &&sub_sampler)
    -> AdaptiveProportionTest<std::decay_t<U>>;

template <typename T>
class SeedSampler {
 public:
  // NIST requires 1024 samples at start-up time. This code is structured so
  // that the entropy generator is considered to be starting afresh for each
  // seed.
  static constexpr unsigned kNumSamples = 1024;

  explicit SeedSampler(T &&sub_sampler)
      : sub_sampler_(std::forward<T>(sub_sampler)) {}

  bool Next(uint8_t out_seed[48]) {
    // HMAC-SHA384 `kNumSamples` samples with an all-zero key:
    SHA512_CTX ctx;
    SHA384_Init(&ctx);

    uint8_t block[kSHA384Block];
    memset(block, 0x36, sizeof(block));
    SHA384_Update(&ctx, block, sizeof(block));

    static_assert(kNumSamples % sizeof(block) == 0);
    for (unsigned i = 0; i < kNumSamples / sizeof(block); i++) {
      for (unsigned j = 0; j < sizeof(block); j++) {
        if (!sub_sampler_.Next(&block[j])) {
          return false;
        }
      }
      SHA384_Update(&ctx, block, sizeof(block));
    }

    SHA384_Final(out_seed, &ctx);

    SHA384_Init(&ctx);
    memset(block, 0x5c, sizeof(block));
    SHA384_Update(&ctx, block, sizeof(block));
    SHA384_Update(&ctx, out_seed, kSHA384DigestLength);
    SHA384_Final(out_seed, &ctx);

    return true;
  }

 private:
  T sub_sampler_;
};

template <typename U>
SeedSampler(U &&sub_sampler) -> SeedSampler<std::decay_t<U>>;

constexpr size_t kMemorySize = 1u << 25;
constexpr size_t kMemoryAccessesPerSample = 16;
constexpr size_t kBitsPerSample = 8;
constexpr uint8_t kMask = (1u << kBitsPerSample) - 1;

}  // namespace

int GetVersion() { return 20250725; }

bool GetSeed(uint8_t out[48]) {
  auto sampler(SeedSampler(AdaptiveProportionTest(RepetitionCountTest(
      MaskSampler(kMask, DeltaSampler(MemoryAccessSampler(
                             kMemorySize, kMemoryAccessesPerSample)))))));
  return sampler.Next(out);
}

bool GetSamples(uint64_t *out, size_t n) {
  auto sampler(
      DeltaSampler(MemoryAccessSampler(kMemorySize, kMemoryAccessesPerSample)));
  for (size_t i = 0; i < n; i++) {
    if (!sampler.Next(&out[i])) {
      return false;
    }
  }
  return true;
}

}  // namespace entropy
BSSL_NAMESPACE_END

#endif  // LINUX || MACOS
