]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/mem.c
Run util/openssl-format-source -v -c .
[thirdparty/openssl.git] / crypto / mem.c
CommitLineData
d02b48c6 1/* crypto/mem.c */
58964a49 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
d02b48c6
RE
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.
0f113f3e 8 *
d02b48c6
RE
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).
0f113f3e 15 *
d02b48c6
RE
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.
0f113f3e 22 *
d02b48c6
RE
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 :-).
0f113f3e 37 * 4. If you include any Windows specific code (or a derivative thereof) from
d02b48c6
RE
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
0f113f3e 40 *
d02b48c6
RE
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.
0f113f3e 52 *
d02b48c6
RE
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>
458cddc1 61#include <openssl/crypto.h>
d02b48c6
RE
62#include "cryptlib.h"
63
0f113f3e
MC
64static int allow_customize = 1; /* we provide flexible functions for */
65static 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. */
1f575f1b 71
0f113f3e
MC
72/*
73 * the following pointers may be changed as long as 'allow_customize' is set
74 */
a5435e8b 75
0f113f3e 76static void *(*malloc_func) (size_t) = malloc;
a5435e8b 77static void *default_malloc_ex(size_t num, const char *file, int line)
0f113f3e
MC
78{
79 return malloc_func(num);
80}
81
82static void *(*malloc_ex_func) (size_t, const char *file, int line)
83 = default_malloc_ex;
a5435e8b 84
0f113f3e 85static void *(*realloc_func) (void *, size_t) = realloc;
a5435e8b 86static void *default_realloc_ex(void *str, size_t num,
0f113f3e
MC
87 const char *file, int line)
88{
89 return realloc_func(str, num);
90}
a5435e8b 91
0f113f3e
MC
92static void *(*realloc_ex_func) (void *, size_t, const char *file, int line)
93 = default_realloc_ex;
0cd08cce 94
0f113f3e 95static void (*free_func) (void *) = free;
a5435e8b 96
0f113f3e
MC
97static void *(*malloc_locked_func) (size_t) = malloc;
98static void *default_malloc_locked_ex(size_t num, const char *file, int line)
99{
100 return malloc_locked_func(num);
101}
65a22e8e 102
0f113f3e
MC
103static void *(*malloc_locked_ex_func) (size_t, const char *file, int line)
104 = default_malloc_locked_ex;
a5435e8b 105
0f113f3e 106static void (*free_locked_func) (void *) = free;
a5435e8b
BM
107
108/* may be changed as long as 'allow_customize_debug' is set */
0cd08cce 109/* XXX use correct function pointer types */
71fa4513 110#ifdef CRYPTO_MDEBUG
65962686 111/* use default functions from mem_dbg.c */
0f113f3e
MC
112static void (*malloc_debug_func) (void *, int, const char *, int, int)
113 = CRYPTO_dbg_malloc;
114static void (*realloc_debug_func) (void *, void *, int, const char *, int,
115 int)
116 = CRYPTO_dbg_realloc;
117static void (*free_debug_func) (void *, int) = CRYPTO_dbg_free;
118static void (*set_debug_options_func) (long) = CRYPTO_dbg_set_options;
119static long (*get_debug_options_func) (void) = CRYPTO_dbg_get_options;
f3a2a044 120#else
0f113f3e
MC
121/*
122 * applications can use CRYPTO_malloc_debug_init() to select above case at
123 * run-time
124 */
125static void (*malloc_debug_func) (void *, int, const char *, int, int) = NULL;
126static void (*realloc_debug_func) (void *, void *, int, const char *, int,
127 int)
128 = NULL;
129static void (*free_debug_func) (void *, int) = NULL;
130static void (*set_debug_options_func) (long) = NULL;
131static long (*get_debug_options_func) (void) = NULL;
f3a2a044 132#endif
9ac42ed8 133
0f113f3e
MC
134int 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 OPENSSL_init();
139 if (!allow_customize)
140 return 0;
141 if ((m == 0) || (r == 0) || (f == 0))
142 return 0;
143 malloc_func = m;
144 malloc_ex_func = default_malloc_ex;
145 realloc_func = r;
146 realloc_ex_func = default_realloc_ex;
147 free_func = f;
148 malloc_locked_func = m;
149 malloc_locked_ex_func = default_malloc_locked_ex;
150 free_locked_func = f;
151 return 1;
152}
153
154int 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 if (!allow_customize)
159 return 0;
160 if ((m == 0) || (r == 0) || (f == 0))
161 return 0;
162 malloc_func = 0;
163 malloc_ex_func = m;
164 realloc_func = 0;
165 realloc_ex_func = r;
166 free_func = f;
167 malloc_locked_func = 0;
168 malloc_locked_ex_func = m;
169 free_locked_func = f;
170 return 1;
171}
172
173int CRYPTO_set_locked_mem_functions(void *(*m) (size_t), void (*f) (void *))
174{
175 if (!allow_customize)
176 return 0;
177 if ((m == NULL) || (f == NULL))
178 return 0;
179 malloc_locked_func = m;
180 malloc_locked_ex_func = default_malloc_locked_ex;
181 free_locked_func = f;
182 return 1;
183}
184
185int CRYPTO_set_locked_mem_ex_functions(void *(*m) (size_t, const char *, int),
186 void (*f) (void *))
187{
188 if (!allow_customize)
189 return 0;
190 if ((m == NULL) || (f == NULL))
191 return 0;
192 malloc_locked_func = 0;
193 malloc_locked_ex_func = m;
194 free_func = f;
195 return 1;
196}
197
198int 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 if (!allow_customize_debug)
206 return 0;
207 malloc_debug_func = m;
208 realloc_debug_func = r;
209 free_debug_func = f;
210 set_debug_options_func = so;
211 get_debug_options_func = go;
212 return 1;
213}
214
215void CRYPTO_get_mem_functions(void *(**m) (size_t),
216 void *(**r) (void *, size_t),
217 void (**f) (void *))
218{
219 if (m != NULL)
220 *m = (malloc_ex_func == default_malloc_ex) ? malloc_func : 0;
221 if (r != NULL)
222 *r = (realloc_ex_func == default_realloc_ex) ? realloc_func : 0;
223 if (f != NULL)
224 *f = free_func;
225}
226
227void CRYPTO_get_mem_ex_functions(void *(**m) (size_t, const char *, int),
228 void *(**r) (void *, size_t, const char *,
229 int), void (**f) (void *))
230{
231 if (m != NULL)
232 *m = (malloc_ex_func != default_malloc_ex) ? malloc_ex_func : 0;
233 if (r != NULL)
234 *r = (realloc_ex_func != default_realloc_ex) ? realloc_ex_func : 0;
235 if (f != NULL)
236 *f = free_func;
237}
238
239void CRYPTO_get_locked_mem_functions(void *(**m) (size_t),
240 void (**f) (void *))
241{
242 if (m != NULL)
243 *m = (malloc_locked_ex_func == default_malloc_locked_ex) ?
244 malloc_locked_func : 0;
245 if (f != NULL)
246 *f = free_locked_func;
247}
248
249void CRYPTO_get_locked_mem_ex_functions(void
250 *(**m) (size_t, const char *, int),
251 void (**f) (void *))
252{
253 if (m != NULL)
254 *m = (malloc_locked_ex_func != default_malloc_locked_ex) ?
255 malloc_locked_ex_func : 0;
256 if (f != NULL)
257 *f = free_locked_func;
258}
259
260void CRYPTO_get_mem_debug_functions(void (**m)
261 (void *, int, const char *, int, int),
262 void (**r) (void *, void *, int,
263 const char *, int, int),
264 void (**f) (void *, int),
265 void (**so) (long), long (**go) (void))
266{
267 if (m != NULL)
268 *m = malloc_debug_func;
269 if (r != NULL)
270 *r = realloc_debug_func;
271 if (f != NULL)
272 *f = free_debug_func;
273 if (so != NULL)
274 *so = set_debug_options_func;
275 if (go != NULL)
276 *go = get_debug_options_func;
277}
d02b48c6 278
6343829a 279void *CRYPTO_malloc_locked(int num, const char *file, int line)
0f113f3e
MC
280{
281 void *ret = NULL;
282
283 if (num <= 0)
284 return NULL;
285
286 if (allow_customize)
287 allow_customize = 0;
288 if (malloc_debug_func != NULL) {
289 if (allow_customize_debug)
290 allow_customize_debug = 0;
291 malloc_debug_func(NULL, num, file, line, 0);
292 }
293 ret = malloc_locked_ex_func(num, file, line);
8d28d5f8 294#ifdef LEVITTE_DEBUG_MEM
0f113f3e 295 fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num);
3dff94c2 296#endif
0f113f3e
MC
297 if (malloc_debug_func != NULL)
298 malloc_debug_func(ret, num, file, line, 1);
1f575f1b 299
b2dba9bf 300#ifndef OPENSSL_CPUID_OBJ
0f113f3e
MC
301 /*
302 * Create a dependency on the value of 'cleanse_ctr' so our memory
303 * sanitisation function can't be optimised out. NB: We only do this for
304 * >2Kb so the overhead doesn't bother us.
305 */
306 if (ret && (num > 2048)) {
307 extern unsigned char cleanse_ctr;
308 ((unsigned char *)ret)[0] = cleanse_ctr;
309 }
b2dba9bf 310#endif
df29cc8f 311
0f113f3e
MC
312 return ret;
313}
d02b48c6 314
9ac42ed8 315void CRYPTO_free_locked(void *str)
0f113f3e
MC
316{
317 if (free_debug_func != NULL)
318 free_debug_func(str, 0);
8d28d5f8 319#ifdef LEVITTE_DEBUG_MEM
0f113f3e 320 fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str);
9ac42ed8 321#endif
0f113f3e
MC
322 free_locked_func(str);
323 if (free_debug_func != NULL)
324 free_debug_func(NULL, 1);
325}
d02b48c6 326
6343829a 327void *CRYPTO_malloc(int num, const char *file, int line)
0f113f3e
MC
328{
329 void *ret = NULL;
330
331 if (num <= 0)
332 return NULL;
333
334 if (allow_customize)
335 allow_customize = 0;
336 if (malloc_debug_func != NULL) {
337 if (allow_customize_debug)
338 allow_customize_debug = 0;
339 malloc_debug_func(NULL, num, file, line, 0);
340 }
341 ret = malloc_ex_func(num, file, line);
8d28d5f8 342#ifdef LEVITTE_DEBUG_MEM
0f113f3e 343 fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num);
9ac42ed8 344#endif
0f113f3e
MC
345 if (malloc_debug_func != NULL)
346 malloc_debug_func(ret, num, file, line, 1);
d02b48c6 347
b2dba9bf 348#ifndef OPENSSL_CPUID_OBJ
0f113f3e
MC
349 /*
350 * Create a dependency on the value of 'cleanse_ctr' so our memory
351 * sanitisation function can't be optimised out. NB: We only do this for
352 * >2Kb so the overhead doesn't bother us.
353 */
354 if (ret && (num > 2048)) {
355 extern unsigned char cleanse_ctr;
356 ((unsigned char *)ret)[0] = cleanse_ctr;
357 }
b2dba9bf 358#endif
df29cc8f 359
0f113f3e
MC
360 return ret;
361}
362
6caa4edd 363char *CRYPTO_strdup(const char *str, const char *file, int line)
0f113f3e
MC
364{
365 char *ret = CRYPTO_malloc(strlen(str) + 1, file, line);
6caa4edd 366
0f113f3e
MC
367 strcpy(ret, str);
368 return ret;
369}
d02b48c6 370
6343829a 371void *CRYPTO_realloc(void *str, int num, const char *file, int line)
0f113f3e
MC
372{
373 void *ret = NULL;
d02b48c6 374
0f113f3e
MC
375 if (str == NULL)
376 return CRYPTO_malloc(num, file, line);
d5234c7b 377
0f113f3e
MC
378 if (num <= 0)
379 return NULL;
d5234c7b 380
0f113f3e
MC
381 if (realloc_debug_func != NULL)
382 realloc_debug_func(str, NULL, num, file, line, 0);
383 ret = realloc_ex_func(str, num, file, line);
8d28d5f8 384#ifdef LEVITTE_DEBUG_MEM
0f113f3e
MC
385 fprintf(stderr, "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n", str,
386 ret, num);
1f575f1b 387#endif
0f113f3e
MC
388 if (realloc_debug_func != NULL)
389 realloc_debug_func(str, ret, num, file, line, 1);
9ac42ed8 390
0f113f3e
MC
391 return ret;
392}
d02b48c6 393
6343829a 394void *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file,
0f113f3e
MC
395 int line)
396{
397 void *ret = NULL;
398
399 if (str == NULL)
400 return CRYPTO_malloc(num, file, line);
401
402 if (num <= 0)
403 return NULL;
404
405 /*
406 * We don't support shrinking the buffer. Note the memcpy that copies
407 * |old_len| bytes to the new buffer, below.
408 */
409 if (num < old_len)
410 return NULL;
411
412 if (realloc_debug_func != NULL)
413 realloc_debug_func(str, NULL, num, file, line, 0);
414 ret = malloc_ex_func(num, file, line);
415 if (ret) {
416 memcpy(ret, str, old_len);
417 OPENSSL_cleanse(str, old_len);
418 free_func(str);
419 }
54a656ef 420#ifdef LEVITTE_DEBUG_MEM
0f113f3e
MC
421 fprintf(stderr,
422 "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n",
423 str, ret, num);
54a656ef 424#endif
0f113f3e
MC
425 if (realloc_debug_func != NULL)
426 realloc_debug_func(str, ret, num, file, line, 1);
54a656ef 427
0f113f3e
MC
428 return ret;
429}
54a656ef 430
9ac42ed8 431void CRYPTO_free(void *str)
0f113f3e
MC
432{
433 if (free_debug_func != NULL)
434 free_debug_func(str, 0);
8d28d5f8 435#ifdef LEVITTE_DEBUG_MEM
0f113f3e 436 fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str);
dfeab068 437#endif
0f113f3e
MC
438 free_func(str);
439 if (free_debug_func != NULL)
440 free_debug_func(NULL, 1);
441}
d02b48c6 442
6343829a 443void *CRYPTO_remalloc(void *a, int num, const char *file, int line)
0f113f3e
MC
444{
445 if (a != NULL)
446 OPENSSL_free(a);
447 a = (char *)OPENSSL_malloc(num);
448 return (a);
449}
d02b48c6 450
0cd08cce 451void CRYPTO_set_mem_debug_options(long bits)
0f113f3e
MC
452{
453 if (set_debug_options_func != NULL)
454 set_debug_options_func(bits);
455}
d02b48c6 456
667ac4ec 457long CRYPTO_get_mem_debug_options(void)
0f113f3e
MC
458{
459 if (get_debug_options_func != NULL)
460 return get_debug_options_func();
461 return 0;
462}