padlkrng.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // via-rng.h - written and placed in public domain by Jeffrey Walton
  2. /// \file padlkrng.h
  3. /// \brief Classes for VIA Padlock RNG
  4. /// \since Crypto++ 6.0
  5. /// \sa <A HREF="http://www.cryptopp.com/wiki/VIA_Padlock">VIA
  6. /// Padlock</A> on the Crypto++ wiki
  7. #ifndef CRYPTOPP_PADLOCK_RNG_H
  8. #define CRYPTOPP_PADLOCK_RNG_H
  9. #include "cryptlib.h"
  10. #include "secblock.h"
  11. NAMESPACE_BEGIN(CryptoPP)
  12. /// \brief Exception thrown when a PadlockRNG generator encounters
  13. /// a generator related error.
  14. /// \since Crypto++ 6.0
  15. class PadlockRNG_Err : public Exception
  16. {
  17. public:
  18. PadlockRNG_Err(const std::string &operation)
  19. : Exception(OTHER_ERROR, "PadlockRNG: " + operation + " operation failed") {}
  20. PadlockRNG_Err(const std::string &component, const std::string &message)
  21. : Exception(OTHER_ERROR, component + ": " + message) {}
  22. };
  23. /// \brief Hardware generated random numbers using VIA XSTORE
  24. /// \details Some VIA processors provide a Security Engine called Padlock. The Padlock
  25. /// Security Engine provides AES, SHA and a RNG. The PadlockRNG class provides access
  26. /// to the RNG.
  27. /// \details The VIA generator uses an 8 byte FIFO buffer for random numbers. The
  28. /// generator can be configured to discard bits from the buffer to resist analysis.
  29. /// The <tt>divisor</tt> controls the number of bytes discarded. The formula for
  30. /// the discard amount is <tt>2**divisor - 1</tt>. When <tt>divisor=0</tt> no bits
  31. /// are discarded and the entire 8 byte buffer is read. If <tt>divisor=3</tt> then
  32. /// 7 bytes are discarded and 1 byte is read. TheVIA SDK samples use <tt>divisor=1</tt>.
  33. /// \details Cryptography Research, Inc (CRI) audited the Padlock Security Engine
  34. /// in 2003. CRI provided recommendations to operate the generator for secure and
  35. /// non-secure applications. Additionally, the Programmers Guide and SDK provided a
  36. /// different configuration in the sample code.
  37. /// \details You can operate the generator according to CRI recommendations by setting
  38. /// <tt>divisor</tt>, reading one word (or partial word) at a time from the FIFO, and
  39. /// then inspecting the MSR after each read.
  40. /// \details The audit report with recommendations is available on the Crypto++ wiki
  41. /// at <A HREF="http://www.cryptopp.com/wiki/VIA_Padlock">VIA Padlock</A>.
  42. /// \sa MaurerRandomnessTest() for random bit generators
  43. /// \since Crypto++ 6.0
  44. class PadlockRNG : public RandomNumberGenerator
  45. {
  46. public:
  47. CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "PadlockRNG"; }
  48. virtual ~PadlockRNG() {}
  49. /// \brief Construct a PadlockRNG generator
  50. /// \param divisor the XSTORE divisor
  51. /// \details Some VIA processors provide a Security Engine called Padlock. The Padlock
  52. /// Security Engine provides AES, SHA and a RNG. The PadlockRNG class provides access
  53. /// to the RNG.
  54. /// \details The VIA generator uses an 8 byte FIFO buffer for random numbers. The
  55. /// generator can be configured to discard bits from the buffer to resist analysis.
  56. /// The <tt>divisor</tt> controls the number of bytes discarded. The formula for
  57. /// the discard amount is <tt>2**divisor - 1</tt>. When <tt>divisor=0</tt> no bits
  58. /// are discarded and the entire 8 byte buffer is read. If <tt>divisor=3</tt> then
  59. /// 7 bytes are discarded and 1 byte is read. VIA SDK samples use <tt>divisor=1</tt>.
  60. /// \details Cryptography Research, Inc (CRI) audited the Padlock Security Engine
  61. /// in 2003. CRI provided recommendations to operate the generator for secure and
  62. /// non-secure applications. Additionally, the Programmers SDK provided a different
  63. /// configuration in the sample code.
  64. /// \details The audit report with recommendations is available on the Crypto++ wiki
  65. /// at <A HREF="http://www.cryptopp.com/wiki/VIA_Padlock">VIA Padlock</A>.
  66. /// \sa SetDivisor, GetDivisor
  67. PadlockRNG(word32 divisor=1);
  68. /// \brief Generate random array of bytes
  69. /// \param output the byte buffer
  70. /// \param size the length of the buffer, in bytes
  71. virtual void GenerateBlock(byte *output, size_t size);
  72. /// \brief Generate and discard n bytes
  73. /// \param n the number of bytes to generate and discard
  74. /// \details the Padlock generator discards words, not bytes. If n is
  75. /// not a multiple of a 32-bit word, then it is rounded up to
  76. /// that size.
  77. virtual void DiscardBytes(size_t n);
  78. /// \brief Update RNG state with additional unpredictable values
  79. /// \param input unused
  80. /// \param length unused
  81. /// \details The operation is a nop for this generator.
  82. virtual void IncorporateEntropy(const byte *input, size_t length)
  83. {
  84. // Override to avoid the base class' throw.
  85. CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(length);
  86. }
  87. std::string AlgorithmProvider() const;
  88. /// \brief Set the XSTORE divisor
  89. /// \param divisor the XSTORE divisor
  90. /// \return the old XSTORE divisor
  91. word32 SetDivisor(word32 divisor)
  92. {
  93. word32 old = m_divisor;
  94. m_divisor = DivisorHelper(divisor);
  95. return old;
  96. }
  97. /// \brief Get the XSTORE divisor
  98. /// \return the current XSTORE divisor
  99. word32 GetDivisor() const
  100. {
  101. return m_divisor;
  102. }
  103. /// \brief Get the MSR for the last operation
  104. /// \return the MSR for the last read operation
  105. word32 GetMSR() const
  106. {
  107. return m_msr;
  108. }
  109. protected:
  110. inline word32 DivisorHelper(word32 divisor)
  111. {
  112. return divisor > 3 ? 3 : divisor;
  113. }
  114. private:
  115. FixedSizeAlignedSecBlock<word32, 4, true> m_buffer;
  116. word32 m_divisor, m_msr;
  117. };
  118. NAMESPACE_END
  119. #endif // CRYPTOPP_PADLOCK_RNG_H