Botan  1.11.15
Public Member Functions | Static Public Member Functions
Botan::High_Resolution_Timestamp Class Reference

#include <hres_timer.h>

Inheritance diagram for Botan::High_Resolution_Timestamp:
Botan::EntropySource

List of all members.

Public Member Functions

std::string name () const
void poll (Entropy_Accumulator &accum)

Static Public Member Functions

static void poll_available_sources (class Entropy_Accumulator &accum)

Detailed Description

Entropy source using high resolution timers

Note:
Any results from timers are marked as not contributing entropy to the poll, as a local attacker could observe them directly.

Definition at line 21 of file hres_timer.h.


Member Function Documentation

std::string Botan::High_Resolution_Timestamp::name ( ) const [inline, virtual]
Returns:
name identifying this entropy source

Implements Botan::EntropySource.

Definition at line 24 of file hres_timer.h.

{ return "High Resolution Timestamp"; }

Perform an entropy gathering poll

Parameters:
accumis an accumulator object that will be given entropy

Implements Botan::EntropySource.

Definition at line 27 of file hres_timer.cpp.

References Botan::Entropy_Accumulator::add(), Botan::CPUID::has_rdtsc(), and STD_CHRONO_POLL.

   {
   // Don't count any timestamps as contributing any entropy
   const double ESTIMATED_ENTROPY_PER_BYTE = 0.0;

#if defined(BOTAN_TARGET_OS_HAS_CLOCK_GETTIME)

#define CLOCK_GETTIME_POLL(src)                              \
   do {                                                      \
     struct timespec ts;                                     \
     ::clock_gettime(src, &ts);                              \
     accum.add(&ts, sizeof(ts), ESTIMATED_ENTROPY_PER_BYTE); \
   } while(0)

#if defined(CLOCK_REALTIME)
   CLOCK_GETTIME_POLL(CLOCK_REALTIME);
#endif

#if defined(CLOCK_MONOTONIC)
   CLOCK_GETTIME_POLL(CLOCK_MONOTONIC);
#endif

#if defined(CLOCK_MONOTONIC_RAW)
   CLOCK_GETTIME_POLL(CLOCK_MONOTONIC_RAW);
#endif

#if defined(CLOCK_PROCESS_CPUTIME_ID)
   CLOCK_GETTIME_POLL(CLOCK_PROCESS_CPUTIME_ID);
#endif

#if defined(CLOCK_THREAD_CPUTIME_ID)
   CLOCK_GETTIME_POLL(CLOCK_THREAD_CPUTIME_ID);
#endif

#undef CLOCK_GETTIME_POLL

#else

#define STD_CHRONO_POLL(clock)                                  \
   do {                                                         \
      auto timestamp = clock::now().time_since_epoch().count(); \
      accum.add(timestamp, ESTIMATED_ENTROPY_PER_BYTE);         \
   } while(0)

  STD_CHRONO_POLL(std::chrono::high_resolution_clock);
  STD_CHRONO_POLL(std::chrono::system_clock);

#undef STD_CHRONO_POLL

#endif

#if BOTAN_USE_GCC_INLINE_ASM

   u64bit rtc = 0;

#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
   if(CPUID::has_rdtsc()) // not availble on all x86 CPUs
      {
      u32bit rtc_low = 0, rtc_high = 0;
      asm volatile("rdtsc" : "=d" (rtc_high), "=a" (rtc_low));
      rtc = (static_cast<u64bit>(rtc_high) << 32) | rtc_low;
      }

#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
   u32bit rtc_low = 0, rtc_high = 0;
   asm volatile("mftbu %0; mftb %1" : "=r" (rtc_high), "=r" (rtc_low));
   rtc = (static_cast<u64bit>(rtc_high) << 32) | rtc_low;

#elif defined(BOTAN_TARGET_ARCH_IS_ALPHA)
   asm volatile("rpcc %0" : "=r" (rtc));

#elif defined(BOTAN_TARGET_ARCH_IS_SPARC64) && !defined(BOTAN_TARGET_OS_IS_OPENBSD)
   asm volatile("rd %%tick, %0" : "=r" (rtc));

#elif defined(BOTAN_TARGET_ARCH_IS_IA64)
   asm volatile("mov %0=ar.itc" : "=r" (rtc));

#elif defined(BOTAN_TARGET_ARCH_IS_S390X)
   asm volatile("stck 0(%0)" : : "a" (&rtc) : "memory", "cc");

#elif defined(BOTAN_TARGET_ARCH_IS_HPPA)
   asm volatile("mfctl 16,%0" : "=r" (rtc)); // 64-bit only?

#endif

   accum.add(rtc, ESTIMATED_ENTROPY_PER_BYTE);

#endif

#if defined(BOTAN_TARGET_OS_HAS_QUERY_PERF_COUNTER)
   {
   LARGE_INTEGER tv;
   ::QueryPerformanceCounter(&tv);
   accum.add(tv.QuadPart, ESTIMATED_ENTROPY_PER_BYTE);
   }
#endif
   }
void Botan::EntropySource::poll_available_sources ( class Entropy_Accumulator accum) [static, inherited]

Definition at line 108 of file entropy_srcs.cpp.

References Botan::Entropy_Accumulator::polling_goal_achieved().

Referenced by Botan::HMAC_RNG::reseed().

   {
   static std::vector<std::unique_ptr<EntropySource>> g_sources(get_default_entropy_sources());

   if(g_sources.empty())
      throw std::runtime_error("No entropy sources enabled at build time, poll failed");

   size_t poll_attempt = 0;

   while(!accum.polling_goal_achieved() && poll_attempt < 16)
      {
      const size_t src_idx = poll_attempt % g_sources.size();
      g_sources[src_idx]->poll(accum);
      ++poll_attempt;
      }
   }

The documentation for this class was generated from the following files: