Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:06

0001 // via-rng.h - written and placed in public domain by Jeffrey Walton

0002 
0003 /// \file padlkrng.h

0004 /// \brief Classes for VIA Padlock RNG

0005 /// \since Crypto++ 6.0

0006 /// \sa <A HREF="http://www.cryptopp.com/wiki/VIA_Padlock">VIA

0007 ///   Padlock</A> on the Crypto++ wiki

0008 
0009 #ifndef CRYPTOPP_PADLOCK_RNG_H
0010 #define CRYPTOPP_PADLOCK_RNG_H
0011 
0012 #include "cryptlib.h"
0013 #include "secblock.h"
0014 
0015 NAMESPACE_BEGIN(CryptoPP)
0016 
0017 /// \brief Exception thrown when a PadlockRNG generator encounters

0018 /// a generator related error.

0019 /// \since Crypto++ 6.0

0020 class PadlockRNG_Err : public Exception
0021 {
0022 public:
0023     PadlockRNG_Err(const std::string &operation)
0024         : Exception(OTHER_ERROR, "PadlockRNG: " + operation + " operation failed") {}
0025     PadlockRNG_Err(const std::string &component, const std::string &message)
0026         : Exception(OTHER_ERROR, component + ": " + message) {}
0027 };
0028 
0029 /// \brief Hardware generated random numbers using VIA XSTORE

0030 /// \details Some VIA processors provide a Security Engine called Padlock. The Padlock

0031 ///   Security Engine provides AES, SHA and a RNG. The PadlockRNG class provides access

0032 ///   to the RNG.

0033 /// \details The VIA generator uses an 8 byte FIFO buffer for random numbers. The

0034 ///   generator can be configured to discard bits from the buffer to resist analysis.

0035 ///   The <tt>divisor</tt> controls the number of bytes discarded. The formula for

0036 ///   the discard amount is <tt>2**divisor - 1</tt>. When <tt>divisor=0</tt> no bits

0037 ///   are discarded and the entire 8 byte buffer is read. If <tt>divisor=3</tt> then

0038 ///   7 bytes are discarded and 1 byte is read. TheVIA SDK samples use <tt>divisor=1</tt>.

0039 /// \details Cryptography Research, Inc (CRI) audited the Padlock Security Engine

0040 ///   in 2003. CRI provided recommendations to operate the generator for secure and

0041 ///   non-secure applications. Additionally, the Programmers Guide and SDK provided a

0042 ///   different configuration in the sample code.

0043 /// \details You can operate the generator according to CRI recommendations by setting

0044 ///   <tt>divisor</tt>, reading one word (or partial word) at a time from the FIFO, and

0045 ///   then inspecting the MSR after each read.

0046 /// \details The audit report with recommendations is available on the Crypto++ wiki

0047 ///   at <A HREF="http://www.cryptopp.com/wiki/VIA_Padlock">VIA Padlock</A>.

0048 /// \sa MaurerRandomnessTest() for random bit generators

0049 /// \since Crypto++ 6.0

0050 class PadlockRNG : public RandomNumberGenerator
0051 {
0052 public:
0053     CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "PadlockRNG"; }
0054 
0055     virtual ~PadlockRNG() {}
0056 
0057     /// \brief Construct a PadlockRNG generator

0058     /// \param divisor the XSTORE divisor

0059     /// \details Some VIA processors provide a Security Engine called Padlock. The Padlock

0060     ///   Security Engine provides AES, SHA and a RNG. The PadlockRNG class provides access

0061     ///   to the RNG.

0062     /// \details The VIA generator uses an 8 byte FIFO buffer for random numbers. The

0063     ///   generator can be configured to discard bits from the buffer to resist analysis.

0064     ///   The <tt>divisor</tt> controls the number of bytes discarded. The formula for

0065     ///   the discard amount is <tt>2**divisor - 1</tt>. When <tt>divisor=0</tt> no bits

0066     ///   are discarded and the entire 8 byte buffer is read. If <tt>divisor=3</tt> then

0067     ///   7 bytes are discarded and 1 byte is read. VIA SDK samples use <tt>divisor=1</tt>.

0068     /// \details Cryptography Research, Inc (CRI) audited the Padlock Security Engine

0069     ///   in 2003. CRI provided recommendations to operate the generator for secure and

0070     ///   non-secure applications. Additionally, the Programmers SDK provided a different

0071     ///   configuration in the sample code.

0072     /// \details The audit report with recommendations is available on the Crypto++ wiki

0073     ///   at <A HREF="http://www.cryptopp.com/wiki/VIA_Padlock">VIA Padlock</A>.

0074     /// \sa SetDivisor, GetDivisor

0075     PadlockRNG(word32 divisor=1);
0076 
0077     /// \brief Generate random array of bytes

0078     /// \param output the byte buffer

0079     /// \param size the length of the buffer, in bytes

0080     virtual void GenerateBlock(byte *output, size_t size);
0081 
0082     /// \brief Generate and discard n bytes

0083     /// \param n the number of bytes to generate and discard

0084     /// \details the Padlock generator discards words, not bytes. If n is

0085     ///   not a multiple of a 32-bit word, then it is rounded up to

0086     ///   that size.

0087     virtual void DiscardBytes(size_t n);
0088 
0089     /// \brief Update RNG state with additional unpredictable values

0090     /// \param input unused

0091     /// \param length unused

0092     /// \details The operation is a nop for this generator.

0093     virtual void IncorporateEntropy(const byte *input, size_t length)
0094     {
0095         // Override to avoid the base class' throw.

0096         CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(length);
0097     }
0098 
0099     std::string AlgorithmProvider() const;
0100 
0101     /// \brief Set the XSTORE divisor

0102     /// \param divisor the XSTORE divisor

0103     /// \return the old XSTORE divisor

0104     word32 SetDivisor(word32 divisor)
0105     {
0106         word32 old = m_divisor;
0107         m_divisor = DivisorHelper(divisor);
0108         return old;
0109     }
0110 
0111     /// \brief Get the XSTORE divisor

0112     /// \return the current XSTORE divisor

0113     word32 GetDivisor() const
0114     {
0115         return m_divisor;
0116     }
0117 
0118     /// \brief Get the MSR for the last operation

0119     /// \return the MSR for the last read operation

0120     word32 GetMSR() const
0121     {
0122         return m_msr;
0123     }
0124 
0125 protected:
0126     inline word32 DivisorHelper(word32 divisor)
0127     {
0128         return divisor > 3 ? 3 : divisor;
0129     }
0130 
0131 private:
0132     FixedSizeAlignedSecBlock<word32, 4, true> m_buffer;
0133     word32 m_divisor, m_msr;
0134 };
0135 
0136 NAMESPACE_END
0137 
0138 #endif  // CRYPTOPP_PADLOCK_RNG_H