MD: Embed digest context structure into MD wrapper context
diff --git a/include/mbedtls/md.h b/include/mbedtls/md.h
index 2776568..942d1f5 100644
--- a/include/mbedtls/md.h
+++ b/include/mbedtls/md.h
@@ -108,6 +108,8 @@
 
 #endif /* !MBEDTLS_MD_SINGLE_HASH */
 
+#include "md_internal.h"
+
 /**
  * The generic message-digest context.
  */
@@ -118,11 +120,20 @@
     mbedtls_md_handle_t md_info;
 #endif
 
+#if !defined(MBEDTLS_MD_SINGLE_HASH)
     /** The digest-specific context. */
     void *md_ctx;
 
     /** The HMAC part of the context. */
     void *hmac_ctx;
+#else
+    unsigned char md_ctx[ sizeof( MBEDTLS_MD_INFO_CTX_TYPE(
+                                      MBEDTLS_MD_SINGLE_HASH ) ) ];
+
+    unsigned char hmac_ctx[ 2 * MBEDTLS_MD_INFO_BLOCKSIZE(
+                                      MBEDTLS_MD_SINGLE_HASH ) ];
+
+#endif /* MBEDTLS_MD_SINGLE_HASH */
 } mbedtls_md_context_t;
 
 #if !defined(MBEDTLS_MD_SINGLE_HASH)
@@ -140,8 +151,6 @@
 }
 #endif /* !MBEDTLS_MD_SINGLE_HASH */
 
-#include "md_internal.h"
-
 /**
  * \brief           This function returns the list of digests supported by the
  *                  generic digest module.
diff --git a/library/md.c b/library/md.c
index 5e9c5b4..accf301 100644
--- a/library/md.c
+++ b/library/md.c
@@ -388,6 +388,11 @@
 void mbedtls_md_init( mbedtls_md_context_t *ctx )
 {
     memset( ctx, 0, sizeof( mbedtls_md_context_t ) );
+
+#if defined(MBEDTLS_MD_SINGLE_HASH)
+    mbedtls_md_info_init( mbedtls_md_get_handle( ctx ),
+                          ctx->md_ctx );
+#endif
 }
 
 void mbedtls_md_free( mbedtls_md_context_t *ctx )
@@ -395,6 +400,7 @@
     if( ctx == NULL || mbedtls_md_get_handle( ctx ) == MBEDTLS_MD_INVALID_HANDLE )
         return;
 
+#if !defined(MBEDTLS_MD_SINGLE_HASH)
     if( ctx->md_ctx != NULL )
     {
         mbedtls_md_info_ctx_free( mbedtls_md_get_handle( ctx ), ctx->md_ctx );
@@ -406,6 +412,7 @@
             2 * mbedtls_md_info_block_size( mbedtls_md_get_handle( ctx ) ) );
         mbedtls_free( ctx->hmac_ctx );
     }
+#endif /* MBEDTLS_MD_SINGLE_HASH */
 
     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
 }
@@ -437,6 +444,7 @@
     if( md_info == MBEDTLS_MD_INVALID_HANDLE || ctx == NULL )
         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
 
+#if !defined(MBEDTLS_MD_SINGLE_HASH)
     ctx->md_ctx = mbedtls_md_info_ctx_alloc( md_info );
     if( ctx->md_ctx == NULL )
         return( MBEDTLS_ERR_MD_ALLOC_FAILED );
@@ -452,8 +460,9 @@
         }
     }
 
-#if !defined(MBEDTLS_MD_SINGLE_HASH)
     ctx->md_info = md_info;
+#else
+    ((void) hmac);
 #endif
 
     return( 0 );