1 /* 2 * Copyright 2018 Google LLC 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef FCP_SECAGG_SHARED_AES_CTR_PRNG_H_ 18 #define FCP_SECAGG_SHARED_AES_CTR_PRNG_H_ 19 20 #include <cstdint> 21 #include <string> 22 23 #include "fcp/secagg/shared/aes_key.h" 24 #include "fcp/secagg/shared/prng.h" 25 #include "openssl/evp.h" 26 27 namespace fcp { 28 namespace secagg { 29 30 // A cryptographically strong Deterministic Pseudorandom Number Generator based 31 // on AES-CTR in OpenSSL. The seed must be supplied by the user. 32 // 33 // This code is used for the very specific purpose of generating *reproduceable* 34 // numbers which appear pseudorandom to any party not in possession of the input 35 // seed. DO NOT use AesCtrPrng in any situation where real randomness would be 36 // useful, because it uses no entropy at all and will always produce the same 37 // numbers if given the same seed. 38 // 39 // A single instance of AesCtrPrng can generate up to 2^36 bytes of 40 // pseudorandom output. If more than 2^36 bytes of output are needed, multiple 41 // instances of AesCtrPrng with different seeds should be used. 42 // 43 // This class is not thread-safe. 44 45 class AesCtrPrng : public SecureBatchPrng { 46 public: 47 // This class should only be instantiated via AesCtrPrngFactory. 48 friend class AesCtrPrngFactory; 49 50 ~AesCtrPrng() override; 51 52 // Returns a new pseudorandom number of the specified size, generating new 53 // pseudorandom bytes as needed. 54 uint8_t Rand8() override; 55 uint64_t Rand64() override; 56 57 // Fills the provided buffer with pseudorandom bytes. Returns the number of 58 // bytes that has been generated, which can be smaller than the requested 59 // buffer_size if it exceeds the maximum buffer size returned by 60 // GetMaxBufferSize(). 61 int RandBuffer(uint8_t* buffer, int buffer_size) override; 62 63 // Get the maximum size of a buffer that can be filled by RandBuffer() in a 64 // single call. GetMaxBufferSize()65 size_t GetMaxBufferSize() const override { return kCacheSize; } 66 67 private: 68 static constexpr size_t kIvSize = 16; // IV size, in bytes 69 70 // Constructs the PRNG with the given seed, and an IV of all zeroes. 71 // This is ONLY secure if the seed is never used more than once. 72 explicit AesCtrPrng(const AesKey& seed); 73 74 // Number of AES blocks in the cache. 75 // The number of blocks is optimized to make kCacheSize to be a multiple 76 // of any possible number of bytes in a SecAgg output (i.e. 1 to 8). 77 static constexpr size_t kBatchSize = 3 * 5 * 7; 78 79 // Block size, in bytes 80 static constexpr size_t kBlockSize = 16; 81 82 // Size of our cache, in bytes. We cache blocks to save leftover bytes. 83 static constexpr int kCacheSize = kBatchSize * kBlockSize; 84 85 // For security, we don't want to generate more than 2^32-1 blocks. 86 static constexpr size_t kMaxBlocks = 0xFFFFFFFF; 87 88 // Fills the selected cache with deterministic pseudorandomly generated bytes. 89 // After this, the associated next_byte_pos counter must be set to 0. 90 void GenerateBytes(uint8_t* cache, int cache_size); 91 92 // Cache used by both Rand8() and Rand64() 93 uint8_t cache_[kCacheSize]; 94 size_t next_byte_pos_; 95 96 // This is used to generate bytes. 97 static constexpr uint8_t kAllZeroes[kCacheSize] = {0}; 98 99 EVP_CIPHER_CTX* ctx_; 100 size_t blocks_generated_; 101 }; 102 103 } // namespace secagg 104 } // namespace fcp 105 106 #endif // FCP_SECAGG_SHARED_AES_CTR_PRNG_H_ 107