Add VIA Padlock RNG
parent
65a96fe983
commit
7fb5953055
|
|
@ -191,6 +191,8 @@ oids.h
|
||||||
osrng.cpp
|
osrng.cpp
|
||||||
osrng.h
|
osrng.h
|
||||||
ossig.h
|
ossig.h
|
||||||
|
padlkrng.cpp
|
||||||
|
padlkrng.h
|
||||||
panama.cpp
|
panama.cpp
|
||||||
panama.h
|
panama.h
|
||||||
pch.cpp
|
pch.cpp
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@
|
||||||
#include "smartptr.h"
|
#include "smartptr.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "drbg.h"
|
#include "drbg.h"
|
||||||
|
#include "rdrand.h"
|
||||||
|
#include "padlkrng.h"
|
||||||
|
|
||||||
#if CRYPTOPP_MSC_VERSION
|
#if CRYPTOPP_MSC_VERSION
|
||||||
# pragma warning(disable: 4355)
|
# pragma warning(disable: 4355)
|
||||||
|
|
@ -439,6 +441,10 @@ void Benchmark1(double t, double hertz)
|
||||||
BenchMarkByNameKeyLess<RandomNumberGenerator>("AutoSeededX917RNG(AES)");
|
BenchMarkByNameKeyLess<RandomNumberGenerator>("AutoSeededX917RNG(AES)");
|
||||||
#endif
|
#endif
|
||||||
BenchMarkByNameKeyLess<RandomNumberGenerator>("MT19937");
|
BenchMarkByNameKeyLess<RandomNumberGenerator>("MT19937");
|
||||||
|
#if (CRYPTOPP_BOOL_X86)
|
||||||
|
if (HasPadlockRNG())
|
||||||
|
BenchMarkByNameKeyLess<RandomNumberGenerator>("PadlockRNG");
|
||||||
|
#endif
|
||||||
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
|
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
|
||||||
if (HasRDRAND())
|
if (HasRDRAND())
|
||||||
BenchMarkByNameKeyLess<RandomNumberGenerator>("RDRAND");
|
BenchMarkByNameKeyLess<RandomNumberGenerator>("RDRAND");
|
||||||
|
|
|
||||||
|
|
@ -252,6 +252,7 @@
|
||||||
<ClCompile Include="network.cpp" />
|
<ClCompile Include="network.cpp" />
|
||||||
<ClCompile Include="oaep.cpp" />
|
<ClCompile Include="oaep.cpp" />
|
||||||
<ClCompile Include="osrng.cpp" />
|
<ClCompile Include="osrng.cpp" />
|
||||||
|
<ClCompile Include="padlkrng.cpp" />
|
||||||
<ClCompile Include="panama.cpp" />
|
<ClCompile Include="panama.cpp" />
|
||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||||
|
|
@ -434,6 +435,7 @@
|
||||||
<ClInclude Include="oaep.h" />
|
<ClInclude Include="oaep.h" />
|
||||||
<ClInclude Include="oids.h" />
|
<ClInclude Include="oids.h" />
|
||||||
<ClInclude Include="osrng.h" />
|
<ClInclude Include="osrng.h" />
|
||||||
|
<ClInclude Include="padlkrng.h" />
|
||||||
<ClInclude Include="panama.h" />
|
<ClInclude Include="panama.h" />
|
||||||
<ClInclude Include="pch.h" />
|
<ClInclude Include="pch.h" />
|
||||||
<ClInclude Include="pkcspad.h" />
|
<ClInclude Include="pkcspad.h" />
|
||||||
|
|
|
||||||
|
|
@ -257,6 +257,9 @@
|
||||||
<ClCompile Include="osrng.cpp">
|
<ClCompile Include="osrng.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="padlkrng.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="panama.cpp">
|
<ClCompile Include="panama.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
@ -699,6 +702,9 @@
|
||||||
<ClInclude Include="osrng.h">
|
<ClInclude Include="osrng.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="padlkrng.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="panama.h">
|
<ClInclude Include="panama.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
// via-rng.cpp - written and placed in public domain by Jeffrey Walton and Uri Blumenthal.
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "cryptlib.h"
|
||||||
|
#include "secblock.h"
|
||||||
|
#include "padlkrng.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
|
||||||
|
NAMESPACE_BEGIN(CryptoPP)
|
||||||
|
|
||||||
|
PadlockRNG::PadlockRNG()
|
||||||
|
{
|
||||||
|
#if CRYPTOPP_BOOL_X86
|
||||||
|
if (!HasPadlockRNG())
|
||||||
|
throw PadlockRNG_Err("HasPadlockRNG");
|
||||||
|
#else
|
||||||
|
throw PadlockRNG_Err("HasPadlockRNG");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void PadlockRNG::GenerateBlock(byte *output, size_t size)
|
||||||
|
{
|
||||||
|
CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(size);
|
||||||
|
#if CRYPTOPP_BOOL_X86
|
||||||
|
while (size)
|
||||||
|
{
|
||||||
|
# if defined(__GNUC__)
|
||||||
|
|
||||||
|
word32 result;
|
||||||
|
__asm__ __volatile__
|
||||||
|
(
|
||||||
|
"movl %1, %%edi ;\n"
|
||||||
|
"movl $1, %%edx ;\n"
|
||||||
|
".byte 0x0f, 0xa7, 0xc0 ;\n"
|
||||||
|
"andl $31, %%eax ;\n"
|
||||||
|
"movl %%eax, %0 ;\n"
|
||||||
|
|
||||||
|
: "=g" (result) : "g" (m_buffer.begin()) : "eax", "edx", "edi", "cc"
|
||||||
|
);
|
||||||
|
|
||||||
|
const size_t rem = STDMIN(result, STDMIN(size, m_buffer.SizeInBytes()));
|
||||||
|
std::memcpy(output, m_buffer, rem);
|
||||||
|
size -= rem; output += rem;
|
||||||
|
|
||||||
|
# elif defined(_MSC_VER)
|
||||||
|
|
||||||
|
word32 result;
|
||||||
|
byte* buffer = reinterpret_cast<byte*>(m_buffer.begin());
|
||||||
|
|
||||||
|
__asm {
|
||||||
|
mov edi, buffer
|
||||||
|
mov edx, 0x01
|
||||||
|
_emit 0x0f
|
||||||
|
_emit 0xa7
|
||||||
|
_emit 0xc0
|
||||||
|
and eax, 31
|
||||||
|
mov result, eax
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t rem = STDMIN(result, STDMIN(size, m_buffer.SizeInBytes()));
|
||||||
|
std::memcpy(output, m_buffer, rem);
|
||||||
|
size -= rem; output += rem;
|
||||||
|
|
||||||
|
# else
|
||||||
|
throw NotImplemented("PadlockRNG::GenerateBlock");
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
#endif // CRYPTOPP_BOOL_X86
|
||||||
|
}
|
||||||
|
|
||||||
|
void PadlockRNG::DiscardBytes(size_t n)
|
||||||
|
{
|
||||||
|
FixedSizeSecBlock<word32, 4> discard;
|
||||||
|
n = RoundUpToMultipleOf(n, sizeof(word32));
|
||||||
|
|
||||||
|
size_t count = STDMIN(n, discard.SizeInBytes());
|
||||||
|
while (count)
|
||||||
|
{
|
||||||
|
GenerateBlock(discard.BytePtr(), count);
|
||||||
|
n -= count;
|
||||||
|
count = STDMIN(n, discard.SizeInBytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NAMESPACE_END
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
// via-rng.h - written and placed in public domain by Jeffrey Walton
|
||||||
|
|
||||||
|
//! \file PadlockRNG.h
|
||||||
|
//! \brief Class for VIA Padlock RNG
|
||||||
|
//! \since Crypto++ 6.0
|
||||||
|
|
||||||
|
#ifndef CRYPTOPP_PADLOCK_RNG_H
|
||||||
|
#define CRYPTOPP_PADLOCK_RNG_H
|
||||||
|
|
||||||
|
#include "cryptlib.h"
|
||||||
|
#include "secblock.h"
|
||||||
|
|
||||||
|
NAMESPACE_BEGIN(CryptoPP)
|
||||||
|
|
||||||
|
//! \brief Exception thrown when a PadlockRNG generator encounters
|
||||||
|
//! 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") {}
|
||||||
|
};
|
||||||
|
|
||||||
|
//! \brief Hardware generated random numbers using PadlockRNG instruction
|
||||||
|
//! \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);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
FixedSizeAlignedSecBlock<word32, 1, true> m_buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
NAMESPACE_END
|
||||||
|
|
||||||
|
#endif // CRYPTOPP_PADLOCK_RNG_H
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
#include "drbg.h"
|
#include "drbg.h"
|
||||||
#include "mersenne.h"
|
#include "mersenne.h"
|
||||||
#include "rdrand.h"
|
#include "rdrand.h"
|
||||||
|
#include "padlkrng.h"
|
||||||
|
|
||||||
#include "modes.h"
|
#include "modes.h"
|
||||||
#include "aes.h"
|
#include "aes.h"
|
||||||
|
|
@ -109,6 +110,10 @@ void RegisterFactories1()
|
||||||
RegisterDefaultFactoryFor<RandomNumberGenerator, AutoSeededX917RNG<AES> >();
|
RegisterDefaultFactoryFor<RandomNumberGenerator, AutoSeededX917RNG<AES> >();
|
||||||
#endif
|
#endif
|
||||||
RegisterDefaultFactoryFor<RandomNumberGenerator, MT19937>();
|
RegisterDefaultFactoryFor<RandomNumberGenerator, MT19937>();
|
||||||
|
#if (CRYPTOPP_BOOL_X86)
|
||||||
|
if (HasPadlockRNG())
|
||||||
|
RegisterDefaultFactoryFor<RandomNumberGenerator, PadlockRNG>();
|
||||||
|
#endif
|
||||||
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
|
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
|
||||||
if (HasRDRAND())
|
if (HasRDRAND())
|
||||||
RegisterDefaultFactoryFor<RandomNumberGenerator, RDRAND>();
|
RegisterDefaultFactoryFor<RandomNumberGenerator, RDRAND>();
|
||||||
|
|
|
||||||
104
validat1.cpp
104
validat1.cpp
|
|
@ -45,6 +45,7 @@
|
||||||
#include "osrng.h"
|
#include "osrng.h"
|
||||||
#include "drbg.h"
|
#include "drbg.h"
|
||||||
#include "rdrand.h"
|
#include "rdrand.h"
|
||||||
|
#include "padlkrng.h"
|
||||||
#include "mersenne.h"
|
#include "mersenne.h"
|
||||||
#include "randpool.h"
|
#include "randpool.h"
|
||||||
#include "zdeflate.h"
|
#include "zdeflate.h"
|
||||||
|
|
@ -84,6 +85,7 @@ bool ValidateAll(bool thorough)
|
||||||
pass=TestMersenne() && pass;
|
pass=TestMersenne() && pass;
|
||||||
#endif
|
#endif
|
||||||
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
|
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
|
||||||
|
pass=TestPadlockRNG() && pass;
|
||||||
pass=TestRDRAND() && pass;
|
pass=TestRDRAND() && pass;
|
||||||
pass=TestRDSEED() && pass;
|
pass=TestRDSEED() && pass;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1043,6 +1045,108 @@ bool TestMersenne()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
|
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
|
||||||
|
bool TestPadlockRNG()
|
||||||
|
{
|
||||||
|
std::cout << "\nTesting Padlock RNG generator...\n\n";
|
||||||
|
|
||||||
|
bool pass = true, fail = false;
|
||||||
|
member_ptr<RandomNumberGenerator> rng;
|
||||||
|
|
||||||
|
try {rng.reset(new PadlockRNG);}
|
||||||
|
catch (const PadlockRNG_Err &) {}
|
||||||
|
if (rng.get())
|
||||||
|
{
|
||||||
|
PadlockRNG& padlock = dynamic_cast<PadlockRNG&>(*rng.get());
|
||||||
|
static const unsigned int SIZE = 10000;
|
||||||
|
|
||||||
|
MeterFilter meter(new Redirector(TheBitBucket()));
|
||||||
|
Deflator deflator(new Redirector(meter));
|
||||||
|
MaurerRandomnessTest maurer;
|
||||||
|
|
||||||
|
ChannelSwitch chsw;
|
||||||
|
chsw.AddDefaultRoute(deflator);
|
||||||
|
chsw.AddDefaultRoute(maurer);
|
||||||
|
|
||||||
|
RandomNumberSource rns(padlock, SIZE, true, new Redirector(chsw));
|
||||||
|
deflator.Flush(true);
|
||||||
|
|
||||||
|
CRYPTOPP_ASSERT(0 == maurer.BytesNeeded());
|
||||||
|
const double mv = maurer.GetTestValue();
|
||||||
|
if (mv < 0.98f)
|
||||||
|
fail = true;
|
||||||
|
|
||||||
|
// Coverity finding, also see http://stackoverflow.com/a/34509163/608639.
|
||||||
|
StreamState ss(std::cout);
|
||||||
|
std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(6);
|
||||||
|
|
||||||
|
pass &= !fail;
|
||||||
|
if (fail)
|
||||||
|
std::cout << "FAILED:";
|
||||||
|
else
|
||||||
|
std::cout << "passed:";
|
||||||
|
std::cout << " Maurer Randomness Test returned value " << mv << "\n";
|
||||||
|
|
||||||
|
fail = false;
|
||||||
|
if (meter.GetTotalBytes() < SIZE)
|
||||||
|
fail = true;
|
||||||
|
|
||||||
|
pass &= !fail;
|
||||||
|
if (fail)
|
||||||
|
std::cout << "FAILED:";
|
||||||
|
else
|
||||||
|
std::cout << "passed:";
|
||||||
|
std::cout << " " << SIZE << " generated bytes compressed to " << meter.GetTotalBytes() << " bytes by DEFLATE\n";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fail = false;
|
||||||
|
padlock.DiscardBytes(SIZE);
|
||||||
|
}
|
||||||
|
catch (const Exception&)
|
||||||
|
{
|
||||||
|
fail = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pass &= !fail;
|
||||||
|
if (fail)
|
||||||
|
std::cout << "FAILED:";
|
||||||
|
else
|
||||||
|
std::cout << "passed:";
|
||||||
|
std::cout << " discarded " << SIZE << " bytes\n";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Miscellaneous for code coverage
|
||||||
|
(void)padlock.AlgorithmName();
|
||||||
|
(void)padlock.CanIncorporateEntropy();
|
||||||
|
padlock.IncorporateEntropy(NULLPTR, 0);
|
||||||
|
|
||||||
|
word32 result = padlock.GenerateWord32();
|
||||||
|
result = padlock.GenerateWord32((result & 0xff), 0xffffffff - (result & 0xff));
|
||||||
|
padlock.GenerateBlock(reinterpret_cast<byte*>(&result), 4);
|
||||||
|
padlock.GenerateBlock(reinterpret_cast<byte*>(&result), 3);
|
||||||
|
padlock.GenerateBlock(reinterpret_cast<byte*>(&result), 2);
|
||||||
|
padlock.GenerateBlock(reinterpret_cast<byte*>(&result), 1);
|
||||||
|
fail = false;
|
||||||
|
}
|
||||||
|
catch (const Exception&)
|
||||||
|
{
|
||||||
|
fail = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pass &= !fail;
|
||||||
|
if (fail)
|
||||||
|
std::cout << "FAILED:";
|
||||||
|
else
|
||||||
|
std::cout << "passed:";
|
||||||
|
std::cout << " GenerateWord32 and Crop\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
std::cout << "Padlock RNG generator not available, skipping test.\n";
|
||||||
|
|
||||||
|
return pass;
|
||||||
|
}
|
||||||
|
|
||||||
bool TestRDRAND()
|
bool TestRDRAND()
|
||||||
{
|
{
|
||||||
std::cout << "\nTesting RDRAND generator...\n\n";
|
std::cout << "\nTesting RDRAND generator...\n\n";
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ bool TestAutoSeededX917();
|
||||||
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
|
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
|
||||||
bool TestRDRAND();
|
bool TestRDRAND();
|
||||||
bool TestRDSEED();
|
bool TestRDSEED();
|
||||||
|
bool TestPadlockRNG();
|
||||||
#endif
|
#endif
|
||||||
bool ValidateBaseCode();
|
bool ValidateBaseCode();
|
||||||
bool ValidateCRC32();
|
bool ValidateCRC32();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue