Merge remote-tracking branch 'upstream-public/pr/1009' into mbedtls-2.1-proposed
diff --git a/ChangeLog b/ChangeLog
index 01c916a..392e747 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -37,6 +37,8 @@
Nick Wilson on issue #355
* In test_suite_pk, pass valid parameters when testing for hash length
overflow. #1179
+ * Fix memory allocation corner cases in memory_buffer_alloc.c module. Found
+ by Guido Vranken. #639
Changes
* Clarified the documentation of mbedtls_ssl_setup.
diff --git a/library/memory_buffer_alloc.c b/library/memory_buffer_alloc.c
index 545d5a2..1cfc27c 100644
--- a/library/memory_buffer_alloc.c
+++ b/library/memory_buffer_alloc.c
@@ -182,9 +182,9 @@
static int verify_chain()
{
- memory_header *prv = heap.first, *cur = heap.first->next;
+ memory_header *prv = heap.first, *cur;
- if( verify_header( heap.first ) != 0 )
+ if( prv == NULL || verify_header( prv ) != 0 )
{
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_fprintf( stderr, "FATAL: verification of first header "
@@ -202,6 +202,8 @@
return( 1 );
}
+ cur = heap.first->next;
+
while( cur != NULL )
{
if( verify_header( cur ) != 0 )
@@ -245,7 +247,9 @@
original_len = len = n * size;
- if( n != 0 && len / n != size )
+ if( n == 0 || size == 0 || len / n != size )
+ return( NULL );
+ else if( len > (size_t)-MBEDTLS_MEMORY_ALIGN_MULTIPLE )
return( NULL );
if( len % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
@@ -386,7 +390,7 @@
if( ptr == NULL || heap.buf == NULL || heap.first == NULL )
return;
- if( p < heap.buf || p > heap.buf + heap.len )
+ if( p < heap.buf || p >= heap.buf + heap.len )
{
#if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_fprintf( stderr, "FATAL: mbedtls_free() outside of managed "
@@ -570,8 +574,7 @@
void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len )
{
- memset( &heap, 0, sizeof(buffer_alloc_ctx) );
- memset( buf, 0, len );
+ memset( &heap, 0, sizeof( buffer_alloc_ctx ) );
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &heap.mutex );
@@ -581,20 +584,24 @@
mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free );
#endif
- if( (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
+ if( len < sizeof( memory_header ) + MBEDTLS_MEMORY_ALIGN_MULTIPLE )
+ return;
+ else if( (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
{
/* Adjust len first since buf is used in the computation */
len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE
- - (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
+ - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE
- - (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
+ - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
}
+ memset( buf, 0, len );
+
heap.buf = buf;
heap.len = len;
- heap.first = (memory_header *) buf;
- heap.first->size = len - sizeof(memory_header);
+ heap.first = (memory_header *)buf;
+ heap.first->size = len - sizeof( memory_header );
heap.first->magic1 = MAGIC1;
heap.first->magic2 = MAGIC2;
heap.first_free = heap.first;
diff --git a/library/pem.c b/library/pem.c
index 756572d..0788619 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -429,7 +429,7 @@
unsigned char *buf, size_t buf_len, size_t *olen )
{
int ret;
- unsigned char *encode_buf, *c, *p = buf;
+ unsigned char *encode_buf = NULL, *c, *p = buf;
size_t len = 0, use_len, add_len = 0;
mbedtls_base64_encode( NULL, 0, &use_len, der_data, der_len );
@@ -441,7 +441,8 @@
return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
}
- if( ( encode_buf = mbedtls_calloc( 1, use_len ) ) == NULL )
+ if( use_len != 0 &&
+ ( ( encode_buf = mbedtls_calloc( 1, use_len ) ) == NULL ) )
return( MBEDTLS_ERR_PEM_ALLOC_FAILED );
if( ( ret = mbedtls_base64_encode( encode_buf, use_len, &use_len, der_data,
diff --git a/library/pkparse.c b/library/pkparse.c
index eb92da4..316dde3 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -1213,6 +1213,9 @@
{
unsigned char *key_copy;
+ if( keylen == 0 )
+ return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
+
if( ( key_copy = mbedtls_calloc( 1, keylen ) ) == NULL )
return( MBEDTLS_ERR_PK_ALLOC_FAILED );
diff --git a/library/x509_crl.c b/library/x509_crl.c
index 91bbf05..bd6b537 100644
--- a/library/x509_crl.c
+++ b/library/x509_crl.c
@@ -257,7 +257,7 @@
{
int ret;
size_t len;
- unsigned char *p, *end;
+ unsigned char *p = NULL, *end = NULL;
mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
mbedtls_x509_crl *crl = chain;
@@ -294,7 +294,11 @@
/*
* Copy raw DER-encoded CRL
*/
- if( ( p = mbedtls_calloc( 1, buflen ) ) == NULL )
+ if( buflen == 0 )
+ return( MBEDTLS_ERR_X509_INVALID_FORMAT );
+
+ p = mbedtls_calloc( 1, buflen );
+ if( p == NULL )
return( MBEDTLS_ERR_X509_ALLOC_FAILED );
memcpy( p, buf, buflen );
diff --git a/tests/scripts/generate_code.pl b/tests/scripts/generate_code.pl
index 7b45d9c..17824c7 100755
--- a/tests/scripts/generate_code.pl
+++ b/tests/scripts/generate_code.pl
@@ -1,4 +1,49 @@
#!/usr/bin/env perl
+
+# generate_code.pl
+#
+# Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
+#
+# Purpose
+#
+# Generates the test suite code given inputs of the test suite directory that
+# contain the test suites, and the test suite file names for the test code and
+# test data.
+#
+# Usage: generate_code.pl <suite dir> <code file> <data file> [main code file]
+#
+# Structure of files
+#
+# - main code file - 'main_test.function'
+# Template file that contains the main() function for the test suite,
+# test dispatch code as well as support functions. It contains the
+# following symbols which are substituted by this script during
+# processing:
+# TEST_FILENAME
+# SUITE_PRE_DEP
+# MAPPING_CODE
+# FUNCTION CODE
+# SUITE_POST_DEP
+# DEP_CHECK_CODE
+# DISPATCH_FUNCTION
+#
+# - common helper code file - 'helpers.function'
+# Common helper functions
+#
+# - test suite code file - file name in the form 'test_suite_xxx.function'
+# Code file that contains the actual test cases. The file contains a
+# series of code sequences delimited by the following:
+# BEGIN_HEADER / END_HEADER - list of headers files
+# BEGIN_SUITE_HELPERS / END_SUITE_HELPERS - helper functions common to
+# the test suite
+# BEGIN_CASE / END_CASE - the test cases in the test suite. Each test
+# case contains at least one function that is used to create the
+# dispatch code.
+#
+# - test data file - file name in the form 'test_suite_xxxx.data'
+# The test case parameters to to be used in execution of the test. The
+# file name is used to replace the symbol 'TEST_FILENAME' in the main
+# code file above.
#
# A test data file consists of a sequence of paragraphs separated by
# a single empty line. Line breaks may be in Unix (LF) or Windows (CRLF)
@@ -29,15 +74,16 @@
my $data_name = shift or die "Missing data name";
my $test_main_file = do { my $arg = shift; defined($arg) ? $arg : $suite_dir."/main_test.function" };
my $test_file = $data_name.".c";
-my $test_helper_file = $suite_dir."/helpers.function";
+my $test_common_helper_file = $suite_dir."/helpers.function";
my $test_case_file = $suite_dir."/".$suite_name.".function";
my $test_case_data = $suite_dir."/".$data_name.".data";
my $line_separator = $/;
undef $/;
-open(TEST_HELPERS, "$test_helper_file") or die "Opening test helpers '$test_helper_file': $!";
-my $test_helpers = <TEST_HELPERS>;
+open(TEST_HELPERS, "$test_common_helper_file") or die "Opening test helpers
+'$test_common_helper_file': $!";
+my $test_common_helpers = <TEST_HELPERS>;
close(TEST_HELPERS);
open(TEST_MAIN, "$test_main_file") or die "Opening test main '$test_main_file': $!";
@@ -54,6 +100,7 @@
my ( $suite_header ) = $test_cases =~ /\/\* BEGIN_HEADER \*\/\n(.*?)\n\/\* END_HEADER \*\//s;
my ( $suite_defines ) = $test_cases =~ /\/\* BEGIN_DEPENDENCIES\n \* (.*?)\n \* END_DEPENDENCIES/s;
+my ( $suite_helpers ) = $test_cases =~ /\/\* BEGIN_SUITE_HELPERS \*\/\n(.*?)\n\/\* END_SUITE_HELPERS \*\//s;
my $requirements;
if ($suite_defines =~ /^depends_on:/)
@@ -81,16 +128,43 @@
open(TEST_FILE, ">$test_file") or die "Opening destination file '$test_file': $!";
print TEST_FILE << "END";
+/*
+ * *** THIS FILE HAS BEEN MACHINE GENERATED ***
+ *
+ * This file has been machine generated using the script: $0
+ *
+ * Test file : $test_file
+ *
+ * The following files were used to create this file.
+ *
+ * Main code file : $test_main_file
+ * Helper file : $test_common_helper_file
+ * Test suite file : $test_case_file
+ * Test suite data : $test_case_data
+ *
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
#if !defined(MBEDTLS_CONFIG_FILE)
#include <mbedtls/config.h>
#else
#include MBEDTLS_CONFIG_FILE
#endif
-$test_helpers
+
+/*----------------------------------------------------------------------------*/
+/* Common helper code */
+
+$test_common_helpers
+
+
+/*----------------------------------------------------------------------------*/
+/* Test Suite Code */
$suite_pre_code
$suite_header
+$suite_helpers
$suite_post_code
END
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index 5c20f81..cad7072 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -1,3 +1,6 @@
+/*----------------------------------------------------------------------------*/
+/* Headers */
+
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
@@ -12,6 +15,10 @@
#define mbedtls_snprintf snprintf
#endif
+#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
+#include "mbedtls/memory_buffer_alloc.h"
+#endif
+
#ifdef _MSC_VER
#include <basetsd.h>
typedef UINT32 uint32_t;
@@ -25,6 +32,25 @@
#include <stdlib.h>
#include <string.h>
+
+/*----------------------------------------------------------------------------*/
+/* Global variables */
+
+static int test_errors = 0;
+
+
+/*----------------------------------------------------------------------------*/
+/* Macros */
+
+#define TEST_ASSERT( TEST ) \
+ do { \
+ if( ! (TEST) ) \
+ { \
+ test_fail( #TEST ); \
+ goto exit; \
+ } \
+ } while( 0 )
+
#define assert(a) if( !( a ) ) \
{ \
mbedtls_fprintf( stderr, "Assertion Failed at %s:%d - %s\n", \
@@ -66,11 +92,14 @@
#define ENTROPY_HAVE_STRONG
#endif
+/*----------------------------------------------------------------------------*/
+/* Helper Functions */
+
static int unhexify( unsigned char *obuf, const char *ibuf )
{
unsigned char c, c2;
int len = strlen( ibuf ) / 2;
- assert( strlen( ibuf ) % 2 == 0 ); // must be even number of bytes
+ assert( strlen( ibuf ) % 2 == 0 ); /* must be even number of bytes */
while( *ibuf != 0 )
{
@@ -311,3 +340,12 @@
return( 0 );
}
+
+static void test_fail( const char *test )
+{
+ test_errors++;
+ if( test_errors == 1 )
+ mbedtls_printf( "FAILED\n" );
+ mbedtls_printf( " %s\n", test );
+}
+
diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function
index db968e1..7fee3d8 100644
--- a/tests/suites/main_test.function
+++ b/tests/suites/main_test.function
@@ -1,44 +1,6 @@
-#include <string.h>
-
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdio.h>
-#include <stdlib.h>
-#define mbedtls_exit exit
-#define mbedtls_free free
-#define mbedtls_calloc calloc
-#define mbedtls_fprintf fprintf
-#define mbedtls_printf printf
-#define mbedtls_snprintf snprintf
-#endif
-
-#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
-#include "mbedtls/memory_buffer_alloc.h"
-#endif
-
-static int test_errors = 0;
-
SUITE_PRE_DEP
#define TEST_SUITE_ACTIVE
-static void test_fail( const char *test )
-{
- test_errors++;
- if( test_errors == 1 )
- mbedtls_printf( "FAILED\n" );
- mbedtls_printf( " %s\n", test );
-}
-
-#define TEST_ASSERT( TEST ) \
- do { \
- if( ! (TEST) ) \
- { \
- test_fail( #TEST ); \
- goto exit; \
- } \
- } while( 0 )
-
int verify_string( char **str )
{
if( (*str)[0] != '"' ||
@@ -101,9 +63,17 @@
return( -1 );
}
+
+/*----------------------------------------------------------------------------*/
+/* Test Case code */
+
FUNCTION_CODE
SUITE_POST_DEP
+
+/*----------------------------------------------------------------------------*/
+/* Test dispatch code */
+
int dep_check( char *str )
{
if( str == NULL )
@@ -133,6 +103,10 @@
return( ret );
}
+
+/*----------------------------------------------------------------------------*/
+/* Main Test code */
+
/** Retrieve one input line into buf, which must have room for len
* bytes. The trailing line break (if any) is stripped from the result.
* Lines beginning with the character '#' are skipped. Lines that are
@@ -191,7 +165,7 @@
p++;
}
- // Replace newlines, question marks and colons in strings
+ /* Replace newlines, question marks and colons in strings */
for( i = 0; i < cnt; i++ )
{
p = params[i];
diff --git a/tests/suites/test_suite_memory_buffer_alloc.data b/tests/suites/test_suite_memory_buffer_alloc.data
index a0b0460..d59f113 100644
--- a/tests/suites/test_suite_memory_buffer_alloc.data
+++ b/tests/suites/test_suite_memory_buffer_alloc.data
@@ -1,2 +1,23 @@
Memory buffer alloc self test
mbedtls_memory_buffer_alloc_self_test:
+
+Memory buffer alloc - free in middle, alloc at end
+memory_buffer_alloc_free_alloc:100:100:100:0:0:1:0:0:200:0
+
+Memory buffer alloc - free in middle, realloc
+memory_buffer_alloc_free_alloc:100:100:100:0:0:1:0:0:100:0
+
+Memory buffer alloc - free in middle, merge, realloc
+memory_buffer_alloc_free_alloc:100:100:100:100:0:1:1:0:201:0
+
+Memory buffer alloc - free at end, merge, realloc
+memory_buffer_alloc_free_alloc:100:64:100:100:0:0:0:1:200:0
+
+Memory buffer alloc - Out of Memory test
+memory_buffer_alloc_oom_test:
+
+Memory buffer small buffer
+memory_buffer_small_buffer:
+
+Memory buffer underalloc
+memory_buffer_underalloc:
diff --git a/tests/suites/test_suite_memory_buffer_alloc.function b/tests/suites/test_suite_memory_buffer_alloc.function
index 59b0643..d0484cd 100644
--- a/tests/suites/test_suite_memory_buffer_alloc.function
+++ b/tests/suites/test_suite_memory_buffer_alloc.function
@@ -1,6 +1,7 @@
/* BEGIN_HEADER */
#include "mbedtls/memory_buffer_alloc.h"
#define TEST_SUITE_MEMORY_BUFFER_ALLOC
+
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@@ -8,9 +9,254 @@
* END_DEPENDENCIES
*/
+/* BEGIN_SUITE_HELPERS */
+static int check_pointer( void *p )
+{
+ if( p == NULL )
+ return( -1 );
+
+ if( (size_t) p % MBEDTLS_MEMORY_ALIGN_MULTIPLE != 0 )
+ return( -1 );
+
+ return( 0 );
+}
+/* END_SUITE_HELPERS */
+
/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
void mbedtls_memory_buffer_alloc_self_test( )
{
TEST_ASSERT( mbedtls_memory_buffer_alloc_self_test( 0 ) == 0 );
}
/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_MEMORY_DEBUG */
+void memory_buffer_alloc_free_alloc( int a_bytes, int b_bytes, int c_bytes,
+ int d_bytes,
+ int free_a, int free_b, int free_c,
+ int free_d,
+ int e_bytes, int f_bytes )
+{
+ unsigned char buf[1024];
+ unsigned char *ptr_a = NULL, *ptr_b = NULL, *ptr_c = NULL, *ptr_d = NULL,
+ *ptr_e = NULL, *ptr_f = NULL;
+
+ size_t reported_blocks;
+ size_t allocated_bytes = 0, reported_bytes;
+
+ mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
+
+ mbedtls_memory_buffer_set_verify( MBEDTLS_MEMORY_VERIFY_ALWAYS );
+
+ if( a_bytes > 0 )
+ {
+ ptr_a = mbedtls_calloc( a_bytes, sizeof(char) );
+ TEST_ASSERT( check_pointer( ptr_a ) == 0 );
+
+ allocated_bytes += a_bytes * sizeof(char);
+ }
+
+ if( b_bytes > 0 )
+ {
+ ptr_b = mbedtls_calloc( b_bytes, sizeof(char) );
+ TEST_ASSERT( check_pointer( ptr_b ) == 0 );
+
+ allocated_bytes += b_bytes * sizeof(char);
+ }
+
+ if( c_bytes > 0 )
+ {
+ ptr_c = mbedtls_calloc( c_bytes, sizeof(char) );
+ TEST_ASSERT( check_pointer( ptr_c ) == 0 );
+
+ allocated_bytes += c_bytes * sizeof(char);
+ }
+
+ if( d_bytes > 0 )
+ {
+ ptr_d = mbedtls_calloc( d_bytes, sizeof(char) );
+ TEST_ASSERT( check_pointer( ptr_d ) == 0 );
+
+ allocated_bytes += d_bytes * sizeof(char);
+ }
+
+ mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
+ TEST_ASSERT( reported_bytes == allocated_bytes );
+
+ if( free_a )
+ {
+ mbedtls_free( ptr_a );
+ ptr_a = NULL;
+ TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+
+ allocated_bytes -= a_bytes * sizeof(char);
+ }
+
+ if( free_b )
+ {
+ mbedtls_free( ptr_b );
+ ptr_b = NULL;
+ TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+
+ allocated_bytes -= b_bytes * sizeof(char);
+ }
+
+ if( free_c )
+ {
+ mbedtls_free( ptr_c );
+ ptr_c = NULL;
+ TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+
+ allocated_bytes -= c_bytes * sizeof(char);
+ }
+
+ if( free_d )
+ {
+ mbedtls_free( ptr_d );
+ ptr_d = NULL;
+ TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+
+ allocated_bytes -= d_bytes * sizeof(char);
+ }
+
+ mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
+ TEST_ASSERT( reported_bytes == allocated_bytes );
+
+ if( e_bytes > 0 )
+ {
+ ptr_e = mbedtls_calloc( e_bytes, sizeof(char) );
+ TEST_ASSERT( check_pointer( ptr_e ) == 0 );
+ }
+
+ if( f_bytes > 0 )
+ {
+ ptr_f = mbedtls_calloc( f_bytes, sizeof(char) );
+ TEST_ASSERT( check_pointer( ptr_f ) == 0 );
+ }
+
+ /* Once blocks are reallocated, the block allocated to the memory request
+ * may be bigger than the request itself, which is indicated by the reported
+ * bytes, and makes it hard to know what the reported size will be, so
+ * we don't check the size after blocks have been reallocated. */
+
+ if( ptr_a != NULL )
+ {
+ mbedtls_free( ptr_a );
+ ptr_a = NULL;
+ TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+ }
+
+ if( ptr_b != NULL )
+ {
+ mbedtls_free( ptr_b );
+ ptr_b = NULL;
+ TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+ }
+
+ if( ptr_c != NULL )
+ {
+ mbedtls_free( ptr_c );
+ ptr_c = NULL;
+ TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+ }
+
+ if( ptr_d != NULL )
+ {
+ mbedtls_free( ptr_d );
+ ptr_d = NULL;
+ TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+ }
+
+ if( ptr_e != NULL )
+ {
+ mbedtls_free( ptr_e );
+ ptr_e = NULL;
+ TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+ }
+
+ if( ptr_f != NULL )
+ {
+ mbedtls_free( ptr_f );
+ ptr_f = NULL;
+ }
+
+ mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
+ TEST_ASSERT( reported_bytes == 0 );
+
+ TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+
+exit:
+ mbedtls_memory_buffer_alloc_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_MEMORY_DEBUG */
+void memory_buffer_alloc_oom_test()
+{
+ unsigned char buf[1024];
+ unsigned char *ptr_a = NULL, *ptr_b = NULL, *ptr_c = NULL;
+ size_t reported_blocks, reported_bytes;
+
+ (void)ptr_c;
+
+ mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
+
+ mbedtls_memory_buffer_set_verify( MBEDTLS_MEMORY_VERIFY_ALWAYS );
+
+ ptr_a = mbedtls_calloc( 432, sizeof(char) );
+ TEST_ASSERT( check_pointer( ptr_a ) == 0 );
+
+ ptr_b = mbedtls_calloc( 432, sizeof(char) );
+ TEST_ASSERT( check_pointer( ptr_b ) == 0 );
+
+ ptr_c = mbedtls_calloc( 431, sizeof(char) );
+ TEST_ASSERT( ptr_c == NULL );
+
+ mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
+ TEST_ASSERT( reported_bytes >= 864 && reported_bytes <= sizeof(buf) );
+
+ mbedtls_free( ptr_a );
+ ptr_a = NULL;
+ TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+
+ mbedtls_free( ptr_b );
+ ptr_b = NULL;
+ TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+
+ mbedtls_memory_buffer_alloc_cur_get( &reported_bytes, &reported_blocks );
+ TEST_ASSERT( reported_bytes == 0 );
+
+ TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+
+exit:
+ mbedtls_memory_buffer_alloc_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_MEMORY_DEBUG */
+void memory_buffer_small_buffer( )
+{
+ unsigned char buf[1];
+
+ mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
+ TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() != 0 );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_MEMORY_DEBUG */
+void memory_buffer_underalloc( )
+{
+ unsigned char buf[100];
+ size_t i;
+
+ mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
+ for( i = 1; i < MBEDTLS_MEMORY_ALIGN_MULTIPLE; i++ )
+ {
+ TEST_ASSERT( mbedtls_calloc( 1,
+ (size_t)-( MBEDTLS_MEMORY_ALIGN_MULTIPLE - i ) ) == NULL );
+ TEST_ASSERT( mbedtls_memory_buffer_alloc_verify() == 0 );
+ }
+
+exit:
+ mbedtls_memory_buffer_alloc_free();
+}
+/* END_CASE */