1 /* Copyright (c) 2014, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15 #include <openssl/crypto.h>
16
17 #include <assert.h>
18
19 #include "fipsmodule/rand/fork_detect.h"
20 #include "fipsmodule/rand/internal.h"
21 #include "internal.h"
22
23
24 static_assert(sizeof(ossl_ssize_t) == sizeof(size_t),
25 "ossl_ssize_t should be the same size as size_t");
26
27 #if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_STATIC_ARMCAP) && \
28 (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \
29 defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
30 // x86, x86_64, and the ARMs need to record the result of a cpuid/getauxval call
31 // for the asm to work correctly, unless compiled without asm code.
32 #define NEED_CPUID
33
34 #else
35
36 // Otherwise, don't emit a static initialiser.
37
38 #if !defined(BORINGSSL_NO_STATIC_INITIALIZER)
39 #define BORINGSSL_NO_STATIC_INITIALIZER
40 #endif
41
42 #endif // !NO_ASM && !STATIC_ARMCAP && (X86 || X86_64 || ARM || AARCH64)
43
44
45 // Our assembly does not use the GOT to reference symbols, which means
46 // references to visible symbols will often require a TEXTREL. This is
47 // undesirable, so all assembly-referenced symbols should be hidden. CPU
48 // capabilities are the only such symbols defined in C. Explicitly hide them,
49 // rather than rely on being built with -fvisibility=hidden.
50 #if defined(OPENSSL_WINDOWS)
51 #define HIDDEN
52 #else
53 #define HIDDEN __attribute__((visibility("hidden")))
54 #endif
55
56
57 // The capability variables are defined in this file in order to work around a
58 // linker bug. When linking with a .a, if no symbols in a .o are referenced
59 // then the .o is discarded, even if it has constructor functions.
60 //
61 // This still means that any binaries that don't include some functionality
62 // that tests the capability values will still skip the constructor but, so
63 // far, the init constructor function only sets the capability variables.
64
65 #if defined(BORINGSSL_DISPATCH_TEST)
66 // This value must be explicitly initialised to zero in order to work around a
67 // bug in libtool or the linker on OS X.
68 //
69 // If not initialised then it becomes a "common symbol". When put into an
70 // archive, linking on OS X will fail to resolve common symbols. By
71 // initialising it to zero, it becomes a "data symbol", which isn't so
72 // affected.
73 HIDDEN uint8_t BORINGSSL_function_hit[7] = {0};
74 #endif
75
76 #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
77
78 // This value must be explicitly initialized to zero. See similar comment above.
79 HIDDEN uint32_t OPENSSL_ia32cap_P[4] = {0};
80
OPENSSL_get_ia32cap(int idx)81 uint32_t OPENSSL_get_ia32cap(int idx) {
82 CRYPTO_library_init();
83 return OPENSSL_ia32cap_P[idx];
84 }
85
86 #elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
87
88 #include <openssl/arm_arch.h>
89
90 #if defined(OPENSSL_STATIC_ARMCAP)
91
92 // See ARM ACLE for the definitions of these macros. Note |__ARM_FEATURE_AES|
93 // covers both AES and PMULL and |__ARM_FEATURE_SHA2| covers SHA-1 and SHA-256.
94 // https://developer.arm.com/architectures/system-architectures/software-standards/acle
95 // https://github.com/ARM-software/acle/issues/152
96 //
97 // TODO(davidben): Do we still need |OPENSSL_STATIC_ARMCAP_*| or are the
98 // standard flags and -march sufficient?
99 HIDDEN uint32_t OPENSSL_armcap_P =
100 #if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON)
101 ARMV7_NEON |
102 #endif
103 #if defined(OPENSSL_STATIC_ARMCAP_AES) || defined(__ARM_FEATURE_AES)
104 ARMV8_AES |
105 #endif
106 #if defined(OPENSSL_STATIC_ARMCAP_PMULL) || defined(__ARM_FEATURE_AES)
107 ARMV8_PMULL |
108 #endif
109 #if defined(OPENSSL_STATIC_ARMCAP_SHA1) || defined(__ARM_FEATURE_SHA2)
110 ARMV8_SHA1 |
111 #endif
112 #if defined(OPENSSL_STATIC_ARMCAP_SHA256) || defined(__ARM_FEATURE_SHA2)
113 ARMV8_SHA256 |
114 #endif
115 #if defined(__ARM_FEATURE_SHA512)
116 ARMV8_SHA512 |
117 #endif
118 0;
119
120 #else
121 HIDDEN uint32_t OPENSSL_armcap_P = 0;
122
OPENSSL_get_armcap_pointer_for_test(void)123 uint32_t *OPENSSL_get_armcap_pointer_for_test(void) {
124 CRYPTO_library_init();
125 return &OPENSSL_armcap_P;
126 }
127 #endif
128
OPENSSL_get_armcap(void)129 uint32_t OPENSSL_get_armcap(void) {
130 CRYPTO_library_init();
131 return OPENSSL_armcap_P;
132 }
133
134 #endif
135
136 #if defined(BORINGSSL_FIPS)
137 // In FIPS mode, the power-on self-test function calls |CRYPTO_library_init|
138 // because we have to ensure that CPUID detection occurs first.
139 #define BORINGSSL_NO_STATIC_INITIALIZER
140 #endif
141
142 #if defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_NO_STATIC_INITIALIZER)
143 #define OPENSSL_CDECL __cdecl
144 #else
145 #define OPENSSL_CDECL
146 #endif
147
148 #if defined(BORINGSSL_NO_STATIC_INITIALIZER)
149 static CRYPTO_once_t once = CRYPTO_ONCE_INIT;
150 #elif defined(_MSC_VER)
151 #pragma section(".CRT$XCU", read)
152 static void __cdecl do_library_init(void);
153 __declspec(allocate(".CRT$XCU")) void(*library_init_constructor)(void) =
154 do_library_init;
155 #else
156 static void do_library_init(void) __attribute__ ((constructor));
157 #endif
158
159 // do_library_init is the actual initialization function. If
160 // BORINGSSL_NO_STATIC_INITIALIZER isn't defined, this is set as a static
161 // initializer. Otherwise, it is called by CRYPTO_library_init.
do_library_init(void)162 static void OPENSSL_CDECL do_library_init(void) {
163 // WARNING: this function may only configure the capability variables. See the
164 // note above about the linker bug.
165 #if defined(NEED_CPUID)
166 OPENSSL_cpuid_setup();
167 #endif
168 }
169
CRYPTO_library_init(void)170 void CRYPTO_library_init(void) {
171 // TODO(davidben): It would be tidier if this build knob could be replaced
172 // with an internal lazy-init mechanism that would handle things correctly
173 // in-library. https://crbug.com/542879
174 #if defined(BORINGSSL_NO_STATIC_INITIALIZER)
175 CRYPTO_once(&once, do_library_init);
176 #endif
177 }
178
CRYPTO_is_confidential_build(void)179 int CRYPTO_is_confidential_build(void) {
180 #if defined(BORINGSSL_CONFIDENTIAL)
181 return 1;
182 #else
183 return 0;
184 #endif
185 }
186
CRYPTO_has_asm(void)187 int CRYPTO_has_asm(void) {
188 #if defined(OPENSSL_NO_ASM)
189 return 0;
190 #else
191 return 1;
192 #endif
193 }
194
CRYPTO_pre_sandbox_init(void)195 void CRYPTO_pre_sandbox_init(void) {
196 // Read from /proc/cpuinfo if needed.
197 CRYPTO_library_init();
198 // Open /dev/urandom if needed.
199 CRYPTO_init_sysrand();
200 // Set up MADV_WIPEONFORK state if needed.
201 CRYPTO_get_fork_generation();
202 }
203
SSLeay_version(int which)204 const char *SSLeay_version(int which) { return OpenSSL_version(which); }
205
OpenSSL_version(int which)206 const char *OpenSSL_version(int which) {
207 switch (which) {
208 case OPENSSL_VERSION:
209 return "BoringSSL";
210 case OPENSSL_CFLAGS:
211 return "compiler: n/a";
212 case OPENSSL_BUILT_ON:
213 return "built on: n/a";
214 case OPENSSL_PLATFORM:
215 return "platform: n/a";
216 case OPENSSL_DIR:
217 return "OPENSSLDIR: n/a";
218 default:
219 return "not available";
220 }
221 }
222
SSLeay(void)223 unsigned long SSLeay(void) { return OPENSSL_VERSION_NUMBER; }
224
OpenSSL_version_num(void)225 unsigned long OpenSSL_version_num(void) { return OPENSSL_VERSION_NUMBER; }
226
CRYPTO_malloc_init(void)227 int CRYPTO_malloc_init(void) { return 1; }
228
OPENSSL_malloc_init(void)229 int OPENSSL_malloc_init(void) { return 1; }
230
ENGINE_load_builtin_engines(void)231 void ENGINE_load_builtin_engines(void) {}
232
ENGINE_register_all_complete(void)233 int ENGINE_register_all_complete(void) { return 1; }
234
OPENSSL_load_builtin_modules(void)235 void OPENSSL_load_builtin_modules(void) {}
236
OPENSSL_init_crypto(uint64_t opts,const OPENSSL_INIT_SETTINGS * settings)237 int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) {
238 CRYPTO_library_init();
239 return 1;
240 }
241
OPENSSL_cleanup(void)242 void OPENSSL_cleanup(void) {}
243