padlkrng.cpp
// 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"
// The Padlock Security Engine RNG has a few items to be aware of. You can
// find copies of the Programmer's manual, Cryptography Research Inc audit
// report, and other goodies at http://www.cryptopp.com/wiki/VIA_Padlock.
#if CRYPTOPP_MSC_VERSION
# pragma warning(disable: 4702)
#endif
NAMESPACE_BEGIN(CryptoPP)
std::string PadlockRNG::AlgorithmProvider() const
{
return "Padlock";
}
PadlockRNG::PadlockRNG(word32 divisor)
: m_divisor(DivisorHelper(divisor)), m_msr(0)
{
#if defined(CRYPTOPP_X86_ASM_AVAILABLE)
if (!HasPadlockRNG())
#endif
throw PadlockRNG_Err("PadlockRNG", "PadlockRNG generator not available");
}
void PadlockRNG::GenerateBlock(byte *output, size_t size)
{
CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(size);
#if defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(__GNUC__)
while (size)
{
__asm__ __volatile__
(
#if (CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
"mov %1, %%rdi ;\n"
"movl %2, %%edx ;\n"
#else
"mov %1, %%edi ;\n"
"movl %2, %%edx ;\n"
#endif
// xstore-rng
".byte 0x0f, 0xa7, 0xc0 ;\n"
"movl %%eax, %0 ;\n"
: "=g" (m_msr) : "g" (m_buffer.data()), "g" (m_divisor)
#if (CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
: "rax", "rdx", "rdi", "cc"
#else
: "eax", "edx", "edi", "cc"
#endif
);
const size_t ret = m_msr & 0x1f;
const size_t rem = STDMIN<size_t>(ret, STDMIN<size_t>(size, 16U /*buffer size*/));
std::memcpy(output, m_buffer, rem);
size -= rem; output += rem;
}
#elif defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(CRYPTOPP_MSC_VERSION) && defined(_M_IX86)
while (size)
{
word32 result, divisor = m_divisor;
byte *buffer = reinterpret_cast<byte*>(m_buffer.data());
__asm {
mov edi, buffer
mov edx, divisor
_emit 0x0f
_emit 0xa7
_emit 0xc0
mov result, eax
}
const size_t ret = (m_msr = result) & 0x1f;
const size_t rem = STDMIN<size_t>(ret, STDMIN<size_t>(size, 16U /*buffer size*/));
std::memcpy(output, buffer, rem);
size -= rem; output += rem;
}
#else
throw PadlockRNG_Err("GenerateBlock", "PadlockRNG generator not available");
#endif // CRYPTOPP_X86_ASM_AVAILABLE
}
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
FixedSizeSecBlock
Fixed size stack-based SecBlock.
Definition secblock.h:1246
PadlockRNG_Err
Exception thrown when a PadlockRNG generator encounters a generator related error.
Definition padlkrng.h:21
PadlockRNG::PadlockRNG
PadlockRNG(word32 divisor=1)
Construct a PadlockRNG generator.
Definition padlkrng.cpp:25
PadlockRNG::DiscardBytes
virtual void DiscardBytes(size_t n)
Generate and discard n bytes.
Definition padlkrng.cpp:91
PadlockRNG::GenerateBlock
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition padlkrng.cpp:34
PadlockRNG::AlgorithmProvider
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Definition padlkrng.cpp:20
SecBlock::SizeInBytes
size_type SizeInBytes() const
Provides the number of bytes in the SecBlock.
Definition secblock.h:885
SecBlock::BytePtr
byte * BytePtr()
Provides a byte pointer to the first element in the memory block.
Definition secblock.h:876
config.h
Library configuration file.
CRYPTOPP_BOOL_X32
#define CRYPTOPP_BOOL_X32
32-bit x32 platform
Definition config_cpu.h:44
CRYPTOPP_BOOL_X64
#define CRYPTOPP_BOOL_X64
32-bit x86 platform
Definition config_cpu.h:48
word32
unsigned int word32
32-bit unsigned datatype
Definition config_int.h:72
cpu.h
Functions for CPU features and intrinsics.
cryptlib.h
Abstract base classes that provide a uniform interface to this library.
RoundUpToMultipleOf
T1 RoundUpToMultipleOf(const T1 &n, const T2 &m)
Rounds a value up to a multiple of a second value.
Definition misc.h:1384
STDMIN
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition misc.h:657
CryptoPP
Crypto++ library namespace.
padlkrng.h
Classes for VIA Padlock RNG.
pch.h
Precompiled header file.
secblock.h
Classes and functions for secure memory allocations.