Botan  2.12.1
Crypto and TLS for C++11
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 <functional>
13 #include <string>
14 #include <vector>
15 
16 namespace Botan {
17 
18 namespace OS {
19 
20 /*
21 * This header is internal (not installed) and these functions are not
22 * intended to be called by applications. However they are given public
23 * visibility (using BOTAN_TEST_API macro) for the tests. This also probably
24 * allows them to be overridden by the application on ELF systems, but
25 * this hasn't been tested.
26 */
27 
28 /**
29 * @return process ID assigned by the operating system.
30 * On Unix and Windows systems, this always returns a result
31 * On IncludeOS it returns 0 since there is no process ID to speak of
32 * in a unikernel.
33 */
35 
36 /**
37 * Test if we are currently running with elevated permissions
38 * eg setuid, setgid, or with POSIX caps set.
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 
55 
56 /**
57 * Return the ELF auxiliary vector cooresponding to the given ID.
58 * This only makes sense on Unix-like systems and is currently
59 * only supported on Linux, Android, and FreeBSD.
60 *
61 * Returns zero if not supported on the current system or if
62 * the id provided is not known.
63 */
64 unsigned long get_auxval(unsigned long id);
65 
66 /*
67 * @return best resolution timestamp available
68 *
69 * The epoch and update rate of this clock is arbitrary and depending
70 * on the hardware it may not tick at a constant rate.
71 *
72 * Uses hardware cycle counter, if available.
73 * On POSIX platforms clock_gettime is used with a monotonic timer
74 * As a final fallback std::chrono::high_resolution_clock is used.
75 */
77 
78 /**
79 * @return system clock (reflecting wall clock) with best resolution
80 * available, normalized to nanoseconds resolution.
81 */
83 
84 /**
85 * @return maximum amount of memory (in bytes) Botan could/should
86 * hyptothetically allocate for the memory poool. Reads environment
87 * variable "BOTAN_MLOCK_POOL_SIZE", set to "0" to disable pool.
88 */
90 
91 /**
92 * Return the size of a memory page, if that can be derived on the
93 * current system. Otherwise returns some default value (eg 4096)
94 */
95 size_t system_page_size();
96 
97 /**
98 * Read the value of an environment variable. Return nullptr if
99 * no such variable is set. If the process seems to be running in
100 * a privileged state (such as setuid) then always returns nullptr,
101 * similiar to glibc's secure_getenv.
102 */
103 const char* read_env_variable(const std::string& var_name);
104 
105 /**
106 * Read the value of an environment variable and convert it to an
107 * integer. If not set or conversion fails, returns the default value.
108 *
109 * If the process seems to be running in a privileged state (such as setuid)
110 * then always returns nullptr, similiar to glibc's secure_getenv.
111 */
112 size_t read_env_variable_sz(const std::string& var_name, size_t def_value = 0);
113 
114 /**
115 * Request count pages of RAM which are locked into memory using mlock,
116 * VirtualLock, or some similar OS specific API. Free it with free_locked_pages.
117 *
118 * Returns an empty list on failure. This function is allowed to return fewer
119 * than count pages.
120 *
121 * The contents of the allocated pages are undefined.
122 *
123 * Each page is preceded by and followed by a page which is marked
124 * as noaccess, such that accessing it will cause a crash. This turns
125 * out of bound reads/writes into crash events.
126 *
127 * @param count requested number of locked pages
128 */
129 std::vector<void*> allocate_locked_pages(size_t count);
130 
131 /**
132 * Free memory allocated by allocate_locked_pages
133 * @param pages a list of pages returned by allocate_locked_pages
134 */
135 void free_locked_pages(const std::vector<void*>& pages);
136 
137 /**
138 * Set the MMU to prohibit access to this page
139 */
140 void page_prohibit_access(void* page);
141 
142 /**
143 * Set the MMU to allow R/W access to this page
144 */
145 void page_allow_access(void* page);
146 
147 
148 /**
149 * Run a probe instruction to test for support for a CPU instruction.
150 * Runs in system-specific env that catches illegal instructions; this
151 * function always fails if the OS doesn't provide this.
152 * Returns value of probe_fn, if it could run.
153 * If error occurs, returns negative number.
154 * This allows probe_fn to indicate errors of its own, if it wants.
155 * For example the instruction might not only be only available on some
156 * CPUs, but also buggy on some subset of these - the probe function
157 * can test to make sure the instruction works properly before
158 * indicating that the instruction is available.
159 *
160 * @warning on Unix systems uses signal handling in a way that is not
161 * thread safe. It should only be called in a single-threaded context
162 * (ie, at static init time).
163 *
164 * If probe_fn throws an exception the result is undefined.
165 *
166 * Return codes:
167 * -1 illegal instruction detected
168 */
169 int BOTAN_TEST_API run_cpu_instruction_probe(std::function<int ()> probe_fn);
170 
171 /**
172 * Represents a terminal state
173 */
175  {
176  public:
177  /**
178  * Reenable echo on this terminal. Can be safely called
179  * multiple times. May throw if an error occurs.
180  */
181  virtual void reenable_echo() = 0;
182 
183  /**
184  * Implicitly calls reenable_echo, but swallows/ignored all
185  * errors which would leave the terminal in an invalid state.
186  */
187  virtual ~Echo_Suppression() = default;
188  };
189 
190 /**
191 * Suppress echo on the terminal
192 * Returns null if this operation is not supported on the current system.
193 */
194 std::unique_ptr<Echo_Suppression> BOTAN_UNSTABLE_API suppress_echo_on_terminal();
195 
196 }
197 
198 }
199 
200 #endif
#define BOTAN_UNSTABLE_API
Definition: compiler.h:38
size_t BOTAN_TEST_API get_cpu_total()
Definition: os_utils.cpp:214
int BOTAN_TEST_API run_cpu_instruction_probe(std::function< int()> probe_fn)
Definition: os_utils.cpp:580
uint64_t BOTAN_TEST_API get_cpu_cycle_counter()
Definition: os_utils.cpp:153
uint32_t BOTAN_TEST_API get_process_id()
Definition: os_utils.cpp:95
void free_locked_pages(const std::vector< void *> &pages)
Definition: os_utils.cpp:542
void page_prohibit_access(void *page)
Definition: os_utils.cpp:530
#define BOTAN_TEST_API
Definition: compiler.h:45
size_t get_memory_locking_limit()
Definition: os_utils.cpp:325
bool running_in_privileged_state()
Definition: os_utils.cpp:142
std::vector< void * > allocate_locked_pages(size_t count)
Definition: os_utils.cpp:438
uint64_t BOTAN_TEST_API get_system_timestamp_ns()
Definition: os_utils.cpp:292
Definition: alg_id.cpp:13
size_t read_env_variable_sz(const std::string &var_name, size_t def_value=0)
Definition: os_utils.cpp:393
unsigned long get_auxval(unsigned long id)
Definition: os_utils.cpp:108
std::unique_ptr< Echo_Suppression > BOTAN_UNSTABLE_API suppress_echo_on_terminal()
Definition: os_utils.cpp:635
size_t system_page_size()
Definition: os_utils.cpp:306
void page_allow_access(void *page)
Definition: os_utils.cpp:518
size_t BOTAN_TEST_API get_cpu_available()
Definition: os_utils.cpp:229
const char * read_env_variable(const std::string &var_name)
Definition: os_utils.cpp:385
uint64_t BOTAN_TEST_API get_high_resolution_clock()
Definition: os_utils.cpp:240