// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "quiche/quic/core/crypto/quic_random.h"

#include <cstdint>
#include <cstring>

#include "openssl/rand.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/common/platform/api/quiche_logging.h"

namespace quic {

namespace {

// Insecure randomness in DefaultRandom uses an implementation of
// xoshiro256++ 1.0 based on code in the public domain from
// <http://prng.di.unimi.it/xoshiro256plusplus.c>.

inline uint64_t Xoshiro256InitializeRngStateMember() {
  uint64_t result;
  RAND_bytes(reinterpret_cast<uint8_t*>(&result), sizeof(result));
  return result;
}

inline uint64_t Xoshiro256PlusPlusRotLeft(uint64_t x, int k) {
  return (x << k) | (x >> (64 - k));
}

uint64_t Xoshiro256PlusPlus() {
  static thread_local uint64_t rng_state[4] = {
      Xoshiro256InitializeRngStateMember(),
      Xoshiro256InitializeRngStateMember(),
      Xoshiro256InitializeRngStateMember(),
      Xoshiro256InitializeRngStateMember()};
  const uint64_t result =
      Xoshiro256PlusPlusRotLeft(rng_state[0] + rng_state[3], 23) + rng_state[0];
  const uint64_t t = rng_state[1] << 17;
  rng_state[2] ^= rng_state[0];
  rng_state[3] ^= rng_state[1];
  rng_state[1] ^= rng_state[2];
  rng_state[0] ^= rng_state[3];
  rng_state[2] ^= t;
  rng_state[3] = Xoshiro256PlusPlusRotLeft(rng_state[3], 45);
  return result;
}

class DefaultRandom : public QuicRandom {
 public:
  DefaultRandom() {}
  DefaultRandom(const DefaultRandom&) = delete;
  DefaultRandom& operator=(const DefaultRandom&) = delete;
  ~DefaultRandom() override {}

  // QuicRandom implementation
  void RandBytes(void* data, size_t len) override;
  uint64_t RandUint64() override;
  void InsecureRandBytes(void* data, size_t len) override;
  uint64_t InsecureRandUint64() override;
};

void DefaultRandom::RandBytes(void* data, size_t len) {
  RAND_bytes(reinterpret_cast<uint8_t*>(data), len);
}

uint64_t DefaultRandom::RandUint64() {
  uint64_t value;
  RandBytes(&value, sizeof(value));
  return value;
}

void DefaultRandom::InsecureRandBytes(void* data, size_t len) {
  while (len >= sizeof(uint64_t)) {
    uint64_t random_bytes64 = Xoshiro256PlusPlus();
    memcpy(data, &random_bytes64, sizeof(uint64_t));
    data = reinterpret_cast<char*>(data) + sizeof(uint64_t);
    len -= sizeof(uint64_t);
  }
  if (len > 0) {
    QUICHE_DCHECK_LT(len, sizeof(uint64_t));
    uint64_t random_bytes64 = Xoshiro256PlusPlus();
    memcpy(data, &random_bytes64, len);
  }
}

uint64_t DefaultRandom::InsecureRandUint64() { return Xoshiro256PlusPlus(); }

}  // namespace

// static
QuicRandom* QuicRandom::GetInstance() {
  static DefaultRandom* random = new DefaultRandom();
  return random;
}

}  // namespace quic
