mem.c revision 109998
155714Skris/* crypto/mem.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 855714Skris * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1555714Skris * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 2255714Skris * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4055714Skris * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 5255714Skris * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5855714Skris 5955714Skris#include <stdio.h> 6055714Skris#include <stdlib.h> 6155714Skris#include <openssl/crypto.h> 6255714Skris#include "cryptlib.h" 6355714Skris 6455714Skris 6559191Skrisstatic int allow_customize = 1; /* we provide flexible functions for */ 6659191Skrisstatic int allow_customize_debug = 1;/* exchanging memory-related functions at 6759191Skris * run-time, but this must be done 6859191Skris * before any blocks are actually 6959191Skris * allocated; or we'll run into huge 7059191Skris * problems when malloc/free pairs 7159191Skris * don't match etc. */ 7255714Skris 73109998Smarkm 74109998Smarkm 75109998Smarkm/* the following pointers may be changed as long as 'allow_customize' is set */ 76109998Smarkm 7759191Skrisstatic void *(*malloc_func)(size_t) = malloc; 78109998Smarkmstatic void *default_malloc_ex(size_t num, const char *file, int line) 79109998Smarkm { return malloc_func(num); } 80109998Smarkmstatic void *(*malloc_ex_func)(size_t, const char *file, int line) 81109998Smarkm = default_malloc_ex; 82109998Smarkm 8359191Skrisstatic void *(*realloc_func)(void *, size_t)= realloc; 84109998Smarkmstatic void *default_realloc_ex(void *str, size_t num, 85109998Smarkm const char *file, int line) 86109998Smarkm { return realloc_func(str,num); } 87109998Smarkmstatic void *(*realloc_ex_func)(void *, size_t, const char *file, int line) 88109998Smarkm = default_realloc_ex; 89109998Smarkm 9059191Skrisstatic void (*free_func)(void *) = free; 9155714Skris 92109998Smarkmstatic void *(*malloc_locked_func)(size_t) = malloc; 93109998Smarkmstatic void *default_malloc_locked_ex(size_t num, const char *file, int line) 94109998Smarkm { return malloc_locked_func(num); } 95109998Smarkmstatic void *(*malloc_locked_ex_func)(size_t, const char *file, int line) 96109998Smarkm = default_malloc_locked_ex; 97109998Smarkm 98109998Smarkmstatic void (*free_locked_func)(void *) = free; 99109998Smarkm 100109998Smarkm 101109998Smarkm 102109998Smarkm/* may be changed as long as 'allow_customize_debug' is set */ 10359191Skris/* XXX use correct function pointer types */ 10459191Skris#ifdef CRYPTO_MDEBUG 10568651Skris/* use default functions from mem_dbg.c */ 10668651Skrisstatic void (*malloc_debug_func)(void *,int,const char *,int,int) 10768651Skris = CRYPTO_dbg_malloc; 10868651Skrisstatic void (*realloc_debug_func)(void *,void *,int,const char *,int,int) 10968651Skris = CRYPTO_dbg_realloc; 11068651Skrisstatic void (*free_debug_func)(void *,int) = CRYPTO_dbg_free; 11168651Skrisstatic void (*set_debug_options_func)(long) = CRYPTO_dbg_set_options; 11268651Skrisstatic long (*get_debug_options_func)(void) = CRYPTO_dbg_get_options; 11359191Skris#else 11468651Skris/* applications can use CRYPTO_malloc_debug_init() to select above case 11568651Skris * at run-time */ 11668651Skrisstatic void (*malloc_debug_func)(void *,int,const char *,int,int) = NULL; 11768651Skrisstatic void (*realloc_debug_func)(void *,void *,int,const char *,int,int) 11868651Skris = NULL; 11968651Skrisstatic void (*free_debug_func)(void *,int) = NULL; 12068651Skrisstatic void (*set_debug_options_func)(long) = NULL; 12168651Skrisstatic long (*get_debug_options_func)(void) = NULL; 12255714Skris#endif 12355714Skris 12455714Skris 12559191Skrisint CRYPTO_set_mem_functions(void *(*m)(size_t), void *(*r)(void *, size_t), 12659191Skris void (*f)(void *)) 12755714Skris { 12859191Skris if (!allow_customize) 12959191Skris return 0; 130109998Smarkm if ((m == 0) || (r == 0) || (f == 0)) 13159191Skris return 0; 132109998Smarkm malloc_func=m; malloc_ex_func=default_malloc_ex; 133109998Smarkm realloc_func=r; realloc_ex_func=default_realloc_ex; 13455714Skris free_func=f; 135109998Smarkm malloc_locked_func=m; malloc_locked_ex_func=default_malloc_locked_ex; 13655714Skris free_locked_func=f; 13759191Skris return 1; 13855714Skris } 13955714Skris 140109998Smarkmint CRYPTO_set_mem_ex_functions( 141109998Smarkm void *(*m)(size_t,const char *,int), 142109998Smarkm void *(*r)(void *, size_t,const char *,int), 143109998Smarkm void (*f)(void *)) 144109998Smarkm { 145109998Smarkm if (!allow_customize) 146109998Smarkm return 0; 147109998Smarkm if ((m == 0) || (r == 0) || (f == 0)) 148109998Smarkm return 0; 149109998Smarkm malloc_func=0; malloc_ex_func=m; 150109998Smarkm realloc_func=0; realloc_ex_func=r; 151109998Smarkm free_func=f; 152109998Smarkm malloc_locked_func=0; malloc_locked_ex_func=m; 153109998Smarkm free_locked_func=f; 154109998Smarkm return 1; 155109998Smarkm } 156109998Smarkm 15759191Skrisint CRYPTO_set_locked_mem_functions(void *(*m)(size_t), void (*f)(void *)) 15855714Skris { 15959191Skris if (!allow_customize) 16059191Skris return 0; 16159191Skris if ((m == NULL) || (f == NULL)) 16259191Skris return 0; 163109998Smarkm malloc_locked_func=m; malloc_locked_ex_func=default_malloc_locked_ex; 16455714Skris free_locked_func=f; 16559191Skris return 1; 16655714Skris } 16755714Skris 168109998Smarkmint CRYPTO_set_locked_mem_ex_functions( 169109998Smarkm void *(*m)(size_t,const char *,int), 170109998Smarkm void (*f)(void *)) 171109998Smarkm { 172109998Smarkm if (!allow_customize) 173109998Smarkm return 0; 174109998Smarkm if ((m == NULL) || (f == NULL)) 175109998Smarkm return 0; 176109998Smarkm malloc_locked_func=0; malloc_locked_ex_func=m; 177109998Smarkm free_func=f; 178109998Smarkm return 1; 179109998Smarkm } 180109998Smarkm 18168651Skrisint CRYPTO_set_mem_debug_functions(void (*m)(void *,int,const char *,int,int), 18268651Skris void (*r)(void *,void *,int,const char *,int,int), 18368651Skris void (*f)(void *,int), 18468651Skris void (*so)(long), 18568651Skris long (*go)(void)) 18655714Skris { 18759191Skris if (!allow_customize_debug) 18859191Skris return 0; 18959191Skris malloc_debug_func=m; 19059191Skris realloc_debug_func=r; 19159191Skris free_debug_func=f; 19259191Skris set_debug_options_func=so; 19359191Skris get_debug_options_func=go; 19459191Skris return 1; 19559191Skris } 19659191Skris 197109998Smarkm 19859191Skrisvoid CRYPTO_get_mem_functions(void *(**m)(size_t), void *(**r)(void *, size_t), 19959191Skris void (**f)(void *)) 20059191Skris { 201109998Smarkm if (m != NULL) *m = (malloc_ex_func == default_malloc_ex) ? 202109998Smarkm malloc_func : 0; 203109998Smarkm if (r != NULL) *r = (realloc_ex_func == default_realloc_ex) ? 204109998Smarkm realloc_func : 0; 20555714Skris if (f != NULL) *f=free_func; 20655714Skris } 20755714Skris 208109998Smarkmvoid CRYPTO_get_mem_ex_functions( 209109998Smarkm void *(**m)(size_t,const char *,int), 210109998Smarkm void *(**r)(void *, size_t,const char *,int), 211109998Smarkm void (**f)(void *)) 212109998Smarkm { 213109998Smarkm if (m != NULL) *m = (malloc_ex_func != default_malloc_ex) ? 214109998Smarkm malloc_ex_func : 0; 215109998Smarkm if (r != NULL) *r = (realloc_ex_func != default_realloc_ex) ? 216109998Smarkm realloc_ex_func : 0; 217109998Smarkm if (f != NULL) *f=free_func; 218109998Smarkm } 219109998Smarkm 22059191Skrisvoid CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *)) 22155714Skris { 222109998Smarkm if (m != NULL) *m = (malloc_locked_ex_func == default_malloc_locked_ex) ? 223109998Smarkm malloc_locked_func : 0; 22455714Skris if (f != NULL) *f=free_locked_func; 22555714Skris } 22655714Skris 227109998Smarkmvoid CRYPTO_get_locked_mem_ex_functions( 228109998Smarkm void *(**m)(size_t,const char *,int), 229109998Smarkm void (**f)(void *)) 230109998Smarkm { 231109998Smarkm if (m != NULL) *m = (malloc_locked_ex_func != default_malloc_locked_ex) ? 232109998Smarkm malloc_locked_ex_func : 0; 233109998Smarkm if (f != NULL) *f=free_locked_func; 234109998Smarkm } 235109998Smarkm 23668651Skrisvoid CRYPTO_get_mem_debug_functions(void (**m)(void *,int,const char *,int,int), 23768651Skris void (**r)(void *,void *,int,const char *,int,int), 23868651Skris void (**f)(void *,int), 23968651Skris void (**so)(long), 24068651Skris long (**go)(void)) 24155714Skris { 24259191Skris if (m != NULL) *m=malloc_debug_func; 24359191Skris if (r != NULL) *r=realloc_debug_func; 24459191Skris if (f != NULL) *f=free_debug_func; 24559191Skris if (so != NULL) *so=set_debug_options_func; 24659191Skris if (go != NULL) *go=get_debug_options_func; 24755714Skris } 24855714Skris 24955714Skris 25059191Skrisvoid *CRYPTO_malloc_locked(int num, const char *file, int line) 25155714Skris { 25268651Skris void *ret = NULL; 253109998Smarkm extern unsigned char cleanse_ctr; 25455714Skris 25559191Skris allow_customize = 0; 25659191Skris if (malloc_debug_func != NULL) 25759191Skris { 25859191Skris allow_customize_debug = 0; 25959191Skris malloc_debug_func(NULL, num, file, line, 0); 26059191Skris } 261109998Smarkm ret = malloc_locked_ex_func(num,file,line); 262109998Smarkm#ifdef LEVITTE_DEBUG_MEM 263109998Smarkm fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num); 26459191Skris#endif 26559191Skris if (malloc_debug_func != NULL) 26659191Skris malloc_debug_func(ret, num, file, line, 1); 26755714Skris 268109998Smarkm /* Create a dependency on the value of 'cleanse_ctr' so our memory 269109998Smarkm * sanitisation function can't be optimised out. NB: We only do 270109998Smarkm * this for >2Kb so the overhead doesn't bother us. */ 271109998Smarkm if(ret && (num > 2048)) 272109998Smarkm ((unsigned char *)ret)[0] = cleanse_ctr; 273109998Smarkm 27459191Skris return ret; 27555714Skris } 27655714Skris 27759191Skrisvoid CRYPTO_free_locked(void *str) 27855714Skris { 27959191Skris if (free_debug_func != NULL) 28059191Skris free_debug_func(str, 0); 281109998Smarkm#ifdef LEVITTE_DEBUG_MEM 282109998Smarkm fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str); 28355714Skris#endif 28459191Skris free_locked_func(str); 28559191Skris if (free_debug_func != NULL) 28659191Skris free_debug_func(NULL, 1); 28755714Skris } 28855714Skris 28959191Skrisvoid *CRYPTO_malloc(int num, const char *file, int line) 29055714Skris { 29168651Skris void *ret = NULL; 292109998Smarkm extern unsigned char cleanse_ctr; 29355714Skris 29459191Skris allow_customize = 0; 29559191Skris if (malloc_debug_func != NULL) 29655714Skris { 29759191Skris allow_customize_debug = 0; 29859191Skris malloc_debug_func(NULL, num, file, line, 0); 29955714Skris } 300109998Smarkm ret = malloc_ex_func(num,file,line); 301109998Smarkm#ifdef LEVITTE_DEBUG_MEM 302109998Smarkm fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num); 30359191Skris#endif 30459191Skris if (malloc_debug_func != NULL) 30559191Skris malloc_debug_func(ret, num, file, line, 1); 30655714Skris 307109998Smarkm /* Create a dependency on the value of 'cleanse_ctr' so our memory 308109998Smarkm * sanitisation function can't be optimised out. NB: We only do 309109998Smarkm * this for >2Kb so the overhead doesn't bother us. */ 310109998Smarkm if(ret && (num > 2048)) 311109998Smarkm ((unsigned char *)ret)[0] = cleanse_ctr; 312109998Smarkm 31359191Skris return ret; 31455714Skris } 31555714Skris 31659191Skrisvoid *CRYPTO_realloc(void *str, int num, const char *file, int line) 31755714Skris { 31868651Skris void *ret = NULL; 31955714Skris 320101613Snectar if (str == NULL) 321101613Snectar return CRYPTO_malloc(num, file, line); 322109998Smarkm if (realloc_debug_func != NULL) 323109998Smarkm realloc_debug_func(str, NULL, num, file, line, 0); 324109998Smarkm ret = realloc_ex_func(str,num,file,line); 325109998Smarkm#ifdef LEVITTE_DEBUG_MEM 326109998Smarkm fprintf(stderr, "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n", str, ret, num); 327109998Smarkm#endif 328109998Smarkm if (realloc_debug_func != NULL) 329109998Smarkm realloc_debug_func(str, ret, num, file, line, 1); 330101613Snectar 331109998Smarkm return ret; 332109998Smarkm } 333109998Smarkm 334109998Smarkmvoid *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file, 335109998Smarkm int line) 336109998Smarkm { 337109998Smarkm void *ret = NULL; 338109998Smarkm 339109998Smarkm if (str == NULL) 340109998Smarkm return CRYPTO_malloc(num, file, line); 34159191Skris if (realloc_debug_func != NULL) 34259191Skris realloc_debug_func(str, NULL, num, file, line, 0); 343109998Smarkm ret=malloc_ex_func(num,file,line); 344109998Smarkm if(ret) 345109998Smarkm memcpy(ret,str,old_len); 346109998Smarkm OPENSSL_cleanse(str,old_len); 347109998Smarkm free_func(str); 348109998Smarkm#ifdef LEVITTE_DEBUG_MEM 349109998Smarkm fprintf(stderr, "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n", str, ret, num); 35055714Skris#endif 35159191Skris if (realloc_debug_func != NULL) 35259191Skris realloc_debug_func(str, ret, num, file, line, 1); 35355714Skris 35459191Skris return ret; 35555714Skris } 35655714Skris 35759191Skrisvoid CRYPTO_free(void *str) 35855714Skris { 35959191Skris if (free_debug_func != NULL) 36059191Skris free_debug_func(str, 0); 361109998Smarkm#ifdef LEVITTE_DEBUG_MEM 362109998Smarkm fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str); 36355714Skris#endif 36459191Skris free_func(str); 36559191Skris if (free_debug_func != NULL) 36659191Skris free_debug_func(NULL, 1); 36755714Skris } 36855714Skris 36959191Skrisvoid *CRYPTO_remalloc(void *a, int num, const char *file, int line) 37055714Skris { 37168651Skris if (a != NULL) OPENSSL_free(a); 37268651Skris a=(char *)OPENSSL_malloc(num); 37359191Skris return(a); 37455714Skris } 37555714Skris 37659191Skrisvoid CRYPTO_set_mem_debug_options(long bits) 37755714Skris { 37859191Skris if (set_debug_options_func != NULL) 37959191Skris set_debug_options_func(bits); 38055714Skris } 38155714Skris 38259191Skrislong CRYPTO_get_mem_debug_options(void) 38355714Skris { 38459191Skris if (get_debug_options_func != NULL) 38559191Skris return get_debug_options_func(); 38659191Skris return 0; 38755714Skris } 388