mirror of
https://github.com/shadps4-emu/ext-cryptopp.git
synced 2025-01-31 18:22:15 +00:00
Add VIA Padlock RNG
This commit is contained in:
parent
65a96fe983
commit
7fb5953055
@ -191,6 +191,8 @@ oids.h
|
||||
osrng.cpp
|
||||
osrng.h
|
||||
ossig.h
|
||||
padlkrng.cpp
|
||||
padlkrng.h
|
||||
panama.cpp
|
||||
panama.h
|
||||
pch.cpp
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "smartptr.h"
|
||||
#include "cpu.h"
|
||||
#include "drbg.h"
|
||||
#include "rdrand.h"
|
||||
#include "padlkrng.h"
|
||||
|
||||
#if CRYPTOPP_MSC_VERSION
|
||||
# pragma warning(disable: 4355)
|
||||
@ -439,6 +441,10 @@ void Benchmark1(double t, double hertz)
|
||||
BenchMarkByNameKeyLess<RandomNumberGenerator>("AutoSeededX917RNG(AES)");
|
||||
#endif
|
||||
BenchMarkByNameKeyLess<RandomNumberGenerator>("MT19937");
|
||||
#if (CRYPTOPP_BOOL_X86)
|
||||
if (HasPadlockRNG())
|
||||
BenchMarkByNameKeyLess<RandomNumberGenerator>("PadlockRNG");
|
||||
#endif
|
||||
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
|
||||
if (HasRDRAND())
|
||||
BenchMarkByNameKeyLess<RandomNumberGenerator>("RDRAND");
|
||||
|
@ -252,6 +252,7 @@
|
||||
<ClCompile Include="network.cpp" />
|
||||
<ClCompile Include="oaep.cpp" />
|
||||
<ClCompile Include="osrng.cpp" />
|
||||
<ClCompile Include="padlkrng.cpp" />
|
||||
<ClCompile Include="panama.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
@ -434,6 +435,7 @@
|
||||
<ClInclude Include="oaep.h" />
|
||||
<ClInclude Include="oids.h" />
|
||||
<ClInclude Include="osrng.h" />
|
||||
<ClInclude Include="padlkrng.h" />
|
||||
<ClInclude Include="panama.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="pkcspad.h" />
|
||||
|
@ -257,6 +257,9 @@
|
||||
<ClCompile Include="osrng.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="padlkrng.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="panama.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -699,6 +702,9 @@
|
||||
<ClInclude Include="osrng.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="padlkrng.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="panama.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
86
padlkrng.cpp
Normal file
86
padlkrng.cpp
Normal file
@ -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
|
70
padlkrng.h
Normal file
70
padlkrng.h
Normal file
@ -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 "mersenne.h"
|
||||
#include "rdrand.h"
|
||||
#include "padlkrng.h"
|
||||
|
||||
#include "modes.h"
|
||||
#include "aes.h"
|
||||
@ -109,6 +110,10 @@ void RegisterFactories1()
|
||||
RegisterDefaultFactoryFor<RandomNumberGenerator, AutoSeededX917RNG<AES> >();
|
||||
#endif
|
||||
RegisterDefaultFactoryFor<RandomNumberGenerator, MT19937>();
|
||||
#if (CRYPTOPP_BOOL_X86)
|
||||
if (HasPadlockRNG())
|
||||
RegisterDefaultFactoryFor<RandomNumberGenerator, PadlockRNG>();
|
||||
#endif
|
||||
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
|
||||
if (HasRDRAND())
|
||||
RegisterDefaultFactoryFor<RandomNumberGenerator, RDRAND>();
|
||||
|
104
validat1.cpp
104
validat1.cpp
@ -45,6 +45,7 @@
|
||||
#include "osrng.h"
|
||||
#include "drbg.h"
|
||||
#include "rdrand.h"
|
||||
#include "padlkrng.h"
|
||||
#include "mersenne.h"
|
||||
#include "randpool.h"
|
||||
#include "zdeflate.h"
|
||||
@ -84,6 +85,7 @@ bool ValidateAll(bool thorough)
|
||||
pass=TestMersenne() && pass;
|
||||
#endif
|
||||
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
|
||||
pass=TestPadlockRNG() && pass;
|
||||
pass=TestRDRAND() && pass;
|
||||
pass=TestRDSEED() && pass;
|
||||
#endif
|
||||
@ -1043,6 +1045,108 @@ bool TestMersenne()
|
||||
#endif
|
||||
|
||||
#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()
|
||||
{
|
||||
std::cout << "\nTesting RDRAND generator...\n\n";
|
||||
|
@ -28,6 +28,7 @@ bool TestAutoSeededX917();
|
||||
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
|
||||
bool TestRDRAND();
|
||||
bool TestRDSEED();
|
||||
bool TestPadlockRNG();
|
||||
#endif
|
||||
bool ValidateBaseCode();
|
||||
bool ValidateCRC32();
|
||||
|
Loading…
x
Reference in New Issue
Block a user