summaryrefslogtreecommitdiff
path: root/padlkrng.h
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2017-08-20 04:09:19 -0400
committerJeffrey Walton <noloader@gmail.com>2017-08-20 04:09:19 -0400
commit61c8b7495199d8c9e5579381ac8a283dc656c68d (patch)
tree3cd712b77f82dce27f7c57492865d07d36f524f9 /padlkrng.h
parentbc4bb9a952432e52d9595db37f10cd5c6b294335 (diff)
downloadcryptopp-git-61c8b7495199d8c9e5579381ac8a283dc656c68d.tar.gz
Add Divisor and MSR member variables
Guard ASM based on CRYPTOPP_X86_ASM_AVAILABLE Increased depth of internal buffer Update documentation for using the generator Whitespace check-in
Diffstat (limited to 'padlkrng.h')
-rw-r--r--padlkrng.h136
1 files changed, 98 insertions, 38 deletions
diff --git a/padlkrng.h b/padlkrng.h
index 9a70fd87..f62dc5dd 100644
--- a/padlkrng.h
+++ b/padlkrng.h
@@ -1,8 +1,10 @@
// via-rng.h - written and placed in public domain by Jeffrey Walton
-//! \file PadlockRNG.h
-//! \brief Class for VIA Padlock RNG
+//! \file padlkrng.h
+//! \brief Classes for VIA Padlock RNG
//! \since Crypto++ 6.0
+//! \sa <A HREF="http://www.cryptopp.com/wiki/VIA_Padlock">VIA
+//! Padlock</A> on the Crypto++ wiki
#ifndef CRYPTOPP_PADLOCK_RNG_H
#define CRYPTOPP_PADLOCK_RNG_H
@@ -13,56 +15,114 @@
NAMESPACE_BEGIN(CryptoPP)
//! \brief Exception thrown when a PadlockRNG generator encounters
-//! a generator related error.
+//! a generator related error.
//! \since Crypto++ 6.0
class PadlockRNG_Err : public Exception
{
public:
- PadlockRNG_Err(const std::string &operation)
- : Exception(OTHER_ERROR, "PadlockRNG: " + operation + " operation failed") {}
+ PadlockRNG_Err(const std::string &operation)
+ : Exception(OTHER_ERROR, "PadlockRNG: " + operation + " operation failed") {}
+ PadlockRNG_Err(const std::string &component, const std::string &message)
+ : Exception(OTHER_ERROR, component + ": " + message) {}
};
//! \brief Hardware generated random numbers using PadlockRNG instruction
+//! \details The PadlockRNG uses an 8 byte FIFO buffer for random numbers. The
+//! generator can be configured to discard bits from the buffer to resist analysis.
+//! The <tt>divisor</tt> controls the number of bytes discarded. The formula for
+//! the discard amount is <tt>2**divisor - 1</tt>. When <tt>divisor=0</tt> no bits
+//! are discarded and the entire 8 byte buffer is read. If <tt>divisor=3</tt> then
+//! 7 bytes are discarded and 1 byte is read. TheVIA SDK samples use <tt>divisor=1</tt>.
+//! \details Cryptography Research, Inc (CRI) audited the Padlock Security Engine
+//! in 2003. CRI provided recommendations to operate the generator for secure and
+//! non-secure applications. Additionally, the Programmers Guide and SDK provided a
+//! different configuration in the sample code.
+//! \details You can operate the generator according to CRI recommendations by setting
+//! <tt>divisor</tt>, reading one word (or partial word) at a time, and then inspecting
+//! the MSR after each read.
+//! \details The audit report with recommendations is available on the Crypto++ wiki
+//! at <A HREF="http://www.cryptopp.com/wiki/VIA_Padlock">VIA Padlock</A>.
//! \sa MaurerRandomnessTest() for random bit generators
//! \since Crypto++ 6.0
class PadlockRNG : public RandomNumberGenerator
{
public:
- CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "PadlockRNG"; }
-
- virtual ~PadlockRNG() {}
-
- //! \brief Construct a PadlockRNG generator
- //! \details According to DJ of Intel, the Intel PadlockRNG circuit does not underflow.
- //! If it did hypothetically underflow, then it would return 0 for the random value.
- //! AMD's PadlockRNG implementation appears to provide the same behavior.
- //! \throws PadlockRNG_Err if the random number generator is not available
- PadlockRNG();
-
- //! \brief Generate random array of bytes
- //! \param output the byte buffer
- //! \param size the length of the buffer, in bytes
- virtual void GenerateBlock(byte *output, size_t size);
-
- //! \brief Generate and discard n bytes
- //! \param n the number of bytes to generate and discard
- //! \details the RDSEED generator discards words, not bytes. If n is
- //! not a multiple of a machine word, then it is rounded up to
- //! that size.
- virtual void DiscardBytes(size_t n);
-
- //! \brief Update RNG state with additional unpredictable values
- //! \param input unused
- //! \param length unused
- //! \details The operation is a nop for this generator.
- virtual void IncorporateEntropy(const byte *input, size_t length)
- {
- // Override to avoid the base class' throw.
- CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(length);
- }
+ CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "PadlockRNG"; }
+
+ virtual ~PadlockRNG() {}
+
+ //! \brief Construct a PadlockRNG generator
+ //! \param divisor the XSTORE divisor
+ //! \details The PadlockRNG uses an 8 byte FIFO buffer for random numbers. The
+ //! generator can be configured to discard bits from the buffer to resist analysis.
+ //! The <tt>divisor</tt> controls the number of bytes discarded. The formula for
+ //! the discard amount is <tt>2**divisor - 1</tt>. When <tt>divisor=0</tt> no bits
+ //! are discarded and the entire 8 byte buffer is read. If <tt>divisor=3</tt> then
+ //! 7 bytes are discarded and 1 byte is read. VIA SDK samples use <tt>divisor=1</tt>.
+ //! \details Cryptography Research, Inc (CRI) audited the Padlock Security Engine
+ //! in 2003. CRI provided recommendations to operate the generator for secure and
+ //! non-secure applications. Additionally, the Programmers SDK provided a different
+ //! configuration in the sample code.
+ //! \details The audit report with recommendations is available on the Crypto++ wiki
+ //! at <A HREF="http://www.cryptopp.com/wiki/VIA_Padlock">VIA Padlock</A>.
+ //! \sa SetDivisor, GetDivisor
+ PadlockRNG(word32 divisor=1);
+
+ //! \brief Generate random array of bytes
+ //! \param output the byte buffer
+ //! \param size the length of the buffer, in bytes
+ virtual void GenerateBlock(byte *output, size_t size);
+
+ //! \brief Generate and discard n bytes
+ //! \param n the number of bytes to generate and discard
+ //! \details the RDSEED generator discards words, not bytes. If n is
+ //! not a multiple of a machine word, then it is rounded up to
+ //! that size.
+ virtual void DiscardBytes(size_t n);
+
+ //! \brief Update RNG state with additional unpredictable values
+ //! \param input unused
+ //! \param length unused
+ //! \details The operation is a nop for this generator.
+ virtual void IncorporateEntropy(const byte *input, size_t length)
+ {
+ // Override to avoid the base class' throw.
+ CRYPTOPP_UNUSED(input); CRYPTOPP_UNUSED(length);
+ }
+
+ //! \brief Set the XSTORE divisor
+ //! \param divisor the XSTORE divisor
+ //! \returns the old XSTORE divisor
+ word32 SetDivisor(word32 divisor)
+ {
+ word32 old = m_divisor;
+ m_divisor = DivisorHelper(divisor);
+ return old;
+ }
+
+ //! \brief Get the XSTORE divisor
+ //! \returns the current XSTORE divisor
+ word32 GetDivisor() const
+ {
+ return m_divisor;
+ }
+
+ //! \brief Get the MSR for the last operation
+ //! \returns the MSR for the last read operation
+ word32 GetMSR() const
+ {
+ return m_msr;
+ }
+
+protected:
+ inline word32 DivisorHelper(word32 divisor)
+ {
+ return divisor > 3 ? 3 : divisor;
+ }
private:
- FixedSizeAlignedSecBlock<word32, 1, true> m_buffer;
+ FixedSizeAlignedSecBlock<word32, 4, true> m_buffer;
+ word32 m_divisor, m_msr;
};
NAMESPACE_END