md: improve parameter validation

Provide consistent checks for input and output parameters
Improve documentation
Expand the md test suite to test more cases
diff --git a/include/mbedtls/md.h b/include/mbedtls/md.h
index e860de2..446eb32 100644
--- a/include/mbedtls/md.h
+++ b/include/mbedtls/md.h
@@ -109,7 +109,8 @@
  * \brief           This function returns the message-digest information
  *                  associated with the given digest name.
  *
- * \param md_name   The name of the digest to search for. This must not be \c NULL.
+ * \param md_name   The name of the digest to search for. This must point to
+ *                  a NULL-terminated string.
  *
  * \return          The message-digest information associated with \p md_name.
  * \return          NULL if the associated message-digest information is not found.
@@ -120,7 +121,7 @@
  * \brief           This function returns the message-digest information
  *                  associated with the given digest type.
  *
- * \param md_type   The type of digest to search for. This must not be \c NULL.
+ * \param md_type   The type of digest to search for.
  *
  * \return          The message-digest information associated with \p md_type.
  * \return          NULL if the associated message-digest information is not found.
@@ -133,7 +134,10 @@
  *
  *                  This function should always be called first. It prepares the
  *                  context for mbedtls_md_setup() for binding it to a
- *                  message-digest algorithm. The \p ctx must not be \c NULL.
+ *                  message-digest algorithm.
+ *
+ * \param ctx       The context to initialize. This must not be \c NULL.
+ *
  */
 void mbedtls_md_init( mbedtls_md_context_t *ctx );
 
@@ -148,7 +152,7 @@
  *                  Calling this function if you have previously
  *                  called mbedtls_md_init() and nothing else is optional.
  *                  You must not call this function if you have not called
- *                  mbedtls_md_init(). The \p ctx must not be \c NULL.
+ *                  mbedtls_md_init().
  */
 void mbedtls_md_free( mbedtls_md_context_t *ctx );
 
@@ -280,7 +284,9 @@
  *                  Afterwards, call mbedtls_md_finish().
  *
  * \param ctx       The generic message-digest context.
- * \param input     The buffer holding the input data. This must not be \c NULL.
+ * \param input     The buffer holding the input data. This must be a readable
+ *                  buffer of length \p ilen Bytes. It may be \c NULL if
+ *                  \p ilen is zero.
  * \param ilen      The length of the input data.
  *
  * \return          \c 0 on success.
@@ -302,7 +308,9 @@
  *
  * \param ctx       The generic message-digest context.
  * \param output    The buffer for the generic message-digest checksum result.
- *                  This must not be \c NULL.
+ *                  This must be a writable buffer large enough to hold the
+ *                  message-digest. You may use mbedtls_md_get_size() to obtain
+ *                  the message-digest size for a particular algorithm.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
@@ -320,10 +328,14 @@
  *
  * \param md_info  The information structure of the message-digest algorithm
  *                 to use. This must not be \c NULL.
- * \param input    The buffer holding the data.
+ * \param input    The buffer holding the data. This must be a readable
+ *                 buffer of length \p ilen Bytes. It may be \c NULL if
+ *                 \p ilen is zero.
  * \param ilen     The length of the input data.
  * \param output   The generic message-digest checksum result.
- *                 This must not be \c NULL.
+ *                 This must be a writable buffer large enough to hold the
+ *                 message-digest. You may use mbedtls_md_get_size() to obtain
+ *                 the message-digest size for a particular algorithm.
  *
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
@@ -342,9 +354,11 @@
  *
  * \param md_info  The information structure of the message-digest algorithm
  *                 to use. This must not be \c NULL.
- * \param path     The input file name. This must not be \c NULL.
+ * \param path     The input file name. This must be a NULL-terminated string.
  * \param output   The generic message-digest checksum result.
- *                 This must not be \c NULL.
+ *                 This must be a writable buffer large enough to hold the
+ *                 message-digest. You may use mbedtls_md_get_size() to obtain
+ *                 the message-digest size for a particular algorithm.
  *
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_MD_FILE_IO_ERROR on an I/O error accessing
@@ -366,7 +380,9 @@
  *
  * \param ctx       The message digest context containing an embedded HMAC
  *                  context.
- * \param key       The HMAC secret key. This must not be \c NULL.
+ * \param key       The HMAC secret key. This must be a readable buffer of
+ *                  length \p keylen Bytes. It may be \c NULL if
+ *                  \p keylen is zero.
  * \param keylen    The length of the HMAC key in Bytes.
  *
  * \return          \c 0 on success.
@@ -388,7 +404,9 @@
  *
  * \param ctx       The message digest context containing an embedded HMAC
  *                  context.
- * \param input     The buffer holding the input data.
+ * \param input     The buffer holding the input data. This must be a readable
+ *                  buffer of length \p ilen Bytes. It may be \c NULL if
+ *                  \p ilen is zero.
  * \param ilen      The length of the input data.
  *
  * \return          \c 0 on success.
@@ -410,7 +428,10 @@
  *
  * \param ctx       The message digest context containing an embedded HMAC
  *                  context.
- * \param output    The generic HMAC checksum result. This must not be \c NULL.
+ * \param output    The generic HMAC checksum result. This must be a writable
+ *                  buffer large enough to hold the message-digest. You may
+ *                  use mbedtls_md_get_size() to obtain the message-digest
+ *                  size for a particular algorithm.
  *
  * \return          \c 0 on success.
  * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
@@ -447,11 +468,18 @@
  *
  * \param md_info  The information structure of the message-digest algorithm
  *                 to use. This must not be \c NULL.
- * \param key      The HMAC secret key. This must not be \c NULL.
+ * \param key      The HMAC secret key. This must be a readable buffer of
+ *                 length \p keylen Bytes. It may be \c NULL if
+ *                 \p keylen is zero.
  * \param keylen   The length of the HMAC secret key in Bytes.
- * \param input    The buffer holding the input data.
+ * \param input    The buffer holding the input data. This must be a readable
+ *                 buffer of length \p ilen Bytes. It may be \c NULL if
+ *                 \p ilen is zero.
  * \param ilen     The length of the input data.
- * \param output   The generic HMAC result. This must not be \c NULL.
+ * \param output   The generic HMAC result. This must be a writable
+ *                 buffer large enough to hold the message-digest. You may
+ *                 use mbedtls_md_get_size() to obtain the message-digest
+ *                 size for a particular algorithm.
  *
  * \return         \c 0 on success.
  * \return         #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
diff --git a/library/md.c b/library/md.c
index 821a5e8..df13ee1 100644
--- a/library/md.c
+++ b/library/md.c
@@ -49,11 +49,11 @@
 #include <stdio.h>
 #endif
 
-#define MBEDTLS_MD_VALIDATE_RET(cond) \
+#define MD_VALIDATE_RET(cond) \
         MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MD_BAD_INPUT_DATA )
-#define MBEDTLS_MD_VALIDATE_RET_NULL(cond) \
+#define MD_VALIDATE_RET_NULL(cond) \
         MBEDTLS_INTERNAL_VALIDATE_RET( cond, NULL )
-#define MBEDTLS_MD_VALIDATE(cond)    MBEDTLS_INTERNAL_VALIDATE( cond )
+#define MD_VALIDATE(cond)    MBEDTLS_INTERNAL_VALIDATE( cond )
 
 /*
  * Reminder: update profiles in x509_crt.c when adding a new hash!
@@ -100,7 +100,7 @@
 
 const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name )
 {
-    MBEDTLS_MD_VALIDATE_RET_NULL( md_name != NULL );
+    MD_VALIDATE_RET_NULL( md_name != NULL );
 
     /* Get the appropriate digest information */
 #if defined(MBEDTLS_MD2_C)
@@ -181,7 +181,7 @@
 
 void mbedtls_md_init( mbedtls_md_context_t *ctx )
 {
-    MBEDTLS_MD_VALIDATE( ctx != NULL );
+    MD_VALIDATE( ctx != NULL );
     memset( ctx, 0, sizeof( mbedtls_md_context_t ) );
 }
 
@@ -206,11 +206,11 @@
 int mbedtls_md_clone( mbedtls_md_context_t *dst,
                       const mbedtls_md_context_t *src )
 {
-    MBEDTLS_MD_VALIDATE_RET( dst != NULL );
-    MBEDTLS_MD_VALIDATE_RET( src != NULL );
-    MBEDTLS_MD_VALIDATE_RET( dst->md_info != NULL );
-    MBEDTLS_MD_VALIDATE_RET( src->md_info != NULL );
-    MBEDTLS_MD_VALIDATE_RET( dst->md_info == src->md_info );
+    MD_VALIDATE_RET( dst != NULL );
+    MD_VALIDATE_RET( src != NULL );
+    MD_VALIDATE_RET( dst->md_info != NULL );
+    MD_VALIDATE_RET( src->md_info != NULL );
+    MD_VALIDATE_RET( dst->md_info == src->md_info );
 
     dst->md_info->clone_func( dst->md_ctx, src->md_ctx );
 
@@ -226,8 +226,8 @@
 
 int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
 {
-    MBEDTLS_MD_VALIDATE_RET( md_info != NULL );
-    MBEDTLS_MD_VALIDATE_RET( ctx != NULL );
+    MD_VALIDATE_RET( md_info != NULL );
+    MD_VALIDATE_RET( ctx != NULL );
 
     if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
         return( MBEDTLS_ERR_MD_ALLOC_FAILED );
@@ -249,26 +249,26 @@
 
 int mbedtls_md_starts( mbedtls_md_context_t *ctx )
 {
-    MBEDTLS_MD_VALIDATE_RET( ctx != NULL );
-    MBEDTLS_MD_VALIDATE_RET( ctx->md_info != NULL );
+    MD_VALIDATE_RET( ctx != NULL );
+    MD_VALIDATE_RET( ctx->md_info != NULL );
 
     return( ctx->md_info->starts_func( ctx->md_ctx ) );
 }
 
 int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
 {
-    MBEDTLS_MD_VALIDATE_RET( ctx != NULL );
-    MBEDTLS_MD_VALIDATE_RET( ctx->md_info != NULL );
-    MBEDTLS_MD_VALIDATE_RET( input != NULL );
+    MD_VALIDATE_RET( ctx != NULL );
+    MD_VALIDATE_RET( ctx->md_info != NULL );
+    MD_VALIDATE_RET( ilen == 0 || input != NULL );
 
     return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
 }
 
 int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
 {
-    MBEDTLS_MD_VALIDATE_RET( ctx != NULL );
-    MBEDTLS_MD_VALIDATE_RET( ctx->md_info != NULL );
-    MBEDTLS_MD_VALIDATE_RET( output != NULL );
+    MD_VALIDATE_RET( ctx != NULL );
+    MD_VALIDATE_RET( ctx->md_info != NULL );
+    MD_VALIDATE_RET( output != NULL );
 
     return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
 }
@@ -276,8 +276,9 @@
 int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
             unsigned char *output )
 {
-    MBEDTLS_MD_VALIDATE_RET( md_info != NULL );
-    MBEDTLS_MD_VALIDATE_RET( output != NULL );
+    MD_VALIDATE_RET( md_info != NULL );
+    MD_VALIDATE_RET( ilen == 0 || input != NULL );
+    MD_VALIDATE_RET( output != NULL );
 
     return( md_info->digest_func( input, ilen, output ) );
 }
@@ -291,9 +292,9 @@
     mbedtls_md_context_t ctx;
     unsigned char buf[1024];
 
-    MBEDTLS_MD_VALIDATE_RET( md_info != NULL );
-    MBEDTLS_MD_VALIDATE_RET( path != NULL );
-    MBEDTLS_MD_VALIDATE_RET( output != NULL );
+    MD_VALIDATE_RET( md_info != NULL );
+    MD_VALIDATE_RET( path != NULL );
+    MD_VALIDATE_RET( output != NULL );
 
     if( ( f = fopen( path, "rb" ) ) == NULL )
         return( MBEDTLS_ERR_MD_FILE_IO_ERROR );
@@ -331,10 +332,10 @@
     unsigned char *ipad, *opad;
     size_t i;
 
-    MBEDTLS_MD_VALIDATE_RET( ctx != NULL );
-    MBEDTLS_MD_VALIDATE_RET( ctx->md_info  != NULL );
-    MBEDTLS_MD_VALIDATE_RET( ctx->hmac_ctx != NULL );
-    MBEDTLS_MD_VALIDATE_RET( key != NULL );
+    MD_VALIDATE_RET( ctx != NULL );
+    MD_VALIDATE_RET( ctx->md_info  != NULL );
+    MD_VALIDATE_RET( ctx->hmac_ctx != NULL );
+    MD_VALIDATE_RET( keylen == 0 || key != NULL );
 
     if( keylen > (size_t) ctx->md_info->block_size )
     {
@@ -375,9 +376,10 @@
 
 int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
 {
-    MBEDTLS_MD_VALIDATE_RET( ctx != NULL );
-    MBEDTLS_MD_VALIDATE_RET( ctx->hmac_ctx != NULL );
-    MBEDTLS_MD_VALIDATE_RET( ctx->md_info != NULL );
+    MD_VALIDATE_RET( ctx != NULL );
+    MD_VALIDATE_RET( ilen == 0 || input != NULL );
+    MD_VALIDATE_RET( ctx->hmac_ctx != NULL );
+    MD_VALIDATE_RET( ctx->md_info != NULL );
 
     return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
 }
@@ -388,10 +390,10 @@
     unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
     unsigned char *opad;
 
-    MBEDTLS_MD_VALIDATE_RET( ctx != NULL );
-    MBEDTLS_MD_VALIDATE_RET( ctx->hmac_ctx != NULL );
-    MBEDTLS_MD_VALIDATE_RET( ctx->md_info != NULL );
-    MBEDTLS_MD_VALIDATE_RET( output != NULL );
+    MD_VALIDATE_RET( ctx != NULL );
+    MD_VALIDATE_RET( ctx->hmac_ctx != NULL );
+    MD_VALIDATE_RET( ctx->md_info != NULL );
+    MD_VALIDATE_RET( output != NULL );
 
     opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
 
@@ -413,9 +415,9 @@
     int ret;
     unsigned char *ipad;
 
-    MBEDTLS_MD_VALIDATE_RET( ctx != NULL );
-    MBEDTLS_MD_VALIDATE_RET( ctx->hmac_ctx != NULL );
-    MBEDTLS_MD_VALIDATE_RET( ctx->md_info != NULL );
+    MD_VALIDATE_RET( ctx != NULL );
+    MD_VALIDATE_RET( ctx->hmac_ctx != NULL );
+    MD_VALIDATE_RET( ctx->md_info != NULL );
 
     ipad = (unsigned char *) ctx->hmac_ctx;
 
@@ -433,9 +435,10 @@
     mbedtls_md_context_t ctx;
     int ret;
 
-    MBEDTLS_MD_VALIDATE_RET( md_info != NULL );
-    MBEDTLS_MD_VALIDATE_RET( key != NULL );
-    MBEDTLS_MD_VALIDATE_RET( output != NULL );
+    MD_VALIDATE_RET( md_info != NULL );
+    MD_VALIDATE_RET( keylen == 0 || key != NULL );
+    MD_VALIDATE_RET( ilen == 0 || input != NULL );
+    MD_VALIDATE_RET( output != NULL );
 
     mbedtls_md_init( &ctx );
 
@@ -457,8 +460,9 @@
 
 int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
 {
-    MBEDTLS_MD_VALIDATE_RET( ctx != NULL );
-    MBEDTLS_MD_VALIDATE_RET( ctx->md_info != NULL );
+    MD_VALIDATE_RET( ctx != NULL );
+    MD_VALIDATE_RET( data != NULL );
+    MD_VALIDATE_RET( ctx->md_info != NULL );
 
     return( ctx->md_info->process_func( ctx->md_ctx, data ) );
 }
@@ -479,7 +483,7 @@
 
 const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info )
 {
-    MBEDTLS_MD_VALIDATE_RET_NULL( md_info != NULL );
+    MD_VALIDATE_RET_NULL( md_info != NULL );
 
     return md_info->name;
 }
diff --git a/tests/suites/test_suite_md.function b/tests/suites/test_suite_md.function
index 8a2e076..4294f87 100644
--- a/tests/suites/test_suite_md.function
+++ b/tests/suites/test_suite_md.function
@@ -43,51 +43,103 @@
 void md_null_args(  )
 {
     mbedtls_md_context_t ctx;
+    mbedtls_md_context_t good_ctx;
     const mbedtls_md_info_t *info = mbedtls_md_info_from_type( *( mbedtls_md_list() ) );
     unsigned char buf[1] = { 0 };
 
     mbedtls_md_init( &ctx );
+    mbedtls_md_init( &good_ctx );
+    TEST_ASSERT( 0 == mbedtls_md_setup( &good_ctx, info, 0 ) );
+	
+    TEST_INVALID_PARAM_RET( 0,
+                            mbedtls_md_get_size( NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_MD_NONE,
+                            mbedtls_md_get_type( NULL ) );
+    TEST_INVALID_PARAM_RET( NULL,
+                            mbedtls_md_get_name( NULL ) );
 
-    TEST_INVALID_PARAM( mbedtls_md_get_size( NULL ) );
-    TEST_INVALID_PARAM( mbedtls_md_get_type( NULL ) );
-    TEST_INVALID_PARAM( mbedtls_md_get_name( NULL ) );
+    TEST_INVALID_PARAM_RET( NULL,
+                            mbedtls_md_info_from_string( NULL ) );
 
-    TEST_INVALID_PARAM( mbedtls_md_info_from_string( NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_setup( &ctx, NULL, 0 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_setup( NULL, info, 0 ) );
 
-    TEST_INVALID_PARAM( mbedtls_md_setup( &ctx, NULL, 0 ) );
-    TEST_INVALID_PARAM( mbedtls_md_setup( NULL, info, 0 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_starts( NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_starts( &ctx ) );
 
-    TEST_INVALID_PARAM( mbedtls_md_starts( NULL ) );
-    TEST_INVALID_PARAM( mbedtls_md_starts( &ctx ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_update( NULL, buf, 1 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_update( &ctx, buf, 1 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_update( &good_ctx, NULL, 1 ) );
 
-    TEST_INVALID_PARAM( mbedtls_md_update( NULL, buf, 1 ) );
-    TEST_INVALID_PARAM( mbedtls_md_update( &ctx, buf, 1 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_finish( NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_finish( &ctx, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_finish( &ctx, NULL ) );
 
-    TEST_INVALID_PARAM( mbedtls_md_finish( NULL, buf ) );
-    TEST_INVALID_PARAM( mbedtls_md_finish( &ctx, buf ) );
-
-    TEST_INVALID_PARAM( mbedtls_md( NULL, buf, 1, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md( NULL, buf, 1, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md( info, NULL, 1, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md( info, buf, 1, NULL ) );
 
 #if defined(MBEDTLS_FS_IO)
-    TEST_INVALID_PARAM( mbedtls_md_file( NULL, "", buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_file( NULL, "", buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_file( info, NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_file( info, "", NULL ) );
 #endif
 
-    TEST_INVALID_PARAM( mbedtls_md_hmac_starts( NULL, buf, 1 ) );
-    TEST_INVALID_PARAM( mbedtls_md_hmac_starts( &ctx, buf, 1 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_hmac_starts( NULL, buf, 1 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_hmac_starts( &ctx, buf, 1 ) );
 
-    TEST_INVALID_PARAM( mbedtls_md_hmac_update( NULL, buf, 1 ) );
-    TEST_INVALID_PARAM( mbedtls_md_hmac_update( &ctx, buf, 1 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_hmac_update( NULL, buf, 1 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_hmac_update( &ctx, buf, 1 ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_hmac_update( &good_ctx, NULL, 1 ) );
 
-    TEST_INVALID_PARAM( mbedtls_md_hmac_finish( NULL, buf ) );
-    TEST_INVALID_PARAM( mbedtls_md_hmac_finish( &ctx, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_hmac_finish( NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_hmac_finish( &ctx, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_hmac_finish( &ctx, NULL ) );
 
-    TEST_INVALID_PARAM( mbedtls_md_hmac_reset( NULL ) );
-    TEST_INVALID_PARAM( mbedtls_md_hmac_reset( &ctx ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_hmac_reset( NULL ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_hmac_reset( &ctx ) );
 
-    TEST_INVALID_PARAM( mbedtls_md_hmac( NULL, buf, 1, buf, 1, buf ) );
-
-    TEST_INVALID_PARAM( mbedtls_md_process( NULL, buf ) );
-    TEST_INVALID_PARAM( mbedtls_md_process( &ctx, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_hmac( NULL, buf, 1, buf, 1, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_hmac( info, NULL, 1, buf, 1, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_hmac( info, buf, 1, NULL, 1, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_hmac( info, buf, 1, buf, 1, NULL ) );
+                            
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_process( NULL, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_process( &ctx, buf ) );
+    TEST_INVALID_PARAM_RET( MBEDTLS_ERR_MD_BAD_INPUT_DATA,
+                            mbedtls_md_process( &good_ctx, NULL ) );
 
     /* Ok, this is not NULL arg but NULL return... */
     TEST_ASSERT( mbedtls_md_info_from_type( MBEDTLS_MD_NONE ) == NULL );