From 9379336ba62e273601623bf28ece112946aec1e1 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 29 Jan 2016 17:18:38 -0500 Subject: 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. --- src/lib/utils/os_utils.cpp | 84 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 4 deletions(-) (limited to 'src/lib/utils/os_utils.cpp') 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 +#include #include #include +#include -//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 #include #include #include #endif +#if defined(BOTAN_TARGET_OS_TYPE_IS_WINDOWS) + #include +#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(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(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(ts.tv_sec) * 1000000000) + static_cast(ts.tv_nsec); + } +#endif + + auto now = std::chrono::high_resolution_clock::now().time_since_epoch(); + return std::chrono::duration_cast(now).count(); + } + size_t get_memory_locking_limit() { #if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) -- cgit v1.2.3