1 #include "quiche/http2/test_tools/http2_random.h"
2
3 #include "absl/strings/escaping.h"
4 #include "openssl/chacha.h"
5 #include "openssl/rand.h"
6 #include "quiche/common/platform/api/quiche_logging.h"
7
8 static const uint8_t kZeroNonce[12] = {0};
9
10 namespace http2 {
11 namespace test {
12
Http2Random()13 Http2Random::Http2Random() {
14 RAND_bytes(key_, sizeof(key_));
15
16 QUICHE_LOG(INFO) << "Initialized test RNG with the following key: " << Key();
17 }
18
Http2Random(absl::string_view key)19 Http2Random::Http2Random(absl::string_view key) {
20 std::string decoded_key = absl::HexStringToBytes(key);
21 QUICHE_CHECK_EQ(sizeof(key_), decoded_key.size());
22 memcpy(key_, decoded_key.data(), sizeof(key_));
23 }
24
Key() const25 std::string Http2Random::Key() const {
26 return absl::BytesToHexString(
27 absl::string_view(reinterpret_cast<const char*>(key_), sizeof(key_)));
28 }
29
FillRandom(void * buffer,size_t buffer_size)30 void Http2Random::FillRandom(void* buffer, size_t buffer_size) {
31 memset(buffer, 0, buffer_size);
32 uint8_t* buffer_u8 = reinterpret_cast<uint8_t*>(buffer);
33 CRYPTO_chacha_20(buffer_u8, buffer_u8, buffer_size, key_, kZeroNonce,
34 counter_++);
35 }
36
RandString(int length)37 std::string Http2Random::RandString(int length) {
38 std::string result;
39 result.resize(length);
40 FillRandom(&result[0], length);
41 return result;
42 }
43
Rand64()44 uint64_t Http2Random::Rand64() {
45 union {
46 uint64_t number;
47 uint8_t bytes[sizeof(uint64_t)];
48 } result;
49 FillRandom(result.bytes, sizeof(result.bytes));
50 return result.number;
51 }
52
RandDouble()53 double Http2Random::RandDouble() {
54 union {
55 double f;
56 uint64_t i;
57 } value;
58 value.i = (1023ull << 52ull) | (Rand64() & 0xfffffffffffffu);
59 return value.f - 1.0;
60 }
61
RandStringWithAlphabet(int length,absl::string_view alphabet)62 std::string Http2Random::RandStringWithAlphabet(int length,
63 absl::string_view alphabet) {
64 std::string result;
65 result.resize(length);
66 for (int i = 0; i < length; i++) {
67 result[i] = alphabet[Uniform(alphabet.size())];
68 }
69 return result;
70 }
71
72 } // namespace test
73 } // namespace http2
74