summaryrefslogtreecommitdiff
path: root/padlkrng.cpp
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2017-08-19 15:41:45 -0400
committerJeffrey Walton <noloader@gmail.com>2017-08-19 15:41:45 -0400
commit7fb5953055d14307a9d4ae95fd6499f3a48f8b95 (patch)
tree8373b41085ae414dd5c06f410f8a7a430d366ba5 /padlkrng.cpp
parent65a96fe983d28e6e51612e3d2361716d7cdf9453 (diff)
downloadcryptopp-git-7fb5953055d14307a9d4ae95fd6499f3a48f8b95.tar.gz
Add VIA Padlock RNG
Diffstat (limited to 'padlkrng.cpp')
-rw-r--r--padlkrng.cpp86
1 files changed, 86 insertions, 0 deletions
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<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