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