Add a calloc self-test

Add a very basic test of calloc to the selftest program. The selftest
program acts in its capacity as a platform compatibility checker rather
than in its capacity as a test of the library.

The main objective is to report whether calloc returns NULL for a size
of 0. Also observe whether a free/alloc sequence returns the address
that was just freed and whether a size overflow is properly detected.
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index 72a3734..f3eb104 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -61,6 +61,8 @@
 #else
 #include <stdio.h>
 #include <stdlib.h>
+#define mbedtls_calloc     calloc
+#define mbedtls_free       free
 #define mbedtls_printf     printf
 #define mbedtls_snprintf   snprintf
 #define mbedtls_exit       exit
@@ -72,6 +74,87 @@
 #include "mbedtls/memory_buffer_alloc.h"
 #endif
 
+
+#if defined MBEDTLS_SELF_TEST
+/* Sanity check for malloc. This is not expected to fail, and is rather
+ * intended to display potentially useful information about the platform,
+ * in particular the behavior of malloc(0). */
+static int calloc_self_test( int verbose )
+{
+    int failures = 0;
+    void *empty1 = mbedtls_calloc( 0, 1 );
+    void *empty2 = mbedtls_calloc( 0, 1 );
+    void *buffer1 = mbedtls_calloc( 1, 1 );
+    void *buffer2 = mbedtls_calloc( 1, 1 );
+    uintptr_t old_buffer1;
+
+    if( empty1 == NULL && empty2 == NULL )
+    {
+        if( verbose )
+            mbedtls_printf( "  CALLOC(0): passed (NULL)\n" );
+    }
+    else if( empty1 == NULL || empty2 == NULL )
+    {
+        if( verbose )
+            mbedtls_printf( "  CALLOC(0): failed (mix of NULL and non-NULL)\n" );
+        ++failures;
+    }
+    else if( empty1 == empty2 )
+    {
+        if( verbose )
+            mbedtls_printf( "  CALLOC(0): passed (same non-null)\n" );
+    }
+    else
+    {
+        if( verbose )
+            mbedtls_printf( "  CALLOC(0): passed (distinct non-null)\n" );
+    }
+
+    if( buffer1 == NULL || buffer2 == NULL )
+    {
+        if( verbose )
+            mbedtls_printf( "  CALLOC(1): failed (NULL)\n" );
+        ++failures;
+    }
+    else if( buffer1 == buffer2 )
+    {
+        if( verbose )
+            mbedtls_printf( "  CALLOC(1): failed (same buffer twice)\n" );
+        ++failures;
+    }
+    else
+    {
+        if( verbose )
+            mbedtls_printf( "  CALLOC(1): passed\n" );
+    }
+
+    old_buffer1 = (uintptr_t) buffer1;
+    mbedtls_free( buffer1 );
+    buffer1 = mbedtls_calloc( 1, 1 );
+    if( buffer1 == NULL )
+    {
+        if( verbose )
+            mbedtls_printf( "  CALLOC(1 again): failed (NULL)\n" );
+        ++failures;
+    }
+    else
+    {
+        if( verbose )
+            mbedtls_printf( "  CALLOC(1 again): passed (%s address)\n",
+                            (uintptr_t) old_buffer1 == (uintptr_t) buffer1 ?
+                            "same" : "different" );
+    }
+
+    if( verbose )
+        mbedtls_printf( "\n" );
+    mbedtls_free( empty1 );
+    mbedtls_free( empty2 );
+    mbedtls_free( buffer1 );
+    mbedtls_free( buffer2 );
+    return( failures );
+}
+#endif /* MBEDTLS_SELF_TEST */
+
 static int test_snprintf( size_t n, const char ref_buf[10], int ref_ret )
 {
     int ret;
@@ -168,6 +251,7 @@
 
 const selftest_t selftests[] =
 {
+    {"calloc", calloc_self_test},
 #if defined(MBEDTLS_MD2_C)
     {"md2", mbedtls_md2_self_test},
 #endif