tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nonsecure_base.h (5429B)


      1 // Copyright 2017 The Abseil Authors.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      https://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #ifndef ABSL_RANDOM_INTERNAL_NONSECURE_BASE_H_
     16 #define ABSL_RANDOM_INTERNAL_NONSECURE_BASE_H_
     17 
     18 #include <algorithm>
     19 #include <cstddef>
     20 #include <cstdint>
     21 #include <iterator>
     22 #include <type_traits>
     23 #include <utility>
     24 #include <vector>
     25 
     26 #include "absl/base/config.h"
     27 #include "absl/container/inlined_vector.h"
     28 #include "absl/meta/type_traits.h"
     29 #include "absl/random/internal/entropy_pool.h"
     30 #include "absl/random/internal/salted_seed_seq.h"
     31 #include "absl/random/internal/seed_material.h"
     32 
     33 namespace absl {
     34 ABSL_NAMESPACE_BEGIN
     35 namespace random_internal {
     36 
     37 // RandenPoolSeedSeq is a custom seed sequence type where generate() fills the
     38 // provided buffer via the RandenPool entropy source.
     39 class RandenPoolSeedSeq {
     40 private:
     41  struct ContiguousTag {};
     42  struct BufferTag {};
     43 
     44  // Generate random unsigned values directly into the buffer.
     45  template <typename Contiguous>
     46  void generate_impl(ContiguousTag, Contiguous begin, Contiguous end) {
     47    const size_t n = static_cast<size_t>(std::distance(begin, end));
     48    auto* a = &(*begin);
     49    GetEntropyFromRandenPool(a, sizeof(*a) * n);
     50  }
     51 
     52  // Construct a buffer of size n and fill it with values, then copy
     53  // those values into the seed iterators.
     54  template <typename RandomAccessIterator>
     55  void generate_impl(BufferTag, RandomAccessIterator begin,
     56                     RandomAccessIterator end) {
     57    const size_t n = std::distance(begin, end);
     58    absl::InlinedVector<uint32_t, 8> data(n, 0);
     59    GetEntropyFromRandenPool(data.begin(), sizeof(data[0]) * n);
     60    std::copy(std::begin(data), std::end(data), begin);
     61  }
     62 
     63 public:
     64  using result_type = uint32_t;
     65 
     66  size_t size() { return 0; }
     67 
     68  template <typename OutIterator>
     69  void param(OutIterator) const {}
     70 
     71  template <typename RandomAccessIterator>
     72  void generate(RandomAccessIterator begin, RandomAccessIterator end) {
     73    // RandomAccessIterator must be assignable from uint32_t
     74    if (begin != end) {
     75      using U = typename std::iterator_traits<RandomAccessIterator>::value_type;
     76      // ContiguousTag indicates the common case of a known contiguous buffer,
     77      // which allows directly filling the buffer. In C++20,
     78      // std::contiguous_iterator_tag provides a mechanism for testing this
     79      // capability, however until Abseil's support requirements allow us to
     80      // assume C++20, limit checks to a few common cases.
     81      using TagType = absl::conditional_t<
     82          (std::is_pointer<RandomAccessIterator>::value ||
     83           std::is_same<RandomAccessIterator,
     84                        typename std::vector<U>::iterator>::value),
     85          ContiguousTag, BufferTag>;
     86 
     87      generate_impl(TagType{}, begin, end);
     88    }
     89  }
     90 };
     91 
     92 // Each instance of NonsecureURBGBase<URBG> will be seeded by variates produced
     93 // by a thread-unique URBG-instance.
     94 template <typename URBG, typename Seeder = RandenPoolSeedSeq>
     95 class NonsecureURBGBase {
     96 public:
     97  using result_type = typename URBG::result_type;
     98 
     99  // Default constructor
    100  NonsecureURBGBase() : urbg_(ConstructURBG()) {}
    101 
    102  // Copy disallowed, move allowed.
    103  NonsecureURBGBase(const NonsecureURBGBase&) = delete;
    104  NonsecureURBGBase& operator=(const NonsecureURBGBase&) = delete;
    105  NonsecureURBGBase(NonsecureURBGBase&&) = default;
    106  NonsecureURBGBase& operator=(NonsecureURBGBase&&) = default;
    107 
    108  // Constructor using a seed
    109  template <class SSeq, typename = typename absl::enable_if_t<
    110                            !std::is_same<SSeq, NonsecureURBGBase>::value>>
    111  explicit NonsecureURBGBase(SSeq&& seq)
    112      : urbg_(ConstructURBG(std::forward<SSeq>(seq))) {}
    113 
    114  // Note: on MSVC, min() or max() can be interpreted as MIN() or MAX(), so we
    115  // enclose min() or max() in parens as (min)() and (max)().
    116  // Additionally, clang-format requires no space before this construction.
    117 
    118  // NonsecureURBGBase::min()
    119  static constexpr result_type(min)() { return (URBG::min)(); }
    120 
    121  // NonsecureURBGBase::max()
    122  static constexpr result_type(max)() { return (URBG::max)(); }
    123 
    124  // NonsecureURBGBase::operator()()
    125  result_type operator()() { return urbg_(); }
    126 
    127  // NonsecureURBGBase::discard()
    128  void discard(unsigned long long values) {  // NOLINT(runtime/int)
    129    urbg_.discard(values);
    130  }
    131 
    132  bool operator==(const NonsecureURBGBase& other) const {
    133    return urbg_ == other.urbg_;
    134  }
    135 
    136  bool operator!=(const NonsecureURBGBase& other) const {
    137    return !(urbg_ == other.urbg_);
    138  }
    139 
    140 private:
    141  static URBG ConstructURBG() {
    142    Seeder seeder;
    143    return URBG(seeder);
    144  }
    145 
    146  template <typename SSeq>
    147  static URBG ConstructURBG(SSeq&& seq) {  // NOLINT(runtime/references)
    148    auto salted_seq =
    149        random_internal::MakeSaltedSeedSeq(std::forward<SSeq>(seq));
    150    return URBG(salted_seq);
    151  }
    152 
    153  URBG urbg_;
    154 };
    155 
    156 }  // namespace random_internal
    157 ABSL_NAMESPACE_END
    158 }  // namespace absl
    159 
    160 #endif  // ABSL_RANDOM_INTERNAL_NONSECURE_BASE_H_