Line data Source code
1 : /* crypto/mem.c */
2 : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 : * All rights reserved.
4 : *
5 : * This package is an SSL implementation written
6 : * by Eric Young (eay@cryptsoft.com).
7 : * The implementation was written so as to conform with Netscapes SSL.
8 : *
9 : * This library is free for commercial and non-commercial use as long as
10 : * the following conditions are aheared to. The following conditions
11 : * apply to all code found in this distribution, be it the RC4, RSA,
12 : * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 : * included with this distribution is covered by the same copyright terms
14 : * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 : *
16 : * Copyright remains Eric Young's, and as such any Copyright notices in
17 : * the code are not to be removed.
18 : * If this package is used in a product, Eric Young should be given attribution
19 : * as the author of the parts of the library used.
20 : * This can be in the form of a textual message at program startup or
21 : * in documentation (online or textual) provided with the package.
22 : *
23 : * Redistribution and use in source and binary forms, with or without
24 : * modification, are permitted provided that the following conditions
25 : * are met:
26 : * 1. Redistributions of source code must retain the copyright
27 : * notice, this list of conditions and the following disclaimer.
28 : * 2. Redistributions in binary form must reproduce the above copyright
29 : * notice, this list of conditions and the following disclaimer in the
30 : * documentation and/or other materials provided with the distribution.
31 : * 3. All advertising materials mentioning features or use of this software
32 : * must display the following acknowledgement:
33 : * "This product includes cryptographic software written by
34 : * Eric Young (eay@cryptsoft.com)"
35 : * The word 'cryptographic' can be left out if the rouines from the library
36 : * being used are not cryptographic related :-).
37 : * 4. If you include any Windows specific code (or a derivative thereof) from
38 : * the apps directory (application code) you must include an acknowledgement:
39 : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 : *
41 : * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 : * SUCH DAMAGE.
52 : *
53 : * The licence and distribution terms for any publically available version or
54 : * derivative of this code cannot be changed. i.e. this code cannot simply be
55 : * copied and put under another distribution licence
56 : * [including the GNU Public Licence.]
57 : */
58 :
59 : #include <stdio.h>
60 : #include <stdlib.h>
61 : #include <openssl/crypto.h>
62 : #include "cryptlib.h"
63 :
64 : static int allow_customize = 1; /* we provide flexible functions for */
65 : static int allow_customize_debug = 1; /* exchanging memory-related functions
66 : * at run-time, but this must be done
67 : * before any blocks are actually
68 : * allocated; or we'll run into huge
69 : * problems when malloc/free pairs
70 : * don't match etc. */
71 :
72 : /*
73 : * the following pointers may be changed as long as 'allow_customize' is set
74 : */
75 :
76 : static void *(*malloc_func) (size_t) = malloc;
77 1458529 : static void *default_malloc_ex(size_t num, const char *file, int line)
78 : {
79 1458529 : return malloc_func(num);
80 : }
81 :
82 : static void *(*malloc_ex_func) (size_t, const char *file, int line)
83 : = default_malloc_ex;
84 :
85 : static void *(*realloc_func) (void *, size_t) = realloc;
86 25856 : static void *default_realloc_ex(void *str, size_t num,
87 : const char *file, int line)
88 : {
89 25856 : return realloc_func(str, num);
90 : }
91 :
92 : static void *(*realloc_ex_func) (void *, size_t, const char *file, int line)
93 : = default_realloc_ex;
94 :
95 : static void (*free_func) (void *) = free;
96 :
97 : static void *(*malloc_locked_func) (size_t) = malloc;
98 0 : static void *default_malloc_locked_ex(size_t num, const char *file, int line)
99 : {
100 0 : return malloc_locked_func(num);
101 : }
102 :
103 : static void *(*malloc_locked_ex_func) (size_t, const char *file, int line)
104 : = default_malloc_locked_ex;
105 :
106 : static void (*free_locked_func) (void *) = free;
107 :
108 : /* may be changed as long as 'allow_customize_debug' is set */
109 : /* XXX use correct function pointer types */
110 : #ifdef CRYPTO_MDEBUG
111 : /* use default functions from mem_dbg.c */
112 : static void (*malloc_debug_func) (void *, int, const char *, int, int)
113 : = CRYPTO_dbg_malloc;
114 : static void (*realloc_debug_func) (void *, void *, int, const char *, int,
115 : int)
116 : = CRYPTO_dbg_realloc;
117 : static void (*free_debug_func) (void *, int) = CRYPTO_dbg_free;
118 : static void (*set_debug_options_func) (long) = CRYPTO_dbg_set_options;
119 : static long (*get_debug_options_func) (void) = CRYPTO_dbg_get_options;
120 : #else
121 : /*
122 : * applications can use CRYPTO_malloc_debug_init() to select above case at
123 : * run-time
124 : */
125 : static void (*malloc_debug_func) (void *, int, const char *, int, int) = NULL;
126 : static void (*realloc_debug_func) (void *, void *, int, const char *, int,
127 : int)
128 : = NULL;
129 : static void (*free_debug_func) (void *, int) = NULL;
130 : static void (*set_debug_options_func) (long) = NULL;
131 : static long (*get_debug_options_func) (void) = NULL;
132 : #endif
133 :
134 0 : int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t),
135 : void (*f) (void *))
136 : {
137 : /* Dummy call just to ensure OPENSSL_init() gets linked in */
138 0 : OPENSSL_init();
139 0 : if (!allow_customize)
140 : return 0;
141 0 : if ((m == 0) || (r == 0) || (f == 0))
142 : return 0;
143 0 : malloc_func = m;
144 0 : malloc_ex_func = default_malloc_ex;
145 0 : realloc_func = r;
146 0 : realloc_ex_func = default_realloc_ex;
147 0 : free_func = f;
148 0 : malloc_locked_func = m;
149 0 : malloc_locked_ex_func = default_malloc_locked_ex;
150 0 : free_locked_func = f;
151 0 : return 1;
152 : }
153 :
154 0 : int CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
155 : void *(*r) (void *, size_t, const char *,
156 : int), void (*f) (void *))
157 : {
158 0 : if (!allow_customize)
159 : return 0;
160 0 : if ((m == 0) || (r == 0) || (f == 0))
161 : return 0;
162 0 : malloc_func = 0;
163 0 : malloc_ex_func = m;
164 0 : realloc_func = 0;
165 0 : realloc_ex_func = r;
166 0 : free_func = f;
167 0 : malloc_locked_func = 0;
168 0 : malloc_locked_ex_func = m;
169 0 : free_locked_func = f;
170 0 : return 1;
171 : }
172 :
173 0 : int CRYPTO_set_locked_mem_functions(void *(*m) (size_t), void (*f) (void *))
174 : {
175 0 : if (!allow_customize)
176 : return 0;
177 0 : if ((m == NULL) || (f == NULL))
178 : return 0;
179 0 : malloc_locked_func = m;
180 0 : malloc_locked_ex_func = default_malloc_locked_ex;
181 0 : free_locked_func = f;
182 0 : return 1;
183 : }
184 :
185 0 : int CRYPTO_set_locked_mem_ex_functions(void *(*m) (size_t, const char *, int),
186 : void (*f) (void *))
187 : {
188 0 : if (!allow_customize)
189 : return 0;
190 0 : if ((m == NULL) || (f == NULL))
191 : return 0;
192 0 : malloc_locked_func = 0;
193 0 : malloc_locked_ex_func = m;
194 0 : free_func = f;
195 0 : return 1;
196 : }
197 :
198 0 : int CRYPTO_set_mem_debug_functions(void (*m)
199 : (void *, int, const char *, int, int),
200 : void (*r) (void *, void *, int,
201 : const char *, int, int),
202 : void (*f) (void *, int), void (*so) (long),
203 : long (*go) (void))
204 : {
205 0 : if (!allow_customize_debug)
206 : return 0;
207 0 : OPENSSL_init();
208 0 : malloc_debug_func = m;
209 0 : realloc_debug_func = r;
210 0 : free_debug_func = f;
211 0 : set_debug_options_func = so;
212 0 : get_debug_options_func = go;
213 0 : return 1;
214 : }
215 :
216 0 : void CRYPTO_get_mem_functions(void *(**m) (size_t),
217 : void *(**r) (void *, size_t),
218 : void (**f) (void *))
219 : {
220 0 : if (m != NULL)
221 0 : *m = (malloc_ex_func == default_malloc_ex) ? malloc_func : 0;
222 0 : if (r != NULL)
223 0 : *r = (realloc_ex_func == default_realloc_ex) ? realloc_func : 0;
224 0 : if (f != NULL)
225 0 : *f = free_func;
226 0 : }
227 :
228 0 : void CRYPTO_get_mem_ex_functions(void *(**m) (size_t, const char *, int),
229 : void *(**r) (void *, size_t, const char *,
230 : int), void (**f) (void *))
231 : {
232 0 : if (m != NULL)
233 0 : *m = (malloc_ex_func != default_malloc_ex) ? malloc_ex_func : 0;
234 0 : if (r != NULL)
235 0 : *r = (realloc_ex_func != default_realloc_ex) ? realloc_ex_func : 0;
236 0 : if (f != NULL)
237 0 : *f = free_func;
238 0 : }
239 :
240 0 : void CRYPTO_get_locked_mem_functions(void *(**m) (size_t),
241 : void (**f) (void *))
242 : {
243 0 : if (m != NULL)
244 0 : *m = (malloc_locked_ex_func == default_malloc_locked_ex) ?
245 0 : malloc_locked_func : 0;
246 0 : if (f != NULL)
247 0 : *f = free_locked_func;
248 0 : }
249 :
250 0 : void CRYPTO_get_locked_mem_ex_functions(void
251 : *(**m) (size_t, const char *, int),
252 : void (**f) (void *))
253 : {
254 0 : if (m != NULL)
255 0 : *m = (malloc_locked_ex_func != default_malloc_locked_ex) ?
256 0 : malloc_locked_ex_func : 0;
257 0 : if (f != NULL)
258 0 : *f = free_locked_func;
259 0 : }
260 :
261 0 : void CRYPTO_get_mem_debug_functions(void (**m)
262 : (void *, int, const char *, int, int),
263 : void (**r) (void *, void *, int,
264 : const char *, int, int),
265 : void (**f) (void *, int),
266 : void (**so) (long), long (**go) (void))
267 : {
268 0 : if (m != NULL)
269 0 : *m = malloc_debug_func;
270 0 : if (r != NULL)
271 0 : *r = realloc_debug_func;
272 0 : if (f != NULL)
273 0 : *f = free_debug_func;
274 0 : if (so != NULL)
275 0 : *so = set_debug_options_func;
276 0 : if (go != NULL)
277 0 : *go = get_debug_options_func;
278 0 : }
279 :
280 0 : void *CRYPTO_malloc_locked(int num, const char *file, int line)
281 : {
282 : void *ret = NULL;
283 :
284 0 : if (num <= 0)
285 : return NULL;
286 :
287 0 : if (allow_customize)
288 0 : allow_customize = 0;
289 0 : if (malloc_debug_func != NULL) {
290 0 : if (allow_customize_debug)
291 0 : allow_customize_debug = 0;
292 0 : malloc_debug_func(NULL, num, file, line, 0);
293 : }
294 0 : ret = malloc_locked_ex_func(num, file, line);
295 : #ifdef LEVITTE_DEBUG_MEM
296 : fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num);
297 : #endif
298 0 : if (malloc_debug_func != NULL)
299 0 : malloc_debug_func(ret, num, file, line, 1);
300 :
301 : #ifndef OPENSSL_CPUID_OBJ
302 : /*
303 : * Create a dependency on the value of 'cleanse_ctr' so our memory
304 : * sanitisation function can't be optimised out. NB: We only do this for
305 : * >2Kb so the overhead doesn't bother us.
306 : */
307 0 : if (ret && (num > 2048)) {
308 : extern unsigned char cleanse_ctr;
309 0 : ((unsigned char *)ret)[0] = cleanse_ctr;
310 : }
311 : #endif
312 :
313 0 : return ret;
314 : }
315 :
316 0 : void CRYPTO_free_locked(void *str)
317 : {
318 0 : if (free_debug_func != NULL)
319 0 : free_debug_func(str, 0);
320 : #ifdef LEVITTE_DEBUG_MEM
321 : fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str);
322 : #endif
323 0 : free_locked_func(str);
324 0 : if (free_debug_func != NULL)
325 0 : free_debug_func(NULL, 1);
326 0 : }
327 :
328 1457048 : void *CRYPTO_malloc(int num, const char *file, int line)
329 : {
330 : void *ret = NULL;
331 :
332 1457048 : if (num <= 0)
333 : return NULL;
334 :
335 1457058 : if (allow_customize)
336 124 : allow_customize = 0;
337 1457058 : if (malloc_debug_func != NULL) {
338 0 : if (allow_customize_debug)
339 0 : allow_customize_debug = 0;
340 0 : malloc_debug_func(NULL, num, file, line, 0);
341 : }
342 1457058 : ret = malloc_ex_func(num, file, line);
343 : #ifdef LEVITTE_DEBUG_MEM
344 : fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num);
345 : #endif
346 1457154 : if (malloc_debug_func != NULL)
347 0 : malloc_debug_func(ret, num, file, line, 1);
348 :
349 : #ifndef OPENSSL_CPUID_OBJ
350 : /*
351 : * Create a dependency on the value of 'cleanse_ctr' so our memory
352 : * sanitisation function can't be optimised out. NB: We only do this for
353 : * >2Kb so the overhead doesn't bother us.
354 : */
355 1457167 : if (ret && (num > 2048)) {
356 : extern unsigned char cleanse_ctr;
357 5322 : ((unsigned char *)ret)[0] = cleanse_ctr;
358 : }
359 : #endif
360 :
361 1457167 : return ret;
362 : }
363 :
364 0 : char *CRYPTO_strdup(const char *str, const char *file, int line)
365 : {
366 0 : char *ret = CRYPTO_malloc(strlen(str) + 1, file, line);
367 :
368 0 : if (ret == NULL)
369 : return NULL;
370 :
371 : strcpy(ret, str);
372 0 : return ret;
373 : }
374 :
375 25856 : void *CRYPTO_realloc(void *str, int num, const char *file, int line)
376 : {
377 : void *ret = NULL;
378 :
379 25856 : if (str == NULL)
380 0 : return CRYPTO_malloc(num, file, line);
381 :
382 25856 : if (num <= 0)
383 : return NULL;
384 :
385 25856 : if (realloc_debug_func != NULL)
386 0 : realloc_debug_func(str, NULL, num, file, line, 0);
387 25856 : ret = realloc_ex_func(str, num, file, line);
388 : #ifdef LEVITTE_DEBUG_MEM
389 : fprintf(stderr, "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n", str,
390 : ret, num);
391 : #endif
392 25856 : if (realloc_debug_func != NULL)
393 0 : realloc_debug_func(str, ret, num, file, line, 1);
394 :
395 25856 : return ret;
396 : }
397 :
398 1479 : void *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file,
399 : int line)
400 : {
401 : void *ret = NULL;
402 :
403 1479 : if (str == NULL)
404 0 : return CRYPTO_malloc(num, file, line);
405 :
406 1479 : if (num <= 0)
407 : return NULL;
408 :
409 : /*
410 : * We don't support shrinking the buffer. Note the memcpy that copies
411 : * |old_len| bytes to the new buffer, below.
412 : */
413 1479 : if (num < old_len)
414 : return NULL;
415 :
416 1479 : if (realloc_debug_func != NULL)
417 0 : realloc_debug_func(str, NULL, num, file, line, 0);
418 1479 : ret = malloc_ex_func(num, file, line);
419 1479 : if (ret) {
420 1479 : memcpy(ret, str, old_len);
421 1479 : OPENSSL_cleanse(str, old_len);
422 1479 : free_func(str);
423 : }
424 : #ifdef LEVITTE_DEBUG_MEM
425 : fprintf(stderr,
426 : "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n",
427 : str, ret, num);
428 : #endif
429 1479 : if (realloc_debug_func != NULL)
430 0 : realloc_debug_func(str, ret, num, file, line, 1);
431 :
432 1479 : return ret;
433 : }
434 :
435 1064903 : void CRYPTO_free(void *str)
436 : {
437 1064903 : if (free_debug_func != NULL)
438 0 : free_debug_func(str, 0);
439 : #ifdef LEVITTE_DEBUG_MEM
440 : fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str);
441 : #endif
442 1064903 : free_func(str);
443 1064969 : if (free_debug_func != NULL)
444 0 : free_debug_func(NULL, 1);
445 1064969 : }
446 :
447 0 : void *CRYPTO_remalloc(void *a, int num, const char *file, int line)
448 : {
449 0 : if (a != NULL)
450 0 : OPENSSL_free(a);
451 0 : a = (char *)OPENSSL_malloc(num);
452 0 : return (a);
453 : }
454 :
455 0 : void CRYPTO_set_mem_debug_options(long bits)
456 : {
457 0 : if (set_debug_options_func != NULL)
458 0 : set_debug_options_func(bits);
459 0 : }
460 :
461 0 : long CRYPTO_get_mem_debug_options(void)
462 : {
463 0 : if (get_debug_options_func != NULL)
464 0 : return get_debug_options_func();
465 : return 0;
466 : }
|