diff --git a/openvpn/random/randapi.hpp b/openvpn/random/randapi.hpp index e8ac4738..662c22c4 100644 --- a/openvpn/random/randapi.hpp +++ b/openvpn/random/randapi.hpp @@ -19,7 +19,10 @@ // along with this program in the COPYING file. // If not, see . -// API for random number implementations. +/** + * @file randapi.cpp + * @brief Implementation of the base classes for random number generators + */ #pragma once @@ -34,29 +37,60 @@ namespace openvpn { +/** + * @class RandomAPI + * @brief Abstract base class for random number generators + * + * This class cannot be inherited from directly, use \ref StrongRandomAPI + * or \ref WeakRandomAPI to implement random number generators. + */ class RandomAPI : public RC { public: + /** + * @typedef RCPtr Ptr + * @brief Smart pointer type for managing the ownership of RandomAPI objects + */ typedef RCPtr Ptr; - // Random algorithm name + /** + * @brief Get the name of the random number generation algorithm + * @return The name of the algorithm + */ virtual std::string name() const = 0; - // Fill buffer with random bytes + /** + * @brief Fill a buffer with random bytes + * @param buf Pointer to the buffer + * @param size Number of bytes to generate + */ virtual void rand_bytes(unsigned char *buf, size_t size) = 0; - // Like rand_bytes, but don't throw exception. - // Return true on successs, false on fail. + /** + * @brief Fill a buffer with random bytes without throwing exceptions + * @param buf Pointer to the buffer + * @param size Number of bytes to generate + * @return true on success + * @return false on failure + */ virtual bool rand_bytes_noexcept(unsigned char *buf, size_t size) = 0; - // Fill a data object with random bits + /** + * @brief Fill a data object with random bytes + * @tparam T Type of the object + * @param obj Reference to the object to be filled + */ template void rand_fill(T &obj) { rand_bytes(reinterpret_cast(&obj), sizeof(T)); } - // Return a data object with random bits + /** + * @brief Create a data object filled with random bytes + * @tparam T Type of the object + * @return The generated object + */ template T rand_get() { @@ -65,7 +99,11 @@ class RandomAPI : public RC return ret; } - // Return a data object with random bits, always >= 0 for signed types + /** + * @brief Create a data object filled with random bytes, always >= 0 for signed types + * @tparam T Type of the object + * @return The generated data object + */ template T rand_get_positive() { @@ -75,19 +113,28 @@ class RandomAPI : public RC // maps (T:min, -1) to (0, T:max) which is fine for random generation ret &= std::numeric_limits::max(); } - return ret; } - // Return a uniformly distributed random number in the range [0, end). - // end must be > 0. + /** + * @brief Return a uniformly distributed random number in the range [0, end) + * @tparam T Type of the object + * @param end The upper bound (exclusive) + * @return The generated random number + */ template T randrange(const T end) { return rand_get_positive() % end; } - // Return a uniformly distributed random number in the range [start, end]. + /** + * @brief Return a uniformly distributed random number in the range [start, end] + * @tparam T Type of the object + * @param start The lower bound + * @param end The upper bound + * @return The generated random number + */ template T randrange(const T start, const T end) { @@ -97,10 +144,15 @@ class RandomAPI : public RC return start + rand_get_positive() % (end - start + 1); } - // Return a uniformly distributed random number in the range [0, end). - // If end==0 or end==1, will always return 0. - // This version is strictly 32-bit only and optimizes by avoiding - // integer division. + /** + * @brief Return a uniformly distributed random number in the range [0, end) + * @param end The upper bound (exclusive) + * @return The generated random number + * + * If end==0 or end==1, will always return 0. + * This version is strictly 32-bit only and optimizes by avoiding + * integer division. + */ std::uint32_t randrange32(const std::uint32_t end) { std::uint32_t r; @@ -108,9 +160,15 @@ class RandomAPI : public RC return rand32_distribute(r, end); } - // Return a uniformly distributed random number in the range [start, end]. - // This version is strictly 32-bit only and optimizes by avoiding - // integer division. + /** + * @brief Return a uniformly distributed random number in the range [start, end] + * @param start The lower bound + * @param end The upper bound + * @return The generated random number + * + * This version is strictly 32-bit only and optimizes by avoiding + * integer division. + */ std::uint32_t randrange32(const std::uint32_t start, const std::uint32_t end) { if (start >= end) @@ -119,7 +177,10 @@ class RandomAPI : public RC return start + randrange32(end - start + 1); } - // Return a random byte + /** + * @brief Return a random byte + * @return The generated random byte + */ std::uint8_t randbyte() { std::uint8_t byte; @@ -127,13 +188,23 @@ class RandomAPI : public RC return byte; } - // Return a random boolean + /** + * @brief Return a random boolean + * @return The generated random boolean + */ bool randbool() { return bool(randbyte() & 1); } - // UniformRandomBitGenerator for std::shuffle + /** + * @name UniformRandomBitGenerator members + * + * These members implement the C++11 UniformRandomBitGenerator requirements + * so that RandomAPI instances can be used with std::shuffle (and others). + * See https://en.cppreference.com/w/cpp/named_req/UniformRandomBitGenerator + */ + ///@{ typedef unsigned int result_type; static constexpr result_type min() { @@ -147,6 +218,7 @@ class RandomAPI : public RC { return rand_get(); } + ///@} private: friend class StrongRandomAPI; @@ -154,15 +226,37 @@ class RandomAPI : public RC RandomAPI() = default; }; +/** + * @class StrongRandomAPI + * @brief Abstract base class for cryptographically strong random number generators + * + * Inherit from this class if your random number generator produces cryptographically + * strong random numbers. + */ class StrongRandomAPI : public RandomAPI { public: + /** + * @typedef RCPtr Ptr + * @brief Smart pointer type for managing the ownership of StrongRandomAPI objects + */ typedef RCPtr Ptr; }; +/** + * @class WeakRandomAPI + * @brief Abstract base class for pseudo random number generators + * + * Inherit from this class if your random number generator produces pseudo random numbers + * which are deterministic and should not be used for operations requiring true randomness. + */ class WeakRandomAPI : public RandomAPI { public: + /** + * @typedef RCPtr Ptr + * @brief Smart pointer type for managing the ownership of WeakRandomAPI objects + */ typedef RCPtr Ptr; };