|
||||
File indexing completed on 2025-01-18 09:55:08
0001 // rdrand.h - written and placed in public domain by Jeffrey Walton and Uri Blumenthal. 0002 0003 /// \file rdrand.h 0004 /// \brief Classes for RDRAND and RDSEED 0005 /// \since Crypto++ 5.6.3 0006 0007 #ifndef CRYPTOPP_RDRAND_H 0008 #define CRYPTOPP_RDRAND_H 0009 0010 #include "cryptlib.h" 0011 0012 // This class file provides both RDRAND and RDSEED. They were added at 0013 // Crypto++ 5.6.3. At compile time, it uses CRYPTOPP_BOOL_{X86|X32|X64} 0014 // to select an implementation or "throw NotImplemented". At runtime the 0015 // constructor will throw RDRAND_Err or RDSEED_Err if a generator is 0016 // is not available. 0017 // The original classes accepted a retry count. Retries were superfluous for 0018 // RDRAND, and RDSEED encountered a failure about 1 in 256 bytes depending 0019 // on the processor. Retries were removed at Crypto++ 6.0 because 0020 // GenerateBlock unconditionally retries and always fulfills the request. 0021 0022 // Throughput varies wildly depending on processor and manufacturer. A Core i5 or 0023 // Core i7 RDRAND can generate at over 200 MiB/s. It is below theroetical 0024 // maximum, but it takes about 5 instructions to generate, retry and store a 0025 // result. A low-end Celeron may perform RDRAND at about 7 MiB/s. RDSEED 0026 // performs at about 1/4 to 1/2 the rate of RDRAND. AMD RDRAND performed poorly 0027 // during testing with Athlon X4 845. The Bulldozer v4 only performed at 1 MiB/s. 0028 0029 // Microsoft added RDRAND in August 2012, VS2012; RDSEED in October 2013, VS2013. 0030 // GCC added RDRAND in December 2010, GCC 4.6. LLVM added RDRAND in July 2012, 0031 // Clang 3.2. Intel added RDRAND in September 2011, ICC 12.1. 0032 0033 NAMESPACE_BEGIN(CryptoPP) 0034 0035 /// \brief Exception thrown when a RDRAND generator encounters 0036 /// a generator related error. 0037 /// \since Crypto++ 5.6.3 0038 class RDRAND_Err : public Exception 0039 { 0040 public: 0041 RDRAND_Err(const std::string &operation) 0042 : Exception(OTHER_ERROR, "RDRAND: " + operation + " operation failed") {} 0043 }; 0044 0045 /// \brief Hardware generated random numbers using RDRAND instruction 0046 /// \sa MaurerRandomnessTest() for random bit generators 0047 /// \since Crypto++ 5.6.3 0048 class RDRAND : public RandomNumberGenerator 0049 { 0050 public: 0051 CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "RDRAND"; } 0052 0053 virtual ~RDRAND() {} 0054 0055 /// \brief Construct a RDRAND generator 0056 /// \details According to DJ of Intel, the Intel RDRAND circuit does not underflow. 0057 /// If it did hypothetically underflow, then it would return 0 for the random value. 0058 /// AMD's RDRAND implementation appears to provide the same behavior. 0059 /// \throw RDRAND_Err if the random number generator is not available 0060 RDRAND(); 0061 0062 /// \brief Generate random array of bytes 0063 /// \param output the byte buffer 0064 /// \param size the length of the buffer, in bytes 0065 virtual void GenerateBlock(byte *output, size_t size); 0066 0067 /// \brief Generate and discard n bytes 0068 /// \param n the number of bytes to generate and discard 0069 /// \details the RDSEED generator discards words, not bytes. If n is 0070 /// not a multiple of a machine word, then it is rounded up to 0071 /// that size. 0072 virtual void DiscardBytes(size_t n); 0073 0074 /// \brief Update RNG state with additional unpredictable values 0075 /// \param input unused 0076 /// \param length unused 0077 /// \details The operation is a nop for this generator. 0078 virtual void IncorporateEntropy(const byte *input, size_t length) 0079 { 0080 // Override to avoid the base class' throw. 0081 CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(length); 0082 } 0083 0084 std::string AlgorithmProvider() const { 0085 return "RDRAND"; 0086 } 0087 }; 0088 0089 /// \brief Exception thrown when a RDSEED generator encounters 0090 /// a generator related error. 0091 /// \since Crypto++ 5.6.3 0092 class RDSEED_Err : public Exception 0093 { 0094 public: 0095 RDSEED_Err(const std::string &operation) 0096 : Exception(OTHER_ERROR, "RDSEED: " + operation + " operation failed") {} 0097 }; 0098 0099 /// \brief Hardware generated random numbers using RDSEED instruction 0100 /// \sa MaurerRandomnessTest() for random bit generators 0101 /// \since Crypto++ 5.6.3 0102 class RDSEED : public RandomNumberGenerator 0103 { 0104 public: 0105 CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "RDSEED"; } 0106 0107 virtual ~RDSEED() {} 0108 0109 /// \brief Construct a RDSEED generator 0110 /// \details Empirical testing under a 6th generation i7 (6200U) shows RDSEED fails 0111 /// to fulfill requests at about once every for every 256 bytes requested. 0112 /// The generator runs about 4 times slower than RDRAND. 0113 /// \throw RDSEED_Err if the random number generator is not available 0114 RDSEED(); 0115 0116 /// \brief Generate random array of bytes 0117 /// \param output the byte buffer 0118 /// \param size the length of the buffer, in bytes 0119 virtual void GenerateBlock(byte *output, size_t size); 0120 0121 /// \brief Generate and discard n bytes 0122 /// \param n the number of bytes to generate and discard 0123 /// \details the RDSEED generator discards words, not bytes. If n is 0124 /// not a multiple of a machine word, then it is rounded up to 0125 /// that size. 0126 virtual void DiscardBytes(size_t n); 0127 0128 /// \brief Update RNG state with additional unpredictable values 0129 /// \param input unused 0130 /// \param length unused 0131 /// \details The operation is a nop for this generator. 0132 virtual void IncorporateEntropy(const byte *input, size_t length) 0133 { 0134 // Override to avoid the base class' throw. 0135 CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(length); 0136 } 0137 0138 std::string AlgorithmProvider() const { 0139 return "RDSEED"; 0140 } 0141 }; 0142 0143 NAMESPACE_END 0144 0145 #endif // CRYPTOPP_RDRAND_H
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |