1 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
2 | * All rights reserved. |
3 | * |
4 | * This package is an SSL implementation written |
5 | * by Eric Young (eay@cryptsoft.com). |
6 | * The implementation was written so as to conform with Netscapes SSL. |
7 | * |
8 | * This library is free for commercial and non-commercial use as long as |
9 | * the following conditions are aheared to. The following conditions |
10 | * apply to all code found in this distribution, be it the RC4, RSA, |
11 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation |
12 | * included with this distribution is covered by the same copyright terms |
13 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). |
14 | * |
15 | * Copyright remains Eric Young's, and as such any Copyright notices in |
16 | * the code are not to be removed. |
17 | * If this package is used in a product, Eric Young should be given attribution |
18 | * as the author of the parts of the library used. |
19 | * This can be in the form of a textual message at program startup or |
20 | * in documentation (online or textual) provided with the package. |
21 | * |
22 | * Redistribution and use in source and binary forms, with or without |
23 | * modification, are permitted provided that the following conditions |
24 | * are met: |
25 | * 1. Redistributions of source code must retain the copyright |
26 | * notice, this list of conditions and the following disclaimer. |
27 | * 2. Redistributions in binary form must reproduce the above copyright |
28 | * notice, this list of conditions and the following disclaimer in the |
29 | * documentation and/or other materials provided with the distribution. |
30 | * 3. All advertising materials mentioning features or use of this software |
31 | * must display the following acknowledgement: |
32 | * "This product includes cryptographic software written by |
33 | * Eric Young (eay@cryptsoft.com)" |
34 | * The word 'cryptographic' can be left out if the rouines from the library |
35 | * being used are not cryptographic related :-). |
36 | * 4. If you include any Windows specific code (or a derivative thereof) from |
37 | * the apps directory (application code) you must include an acknowledgement: |
38 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" |
39 | * |
40 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
41 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
42 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
43 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
44 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
45 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
46 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
48 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
49 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
50 | * SUCH DAMAGE. |
51 | * |
52 | * The licence and distribution terms for any publically available version or |
53 | * derivative of this code cannot be changed. i.e. this code cannot simply be |
54 | * copied and put under another distribution licence |
55 | * [including the GNU Public Licence.] */ |
56 | |
57 | #include <openssl/mem.h> |
58 | |
59 | #include <assert.h> |
60 | #include <stdarg.h> |
61 | #include <stdio.h> |
62 | |
63 | #if defined(OPENSSL_WINDOWS) |
64 | OPENSSL_MSVC_PRAGMA(warning(push, 3)) |
65 | #include <windows.h> |
66 | OPENSSL_MSVC_PRAGMA(warning(pop)) |
67 | #endif |
68 | |
69 | #include "internal.h" |
70 | |
71 | |
72 | #define OPENSSL_MALLOC_PREFIX 8 |
73 | |
74 | #if defined(OPENSSL_ASAN) |
75 | void __asan_poison_memory_region(const volatile void *addr, size_t size); |
76 | void __asan_unpoison_memory_region(const volatile void *addr, size_t size); |
77 | #else |
78 | static void __asan_poison_memory_region(const void *addr, size_t size) {} |
79 | static void __asan_unpoison_memory_region(const void *addr, size_t size) {} |
80 | #endif |
81 | |
82 | // Windows doesn't really support weak symbols as of May 2019, and Clang on |
83 | // Windows will emit strong symbols instead. See |
84 | // https://bugs.llvm.org/show_bug.cgi?id=37598 |
85 | #if defined(__GNUC__) || (defined(__clang__) && !defined(_MSC_VER)) |
86 | // sdallocx is a sized |free| function. By passing the size (which we happen to |
87 | // always know in BoringSSL), the malloc implementation can save work. We cannot |
88 | // depend on |sdallocx| being available so we declare a wrapper that falls back |
89 | // to |free| as a weak symbol. |
90 | // |
91 | // This will always be safe, but will only be overridden if the malloc |
92 | // implementation is statically linked with BoringSSL. So, if |sdallocx| is |
93 | // provided in, say, libc.so, we still won't use it because that's dynamically |
94 | // linked. This isn't an ideal result, but its helps in some cases. |
95 | void sdallocx(void *ptr, size_t size, int flags); |
96 | |
97 | __attribute((weak, noinline)) |
98 | #else |
99 | static |
100 | #endif |
101 | void sdallocx(void *ptr, size_t size, int flags) { |
102 | free(ptr); |
103 | } |
104 | |
105 | void *OPENSSL_malloc(size_t size) { |
106 | void *ptr = malloc(size + OPENSSL_MALLOC_PREFIX); |
107 | if (ptr == NULL) { |
108 | return NULL; |
109 | } |
110 | |
111 | *(size_t *)ptr = size; |
112 | |
113 | __asan_poison_memory_region(ptr, OPENSSL_MALLOC_PREFIX); |
114 | return ((uint8_t *)ptr) + OPENSSL_MALLOC_PREFIX; |
115 | } |
116 | |
117 | void OPENSSL_free(void *orig_ptr) { |
118 | if (orig_ptr == NULL) { |
119 | return; |
120 | } |
121 | |
122 | void *ptr = ((uint8_t *)orig_ptr) - OPENSSL_MALLOC_PREFIX; |
123 | __asan_unpoison_memory_region(ptr, OPENSSL_MALLOC_PREFIX); |
124 | |
125 | size_t size = *(size_t *)ptr; |
126 | OPENSSL_cleanse(ptr, size + OPENSSL_MALLOC_PREFIX); |
127 | sdallocx(ptr, size + OPENSSL_MALLOC_PREFIX, 0 /* flags */); |
128 | } |
129 | |
130 | void *OPENSSL_realloc(void *orig_ptr, size_t new_size) { |
131 | if (orig_ptr == NULL) { |
132 | return OPENSSL_malloc(new_size); |
133 | } |
134 | |
135 | void *ptr = ((uint8_t *)orig_ptr) - OPENSSL_MALLOC_PREFIX; |
136 | __asan_unpoison_memory_region(ptr, OPENSSL_MALLOC_PREFIX); |
137 | size_t old_size = *(size_t *)ptr; |
138 | __asan_poison_memory_region(ptr, OPENSSL_MALLOC_PREFIX); |
139 | |
140 | void *ret = OPENSSL_malloc(new_size); |
141 | if (ret == NULL) { |
142 | return NULL; |
143 | } |
144 | |
145 | size_t to_copy = new_size; |
146 | if (old_size < to_copy) { |
147 | to_copy = old_size; |
148 | } |
149 | |
150 | memcpy(ret, orig_ptr, to_copy); |
151 | OPENSSL_free(orig_ptr); |
152 | |
153 | return ret; |
154 | } |
155 | |
156 | void OPENSSL_cleanse(void *ptr, size_t len) { |
157 | #if defined(OPENSSL_WINDOWS) |
158 | SecureZeroMemory(ptr, len); |
159 | #else |
160 | OPENSSL_memset(ptr, 0, len); |
161 | |
162 | #if !defined(OPENSSL_NO_ASM) |
163 | /* As best as we can tell, this is sufficient to break any optimisations that |
164 | might try to eliminate "superfluous" memsets. If there's an easy way to |
165 | detect memset_s, it would be better to use that. */ |
166 | __asm__ __volatile__("" : : "r" (ptr) : "memory" ); |
167 | #endif |
168 | #endif // !OPENSSL_NO_ASM |
169 | } |
170 | |
171 | void OPENSSL_clear_free(void *ptr, size_t unused) { |
172 | OPENSSL_free(ptr); |
173 | } |
174 | |
175 | int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) { |
176 | const uint8_t *a = in_a; |
177 | const uint8_t *b = in_b; |
178 | uint8_t x = 0; |
179 | |
180 | for (size_t i = 0; i < len; i++) { |
181 | x |= a[i] ^ b[i]; |
182 | } |
183 | |
184 | return x; |
185 | } |
186 | |
187 | uint32_t OPENSSL_hash32(const void *ptr, size_t len) { |
188 | // These are the FNV-1a parameters for 32 bits. |
189 | static const uint32_t kPrime = 16777619u; |
190 | static const uint32_t kOffsetBasis = 2166136261u; |
191 | |
192 | const uint8_t *in = ptr; |
193 | uint32_t h = kOffsetBasis; |
194 | |
195 | for (size_t i = 0; i < len; i++) { |
196 | h ^= in[i]; |
197 | h *= kPrime; |
198 | } |
199 | |
200 | return h; |
201 | } |
202 | |
203 | size_t OPENSSL_strnlen(const char *s, size_t len) { |
204 | for (size_t i = 0; i < len; i++) { |
205 | if (s[i] == 0) { |
206 | return i; |
207 | } |
208 | } |
209 | |
210 | return len; |
211 | } |
212 | |
213 | char *OPENSSL_strdup(const char *s) { |
214 | const size_t len = strlen(s) + 1; |
215 | char *ret = OPENSSL_malloc(len); |
216 | if (ret == NULL) { |
217 | return NULL; |
218 | } |
219 | OPENSSL_memcpy(ret, s, len); |
220 | return ret; |
221 | } |
222 | |
223 | int OPENSSL_tolower(int c) { |
224 | if (c >= 'A' && c <= 'Z') { |
225 | return c + ('a' - 'A'); |
226 | } |
227 | return c; |
228 | } |
229 | |
230 | int OPENSSL_strcasecmp(const char *a, const char *b) { |
231 | for (size_t i = 0;; i++) { |
232 | const int aa = OPENSSL_tolower(a[i]); |
233 | const int bb = OPENSSL_tolower(b[i]); |
234 | |
235 | if (aa < bb) { |
236 | return -1; |
237 | } else if (aa > bb) { |
238 | return 1; |
239 | } else if (aa == 0) { |
240 | return 0; |
241 | } |
242 | } |
243 | } |
244 | |
245 | int OPENSSL_strncasecmp(const char *a, const char *b, size_t n) { |
246 | for (size_t i = 0; i < n; i++) { |
247 | const int aa = OPENSSL_tolower(a[i]); |
248 | const int bb = OPENSSL_tolower(b[i]); |
249 | |
250 | if (aa < bb) { |
251 | return -1; |
252 | } else if (aa > bb) { |
253 | return 1; |
254 | } else if (aa == 0) { |
255 | return 0; |
256 | } |
257 | } |
258 | |
259 | return 0; |
260 | } |
261 | |
262 | int BIO_snprintf(char *buf, size_t n, const char *format, ...) { |
263 | va_list args; |
264 | va_start(args, format); |
265 | int ret = BIO_vsnprintf(buf, n, format, args); |
266 | va_end(args); |
267 | return ret; |
268 | } |
269 | |
270 | int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) { |
271 | return vsnprintf(buf, n, format, args); |
272 | } |
273 | |