Memory-allocation abstraction layer and buffer-based allocator added
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index f702ea7..948737d 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -29,6 +29,8 @@
      md2.c
      md4.c
      md5.c
+     memory.c
+     memory_buffer_alloc.c
      net.c
      oid.c
      padlock.c
diff --git a/library/Makefile b/library/Makefile
index a0e3105..f670dcc 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -44,7 +44,8 @@
 		entropy.o	entropy_poll.o				\
 		error.o		gcm.o		havege.o		\
 		md.o		md_wrap.o	md2.o			\
-		md4.o		md5.o		net.o			\
+		md4.o		md5.o		memory.o		\
+		memory_buffer_alloc.c	net.o			\
 		oid.o									\
 		padlock.o	pbkdf2.o	pem.o			\
 		pkcs5.o		pkcs11.o	pkcs12.o		\
diff --git a/library/asn1parse.c b/library/asn1parse.c
index b8823c1..d0a2234 100644
--- a/library/asn1parse.c
+++ b/library/asn1parse.c
@@ -33,6 +33,13 @@
 #include "polarssl/bignum.h"
 #endif
 
+#if defined(POLARSSL_MEMORY_C)
+#include "polarssl/memory.h"
+#else
+#define polarssl_malloc     malloc
+#define polarssl_free       free
+#endif
+
 #include <string.h>
 #include <stdlib.h>
 #include <time.h>
@@ -238,7 +245,7 @@
         /* Allocate and assign next pointer */
         if (*p < end)
         {
-            cur->next = (asn1_sequence *) malloc(
+            cur->next = (asn1_sequence *) polarssl_malloc(
                  sizeof( asn1_sequence ) );
 
             if( cur->next == NULL )
diff --git a/library/bignum.c b/library/bignum.c
index 1422d50..cc4b1f3 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -37,6 +37,13 @@
 #include "polarssl/bignum.h"
 #include "polarssl/bn_mul.h"
 
+#if defined(POLARSSL_MEMORY_C)
+#include "polarssl/memory.h"
+#else
+#define polarssl_malloc     malloc
+#define polarssl_free       free
+#endif
+
 #include <stdlib.h>
 
 #define ciL    (sizeof(t_uint))         /* chars in limb  */
@@ -73,7 +80,7 @@
     if( X->p != NULL )
     {
         memset( X->p, 0, X->n * ciL );
-        free( X->p );
+        polarssl_free( X->p );
     }
 
     X->s = 1;
@@ -93,7 +100,7 @@
 
     if( X->n < nblimbs )
     {
-        if( ( p = (t_uint *) malloc( nblimbs * ciL ) ) == NULL )
+        if( ( p = (t_uint *) polarssl_malloc( nblimbs * ciL ) ) == NULL )
             return( POLARSSL_ERR_MPI_MALLOC_FAILED );
 
         memset( p, 0, nblimbs * ciL );
@@ -102,7 +109,7 @@
         {
             memcpy( p, X->p, X->n * ciL );
             memset( X->p, 0, X->n * ciL );
-            free( X->p );
+            polarssl_free( X->p );
         }
 
         X->n = nblimbs;
diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c
index 030477f..baff2aa 100644
--- a/library/cipher_wrap.c
+++ b/library/cipher_wrap.c
@@ -49,6 +49,13 @@
 #include "polarssl/blowfish.h"
 #endif
 
+#if defined(POLARSSL_MEMORY_C)
+#include "polarssl/memory.h"
+#else
+#define polarssl_malloc     malloc
+#define polarssl_free       free
+#endif
+
 #include <stdlib.h>
 
 #if defined(POLARSSL_AES_C)
@@ -109,12 +116,12 @@
 
 static void * aes_ctx_alloc( void )
 {
-    return malloc( sizeof( aes_context ) );
+    return polarssl_malloc( sizeof( aes_context ) );
 }
 
 static void aes_ctx_free( void *ctx )
 {
-    free( ctx );
+    polarssl_free( ctx );
 }
 
 const cipher_base_t aes_info = {
@@ -304,12 +311,12 @@
 
 static void * camellia_ctx_alloc( void )
 {
-    return malloc( sizeof( camellia_context ) );
+    return polarssl_malloc( sizeof( camellia_context ) );
 }
 
 static void camellia_ctx_free( void *ctx )
 {
-    free( ctx );
+    polarssl_free( ctx );
 }
 
 const cipher_base_t camellia_info = {
@@ -506,17 +513,17 @@
 
 static void * des_ctx_alloc( void )
 {
-    return malloc( sizeof( des_context ) );
+    return polarssl_malloc( sizeof( des_context ) );
 }
 
 static void * des3_ctx_alloc( void )
 {
-    return malloc( sizeof( des3_context ) );
+    return polarssl_malloc( sizeof( des3_context ) );
 }
 
 static void des_ctx_free( void *ctx )
 {
-    free( ctx );
+    polarssl_free( ctx );
 }
 
 const cipher_base_t des_info = {
@@ -641,12 +648,12 @@
 
 static void * blowfish_ctx_alloc( void )
 {
-    return malloc( sizeof( blowfish_context ) );
+    return polarssl_malloc( sizeof( blowfish_context ) );
 }
 
 static void blowfish_ctx_free( void *ctx )
 {
-    free( ctx );
+    polarssl_free( ctx );
 }
 
 const cipher_base_t blowfish_info = {
diff --git a/library/ecp.c b/library/ecp.c
index d2d2e18..af18e5b 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -37,6 +37,14 @@
 #if defined(POLARSSL_ECP_C)
 
 #include "polarssl/ecp.h"
+
+#if defined(POLARSSL_MEMORY_C)
+#include "polarssl/memory.h"
+#else
+#define polarssl_malloc     malloc
+#define polarssl_free       free
+#endif
+
 #include <limits.h>
 #include <stdlib.h>
 
@@ -793,7 +801,7 @@
     if( t_len < 2 )
         return( ecp_normalize( grp, T ) );
 
-    if( ( c = (mpi *) malloc( t_len * sizeof( mpi ) ) ) == NULL )
+    if( ( c = (mpi *) polarssl_malloc( t_len * sizeof( mpi ) ) ) == NULL )
         return( POLARSSL_ERR_ECP_GENERIC );
 
     mpi_init( &u ); mpi_init( &Zi ); mpi_init( &ZZi );
@@ -848,7 +856,7 @@
     mpi_free( &u ); mpi_free( &Zi ); mpi_free( &ZZi );
     for( i = 0; i < t_len; i++ )
         mpi_free( &c[i] );
-    free( c );
+    polarssl_free( c );
 
     return( ret );
 }
diff --git a/library/md_wrap.c b/library/md_wrap.c
index d72852b..038b132 100644
--- a/library/md_wrap.c
+++ b/library/md_wrap.c
@@ -57,6 +57,13 @@
 #include "polarssl/sha512.h"
 #endif
 
+#if defined(POLARSSL_MEMORY_C)
+#include "polarssl/memory.h"
+#else
+#define polarssl_malloc     malloc
+#define polarssl_free       free
+#endif
+
 #include <stdlib.h>
 
 #if defined(POLARSSL_MD2_C)
@@ -109,12 +116,12 @@
 
 static void * md2_ctx_alloc( void )
 {
-    return malloc( sizeof( md2_context ) );
+    return polarssl_malloc( sizeof( md2_context ) );
 }
 
 static void md2_ctx_free( void *ctx )
 {
-    free( ctx );
+    polarssl_free( ctx );
 }
 
 static void md2_process_wrap( void *ctx, const unsigned char *data )
@@ -195,12 +202,12 @@
 
 static void *md4_ctx_alloc( void )
 {
-    return malloc( sizeof( md4_context ) );
+    return polarssl_malloc( sizeof( md4_context ) );
 }
 
 static void md4_ctx_free( void *ctx )
 {
-    free( ctx );
+    polarssl_free( ctx );
 }
 
 static void md4_process_wrap( void *ctx, const unsigned char *data )
@@ -279,12 +286,12 @@
 
 static void * md5_ctx_alloc( void )
 {
-    return malloc( sizeof( md5_context ) );
+    return polarssl_malloc( sizeof( md5_context ) );
 }
 
 static void md5_ctx_free( void *ctx )
 {
-    free( ctx );
+    polarssl_free( ctx );
 }
 
 static void md5_process_wrap( void *ctx, const unsigned char *data )
@@ -363,12 +370,12 @@
 
 static void * sha1_ctx_alloc( void )
 {
-    return malloc( sizeof( sha1_context ) );
+    return polarssl_malloc( sizeof( sha1_context ) );
 }
 
 static void sha1_ctx_free( void *ctx )
 {
-    free( ctx );
+    polarssl_free( ctx );
 }
 
 static void sha1_process_wrap( void *ctx, const unsigned char *data )
@@ -463,12 +470,12 @@
 
 static void * sha224_ctx_alloc( void )
 {
-    return malloc( sizeof( sha256_context ) );
+    return polarssl_malloc( sizeof( sha256_context ) );
 }
 
 static void sha224_ctx_free( void *ctx )
 {
-    free( ctx );
+    polarssl_free( ctx );
 }
 
 static void sha224_process_wrap( void *ctx, const unsigned char *data )
@@ -556,12 +563,12 @@
 
 static void * sha256_ctx_alloc( void )
 {
-    return malloc( sizeof( sha256_context ) );
+    return polarssl_malloc( sizeof( sha256_context ) );
 }
 
 static void sha256_ctx_free( void *ctx )
 {
-    free( ctx );
+    polarssl_free( ctx );
 }
 
 static void sha256_process_wrap( void *ctx, const unsigned char *data )
@@ -653,12 +660,12 @@
 
 static void * sha384_ctx_alloc( void )
 {
-    return malloc( sizeof( sha512_context ) );
+    return polarssl_malloc( sizeof( sha512_context ) );
 }
 
 static void sha384_ctx_free( void *ctx )
 {
-    free( ctx );
+    polarssl_free( ctx );
 }
 
 static void sha384_process_wrap( void *ctx, const unsigned char *data )
@@ -746,12 +753,12 @@
 
 static void * sha512_ctx_alloc( void )
 {
-    return malloc( sizeof( sha512_context ) );
+    return polarssl_malloc( sizeof( sha512_context ) );
 }
 
 static void sha512_ctx_free( void *ctx )
 {
-    free( ctx );
+    polarssl_free( ctx );
 }
 
 static void sha512_process_wrap( void *ctx, const unsigned char *data )
diff --git a/library/memory.c b/library/memory.c
new file mode 100644
index 0000000..93ca379
--- /dev/null
+++ b/library/memory.c
@@ -0,0 +1,63 @@
+/*
+ *  Memory allocation layer
+ *
+ *  Copyright (C) 2006-2013, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_MEMORY_C)
+
+#include "polarssl/memory.h"
+
+#if !defined(POLARSSL_MEMORY_STDMALLOC)
+static void *memory_malloc_uninit( size_t len )
+{
+    ((void) len);
+    return( NULL );
+}
+
+#define POLARSSL_MEMORY_STDMALLOC   memory_malloc_uninit
+#endif /* !POLARSSL_MEMORY_STDMALLOC */
+
+#if !defined(POLARSSL_MEMORY_STDFREE)
+static void memory_free_uninit( void *ptr )
+{
+    ((void) ptr);
+}
+
+#define POLARSSL_MEMORY_STDFREE     memory_free_uninit
+#endif /* !POLARSSL_MEMORY_STDFREE */
+
+void * (*polarssl_malloc)( size_t ) = POLARSSL_MEMORY_STDMALLOC;
+void (*polarssl_free)( void * )     = POLARSSL_MEMORY_STDFREE;
+
+int memory_set_own( void * (*malloc_func)( size_t ),
+                    void (*free_func)( void * ) )
+{
+    polarssl_malloc = malloc_func;
+    polarssl_free = free_func;
+
+    return( 0 );
+}
+
+#endif /* POLARSSL_MEMORY_C */
diff --git a/library/memory_buffer_alloc.c b/library/memory_buffer_alloc.c
new file mode 100644
index 0000000..c7df7b4
--- /dev/null
+++ b/library/memory_buffer_alloc.c
@@ -0,0 +1,376 @@
+/*
+ *  Buffer-based memory allocator
+ *
+ *  Copyright (C) 2006-2013, Brainspark B.V.
+ *
+ *  This file is part of PolarSSL (http://www.polarssl.org)
+ *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ *  All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_MEMORY_C) && defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
+
+#include "polarssl/memory.h"
+
+#include <string.h>
+
+#if defined(POLARSSL_MEMORY_DEBUG)
+#include <stdio.h>
+#if defined(POLARSSL_MEMORY_BACKTRACE)
+#include <execinfo.h>
+#endif
+#endif
+
+#define MAGIC1       0xFF00AA55
+#define MAGIC2       0xEE119966
+#define MAX_BT 20
+
+typedef struct _memory_header memory_header;
+struct _memory_header
+{
+    size_t          magic1;
+    size_t          size;
+    size_t          alloc;
+    memory_header   *prev;
+    memory_header   *next;
+#if defined(POLARSSL_MEMORY_BACKTRACE)
+    char            **trace;
+    size_t          trace_count;
+#endif
+    size_t          magic2;
+};
+
+typedef struct
+{
+    unsigned char   *buf;
+    size_t          len;
+    memory_header   *first;
+    size_t          largest_free;
+    size_t          current_alloc_size;
+    int             verify;
+}
+buffer_alloc_ctx;
+
+static buffer_alloc_ctx heap;
+
+#if defined(POLARSSL_MEMORY_DEBUG)
+static void debug_header( memory_header *hdr )
+{
+#if defined(POLARSSL_MEMORY_BACKTRACE)
+    size_t i;
+#endif
+
+    fprintf(stderr, "HDR:  PTR(%10u), PREV(%10u), NEXT(%10u), ALLOC(%u), SIZE(%10u)\n",
+            (size_t) hdr, (size_t) hdr->prev, (size_t) hdr->next,
+            hdr->alloc, hdr->size );
+
+#if defined(POLARSSL_MEMORY_BACKTRACE)
+    fprintf(stderr, "TRACE: \n");
+    for( i = 0; i < hdr->trace_count; i++ )
+        fprintf(stderr, "%s\n", hdr->trace[i]);
+#endif
+}
+
+static void debug_chain()
+{
+    memory_header *cur = heap.first;
+
+    while( cur != NULL )
+    {
+        debug_header( cur );
+        fprintf(stderr, "\n");
+        cur = cur->next;
+    }
+}
+#endif /* POLARSSL_MEMORY_DEBUG */
+
+static int verify_header( memory_header *hdr )
+{
+    if( hdr->magic1 != MAGIC1 )
+    {
+#if defined(POLARSSL_MEMORY_DEBUG)
+        fprintf(stderr, "FATAL: MAGIC1 mismatch\n");
+#endif
+        return( 1 );
+    }
+
+    if( hdr->magic2 != MAGIC2 )
+    {
+#if defined(POLARSSL_MEMORY_DEBUG)
+        fprintf(stderr, "FATAL: MAGIC2 mismatch\n");
+#endif
+        return( 1 );
+    }
+
+    if( hdr->alloc > 1 )
+    {
+#if defined(POLARSSL_MEMORY_DEBUG)
+        fprintf(stderr, "FATAL: alloc has illegal value\n");
+#endif
+        return( 1 );
+    }
+
+    return( 0 );
+}
+
+static int verify_chain()
+{
+    memory_header *prv = heap.first, *cur = heap.first->next;
+
+    if( verify_header( heap.first ) != 0 )
+    {
+#if defined(POLARSSL_MEMORY_DEBUG)
+        fprintf(stderr, "FATAL: verification of first header failed\n");
+#endif
+        return( 1 );
+    }
+
+    if( heap.first->prev != NULL )
+    {
+#if defined(POLARSSL_MEMORY_DEBUG)
+        fprintf(stderr, "FATAL: verification failed: first->prev != NULL\n");
+#endif
+        return( 1 );
+    }
+
+    while( cur != NULL )
+    {
+        if( verify_header( cur ) != 0 )
+        {
+#if defined(POLARSSL_MEMORY_DEBUG)
+            fprintf(stderr, "FATAL: verification of header failed\n");
+#endif
+            return( 1 );
+        }
+
+        if( cur->prev != prv )
+        {
+#if defined(POLARSSL_MEMORY_DEBUG)
+            fprintf(stderr, "FATAL: verification failed: cur->prev != prv\n");
+#endif
+            return( 1 );
+        }
+
+        prv = cur;
+        cur = cur->next;
+    }
+
+    return( 0 );
+}
+
+static void *buffer_alloc_malloc( size_t len )
+{
+    memory_header *new, *cur = heap.first;
+    unsigned char *p;
+#if defined(POLARSSL_MEMORY_BACKTRACE)
+    void *trace_buffer[MAX_BT];
+    size_t trace_cnt;
+#endif
+
+    if( heap.buf == NULL || heap.first == NULL )
+        return( NULL );
+
+    if( len % POLARSSL_MEMORY_ALIGN_MULTIPLE )
+    {
+        len -= len % POLARSSL_MEMORY_ALIGN_MULTIPLE;
+        len += POLARSSL_MEMORY_ALIGN_MULTIPLE;
+    }
+
+    // Find block that fits
+    //
+    while( cur != NULL )
+    {
+        if( cur->alloc == 0 && cur->size >= len )
+            break;
+
+        cur = cur->next;
+    }
+
+    if( cur == NULL )
+        return( NULL );
+
+    // Found location, split block if > memory_header + 4 room left
+    //
+    if( cur->size - len < sizeof(memory_header) + POLARSSL_MEMORY_ALIGN_MULTIPLE )
+    {
+        cur->alloc = 1;
+
+#if defined(POLARSSL_MEMORY_BACKTRACE)
+        trace_cnt = backtrace( trace_buffer, MAX_BT );
+        cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
+        cur->trace_count = trace_cnt;
+#endif
+
+        if( ( heap.verify & MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 )
+            exit( 1 );
+
+        return ( (unsigned char *) cur ) + sizeof(memory_header);
+    }
+
+    p = ( (unsigned char *) cur ) + sizeof(memory_header) + len;
+    new = (memory_header *) p;
+
+    new->size = cur->size - len - sizeof(memory_header);
+    new->alloc = 0;
+    new->prev = cur;
+    new->next = cur->next;
+#if defined(POLARSSL_MEMORY_BACKTRACE)
+    new->trace = NULL;
+    new->trace_count = 0;
+#endif
+    new->magic1 = MAGIC1;
+    new->magic2 = MAGIC2;
+
+    if( new->next != NULL )
+        new->next->prev = new;
+
+    cur->alloc = 1;
+    cur->size = len;
+    cur->next = new;
+
+#if defined(POLARSSL_MEMORY_BACKTRACE)
+    trace_cnt = backtrace( trace_buffer, MAX_BT );
+    cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
+    cur->trace_count = trace_cnt;
+#endif
+
+    if( ( heap.verify & MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 )
+        exit( 1 );
+
+    return ( (unsigned char *) cur ) + sizeof(memory_header);
+}
+
+static void buffer_alloc_free( void *ptr )
+{
+    memory_header *hdr, *old;
+    unsigned char *p = (unsigned char *) ptr;
+
+
+    if( ptr == NULL || heap.buf == NULL || heap.first == NULL )
+        return;
+
+    if( p < heap.buf || p > heap.buf + heap.len )
+    {
+#if defined(POLARSSL_MEMORY_DEBUG)
+        fprintf(stderr, "FATAL: polarssl_free() outside of managed space\n");
+#endif
+        exit(1);
+    }
+
+    p -= sizeof(memory_header);
+    hdr = (memory_header *) p;
+
+    if( verify_header( hdr ) != 0 )
+        exit( 1 );
+
+    if( hdr->alloc != 1 )
+    {
+#if defined(POLARSSL_MEMORY_DEBUG)
+        fprintf(stderr, "FATAL: polarssl_free() on unallocated data\n");
+#endif
+        exit(1);
+    }
+
+    hdr->alloc = 0;
+
+    // Regroup with block before
+    //
+    if( hdr->prev != NULL && hdr->prev->alloc == 0 )
+    {
+        hdr->prev->size += sizeof(memory_header) + hdr->size;
+        hdr->prev->next = hdr->next;
+        old = hdr;
+        hdr = hdr->prev;
+
+        if( hdr->next != NULL )
+            hdr->next->prev = hdr;
+
+#if defined(POLARSSL_MEMORY_BACKTRACE)
+        free( old->trace );
+#endif
+        memset( old, 0, sizeof(memory_header) );
+    }
+
+    // Regroup with block after
+    //
+    if( hdr->next != NULL && hdr->next->alloc == 0 )
+    {
+        hdr->size += sizeof(memory_header) + hdr->next->size;
+        old = hdr->next;
+        hdr->next = hdr->next->next;
+
+        if( hdr->next != NULL )
+            hdr->next->prev = hdr;
+
+#if defined(POLARSSL_MEMORY_BACKTRACE)
+        free( old->trace );
+#endif
+        memset( old, 0, sizeof(memory_header) );
+    }
+
+#if defined(POLARSSL_MEMORY_BACKTRACE)
+    hdr->trace = NULL;
+    hdr->trace_count = 0;
+#endif
+
+    if( ( heap.verify & MEMORY_VERIFY_FREE ) && verify_chain() != 0 )
+        exit( 1 );
+}
+
+int memory_buffer_alloc_verify()
+{
+    return verify_chain();
+}
+
+#if defined(POLARSSL_MEMORY_DEBUG)
+void memory_buffer_alloc_status()
+{
+    if( heap.first->next == NULL )
+        fprintf(stderr, "All memory de-allocated in stack buffer\n");
+    else
+    {
+        fprintf(stderr, "Memory currently allocated:\n");
+        debug_chain();
+    }
+}
+#endif /* POLARSSL_MEMORY_BUFFER_ALLOC_DEBUG */
+
+int memory_buffer_alloc_init( unsigned char *buf, size_t len )
+{
+    polarssl_malloc = buffer_alloc_malloc;
+    polarssl_free = buffer_alloc_free;
+
+    memset( &heap, 0, sizeof(buffer_alloc_ctx) );
+    memset( buf, 0, len );
+
+    heap.buf = buf;
+    heap.len = len;
+
+    heap.first = (memory_header *) buf;
+    heap.first->size = len - sizeof(memory_header);
+    heap.first->magic1 = MAGIC1;
+    heap.first->magic2 = MAGIC2;
+
+    heap.largest_free = heap.first->size;
+
+    return( 0 );
+}
+
+#endif /* POLARSSL_MEMORY_C && POLARSSL_MEMORY_BUFFER_ALLOC_C */
diff --git a/library/pem.c b/library/pem.c
index d2d70ab..c4c5cb4 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -34,6 +34,13 @@
 #include "polarssl/md5.h"
 #include "polarssl/cipher.h"
 
+#if defined(POLARSSL_MEMORY_C)
+#include "polarssl/memory.h"
+#else
+#define polarssl_malloc     malloc
+#define polarssl_free       free
+#endif
+
 #include <stdlib.h>
 
 void pem_init( pem_context *ctx )
@@ -291,12 +298,12 @@
     if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
         return( POLARSSL_ERR_PEM_INVALID_DATA + ret );
 
-    if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
+    if( ( buf = (unsigned char *) polarssl_malloc( len ) ) == NULL )
         return( POLARSSL_ERR_PEM_MALLOC_FAILED );
 
     if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
     {
-        free( buf );
+        polarssl_free( buf );
         return( POLARSSL_ERR_PEM_INVALID_DATA + ret );
     }
     
@@ -305,7 +312,7 @@
 #if defined(POLARSSL_MD5_C) && (defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C))
         if( pwd == NULL )
         {
-            free( buf );
+            polarssl_free( buf );
             return( POLARSSL_ERR_PEM_PASSWORD_REQUIRED );
         }
 
@@ -328,11 +335,11 @@
         if( buf[0] != 0x30 || buf[1] != 0x82 ||
             buf[4] != 0x02 || buf[5] != 0x01 )
         {
-            free( buf );
+            polarssl_free( buf );
             return( POLARSSL_ERR_PEM_PASSWORD_MISMATCH );
         }
 #else
-        free( buf );
+        polarssl_free( buf );
         return( POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE );
 #endif
     }
@@ -346,10 +353,10 @@
 void pem_free( pem_context *ctx )
 {
     if( ctx->buf )
-        free( ctx->buf );
+        polarssl_free( ctx->buf );
 
     if( ctx->info )
-        free( ctx->info );
+        polarssl_free( ctx->info );
 
     memset( ctx, 0, sizeof( pem_context ) );
 }
diff --git a/library/pkcs11.c b/library/pkcs11.c
index b68d688..5343659 100644
--- a/library/pkcs11.c
+++ b/library/pkcs11.c
@@ -5,7 +5,7 @@
  *
  * \author Adriaan de Jong <dejong@fox-it.com>
  *
- *  Copyright (C) 2006-2010, Brainspark B.V.
+ *  Copyright (C) 2006-2013, Brainspark B.V.
  *
  *  This file is part of PolarSSL (http://www.polarssl.org)
  *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -31,6 +31,13 @@
 
 #if defined(POLARSSL_PKCS11_C)
 
+#if defined(POLARSSL_MEMORY_C)
+#include "polarssl/memory.h"
+#else
+#define polarssl_malloc     malloc
+#define polarssl_free       free
+#endif
+
 #include <stdlib.h>
 
 int pkcs11_x509_cert_init( x509_cert *cert, pkcs11h_certificate_t pkcs11_cert )
@@ -51,7 +58,7 @@
         goto cleanup;
     }
 
-    cert_blob = malloc( cert_blob_size );
+    cert_blob = polarssl_malloc( cert_blob_size );
     if( NULL == cert_blob )
     {
         ret = 4;
@@ -74,7 +81,7 @@
 
 cleanup:
     if( NULL != cert_blob )
-        free( cert_blob );
+        polarssl_free( cert_blob );
 
     return ret;
 }
diff --git a/library/ssl_cache.c b/library/ssl_cache.c
index 93d5d8b..bc4326a 100644
--- a/library/ssl_cache.c
+++ b/library/ssl_cache.c
@@ -33,6 +33,13 @@
 
 #include "polarssl/ssl_cache.h"
 
+#if defined(POLARSSL_MEMORY_C)
+#include "polarssl/memory.h"
+#else
+#define polarssl_malloc     malloc
+#define polarssl_free       free
+#endif
+
 #include <stdlib.h>
 
 void ssl_cache_init( ssl_cache_context *cache )
@@ -78,7 +85,7 @@
          */
         if( entry->peer_cert.p != NULL )
         {
-            session->peer_cert = (x509_cert *) malloc( sizeof(x509_cert) );
+            session->peer_cert = (x509_cert *) polarssl_malloc( sizeof(x509_cert) );
             if( session->peer_cert == NULL )
                 return( 1 );
 
@@ -86,7 +93,7 @@
             if( x509parse_crt( session->peer_cert, entry->peer_cert.p,
                                entry->peer_cert.len ) != 0 )
             {
-                free( session->peer_cert );
+                polarssl_free( session->peer_cert );
                 session->peer_cert = NULL;
                 return( 1 );
             }
@@ -145,14 +152,14 @@
 #if defined(POLARSSL_X509_PARSE_C)
             if( cur->peer_cert.p != NULL )
             {
-                free( cur->peer_cert.p );
+                polarssl_free( cur->peer_cert.p );
                 memset( &cur->peer_cert, 0, sizeof(x509_buf) );
             }
 #endif /* POLARSSL_X509_PARSE_C */
         }
         else
         {
-            cur = (ssl_cache_entry *) malloc( sizeof(ssl_cache_entry) );
+            cur = (ssl_cache_entry *) polarssl_malloc( sizeof(ssl_cache_entry) );
             if( cur == NULL )
                 return( 1 );
 
@@ -175,7 +182,7 @@
      */
     if( session->peer_cert != NULL )
     {
-        cur->peer_cert.p = (unsigned char *) malloc( session->peer_cert->raw.len );
+        cur->peer_cert.p = (unsigned char *) polarssl_malloc( session->peer_cert->raw.len );
         if( cur->peer_cert.p == NULL )
             return( 1 );
 
@@ -219,10 +226,10 @@
 
 #if defined(POLARSSL_X509_PARSE_C)
         if( prv->peer_cert.p != NULL )
-            free( prv->peer_cert.p );
+            polarssl_free( prv->peer_cert.p );
 #endif /* POLARSSL_X509_PARSE_C */
 
-        free( prv );
+        polarssl_free( prv );
     }
 }
 
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 62d8d55..3ac60f5 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -46,6 +46,13 @@
 #include "polarssl/gcm.h"
 #endif
 
+#if defined(POLARSSL_MEMORY_C)
+#include "polarssl/memory.h"
+#else
+#define polarssl_malloc     malloc
+#define polarssl_free       free
+#endif
+
 #include <stdlib.h>
 #include <time.h>
 
@@ -1299,7 +1306,7 @@
     if( len_pre == 0 )
         return( 0 );
 
-    msg_pre = (unsigned char*) malloc( len_pre );
+    msg_pre = (unsigned char*) polarssl_malloc( len_pre );
     if( msg_pre == NULL )
     {
         SSL_DEBUG_MSG( 1, ( "malloc(%d bytes) failed", len_pre ) );
@@ -1328,7 +1335,7 @@
 
     ssl->out_msglen = SSL_BUFFER_LEN - ssl->transform_out->ctx_deflate.avail_out;
 
-    free( msg_pre );
+    polarssl_free( msg_pre );
 
     SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ",
                    ssl->out_msglen ) );
@@ -1353,7 +1360,7 @@
     if( len_pre == 0 )
         return( 0 );
 
-    msg_pre = (unsigned char*) malloc( len_pre );
+    msg_pre = (unsigned char*) polarssl_malloc( len_pre );
     if( msg_pre == NULL )
     {
         SSL_DEBUG_MSG( 1, ( "malloc(%d bytes) failed", len_pre ) );
@@ -1382,7 +1389,7 @@
 
     ssl->in_msglen = SSL_MAX_CONTENT_LEN - ssl->transform_in->ctx_inflate.avail_out;
 
-    free( msg_pre );
+    polarssl_free( msg_pre );
 
     SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ",
                    ssl->in_msglen ) );
@@ -2094,7 +2101,7 @@
         return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE );
     }
 
-    if( ( ssl->session_negotiate->peer_cert = (x509_cert *) malloc(
+    if( ( ssl->session_negotiate->peer_cert = (x509_cert *) polarssl_malloc(
                     sizeof( x509_cert ) ) ) == NULL )
     {
         SSL_DEBUG_MSG( 1, ( "malloc(%d bytes) failed",
@@ -2504,7 +2511,7 @@
      * Free our handshake params
      */
     ssl_handshake_free( ssl->handshake );
-    free( ssl->handshake );
+    polarssl_free( ssl->handshake );
     ssl->handshake = NULL;
 
     /*
@@ -2513,7 +2520,7 @@
     if( ssl->transform )
     {
         ssl_transform_free( ssl->transform );
-        free( ssl->transform );
+        polarssl_free( ssl->transform );
     }
     ssl->transform = ssl->transform_negotiate;
     ssl->transform_negotiate = NULL;
@@ -2521,7 +2528,7 @@
     if( ssl->session )
     {
         ssl_session_free( ssl->session );
-        free( ssl->session );
+        polarssl_free( ssl->session );
     }
     ssl->session = ssl->session_negotiate;
     ssl->session_negotiate = NULL;
@@ -2703,17 +2710,17 @@
     if( ssl->transform_negotiate )
         ssl_transform_free( ssl->transform_negotiate );
     else
-        ssl->transform_negotiate = malloc( sizeof(ssl_transform) );
+        ssl->transform_negotiate = polarssl_malloc( sizeof(ssl_transform) );
 
     if( ssl->session_negotiate )
         ssl_session_free( ssl->session_negotiate );
     else
-        ssl->session_negotiate = malloc( sizeof(ssl_session) );
+        ssl->session_negotiate = polarssl_malloc( sizeof(ssl_session) );
 
     if( ssl->handshake )
         ssl_handshake_free( ssl->handshake );
     else
-        ssl->handshake = malloc( sizeof(ssl_handshake_params) );
+        ssl->handshake = polarssl_malloc( sizeof(ssl_handshake_params) );
 
     if( ssl->handshake == NULL ||
         ssl->transform_negotiate == NULL ||
@@ -2780,7 +2787,7 @@
     /*
      * Prepare base structures
      */
-    ssl->in_ctr = (unsigned char *) malloc( len );
+    ssl->in_ctr = (unsigned char *) polarssl_malloc( len );
     ssl->in_hdr = ssl->in_ctr +  8;
     ssl->in_iv  = ssl->in_ctr + 13;
     ssl->in_msg = ssl->in_ctr + 13;
@@ -2791,7 +2798,7 @@
         return( POLARSSL_ERR_SSL_MALLOC_FAILED );
     }
 
-    ssl->out_ctr = (unsigned char *) malloc( len );
+    ssl->out_ctr = (unsigned char *) polarssl_malloc( len );
     ssl->out_hdr = ssl->out_ctr +  8;
     ssl->out_iv  = ssl->out_ctr + 13;
     ssl->out_msg = ssl->out_ctr + 13;
@@ -2799,7 +2806,7 @@
     if( ssl->out_ctr == NULL )
     {
         SSL_DEBUG_MSG( 1, ( "malloc(%d bytes) failed", len ) );
-        free( ssl-> in_ctr );
+        polarssl_free( ssl-> in_ctr );
         return( POLARSSL_ERR_SSL_MALLOC_FAILED );
     }
 
@@ -2868,14 +2875,14 @@
     if( ssl->transform )
     {
         ssl_transform_free( ssl->transform );
-        free( ssl->transform );
+        polarssl_free( ssl->transform );
         ssl->transform = NULL;
     }
 
     if( ssl->session )
     {
         ssl_session_free( ssl->session );
-        free( ssl->session );
+        polarssl_free( ssl->session );
         ssl->session = NULL;
     }
 
@@ -3057,7 +3064,7 @@
         return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
 
     ssl->hostname_len = strlen( hostname );
-    ssl->hostname = (unsigned char *) malloc( ssl->hostname_len + 1 );
+    ssl->hostname = (unsigned char *) polarssl_malloc( ssl->hostname_len + 1 );
 
     if( ssl->hostname == NULL )
         return( POLARSSL_ERR_SSL_MALLOC_FAILED );
@@ -3447,7 +3454,7 @@
     if( session->peer_cert != NULL )
     {
         x509_free( session->peer_cert );
-        free( session->peer_cert );
+        polarssl_free( session->peer_cert );
     }
 #endif
 
@@ -3464,13 +3471,13 @@
     if( ssl->out_ctr != NULL )
     {
         memset( ssl->out_ctr, 0, SSL_BUFFER_LEN );
-          free( ssl->out_ctr );
+        polarssl_free( ssl->out_ctr );
     }
 
     if( ssl->in_ctr != NULL )
     {
         memset( ssl->in_ctr, 0, SSL_BUFFER_LEN );
-          free( ssl->in_ctr );
+        polarssl_free( ssl->in_ctr );
     }
 
 #if defined(POLARSSL_DHM_C)
@@ -3481,7 +3488,7 @@
     if( ssl->transform )
     {
         ssl_transform_free( ssl->transform );
-        free( ssl->transform );
+        polarssl_free( ssl->transform );
     }
 
     if( ssl->handshake )
@@ -3490,21 +3497,21 @@
         ssl_transform_free( ssl->transform_negotiate );
         ssl_session_free( ssl->session_negotiate );
 
-        free( ssl->handshake );
-        free( ssl->transform_negotiate );
-        free( ssl->session_negotiate );
+        polarssl_free( ssl->handshake );
+        polarssl_free( ssl->transform_negotiate );
+        polarssl_free( ssl->session_negotiate );
     }
 
     if( ssl->session )
     {
         ssl_session_free( ssl->session );
-        free( ssl->session );
+        polarssl_free( ssl->session );
     }
 
     if ( ssl->hostname != NULL)
     {
         memset( ssl->hostname, 0, ssl->hostname_len );
-        free( ssl->hostname );
+        polarssl_free( ssl->hostname );
         ssl->hostname_len = 0;
     }
 
diff --git a/library/x509parse.c b/library/x509parse.c
index 49c1705..b27faf9 100644
--- a/library/x509parse.c
+++ b/library/x509parse.c
@@ -50,6 +50,13 @@
 #include "polarssl/pkcs12.h"
 #endif
 
+#if defined(POLARSSL_MEMORY_C)
+#include "polarssl/memory.h"
+#else
+#define polarssl_malloc     malloc
+#define polarssl_free       free
+#endif
+
 #include <string.h>
 #include <stdlib.h>
 #if defined(_WIN32)
@@ -261,7 +268,7 @@
         
         if( *p != end )
         {
-            use->next = (x509_name *) malloc(
+            use->next = (x509_name *) polarssl_malloc(
                     sizeof( x509_name ) );
 
             if( use->next == NULL )
@@ -280,7 +287,7 @@
     if( *p == end2 )
         return( 0 );
 
-    cur->next = (x509_name *) malloc(
+    cur->next = (x509_name *) polarssl_malloc(
          sizeof( x509_name ) );
 
     if( cur->next == NULL )
@@ -827,7 +834,7 @@
         /* Allocate and assign next pointer */
         if (*p < end)
         {
-            cur->next = (asn1_sequence *) malloc(
+            cur->next = (asn1_sequence *) polarssl_malloc(
                  sizeof( asn1_sequence ) );
 
             if( cur->next == NULL )
@@ -1043,7 +1050,7 @@
 
         if ( *p < end )
         {
-            cur_entry->next = malloc( sizeof( x509_crl_entry ) );
+            cur_entry->next = polarssl_malloc( sizeof( x509_crl_entry ) );
 
             if( cur_entry->next == NULL )
                 return( POLARSSL_ERR_X509_MALLOC_FAILED );
@@ -1083,7 +1090,7 @@
     if( crt == NULL || buf == NULL )
         return( POLARSSL_ERR_X509_INVALID_INPUT );
 
-    p = (unsigned char *) malloc( len = buflen );
+    p = (unsigned char *) polarssl_malloc( len = buflen );
 
     if( p == NULL )
         return( POLARSSL_ERR_X509_MALLOC_FAILED );
@@ -1348,7 +1355,7 @@
      */
     if ( crt->version != 0 && crt->next == NULL)
     {
-        crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
+        crt->next = (x509_cert *) polarssl_malloc( sizeof( x509_cert ) );
 
         if( crt->next == NULL )
             return( POLARSSL_ERR_X509_MALLOC_FAILED );
@@ -1364,7 +1371,7 @@
             prev->next = NULL;
 
         if( crt != chain )
-            free( crt );
+            polarssl_free( crt );
 
         return( ret );
     }
@@ -1505,7 +1512,7 @@
      */
     if ( crl->version != 0 && crl->next == NULL)
     {
-        crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
+        crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
 
         if( crl->next == NULL )
         {
@@ -1550,7 +1557,7 @@
         /*
          * nope, copy the raw DER data
          */
-        p = (unsigned char *) malloc( len = buflen );
+        p = (unsigned char *) polarssl_malloc( len = buflen );
 
         if( p == NULL )
             return( POLARSSL_ERR_X509_MALLOC_FAILED );
@@ -1560,7 +1567,7 @@
         buflen = 0;
     }
 #else
-    p = (unsigned char *) malloc( len = buflen );
+    p = (unsigned char *) polarssl_malloc( len = buflen );
 
     if( p == NULL )
         return( POLARSSL_ERR_X509_MALLOC_FAILED );
@@ -1749,7 +1756,7 @@
 
     if( buflen > 0 )
     {
-        crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
+        crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );
 
         if( crl->next == NULL )
         {
@@ -1781,7 +1788,7 @@
     *n = (size_t) ftell( f );
     fseek( f, 0, SEEK_SET );
 
-    if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
+    if( ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
     {
         fclose( f );
         return( POLARSSL_ERR_X509_MALLOC_FAILED );
@@ -1790,7 +1797,7 @@
     if( fread( *buf, 1, *n, f ) != *n )
     {
         fclose( f );
-        free( *buf );
+        polarssl_free( *buf );
         return( POLARSSL_ERR_X509_FILE_IO_ERROR );
     }
 
@@ -1816,7 +1823,7 @@
     ret = x509parse_crt( chain, buf, n );
 
     memset( buf, 0, n + 1 );
-    free( buf );
+    polarssl_free( buf );
 
     return( ret );
 }
@@ -1930,7 +1937,7 @@
     ret = x509parse_crl( chain, buf, n );
 
     memset( buf, 0, n + 1 );
-    free( buf );
+    polarssl_free( buf );
 
     return( ret );
 }
@@ -1954,7 +1961,7 @@
                 (const unsigned char *) pwd, strlen( pwd ) );
 
     memset( buf, 0, n + 1 );
-    free( buf );
+    polarssl_free( buf );
 
     return( ret );
 }
@@ -1974,7 +1981,7 @@
     ret = x509parse_public_key( rsa, buf, n );
 
     memset( buf, 0, n + 1 );
-    free( buf );
+    polarssl_free( buf );
 
     return( ret );
 }
@@ -2546,7 +2553,7 @@
     ret = x509parse_dhm( dhm, buf, n );
 
     memset( buf, 0, n + 1 );
-    free( buf );
+    polarssl_free( buf );
 
     return( ret );
 }
@@ -3381,7 +3388,7 @@
             name_prv = name_cur;
             name_cur = name_cur->next;
             memset( name_prv, 0, sizeof( x509_name ) );
-            free( name_prv );
+            polarssl_free( name_prv );
         }
 
         name_cur = cert_cur->subject.next;
@@ -3390,7 +3397,7 @@
             name_prv = name_cur;
             name_cur = name_cur->next;
             memset( name_prv, 0, sizeof( x509_name ) );
-            free( name_prv );
+            polarssl_free( name_prv );
         }
 
         seq_cur = cert_cur->ext_key_usage.next;
@@ -3399,7 +3406,7 @@
             seq_prv = seq_cur;
             seq_cur = seq_cur->next;
             memset( seq_prv, 0, sizeof( x509_sequence ) );
-            free( seq_prv );
+            polarssl_free( seq_prv );
         }
 
         seq_cur = cert_cur->subject_alt_names.next;
@@ -3408,13 +3415,13 @@
             seq_prv = seq_cur;
             seq_cur = seq_cur->next;
             memset( seq_prv, 0, sizeof( x509_sequence ) );
-            free( seq_prv );
+            polarssl_free( seq_prv );
         }
 
         if( cert_cur->raw.p != NULL )
         {
             memset( cert_cur->raw.p, 0, cert_cur->raw.len );
-            free( cert_cur->raw.p );
+            polarssl_free( cert_cur->raw.p );
         }
 
         cert_cur = cert_cur->next;
@@ -3429,7 +3436,7 @@
 
         memset( cert_prv, 0, sizeof( x509_cert ) );
         if( cert_prv != crt )
-            free( cert_prv );
+            polarssl_free( cert_prv );
     }
     while( cert_cur != NULL );
 }
@@ -3457,7 +3464,7 @@
             name_prv = name_cur;
             name_cur = name_cur->next;
             memset( name_prv, 0, sizeof( x509_name ) );
-            free( name_prv );
+            polarssl_free( name_prv );
         }
 
         entry_cur = crl_cur->entry.next;
@@ -3466,13 +3473,13 @@
             entry_prv = entry_cur;
             entry_cur = entry_cur->next;
             memset( entry_prv, 0, sizeof( x509_crl_entry ) );
-            free( entry_prv );
+            polarssl_free( entry_prv );
         }
 
         if( crl_cur->raw.p != NULL )
         {
             memset( crl_cur->raw.p, 0, crl_cur->raw.len );
-            free( crl_cur->raw.p );
+            polarssl_free( crl_cur->raw.p );
         }
 
         crl_cur = crl_cur->next;
@@ -3487,7 +3494,7 @@
 
         memset( crl_prv, 0, sizeof( x509_crl ) );
         if( crl_prv != crl )
-            free( crl_prv );
+            polarssl_free( crl_prv );
     }
     while( crl_cur != NULL );
 }