Botan 3.8.1
Crypto and TLS for C&
os_utils.h
Go to the documentation of this file.
1/*
2* OS specific utility functions
3* (C) 2015,2016,2017,2018 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#ifndef BOTAN_OS_UTILS_H_
9#define BOTAN_OS_UTILS_H_
10
11#include <botan/types.h>
12#include <ctime>
13#include <functional>
14#include <memory>
15#include <optional>
16#include <string>
17#include <vector>
18
19#if defined(BOTAN_TARGET_OS_HAS_THREADS)
20 #include <thread>
21#endif
22
23namespace Botan::OS {
24
25/*
26* This header is internal (not installed) and these functions are not
27* intended to be called by applications. However they are given public
28* visibility (using BOTAN_TEST_API macro) for the tests. This also probably
29* allows them to be overridden by the application on ELF systems, but
30* this hasn't been tested.
31*/
32
33/**
34* @return process ID assigned by the operating system.
35*
36* On Unix and Windows systems, this always returns a result
37*
38* On systems where there is no processes to speak of (for example on baremetal
39* systems or within a unikernel), this function returns zero.
40*/
42
43/**
44* @return CPU processor clock, if available
45*
46* On Windows, calls QueryPerformanceCounter.
47*
48* Under GCC or Clang on supported platforms the hardware cycle counter is queried.
49* Currently supported processors are x86, PPC, Alpha, SPARC, IA-64, S/390x, and HP-PA.
50* If no CPU cycle counter is available on this system, returns zero.
51*/
53
55
56/**
57* If this system supports getauxval (or an equivalent interface,
58* like FreeBSD's elf_aux_info) queries AT_HWCAP and AT_HWCAP2
59* and returns both.
60*
61* Otherwise returns nullopt.
62*/
63std::optional<std::pair<unsigned long, unsigned long>> get_auxval_hwcap();
64
65/*
66* @return best resolution timestamp available
67*
68* The epoch and update rate of this clock is arbitrary and depending
69* on the hardware it may not tick at a constant rate.
70*
71* Uses hardware cycle counter, if available.
72* On POSIX platforms clock_gettime is used with a monotonic timer
73*
74* As a final fallback std::chrono::high_resolution_clock is used.
75*
76* On systems that are lacking a real time clock, this may return 0
77*/
79
80/**
81* @return system clock (reflecting wall clock) with best resolution
82* available, normalized to nanoseconds resolution, using Unix epoch.
83*
84* If the system does not have a real time clock this function will throw
85* Not_Implemented
86*/
88
89/**
90* Format a time
91*
92* Converts the time_t to a local time representation,
93* then invokes std::put_time with the specified format.
94*/
95std::string BOTAN_TEST_API format_time(time_t time, const std::string& format);
96
97/**
98* @return maximum amount of memory (in bytes) Botan could/should
99* hyptothetically allocate for the memory poool. Reads environment
100* variable "BOTAN_MLOCK_POOL_SIZE", set to "0" to disable pool.
101*/
103
104/**
105* Return the size of a memory page, if that can be derived on the
106* current system. Otherwise returns some default value (eg 4096)
107*/
108size_t system_page_size();
109
110/**
111* Read the value of an environment variable, setting it to value_out if it
112* exists. Returns false and sets value_out to empty string if no such variable
113* is set. If the process seems to be running in a privileged state (such as
114* setuid) then always returns false and does not examine the environment.
115*/
116bool read_env_variable(std::string& value_out, std::string_view var_name);
117
118/**
119* Read the value of an environment variable and convert it to an
120* integer. If not set or conversion fails, returns the default value.
121*
122* If the process seems to be running in a privileged state (such as setuid)
123* then always returns nullptr, similiar to glibc's secure_getenv.
124*/
125size_t read_env_variable_sz(std::string_view var_name, size_t def_value = 0);
126
127/**
128* Request count pages of RAM which are locked into memory using mlock,
129* VirtualLock, or some similar OS specific API. Free it with free_locked_pages.
130*
131* Returns an empty list on failure. This function is allowed to return fewer
132* than count pages.
133*
134* The contents of the allocated pages are undefined.
135*
136* Each page is preceded by and followed by a page which is marked
137* as noaccess, such that accessing it will cause a crash. This turns
138* out of bound reads/writes into crash events.
139*
140* @param count requested number of locked pages
141*/
142std::vector<void*> allocate_locked_pages(size_t count);
143
144/**
145* Free memory allocated by allocate_locked_pages
146* @param pages a list of pages returned by allocate_locked_pages
147*/
148void free_locked_pages(const std::vector<void*>& pages);
149
150/**
151* Set the MMU to prohibit access to this page
152*/
153void page_prohibit_access(void* page);
154
155/**
156* Set the MMU to allow R/W access to this page
157*/
158void page_allow_access(void* page);
159
160/**
161* Set a ID to a page's range expressed by size bytes
162*/
163void page_named(void* page, size_t size);
164
165#if defined(BOTAN_TARGET_OS_HAS_THREADS)
166void set_thread_name(std::thread& thread, const std::string& name);
167#endif
168
169/**
170* Run a probe instruction to test for support for a CPU instruction.
171* Runs in system-specific env that catches illegal instructions; this
172* function always fails if the OS doesn't provide this.
173* Returns value of probe_fn, if it could run.
174* If error occurs, returns negative number.
175* This allows probe_fn to indicate errors of its own, if it wants.
176* For example the instruction might not only be only available on some
177* CPUs, but also buggy on some subset of these - the probe function
178* can test to make sure the instruction works properly before
179* indicating that the instruction is available.
180*
181* @warning on Unix systems uses signal handling in a way that is not
182* thread safe. It should only be called in a single-threaded context
183* (ie, at static init time).
184*
185* If probe_fn throws an exception the result is undefined.
186*
187* Return codes:
188* -1 illegal instruction detected
189*/
190int BOTAN_TEST_API run_cpu_instruction_probe(const std::function<int()>& probe_fn);
191
192/**
193* Represents a terminal state
194*/
196 public:
197 /**
198 * Reenable echo on this terminal. Can be safely called
199 * multiple times. May throw if an error occurs.
200 */
201 virtual void reenable_echo() = 0;
202
203 /**
204 * Implicitly calls reenable_echo, but swallows/ignored all
205 * errors which would leave the terminal in an invalid state.
206 */
207 virtual ~Echo_Suppression() = default;
208};
209
210/**
211* Suppress echo on the terminal
212* Returns null if this operation is not supported on the current system.
213*/
214std::unique_ptr<Echo_Suppression> BOTAN_UNSTABLE_API suppress_echo_on_terminal();
215
216} // namespace Botan::OS
217
218#endif
#define BOTAN_UNSTABLE_API
Definition api.h:32
#define BOTAN_TEST_API
Definition api.h:39
virtual void reenable_echo()=0
virtual ~Echo_Suppression()=default
size_t get_memory_locking_limit()
Definition os_utils.cpp:374
uint64_t BOTAN_TEST_API get_high_resolution_clock()
Definition os_utils.cpp:264
size_t BOTAN_TEST_API get_cpu_available()
Definition os_utils.cpp:232
std::unique_ptr< Echo_Suppression > BOTAN_UNSTABLE_API suppress_echo_on_terminal()
Definition os_utils.cpp:749
size_t read_env_variable_sz(std::string_view var_name, size_t def_value=0)
Definition os_utils.cpp:468
void page_allow_access(void *page)
Definition os_utils.cpp:599
std::string BOTAN_TEST_API format_time(time_t time, const std::string &format)
Definition os_utils.cpp:334
bool read_env_variable(std::string &value_out, std::string_view var_name)
Definition os_utils.cpp:435
void page_prohibit_access(void *page)
Definition os_utils.cpp:613
std::optional< std::pair< unsigned long, unsigned long > > get_auxval_hwcap()
Definition os_utils.cpp:136
int BOTAN_TEST_API run_cpu_instruction_probe(const std::function< int()> &probe_fn)
Definition os_utils.cpp:709
std::vector< void * > allocate_locked_pages(size_t count)
Definition os_utils.cpp:508
size_t system_page_size()
Definition os_utils.cpp:354
uint64_t BOTAN_TEST_API get_system_timestamp_ns()
Definition os_utils.cpp:318
void free_locked_pages(const std::vector< void * > &pages)
Definition os_utils.cpp:627
void page_named(void *page, size_t size)
Definition os_utils.cpp:649
uint32_t BOTAN_TEST_API get_process_id()
Definition os_utils.cpp:77
uint64_t BOTAN_TEST_API get_cpu_cycle_counter()
Definition os_utils.cpp:169