Crypto++  6.1
Free C++ class library of cryptographic schemes
padlkrng.cpp
1 // via-rng.cpp - written and placed in public domain by Jeffrey Walton and Uri Blumenthal.
2 
3 #include "pch.h"
4 #include "config.h"
5 #include "cryptlib.h"
6 #include "secblock.h"
7 #include "padlkrng.h"
8 #include "cpu.h"
9 
10 // The Padlock Security Engine RNG has a few items to be aware of. You can
11 // find copies of the Programmer's manual, Cryptography Research Inc audit
12 // report, and other goodies at http://www.cryptopp.com/wiki/VIA_Padlock.
13 
14 #if CRYPTOPP_MSC_VERSION
15 # pragma warning(disable: 4702)
16 #endif
17 
18 NAMESPACE_BEGIN(CryptoPP)
19 
20 PadlockRNG::PadlockRNG(word32 divisor)
21 : m_divisor(DivisorHelper(divisor)), m_msr(0)
22 {
23 #if defined(CRYPTOPP_X86_ASM_AVAILABLE)
24  if (!HasPadlockRNG())
25  throw PadlockRNG_Err("PadlockRNG", "PadlockRNG generator not available");
26 #else
27  throw PadlockRNG_Err("PadlockRNG", "PadlockRNG generator not available");
28 #endif
29 }
30 
31 void PadlockRNG::GenerateBlock(byte *output, size_t size)
32 {
33  CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(size);
34 #if defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(__GNUC__)
35  while (size)
36  {
37  __asm__ __volatile__
38  (
39 #if (CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
40  "mov %1, %%rdi ;\n"
41  "movl %2, %%edx ;\n"
42 #else
43  "mov %1, %%edi ;\n"
44  "movl %2, %%edx ;\n"
45 #endif
46 
47  ".byte 0x0f, 0xa7, 0xc0 ;\n"
48  "movl %%eax, %0 ;\n"
49 
50  : "=g" (m_msr) : "g" (m_buffer.data()), "g" (m_divisor)
51 #if (CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
52  : "eax", "edx", "rdi", "cc"
53 #else
54  : "eax", "edx", "edi", "cc"
55 #endif
56  );
57 
58  const size_t ret = m_msr & 0x1f;
59  const size_t rem = STDMIN<size_t>(ret, STDMIN<size_t>(size, 16U /*buffer size*/));
60  std::memcpy(output, m_buffer, rem);
61  size -= rem; output += rem;
62  }
63 #elif defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(_MSC_VER) && defined(_M_IX86)
64  while (size)
65  {
66  word32 result, divisor = m_divisor;
67  byte *buffer = reinterpret_cast<byte*>(m_buffer.data());
68  __asm {
69  mov edi, buffer
70  mov edx, divisor
71  _emit 0x0f
72  _emit 0xa7
73  _emit 0xc0
74  mov result, eax
75  }
76 
77  const size_t ret = (m_msr = result) & 0x1f;
78  const size_t rem = STDMIN<size_t>(ret, STDMIN<size_t>(size, 16U /*buffer size*/));
79  std::memcpy(output, buffer, rem);
80  size -= rem; output += rem;
81  }
82 #else
83  throw PadlockRNG_Err("GenerateBlock", "PadlockRNG generator not available");
84 #endif // CRYPTOPP_X86_ASM_AVAILABLE
85 }
86 
88 {
90  n = RoundUpToMultipleOf(n, sizeof(word32));
91 
92  size_t count = STDMIN(n, discard.SizeInBytes());
93  while (count)
94  {
95  GenerateBlock(discard.BytePtr(), count);
96  n -= count;
97  count = STDMIN(n, discard.SizeInBytes());
98  }
99 }
100 
101 NAMESPACE_END
virtual void DiscardBytes(size_t n)
Generate and discard n bytes.
Definition: padlkrng.cpp:87
size_type SizeInBytes() const
Provides the number of bytes in the SecBlock.
Definition: secblock.h:575
Classes for VIA Padlock RNG.
bool HasPadlockRNG()
Determines Padlock RNG availability.
Definition: cpu.h:239
Abstract base classes that provide a uniform interface to this library.
Library configuration file.
Hardware generated random numbers using VIA XSTORE.
Definition: padlkrng.h:50
Classes and functions for secure memory allocations.
A::pointer data()
Provides a pointer to the first element in the memory block.
Definition: secblock.h:553
Exception thrown when a PadlockRNG generator encounters a generator related error.
Definition: padlkrng.h:20
Precompiled header file.
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:507
Functions for CPU features and intrinsics.
T1 RoundUpToMultipleOf(const T1 &n, const T2 &m)
Rounds a value up to a multiple of a second value.
Definition: misc.h:971
Crypto++ library namespace.
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: padlkrng.cpp:31
byte * BytePtr()
Provides a byte pointer to the first element in the memory block.
Definition: secblock.h:568