Skip to content

Instantly share code, notes, and snippets.

@hausdorff
Created April 12, 2014 20:13
Show Gist options
  • Save hausdorff/10554471 to your computer and use it in GitHub Desktop.
Save hausdorff/10554471 to your computer and use it in GitHub Desktop.
Akamai OpenSSL patch
diff -uNr -x'*.[oas]' openssl-1.0.1g.orig/crypto/Makefile openssl-1.0.1g/crypto/Makefile
--- openssl-1.0.1g.orig/crypto/Makefile 2014-04-10 13:11:56.000000000 -0400
+++ openssl-1.0.1g/crypto/Makefile 2014-04-10 13:02:39.000000000 -0400
@@ -35,14 +35,16 @@
LIB= $(TOP)/libcrypto.a
SHARED_LIB= libcrypto$(SHLIB_EXT)
LIBSRC= cryptlib.c mem.c mem_clr.c mem_dbg.c cversion.c ex_data.c cpt_err.c \
- ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fips.c o_init.c fips_ers.c
+ ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fips.c o_init.c fips_ers.c \
+ secure_malloc.c buddy_allocator.c
LIBOBJ= cryptlib.o mem.o mem_dbg.o cversion.o ex_data.o cpt_err.o ebcdic.o \
- uid.o o_time.o o_str.o o_dir.o o_fips.o o_init.o fips_ers.o $(CPUID_OBJ)
+ uid.o o_time.o o_str.o o_dir.o o_fips.o o_init.o fips_ers.o $(CPUID_OBJ) \
+ secure_malloc.o buddy_allocator.o
SRC= $(LIBSRC)
EXHEADER= crypto.h opensslv.h opensslconf.h ebcdic.h symhacks.h \
- ossl_typ.h
+ ossl_typ.h secure_malloc.h
HEADER= cryptlib.h buildinf.h md32_common.h o_time.h o_str.h o_dir.h $(EXHEADER)
ALL= $(GENERAL) $(SRC) $(HEADER)
diff -uNr -x'*.[oas]' openssl-1.0.1g.orig/crypto/asn1/tasn_dec.c openssl-1.0.1g/crypto/asn1/tasn_dec.c
--- openssl-1.0.1g.orig/crypto/asn1/tasn_dec.c 2014-03-17 12:14:20.000000000 -0400
+++ openssl-1.0.1g/crypto/asn1/tasn_dec.c 2014-04-10 16:32:23.000000000 -0400
@@ -169,6 +169,11 @@
int otag;
int ret = 0;
ASN1_VALUE **pchptr, *ptmpval;
+
+ int ak_is_rsa_key = 0; /* Are we parsing an RSA key? */
+ int ak_is_secure_field = 0; /* should this field be allocated from the secure arena? */
+ int ak_is_arena_active = 0; /* was the secure arena already activated? */
+
if (!pval)
return 0;
if (aux && aux->asn1_cb)
@@ -407,6 +412,11 @@
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
goto auxerr;
+ /* Watch out for this when OpenSSL is upgraded! */
+ /* We have to be sure that it->sname will still be "RSA" */
+ if (it->sname[0] == 'R' && it->sname[1] == 'S' && it->sname[2] == 'A' && it->sname[3] == 0)
+ ak_is_rsa_key = 1;
+
/* Get each field entry */
for (i = 0, tt = it->templates; i < it->tcount; i++, tt++)
{
@@ -445,8 +455,30 @@
/* attempt to read in field, allowing each to be
* OPTIONAL */
+
+ /* Watch out for this when OpenSSL is upgraded! */
+ /* We have to be sure that seqtt->field_name will still be */
+ /* "d", "p", and "q" */
+ ak_is_secure_field = 0;
+ ak_is_arena_active = 0;
+ if (ak_is_rsa_key)
+ {
+ /* ak_is_rsa_key is set for public keys too */
+ /* however those don't have these variables */
+ const char *f = seqtt->field_name;
+ if ((f[0] == 'd' || f[0] == 'p' || f[0] == 'q') && f[1] == 0)
+ {
+ ak_is_secure_field = 1;
+ ak_is_arena_active = start_secure_allocation();
+ }
+ }
+
ret = asn1_template_ex_d2i(pseqval, &p, len,
seqtt, isopt, ctx);
+
+ if (ak_is_secure_field && !ak_is_arena_active)
+ stop_secure_allocation();
+
if (!ret)
{
errtt = seqtt;
diff -uNr -x'*.[oas]' openssl-1.0.1g.orig/crypto/buddy_allocator.c openssl-1.0.1g/crypto/buddy_allocator.c
--- openssl-1.0.1g.orig/crypto/buddy_allocator.c 1969-12-31 19:00:00.000000000 -0500
+++ openssl-1.0.1g/crypto/buddy_allocator.c 2014-04-10 16:23:06.000000000 -0400
@@ -0,0 +1,407 @@
+/*
+ * Memory allocator for secure heap for OpenSSL key storage.
+ * Copyright, 2001-2014, Akamai Technologies. All Rights Reserved.
+ * Distributed under the terms of the OpenSSL license.
+ */
+#include <stdlib.h>
+#include <assert.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+
+static void *cmm_arena = NULL;
+static void **cmm_free_list = NULL;
+static int cmm_max_free_lists;
+static int mem_arena_size = 0;
+static int Mem_min_unit = 0;
+static int Overrun_bytes = 0;
+
+typedef unsigned char u_int8;
+
+static u_int8 *cmm_bittable;
+static u_int8 *cmm_bitmalloc;
+/* size in bits */
+static int cmm_bittable_size;
+
+#define SETBIT(_a,_b) ((_a)[(_b)>>3] |= (1<<((_b)&7)))
+#define CLEARBIT(_a,_b) ((_a)[(_b)>>3] &= (0xff&~(1<<((_b)&7))))
+#define TESTBIT(_a,_b) ((_a)[(_b)>>3] & (1<<((_b)&7)))
+
+static void cmm_add_to_list(void **list, void *lamb);
+static void cmm_remove_from_list(void *lamb, void *list);
+static void *mybuddy(void *lamb, int list);
+static int getlist(void *lamb);
+static int testbit(void *lamb, int list, u_int8 *table);
+static void clearbit(void *lamb, int list, u_int8 *table);
+static void set_bit(void *lamb, int list, u_int8 *table);
+
+void *
+cmm_init(int size, int mem_min_unit, int overrun_bytes)
+{
+ int i;
+
+ mem_arena_size = size;
+ Mem_min_unit = mem_min_unit,
+ Overrun_bytes = overrun_bytes;
+ /* make sure mem_arena_size and Mem_min_unit are powers of 2 */
+ assert(mem_arena_size > 0);
+ assert(mem_min_unit > 0);
+ assert(0 == ((mem_arena_size-1)&mem_arena_size));
+ assert(0 == ((Mem_min_unit-1)&Mem_min_unit));
+
+ cmm_bittable_size = (mem_arena_size/Mem_min_unit) * 2;
+
+ i = cmm_bittable_size;
+ cmm_max_free_lists = -1;
+ while(i) {
+ i>>=1;
+ cmm_max_free_lists++;
+ }
+
+ cmm_free_list = malloc(cmm_max_free_lists * sizeof(void *));
+ assert(cmm_free_list);
+ memset(cmm_free_list, 0, cmm_max_free_lists*sizeof(void *));
+
+ cmm_bittable = malloc(cmm_bittable_size>>3);
+ assert(cmm_bittable);
+ memset(cmm_bittable, 0, cmm_bittable_size>>3);
+
+ cmm_bitmalloc = malloc(cmm_bittable_size>>3);
+ assert(cmm_bitmalloc);
+ memset(cmm_bitmalloc, 0, cmm_bittable_size>>3);
+
+ cmm_arena = mmap(NULL, mem_arena_size, PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, 0, 0);
+ assert(MAP_FAILED != cmm_arena);
+ set_bit(cmm_arena, 0, cmm_bittable);
+ cmm_add_to_list(&cmm_free_list[0], cmm_arena);
+
+ /* first bit means that table is in use, multi-arena management */
+ /* SETBIT(cmm_bittable, 0); */
+
+ return cmm_arena;
+}
+
+void *
+cmm_malloc(int size)
+{
+ int i, list, slist;
+ void *chunk = NULL, *temp;
+
+ i = Mem_min_unit; list = cmm_max_free_lists-1;
+ while (i < size + Overrun_bytes) {
+ i<<=1;
+ list--;
+ }
+ if (list < 0) goto out;
+
+ /* try to find a larger entry to split */
+ slist = list;
+ while (slist >= 0) {
+ if (cmm_free_list[slist] != NULL)
+ break;
+ slist--;
+ }
+ if (slist < 0) goto out;
+
+ /* split larger entry */
+ while (slist != list) {
+ temp = cmm_free_list[slist];
+
+ /* remove from bigger list */
+ assert(!testbit(temp, slist, cmm_bitmalloc));
+ clearbit(temp, slist, cmm_bittable);
+ cmm_remove_from_list(temp, cmm_free_list[slist]);
+ assert(temp != cmm_free_list[slist]);
+
+ /* done with bigger list */
+ slist++;
+
+ /* add to smaller list */
+ assert(!testbit(temp, slist, cmm_bitmalloc));
+ set_bit(temp, slist, cmm_bittable);
+ cmm_add_to_list(&cmm_free_list[slist], temp);
+ assert(cmm_free_list[slist] == temp);
+
+ /* split in 2 */
+ temp += mem_arena_size >> slist;
+ assert(!testbit(temp, slist, cmm_bitmalloc));
+ set_bit(temp, slist, cmm_bittable);
+ cmm_add_to_list(&cmm_free_list[slist], temp);
+ assert(cmm_free_list[slist] == temp);
+
+ assert(temp-(mem_arena_size>>slist) == mybuddy(temp, slist));
+ }
+
+ /* peel off memory to hand back */
+ chunk = cmm_free_list[list];
+ assert(testbit(chunk, list, cmm_bittable));
+ set_bit(chunk, list, cmm_bitmalloc);
+ cmm_remove_from_list(chunk, cmm_free_list[list]);
+
+ assert(chunk >= cmm_arena && chunk < cmm_arena+mem_arena_size);
+
+#ifdef CMM_DEBUG
+ for (i = 0; i < cmm_bittable_size; i++) {
+ if (TESTBIT(cmm_bitmalloc,i)) {
+ assert(TESTBIT(cmm_bittable,i));
+ }
+ }
+#endif
+
+ out:
+ return chunk;
+}
+
+static int cmm_free_calls = 0;
+
+int
+cmm_free(void *lamb)
+{
+ int list;
+ void *buddy;
+#ifdef CMM_DEBUG
+ int i;
+#endif
+ cmm_free_calls++;
+
+ assert(lamb >= cmm_arena && lamb < cmm_arena+mem_arena_size);
+
+ list = getlist(lamb);
+ assert(testbit(lamb, list, cmm_bittable));
+ clearbit(lamb, list, cmm_bitmalloc);
+ cmm_add_to_list(&cmm_free_list[list], lamb);
+
+ while (NULL != (buddy = mybuddy(lamb, list))) {
+ assert(lamb == mybuddy(buddy, list));
+
+ assert(lamb);
+ assert(!testbit(lamb, list, cmm_bitmalloc));
+ clearbit(lamb, list, cmm_bittable);
+ cmm_remove_from_list(lamb, cmm_free_list[list]);
+ assert(!testbit(lamb, list, cmm_bitmalloc));
+ clearbit(buddy, list, cmm_bittable);
+ cmm_remove_from_list(buddy, cmm_free_list[list]);
+
+ list--;
+
+ if (lamb > buddy) lamb = buddy;
+
+ assert(!testbit(lamb, list, cmm_bitmalloc));
+ set_bit(lamb, list, cmm_bittable);
+ cmm_add_to_list(&cmm_free_list[list], lamb);
+ assert(cmm_free_list[list] == lamb);
+ }
+
+#ifdef CMM_DEBUG
+ for (i = 0; i < cmm_bittable_size; i++) {
+ if (TESTBIT(cmm_bitmalloc,i)) {
+ assert(TESTBIT(cmm_bittable,i));
+ }
+ }
+#endif
+
+ return 0;
+}
+
+int
+cmm_usable_size(void *lamb)
+{
+ int list = getlist(lamb);
+ int size;
+
+ assert(lamb >= cmm_arena && lamb < cmm_arena+mem_arena_size);
+ assert(testbit(lamb, list, cmm_bittable));
+
+ size = mem_arena_size/(1<<list);
+
+ return size;
+}
+
+void *
+cmm_realloc(void *lamb, int size)
+{
+ void *temp;
+ int oldsize;
+
+ oldsize = cmm_usable_size(lamb);
+
+ if ((size > oldsize/2) && (size <= oldsize))
+ return lamb;
+
+ if ((size < Mem_min_unit) && (Mem_min_unit == oldsize))
+ return lamb;
+
+ temp = lamb;
+ lamb = cmm_malloc(size);
+
+ if (NULL == lamb)
+ return NULL;
+
+ size = MIN(size, oldsize);
+ memcpy(lamb, temp, size);
+
+ cmm_free(temp);
+
+ return lamb;
+}
+
+typedef struct _cmm_list cmm_list;
+struct _cmm_list {
+ cmm_list *next;
+ cmm_list **p_next;
+};
+
+static void
+cmm_add_to_list(void **list, void *lamb)
+{
+ cmm_list *temp;
+#ifdef CMM_DEBUG
+ cmm_list *temp2;
+#endif
+
+ assert(list >= cmm_free_list &&
+ list < cmm_free_list + cmm_max_free_lists);
+ assert(lamb >= cmm_arena &&
+ lamb < cmm_arena + mem_arena_size);
+
+ temp = (cmm_list *)lamb;
+ temp->next = *(cmm_list **)list;
+ assert(temp->next == NULL ||
+ ((void *)temp->next >= cmm_arena &&
+ (void *)temp->next < cmm_arena+mem_arena_size));
+ temp->p_next = (cmm_list **)list;
+
+ if (NULL != temp->next) {
+ assert((void **)temp->next->p_next == list);
+ temp->next->p_next = &(temp->next);
+ }
+
+ *list = lamb;
+
+#ifdef CMM_DEBUG
+ for (temp = *list; temp != NULL; temp = temp->next) {
+ if (NULL != temp->next)
+ assert(temp->next->p_next == &temp->next);
+ if (lamb == temp) temp2 = lamb;
+ }
+ assert (NULL != temp2);
+#endif
+}
+
+static void
+cmm_remove_from_list(void *lamb, void *list)
+{
+ cmm_list *temp, *temp2;
+
+#ifdef CMM_DEBUG
+ temp2 = NULL;
+
+ for (temp = list; temp != NULL; temp = temp->next) {
+ if (NULL != temp->next)
+ assert(temp->next->p_next == &temp->next);
+ if (lamb == temp) temp2 = lamb;
+ }
+ assert (NULL != temp2);
+#endif
+
+ temp = (cmm_list *)lamb;
+ if (NULL != temp->next)
+ temp->next->p_next = temp->p_next;
+ *temp->p_next = temp->next;
+
+ if (NULL == temp->next)
+ return;
+
+ temp2 = temp->next;
+ assert((((void **)temp2->p_next >= cmm_free_list) &&
+ ((void **)temp2->p_next < cmm_free_list + cmm_max_free_lists))
+ ||
+ (((void *)temp2->p_next >= cmm_arena) &&
+ ((void *)temp2->p_next < cmm_arena + mem_arena_size)));
+}
+
+static void *
+mybuddy(void *lamb, int list)
+{
+ int index;
+ void *chunk = NULL;
+
+ index = (1<<list) + ((lamb-cmm_arena)/(mem_arena_size>>list));
+ index ^= 1;
+
+ if (TESTBIT(cmm_bittable,index) &&
+ !TESTBIT(cmm_bitmalloc,index)) {
+ chunk = cmm_arena + ((index & ((1<<list)-1)) * (mem_arena_size>>list));
+ }
+
+ return chunk;
+}
+
+static int
+getlist(void *lamb)
+{
+ int index, list;
+
+ list = cmm_max_free_lists-1;
+ index = (mem_arena_size + lamb - cmm_arena) / Mem_min_unit;
+
+ while (index) {
+ if (TESTBIT(cmm_bittable,index)) {
+ break;
+ }
+ assert(!(index & 1));
+ index >>= 1;
+ list--;
+ }
+
+ return list;
+}
+
+static int
+testbit(void *lamb, int list, u_int8 *table)
+{
+ int index;
+
+ assert(list < cmm_max_free_lists && list >= 0);
+ assert(!((lamb-cmm_arena)&((mem_arena_size>>list)-1)));
+
+ index = (1<<list) + ((lamb - cmm_arena) / (mem_arena_size>>list));
+
+ assert(index > 0 && index < cmm_bittable_size);
+
+ return TESTBIT(table,index);
+}
+
+static void
+clearbit(void *lamb, int list, u_int8 *table)
+{
+ int index;
+
+ assert(list < cmm_max_free_lists && list >= 0);
+ assert(!((lamb-cmm_arena)&((mem_arena_size>>list)-1)));
+
+ index = (1<<list) + ((lamb - cmm_arena) / (mem_arena_size>>list));
+
+ assert(index > 0 && index < cmm_bittable_size);
+
+ assert(TESTBIT(table,index));
+ CLEARBIT(table,index);
+}
+
+static void
+set_bit(void *lamb, int list, u_int8 *table)
+{
+ int index;
+
+ assert(list < cmm_max_free_lists && list >= 0);
+ assert(!((lamb-cmm_arena)&((mem_arena_size>>list)-1)));
+
+ index = (1<<list) + ((lamb - cmm_arena) / (mem_arena_size>>list));
+
+ assert(index > 0 && index < cmm_bittable_size);
+
+ assert(!TESTBIT(table,index));
+ SETBIT(table,index);
+}
diff -uNr -x'*.[oas]' openssl-1.0.1g.orig/crypto/crypto.h openssl-1.0.1g/crypto/crypto.h
--- openssl-1.0.1g.orig/crypto/crypto.h 2014-03-17 12:14:20.000000000 -0400
+++ openssl-1.0.1g/crypto/crypto.h 2014-04-10 13:01:08.000000000 -0400
@@ -365,20 +365,16 @@
#define MemCheck_off() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE)
#define is_MemCheck_on() CRYPTO_is_mem_check_on()
-#define OPENSSL_malloc(num) CRYPTO_malloc((int)num,__FILE__,__LINE__)
-#define OPENSSL_strdup(str) CRYPTO_strdup((str),__FILE__,__LINE__)
-#define OPENSSL_realloc(addr,num) \
- CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__)
-#define OPENSSL_realloc_clean(addr,old_num,num) \
- CRYPTO_realloc_clean(addr,old_num,num,__FILE__,__LINE__)
-#define OPENSSL_remalloc(addr,num) \
- CRYPTO_remalloc((char **)addr,(int)num,__FILE__,__LINE__)
-#define OPENSSL_freeFunc CRYPTO_free
-#define OPENSSL_free(addr) CRYPTO_free(addr)
-
-#define OPENSSL_malloc_locked(num) \
- CRYPTO_malloc_locked((int)num,__FILE__,__LINE__)
-#define OPENSSL_free_locked(addr) CRYPTO_free_locked(addr)
+#include <openssl/secure_malloc.h>
+#define OPENSSL_malloc(s) secure_malloc(s)
+#define OPENSSL_strdup(str) secure_strdup(str)
+#define OPENSSL_free(a) secure_free(a)
+#define OPENSSL_realloc(a,s) secure_realloc(a,s)
+#define OPENSSL_realloc_clean(a,o,s) secure_realloc_clean(a,o,s)
+#define OPENSSL_remalloc(a,s) (OPENSSL_free(a), OPENSSL_malloc(s))
+#define OPENSSL_freeFunc secure_free
+#define OPENSSL_malloc_locked(s) OPENSSL_malloc(s)
+#define OPENSSL_free_locked(a) OPENSSL_free(a)
const char *SSLeay_version(int type);
diff -uNr -x'*.[oas]' openssl-1.0.1g.orig/crypto/secure_malloc.c openssl-1.0.1g/crypto/secure_malloc.c
--- openssl-1.0.1g.orig/crypto/secure_malloc.c 1969-12-31 19:00:00.000000000 -0500
+++ openssl-1.0.1g/crypto/secure_malloc.c 2014-04-10 16:43:35.000000000 -0400
@@ -0,0 +1,223 @@
+/*
+ * Memory allocator for secure heap for OpenSSL key storage.
+ * Copyright, 2001-2014, Akamai Technologies. All Rights Reserved.
+ * Distributed under the terms of the OpenSSL license.
+ *
+ * Note that to improve performance and simplfy the code, this allocator
+ * works only in the same thread where we called the init function;
+ * trying to allocate/free blocks from different threads will
+ * just delegate the calls to the standard malloc library.
+ */
+
+#include <pthread.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "secure_malloc.h"
+
+extern void OPENSSL_cleanse(void *ptr, size_t len);
+
+/*
+ * Set to 1 when secure_malloc_init() is called successfully. Can
+ * never be set back to 0
+ */
+int secure_allocation_support = 0;
+
+static pthread_mutex_t secure_allocation_lock = PTHREAD_MUTEX_INITIALIZER;
+
+#define LOCK() pthread_mutex_lock(&secure_allocation_lock)
+#define UNLOCK() pthread_mutex_unlock(&secure_allocation_lock)
+
+static pthread_key_t secure_allocation_key;
+static const int secure_yes = 1;
+static const int secure_no = 0;
+
+static char *arena = NULL;
+static size_t arena_size = 0;
+
+/* The low-level secure heap interface. */
+extern void *cmm_init(int size, int mem_min_unit, int overrun_bytes);
+extern void *cmm_malloc(int size);
+extern int cmm_free(void *lamb);
+extern void *cmm_realloc(void *lamb, int size);
+
+static int secure_allocation_enabled()
+{
+ if (!secure_allocation_support)
+ {
+ return 0;
+ }
+ int* answer = (int*)pthread_getspecific(secure_allocation_key);
+ return answer == &secure_yes;
+}
+
+static void secure_allocation_enable(int status)
+{
+ if (secure_allocation_support)
+ {
+ pthread_setspecific(secure_allocation_key,
+ status ? &secure_yes : &secure_no);
+ }
+}
+
+/*
+ * Start/stop secure allocation.
+ */
+int start_secure_allocation()
+{
+ int ret = secure_allocation_enabled();
+ if (ret == 0)
+ {
+ secure_allocation_enable(1);
+ }
+
+ return ret;
+}
+
+int stop_secure_allocation()
+{
+ int ret = secure_allocation_enabled();
+ if (ret == 1)
+ {
+ secure_allocation_enable(0);
+ }
+
+ return ret;
+}
+
+void flush_secure_arena()
+{
+ if (arena)
+ memset(arena, 0, arena_size);
+}
+
+/* Module initialization, returns >0 upon success */
+int secure_malloc_init(size_t size, int mem_min_unit, int overrun_bytes)
+{
+ int ret = 0;
+ arena_size = size;
+
+ LOCK();
+ if (arena)
+ {
+ assert(0);
+ }
+
+ else if ((arena = (char *) cmm_init(arena_size, mem_min_unit, overrun_bytes)) == NULL)
+ {
+ }
+ else if (mlock(arena, arena_size))
+ {
+ }
+ else if (pthread_key_create(&secure_allocation_key, 0) != 0)
+ {
+ }
+ else
+ {
+ secure_allocation_support = 1;
+ ret = 1;
+ }
+
+ /* MADV_DONTDUMP is supported from Kernel 3.4 and from glibc 2.16 */
+#ifdef MADV_DONTDUMP
+ if (madvise(arena, arena_size, MADV_DONTDUMP) == 0)
+ {
+ ret = 2;
+ }
+#endif
+
+ UNLOCK();
+ return ret;
+}
+
+/* Helper func to figure out whether a pointer was allocated from the
+ secure chunk.
+*/
+static int is_secured_ptr(void *ptr)
+{
+ return secure_allocation_support
+ && (char*)ptr >= arena && (char*)ptr < arena + arena_size;
+}
+
+void *secure_calloc(size_t nmemb, size_t size)
+{
+ void *ret;
+ int tot_size = nmemb*size;
+
+ if (!secure_allocation_enabled())
+ return calloc(nmemb,size);
+ LOCK();
+ ret = cmm_malloc(tot_size);
+ if (ret)
+ {
+ memset(ret,0,tot_size);
+ }
+ UNLOCK();
+ return ret;
+}
+
+void *secure_malloc(size_t size)
+{
+ void *ret;
+
+ if (!secure_allocation_enabled())
+ return malloc(size);
+ LOCK();
+ ret = cmm_malloc(size);
+ UNLOCK();
+ return ret;
+}
+
+void *secure_strdup(const char *str)
+{
+ return strcpy(secure_malloc(strlen(str) + 1), str);
+}
+
+void secure_free(void *ptr)
+{
+ if (secure_allocation_support && is_secured_ptr(ptr))
+ {
+ LOCK();
+ cmm_free(ptr);
+ UNLOCK();
+ }
+ else
+ {
+ free(ptr);
+ }
+
+}
+
+void *secure_realloc(void *ptr, size_t size)
+{
+ void *ret;
+
+ if (secure_allocation_support && is_secured_ptr(ptr))
+ {
+ LOCK();
+ ret = cmm_realloc(ptr,size);
+ UNLOCK();
+ }
+ else
+ {
+ ret = realloc(ptr,size);
+ }
+
+ return ret;
+}
+
+void *secure_realloc_clean(void *ptr, int old_len, size_t size)
+{
+ void *ret;
+
+ ret = secure_malloc(size);
+ if (ret)
+ memcpy(ret, ptr, old_len);
+
+ OPENSSL_cleanse(ptr, old_len);
+ secure_free(ptr);
+
+ return ret;
+}
diff -uNr -x'*.[oas]' openssl-1.0.1g.orig/crypto/secure_malloc.h openssl-1.0.1g/crypto/secure_malloc.h
--- openssl-1.0.1g.orig/crypto/secure_malloc.h 1969-12-31 19:00:00.000000000 -0500
+++ openssl-1.0.1g/crypto/secure_malloc.h 2014-04-10 16:40:48.000000000 -0400
@@ -0,0 +1,45 @@
+/*
+ * Memory allocator for secure heap for OpenSSL key storage.
+ * Copyright, 2001-2014, Akamai Technologies. All Rights Reserved.
+ * Distributed under the terms of the OpenSSL license.
+ */
+
+#ifndef __openssl_secure_malloc_h
+#define __openssl_secure_malloc_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Global flag to designate whether secure malloc support is turned on */
+extern int secure_allocation_support;
+
+/* Secure versions of the malloc interface functions */
+extern void *secure_calloc(size_t nmemb, size_t size);
+extern void *secure_malloc(size_t size);
+extern void *secure_strdup(const char *str);
+extern void secure_free(void *ptr);
+extern void *secure_realloc(void *ptr, size_t size);
+extern void *secure_realloc_clean(void *ptr, int old_len, size_t size);
+
+/* Module initialization including setting secure_malloc_support. */
+extern int secure_malloc_init(size_t arena_size, int mem_min_unit, int overrun_bytes);
+
+/*
+ * Enabling/Disabling the secure allocation. Use like this to ensure
+ * proper nesting:
+ * int x = start_secure_allocation();
+ * .... do some work, calling OPENSSL_malloc etc ...
+ * if (x) stop_secure_allocation();
+ */
+extern int start_secure_allocation();
+extern int stop_secure_allocation();
+
+/* Erasing the content of all allocated buffers */
+extern void flush_secure_arena();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment