aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/utils/os_utils.cpp
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2016-01-29 17:18:38 -0500
committerJack Lloyd <[email protected]>2016-02-07 03:00:53 -0500
commit9379336ba62e273601623bf28ece112946aec1e1 (patch)
treeaf57abfbe639d4f2662ed0830db0a262610cbdd5 /src/lib/utils/os_utils.cpp
parente23cfdeb6d079a2c8d147142f31934d2c8b3a881 (diff)
Add explicit fork check to HMAC_RNG
Add OS functions get_process_id, get_processor_timestamp, and get_system_timestamp_ns. HMAC_RNG uses the pid call to detect forks to initiate a reseed. It also adds the output of all three functions (the pid, the CPU cycle counter, and the system timestamp) into the PRF input. Calls the new OS timer functions from hres_timer entropy source. Removes the call to QPC in es_win32 which is mostly redundant with the one in hres_timer.
Diffstat (limited to 'src/lib/utils/os_utils.cpp')
-rw-r--r--src/lib/utils/os_utils.cpp84
1 files changed, 80 insertions, 4 deletions
diff --git a/src/lib/utils/os_utils.cpp b/src/lib/utils/os_utils.cpp
index ae93d58d7..bd87ca2ed 100644
--- a/src/lib/utils/os_utils.cpp
+++ b/src/lib/utils/os_utils.cpp
@@ -1,27 +1,103 @@
/*
* OS and machine specific utility functions
-* (C) 2015 Jack Lloyd
+* (C) 2015,2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#include <botan/internal/os_utils.h>
+#include <botan/cpuid.h>
#include <botan/exceptn.h>
#include <botan/mem_ops.h>
+#include <chrono>
-//TODO: defined(BOTAN_TARGET_OS_TYPE_IS_POSIX)
-
-#if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK)
+#if defined(BOTAN_TARGET_OS_TYPE_IS_UNIX)
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <unistd.h>
#endif
+#if defined(BOTAN_TARGET_OS_TYPE_IS_WINDOWS)
+ #include <windows.h>
+#endif
+
namespace Botan {
namespace OS {
+uint32_t get_process_id()
+ {
+#if defined(BOTAN_TARGET_OS_IS_UNIX)
+ return ::getpid();
+#elif defined(BOTAN_TARGET_OS_IS_WIDOWS)
+ return ::GetProcessId();
+#else
+ return 0;
+#endif
+ }
+
+uint64_t get_processor_timestamp()
+ {
+ uint64_t rtc = 0;
+
+#if defined(BOTAN_TARGET_OS_HAS_QUERY_PERF_COUNTER)
+ LARGE_INTEGER tv;
+ ::QueryPerformanceCounter(&tv);
+ rtc = tv.QuadPart;
+#endif
+
+#if defined(BOTAN_USE_GCC_INLINE_ASM)
+
+#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
+ if(CPUID::has_rdtsc()) // not availble on all x86 CPUs
+ {
+ uint32_t 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)
+ uint32_t 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)
+ // OpenBSD does not trap access to the %tick register
+ 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
+
+#endif
+
+ return rtc;
+ }
+
+uint64_t get_system_timestamp_ns()
+ {
+#if defined(BOTAN_TARGET_OS_HAS_CLOCK_GETTIME)
+ struct timespec ts;
+ if(::clock_gettime(CLOCK_REALTIME, &ts) == 0)
+ {
+ return (static_cast<uint64_t>(ts.tv_sec) * 1000000000) + static_cast<uint64_t>(ts.tv_nsec);
+ }
+#endif
+
+ auto now = std::chrono::high_resolution_clock::now().time_since_epoch();
+ return std::chrono::duration_cast<std::chrono::nanoseconds>(now).count();
+ }
+
size_t get_memory_locking_limit()
{
#if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK)