From 7fb5953055d14307a9d4ae95fd6499f3a48f8b95 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Sat, 19 Aug 2017 15:41:45 -0400 Subject: Add VIA Padlock RNG --- padlkrng.cpp | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 padlkrng.cpp (limited to 'padlkrng.cpp') diff --git a/padlkrng.cpp b/padlkrng.cpp new file mode 100644 index 00000000..ebe7d4f2 --- /dev/null +++ b/padlkrng.cpp @@ -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(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 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 -- cgit v1.2.1