xref: /aosp_15_r20/external/cronet/third_party/boringssl/src/crypto/crypto.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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