- Split current md_starts() and md_hmac_starts() functionality into separate md_init_ctx() for allocating the context and the existing starts() functions to initialize the message digest for use.

diff --git a/include/polarssl/md.h b/include/polarssl/md.h
index 05f6eb0..76c480c 100644
--- a/include/polarssl/md.h
+++ b/include/polarssl/md.h
@@ -31,7 +31,8 @@
 #define POLARSSL_MD_H
 
 typedef enum {
-    POLARSSL_MD_MD2=0,
+    POLARSSL_MD_NONE=0,
+    POLARSSL_MD_MD2,
     POLARSSL_MD_MD4,
     POLARSSL_MD_MD5,
     POLARSSL_MD_SHA1,
@@ -149,6 +150,31 @@
 const md_info_t *md_info_from_type( md_type_t md_type );
 
 /**
+ * \brief          Initialises and fills the message digest context structure with
+ *                 the appropriate values.
+ *
+ * \param ctx      context to initialise. May not be NULL. The
+ *                 digest-specific context (ctx->md_ctx) must be NULL. It will
+ *                 be allocated, and must be freed using md_free_ctx() later.
+ * \param md_info  message digest to use.
+ *
+ * \returns        \c 0 on success, \c 1 on parameter failure, \c 2 if
+ *                 allocation of the cipher-specific context failed.
+ */
+int md_init_ctx( md_context_t *ctx, const md_info_t *md_info );
+
+/**
+ * \brief          Free the message-specific context of ctx. Freeing ctx itself
+ *                 remains the responsibility of the caller.
+ *
+ * \param ctx      Free the -specific context
+ * \param output   Generic message digest checksum result
+ *
+ * \returns        0 on success, 1 if parameter verification fails.
+ */
+int md_free_ctx( md_context_t *ctx );
+
+/**
  * \brief           Returns the size of the message digest output.
  *
  * \param md_info   message digest info
@@ -185,16 +211,13 @@
 }
 
 /**
- * \brief          Generic message digest context setup.
+ * \brief          Set-up the given context for a new message digest
  *
- * \param md_info  message digest info
- * \param ctx      generic message digest context. May not be NULL. The
- *                 digest-specific context (ctx->md_ctx) must be NULL. It will
- *                 be allocated, and must be freed using md_free() later.
+ * \param ctx      generic message digest context.
  *
  * \returns        0 on success, 1 if parameter verification fails.
  */
-int md_starts( const md_info_t *md_info, md_context_t *ctx );
+int md_starts( md_context_t *ctx );
 
 /**
  * \brief          Generic message digest process buffer
@@ -218,17 +241,6 @@
 int md_finish( md_context_t *ctx, unsigned char *output );
 
 /**
- * \brief          Free the message-specific context of ctx. Freeing ctx itself
- *                 remains the responsibility of the caller.
- *
- * \param ctx      Free the -specific context
- * \param output   Generic message digest checksum result
- *
- * \returns        0 on success, 1 if parameter verification fails.
- */
-int md_free_ctx( md_context_t *ctx );
-
-/**
  * \brief          Output = message_digest( input buffer )
  *
  * \param md_info  message digest info
@@ -256,15 +268,13 @@
 /**
  * \brief          Generic HMAC context setup
  *
- * \param md_info  message digest info
  * \param ctx      HMAC context to be initialized
  * \param key      HMAC secret key
  * \param keylen   length of the HMAC key
  *
  * \returns        0 on success, 1 if parameter verification fails.
  */
-int md_hmac_starts( const md_info_t *md_info, md_context_t *ctx,
-                    const unsigned char *key, int keylen );
+int md_hmac_starts( md_context_t *ctx, const unsigned char *key, int keylen );
 
 /**
  * \brief          Generic HMAC process buffer
diff --git a/library/md.c b/library/md.c
index 9aa7b38..6348271 100644
--- a/library/md.c
+++ b/library/md.c
@@ -147,7 +147,7 @@
     }
 }
 
-int md_starts( const md_info_t *md_info, md_context_t *ctx )
+int md_init_ctx( md_context_t *ctx, const md_info_t *md_info )
 {
     if( md_info == NULL )
         return 1;
@@ -165,6 +165,27 @@
     return 0;
 }
 
+int md_free_ctx( md_context_t *ctx )
+{
+    if( ctx == NULL || ctx->md_info == NULL )
+        return 1;
+
+    ctx->md_info->ctx_free_func( ctx->md_ctx );
+    ctx->md_ctx = NULL;
+
+    return 0;
+}
+
+int md_starts( md_context_t *ctx )
+{
+    if( ctx == NULL || ctx->md_info == NULL )
+        return 1;
+
+    ctx->md_info->starts_func( ctx->md_ctx );
+
+    return 0;
+}
+
 int md_update( md_context_t *ctx, const unsigned char *input, int ilen )
 {
     if( ctx == NULL || ctx->md_info == NULL )
@@ -185,16 +206,6 @@
     return 0;
 }
 
-int md_free_ctx( md_context_t *ctx )
-{
-    if( ctx == NULL || ctx->md_info == NULL )
-        return 1;
-
-    ctx->md_info->ctx_free_func( ctx->md_ctx );
-
-    return 0;
-}
-
 int md( const md_info_t *md_info, const unsigned char *input, int ilen,
             unsigned char *output )
 {
@@ -214,21 +225,12 @@
     return md_info->file_func( path, output );
 }
 
-int md_hmac_starts( const md_info_t *md_info, md_context_t *ctx,
-                        const unsigned char *key, int keylen )
+int md_hmac_starts( md_context_t *ctx, const unsigned char *key, int keylen )
 {
-    if(md_info == NULL )
+    if( ctx == NULL || ctx->md_info == NULL )
         return 1;
 
-    if( ctx == NULL || ctx->md_ctx != NULL )
-        return 1;
-
-    if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
-        return 1;
-
-    ctx->md_info = md_info;
-
-    md_info->hmac_starts_func( ctx->md_ctx, key, keylen);
+    ctx->md_info->hmac_starts_func( ctx->md_ctx, key, keylen);
 
     return 0;
 }
diff --git a/tests/suites/test_suite_md.function b/tests/suites/test_suite_md.function
index 82f82b1..486eacd 100644
--- a/tests/suites/test_suite_md.function
+++ b/tests/suites/test_suite_md.function
@@ -85,8 +85,9 @@
     strncpy( (char *) md_name, {text_md_name}, 100 );
     md_info = md_info_from_string(md_name);
     TEST_ASSERT( md_info != NULL );
+    TEST_ASSERT ( 0 == md_init_ctx( &ctx, md_info ) );
 
-    TEST_ASSERT ( 0 == md_starts( md_info, &ctx ) );
+    TEST_ASSERT ( 0 == md_starts( &ctx ) );
     TEST_ASSERT ( ctx.md_ctx != NULL );
     TEST_ASSERT ( 0 == md_update( &ctx, src_str, strlen( (char *) src_str ) ) );
     TEST_ASSERT ( 0 == md_finish( &ctx, output ) );
@@ -117,10 +118,11 @@
     strncpy( (char *) md_name, {text_md_name}, 100 );
     md_info = md_info_from_string(md_name);
     TEST_ASSERT( md_info != NULL );
+    TEST_ASSERT ( 0 == md_init_ctx( &ctx, md_info ) );
 
     src_len = unhexify( src_str, {hex_src_string} );
     
-    TEST_ASSERT ( 0 == md_starts( md_info, &ctx ) );
+    TEST_ASSERT ( 0 == md_starts( &ctx ) );
     TEST_ASSERT ( ctx.md_ctx != NULL );
     TEST_ASSERT ( 0 == md_update( &ctx, src_str, src_len ) );
     TEST_ASSERT ( 0 == md_finish( &ctx, output ) );
@@ -184,11 +186,12 @@
     strncpy( (char *) md_name, {text_md_name}, 100 );
     md_info = md_info_from_string( md_name );
     TEST_ASSERT( md_info != NULL );
+    TEST_ASSERT ( 0 == md_init_ctx( &ctx, md_info ) );
 
     key_len = unhexify( key_str, {hex_key_string} );
     src_len = unhexify( src_str, {hex_src_string} );
 
-    TEST_ASSERT ( 0 == md_hmac_starts( md_info, &ctx, key_str, key_len ) );
+    TEST_ASSERT ( 0 == md_hmac_starts( &ctx, key_str, key_len ) );
     TEST_ASSERT ( ctx.md_ctx != NULL );
     TEST_ASSERT ( 0 == md_hmac_update( &ctx, src_str, src_len ) );
     TEST_ASSERT ( 0 == md_hmac_finish( &ctx, output ) );