Merge pull request #7120 from mpg/md-light

Define "MD light" subset of MD
diff --git a/include/mbedtls/build_info.h b/include/mbedtls/build_info.h
index 6e35a38..4835beb 100644
--- a/include/mbedtls/build_info.h
+++ b/include/mbedtls/build_info.h
@@ -80,6 +80,13 @@
 #include MBEDTLS_USER_CONFIG_FILE
 #endif
 
+/* Auto-enable MBEDTLS_MD_LIGHT based on MBEDTLS_MD_C.
+ * This allows checking for MD_LIGHT rather than MD_LIGHT || MD_C.
+ */
+#if defined(MBEDTLS_MD_C)
+#define MBEDTLS_MD_LIGHT
+#endif
+
 /* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT
  * is defined as well to include all PSA code.
  */
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index 15b120d..4814d50 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -2671,7 +2671,7 @@
 /**
  * \def MBEDTLS_MD_C
  *
- * Enable the generic message digest layer.
+ * Enable the generic layer for message digest (hashing) and HMAC.
  *
  * Requires: one of: MBEDTLS_MD5_C, MBEDTLS_RIPEMD160_C, MBEDTLS_SHA1_C,
  *                   MBEDTLS_SHA224_C, MBEDTLS_SHA256_C, MBEDTLS_SHA384_C,
diff --git a/include/mbedtls/md.h b/include/mbedtls/md.h
index 1a92c57..3341d1c 100644
--- a/include/mbedtls/md.h
+++ b/include/mbedtls/md.h
@@ -1,7 +1,8 @@
 /**
  * \file md.h
  *
- * \brief This file contains the generic message-digest wrapper.
+ * \brief   This file contains the generic functions for message-digest
+ *          (hashing) and HMAC.
  *
  * \author Adriaan de Jong <dejong@fox-it.com>
  */
@@ -108,30 +109,6 @@
 } mbedtls_md_context_t;
 
 /**
- * \brief           This function returns the list of digests supported by the
- *                  generic digest module.
- *
- * \note            The list starts with the strongest available hashes.
- *
- * \return          A statically allocated array of digests. Each element
- *                  in the returned list is an integer belonging to the
- *                  message-digest enumeration #mbedtls_md_type_t.
- *                  The last entry is 0.
- */
-const int *mbedtls_md_list(void);
-
-/**
- * \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.
- *
- * \return          The message-digest information associated with \p md_name.
- * \return          NULL if the associated message-digest information is not found.
- */
-const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name);
-
-/**
  * \brief           This function returns the message-digest information
  *                  associated with the given digest type.
  *
@@ -143,19 +120,6 @@
 const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type);
 
 /**
- * \brief           This function returns the message-digest information
- *                  from the given context.
- *
- * \param ctx       The context from which to extract the information.
- *                  This must be initialized (or \c NULL).
- *
- * \return          The message-digest information associated with \p ctx.
- * \return          \c NULL if \p ctx is \c NULL.
- */
-const mbedtls_md_info_t *mbedtls_md_info_from_ctx(
-    const mbedtls_md_context_t *ctx);
-
-/**
  * \brief           This function initializes a message-digest context without
  *                  binding it to a particular message-digest algorithm.
  *
@@ -249,17 +213,6 @@
 mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info);
 
 /**
- * \brief           This function extracts the message-digest name from the
- *                  message-digest information structure.
- *
- * \param md_info   The information structure of the message-digest algorithm
- *                  to use.
- *
- * \return          The name of the message digest.
- */
-const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info);
-
-/**
  * \brief           This function starts a message-digest computation.
  *
  *                  You must call this function after setting up the context
@@ -337,6 +290,54 @@
 int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
                unsigned char *output);
 
+/**
+ * \brief           This function returns the list of digests supported by the
+ *                  generic digest module.
+ *
+ * \note            The list starts with the strongest available hashes.
+ *
+ * \return          A statically allocated array of digests. Each element
+ *                  in the returned list is an integer belonging to the
+ *                  message-digest enumeration #mbedtls_md_type_t.
+ *                  The last entry is 0.
+ */
+const int *mbedtls_md_list(void);
+
+/**
+ * \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.
+ *
+ * \return          The message-digest information associated with \p md_name.
+ * \return          NULL if the associated message-digest information is not found.
+ */
+const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name);
+
+/**
+ * \brief           This function extracts the message-digest name from the
+ *                  message-digest information structure.
+ *
+ * \param md_info   The information structure of the message-digest algorithm
+ *                  to use.
+ *
+ * \return          The name of the message digest.
+ */
+const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info);
+
+/**
+ * \brief           This function returns the message-digest information
+ *                  from the given context.
+ *
+ * \param ctx       The context from which to extract the information.
+ *                  This must be initialized (or \c NULL).
+ *
+ * \return          The message-digest information associated with \p ctx.
+ * \return          \c NULL if \p ctx is \c NULL.
+ */
+const mbedtls_md_info_t *mbedtls_md_info_from_ctx(
+    const mbedtls_md_context_t *ctx);
+
 #if defined(MBEDTLS_FS_IO)
 /**
  * \brief          This function calculates the message-digest checksum
@@ -471,10 +472,6 @@
                     const unsigned char *input, size_t ilen,
                     unsigned char *output);
 
-/* Internal use */
-MBEDTLS_CHECK_RETURN_TYPICAL
-int mbedtls_md_process(mbedtls_md_context_t *ctx, const unsigned char *data);
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/library/md.c b/library/md.c
index a729878..6681f9a 100644
--- a/library/md.c
+++ b/library/md.c
@@ -23,7 +23,23 @@
 
 #include "common.h"
 
-#if defined(MBEDTLS_MD_C)
+/*
+ * Availability of functions in this module is controlled by two
+ * feature macros:
+ * - MBEDTLS_MD_C enables the whole module;
+ * - MBEDTLS_MD_LIGHT enables only functions for hashing and accessing
+ * most hash metadata (everything except string names); is it
+ * automatically set whenever MBEDTLS_MD_C is defined.
+ *
+ * In this file, functions from MD_LIGHT are at the top, MD_C at the end.
+ *
+ * In the future we may want to change the contract of some functions
+ * (behaviour with NULL arguments) depending on whether MD_C is defined or
+ * only MD_LIGHT. Also, the exact scope of MD_LIGHT might vary.
+ *
+ * For these reasons, we're keeping MD_LIGHT internal for now.
+ */
+#if defined(MBEDTLS_MD_LIGHT)
 
 #include "mbedtls/md.h"
 #include "md_wrap.h"
@@ -107,91 +123,6 @@
 };
 #endif
 
-/*
- * Reminder: update profiles in x509_crt.c when adding a new hash!
- */
-static const int supported_digests[] = {
-
-#if defined(MBEDTLS_SHA512_C)
-    MBEDTLS_MD_SHA512,
-#endif
-
-#if defined(MBEDTLS_SHA384_C)
-    MBEDTLS_MD_SHA384,
-#endif
-
-#if defined(MBEDTLS_SHA256_C)
-    MBEDTLS_MD_SHA256,
-#endif
-#if defined(MBEDTLS_SHA224_C)
-    MBEDTLS_MD_SHA224,
-#endif
-
-#if defined(MBEDTLS_SHA1_C)
-    MBEDTLS_MD_SHA1,
-#endif
-
-#if defined(MBEDTLS_RIPEMD160_C)
-    MBEDTLS_MD_RIPEMD160,
-#endif
-
-#if defined(MBEDTLS_MD5_C)
-    MBEDTLS_MD_MD5,
-#endif
-
-    MBEDTLS_MD_NONE
-};
-
-const int *mbedtls_md_list(void)
-{
-    return supported_digests;
-}
-
-const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name)
-{
-    if (NULL == md_name) {
-        return NULL;
-    }
-
-    /* Get the appropriate digest information */
-#if defined(MBEDTLS_MD5_C)
-    if (!strcmp("MD5", md_name)) {
-        return mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
-    }
-#endif
-#if defined(MBEDTLS_RIPEMD160_C)
-    if (!strcmp("RIPEMD160", md_name)) {
-        return mbedtls_md_info_from_type(MBEDTLS_MD_RIPEMD160);
-    }
-#endif
-#if defined(MBEDTLS_SHA1_C)
-    if (!strcmp("SHA1", md_name) || !strcmp("SHA", md_name)) {
-        return mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
-    }
-#endif
-#if defined(MBEDTLS_SHA224_C)
-    if (!strcmp("SHA224", md_name)) {
-        return mbedtls_md_info_from_type(MBEDTLS_MD_SHA224);
-    }
-#endif
-#if defined(MBEDTLS_SHA256_C)
-    if (!strcmp("SHA256", md_name)) {
-        return mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
-    }
-#endif
-#if defined(MBEDTLS_SHA384_C)
-    if (!strcmp("SHA384", md_name)) {
-        return mbedtls_md_info_from_type(MBEDTLS_MD_SHA384);
-    }
-#endif
-#if defined(MBEDTLS_SHA512_C)
-    if (!strcmp("SHA512", md_name)) {
-        return mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
-    }
-#endif
-    return NULL;
-}
-
 const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type)
 {
     switch (md_type) {
@@ -228,16 +159,6 @@
     }
 }
 
-const mbedtls_md_info_t *mbedtls_md_info_from_ctx(
-    const mbedtls_md_context_t *ctx)
-{
-    if (ctx == NULL) {
-        return NULL;
-    }
-
-    return ctx->MBEDTLS_PRIVATE(md_info);
-}
-
 void mbedtls_md_init(mbedtls_md_context_t *ctx)
 {
     memset(ctx, 0, sizeof(mbedtls_md_context_t));
@@ -586,6 +507,125 @@
     }
 }
 
+unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info)
+{
+    if (md_info == NULL) {
+        return 0;
+    }
+
+    return md_info->size;
+}
+
+mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info)
+{
+    if (md_info == NULL) {
+        return MBEDTLS_MD_NONE;
+    }
+
+    return md_info->type;
+}
+
+/************************************************************************
+ * Functions above this separator are part of MBEDTLS_MD_LIGHT,         *
+ * functions below are only available when MBEDTLS_MD_C is set.         *
+ ************************************************************************/
+#if defined(MBEDTLS_MD_C)
+
+/*
+ * Reminder: update profiles in x509_crt.c when adding a new hash!
+ */
+static const int supported_digests[] = {
+
+#if defined(MBEDTLS_SHA512_C)
+    MBEDTLS_MD_SHA512,
+#endif
+
+#if defined(MBEDTLS_SHA384_C)
+    MBEDTLS_MD_SHA384,
+#endif
+
+#if defined(MBEDTLS_SHA256_C)
+    MBEDTLS_MD_SHA256,
+#endif
+#if defined(MBEDTLS_SHA224_C)
+    MBEDTLS_MD_SHA224,
+#endif
+
+#if defined(MBEDTLS_SHA1_C)
+    MBEDTLS_MD_SHA1,
+#endif
+
+#if defined(MBEDTLS_RIPEMD160_C)
+    MBEDTLS_MD_RIPEMD160,
+#endif
+
+#if defined(MBEDTLS_MD5_C)
+    MBEDTLS_MD_MD5,
+#endif
+
+    MBEDTLS_MD_NONE
+};
+
+const int *mbedtls_md_list(void)
+{
+    return supported_digests;
+}
+
+const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name)
+{
+    if (NULL == md_name) {
+        return NULL;
+    }
+
+    /* Get the appropriate digest information */
+#if defined(MBEDTLS_MD5_C)
+    if (!strcmp("MD5", md_name)) {
+        return mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
+    }
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+    if (!strcmp("RIPEMD160", md_name)) {
+        return mbedtls_md_info_from_type(MBEDTLS_MD_RIPEMD160);
+    }
+#endif
+#if defined(MBEDTLS_SHA1_C)
+    if (!strcmp("SHA1", md_name) || !strcmp("SHA", md_name)) {
+        return mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
+    }
+#endif
+#if defined(MBEDTLS_SHA224_C)
+    if (!strcmp("SHA224", md_name)) {
+        return mbedtls_md_info_from_type(MBEDTLS_MD_SHA224);
+    }
+#endif
+#if defined(MBEDTLS_SHA256_C)
+    if (!strcmp("SHA256", md_name)) {
+        return mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
+    }
+#endif
+#if defined(MBEDTLS_SHA384_C)
+    if (!strcmp("SHA384", md_name)) {
+        return mbedtls_md_info_from_type(MBEDTLS_MD_SHA384);
+    }
+#endif
+#if defined(MBEDTLS_SHA512_C)
+    if (!strcmp("SHA512", md_name)) {
+        return mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
+    }
+#endif
+    return NULL;
+}
+
+const mbedtls_md_info_t *mbedtls_md_info_from_ctx(
+    const mbedtls_md_context_t *ctx)
+{
+    if (ctx == NULL) {
+        return NULL;
+    }
+
+    return ctx->MBEDTLS_PRIVATE(md_info);
+}
+
 #if defined(MBEDTLS_FS_IO)
 int mbedtls_md_file(const mbedtls_md_info_t *md_info, const char *path, unsigned char *output)
 {
@@ -774,64 +814,6 @@
     return ret;
 }
 
-int mbedtls_md_process(mbedtls_md_context_t *ctx, const unsigned char *data)
-{
-    if (ctx == NULL || ctx->md_info == NULL) {
-        return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
-    }
-
-    switch (ctx->md_info->type) {
-#if defined(MBEDTLS_MD5_C)
-        case MBEDTLS_MD_MD5:
-            return mbedtls_internal_md5_process(ctx->md_ctx, data);
-#endif
-#if defined(MBEDTLS_RIPEMD160_C)
-        case MBEDTLS_MD_RIPEMD160:
-            return mbedtls_internal_ripemd160_process(ctx->md_ctx, data);
-#endif
-#if defined(MBEDTLS_SHA1_C)
-        case MBEDTLS_MD_SHA1:
-            return mbedtls_internal_sha1_process(ctx->md_ctx, data);
-#endif
-#if defined(MBEDTLS_SHA224_C)
-        case MBEDTLS_MD_SHA224:
-            return mbedtls_internal_sha256_process(ctx->md_ctx, data);
-#endif
-#if defined(MBEDTLS_SHA256_C)
-        case MBEDTLS_MD_SHA256:
-            return mbedtls_internal_sha256_process(ctx->md_ctx, data);
-#endif
-#if defined(MBEDTLS_SHA384_C)
-        case MBEDTLS_MD_SHA384:
-            return mbedtls_internal_sha512_process(ctx->md_ctx, data);
-#endif
-#if defined(MBEDTLS_SHA512_C)
-        case MBEDTLS_MD_SHA512:
-            return mbedtls_internal_sha512_process(ctx->md_ctx, data);
-#endif
-        default:
-            return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
-    }
-}
-
-unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info)
-{
-    if (md_info == NULL) {
-        return 0;
-    }
-
-    return md_info->size;
-}
-
-mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info)
-{
-    if (md_info == NULL) {
-        return MBEDTLS_MD_NONE;
-    }
-
-    return md_info->type;
-}
-
 const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info)
 {
     if (md_info == NULL) {
@@ -842,3 +824,5 @@
 }
 
 #endif /* MBEDTLS_MD_C */
+
+#endif /* MBEDTLS_MD_LIGHT */
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index d438f79..f1f53e3 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1219,19 +1219,25 @@
     tests/ssl-opt.sh -f 'Default\|opaque'
 }
 
-component_test_crypto_full_no_md () {
-    msg "build: crypto_full minus MD"
+component_test_crypto_full_md_light_only () {
+    msg "build: crypto_full with only the light subset of MD"
     scripts/config.py crypto_full
+    # Disable MD
     scripts/config.py unset MBEDTLS_MD_C
-    # Direct dependencies
+    # Disable direct dependencies of MD
     scripts/config.py unset MBEDTLS_HKDF_C
     scripts/config.py unset MBEDTLS_HMAC_DRBG_C
     scripts/config.py unset MBEDTLS_PKCS7_C
-    # Indirect dependencies
-    scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC
-    make
+    # Disable indirect dependencies of MD
+    scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC # needs HMAC_DRBG
+    # Enable "light" subset of MD
+    make CFLAGS="$ASAN_CFLAGS -DMBEDTLS_MD_LIGHT" LDFLAGS="$ASAN_CFLAGS"
 
-    msg "test: crypto_full minus MD"
+    # Make sure we don't have the HMAC functions, but the hashing functions
+    not grep mbedtls_md_hmac library/md.o
+    grep mbedtls_md library/md.o
+
+    msg "test: crypto_full with only the light subset of MD"
     make test
 }
 
@@ -2346,8 +2352,7 @@
     scripts/config.py unset MBEDTLS_ENTROPY_C
     scripts/config.py unset MBEDTLS_ENTROPY_NV_SEED # depends on ENTROPY_C
     scripts/config.py unset MBEDTLS_PLATFORM_NV_SEED_ALT # depends on former
-    # Also unset MD_C and things that depend on it;
-    # see component_test_crypto_full_no_md.
+    # Also unset MD_C and things that depend on it.
     if [ "$DRIVER_ONLY" -eq 1 ]; then
         scripts/config.py unset MBEDTLS_MD_C
     fi
diff --git a/tests/suites/test_suite_md.data b/tests/suites/test_suite_md.data
index 5659ff4..79b8376 100644
--- a/tests/suites/test_suite_md.data
+++ b/tests/suites/test_suite_md.data
@@ -1,6 +1,6 @@
 # Tests of the generic message digest interface
-MD process
-mbedtls_md_process:
+MD list
+mbedtls_md_list:
 
 MD NULL/uninitialised arguments
 md_null_args:
diff --git a/tests/suites/test_suite_md.function b/tests/suites/test_suite_md.function
index 2f60c4e..1e8622b 100644
--- a/tests/suites/test_suite_md.function
+++ b/tests/suites/test_suite_md.function
@@ -3,35 +3,29 @@
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
- * depends_on:MBEDTLS_MD_C
+ * depends_on:MBEDTLS_MD_LIGHT
  * END_DEPENDENCIES
  */
 
-/* BEGIN_CASE */
-void mbedtls_md_process()
+/* BEGIN_CASE depends_on:MBEDTLS_MD_C */
+void mbedtls_md_list()
 {
     const int *md_type_ptr;
     const mbedtls_md_info_t *info;
     mbedtls_md_context_t ctx;
-    unsigned char buf[150];
+    unsigned char out[MBEDTLS_MD_MAX_SIZE] = { 0 };
 
     mbedtls_md_init(&ctx);
-    memset(buf, 0, sizeof(buf));
 
     /*
-     * Very minimal testing of mbedtls_md_process, just make sure the various
-     * xxx_process_wrap() function pointers are valid. (Testing that they
-     * indeed do the right thing would require messing with the internal
-     * state of the underlying mbedtls_md/sha context.)
-     *
-     * Also tests that mbedtls_md_list() only returns valid MDs.
+     * Test that mbedtls_md_list() only returns valid MDs.
      */
     for (md_type_ptr = mbedtls_md_list(); *md_type_ptr != 0; md_type_ptr++) {
         info = mbedtls_md_info_from_type(*md_type_ptr);
         TEST_ASSERT(info != NULL);
         TEST_EQUAL(0, mbedtls_md_setup(&ctx, info, 0));
         TEST_EQUAL(0, mbedtls_md_starts(&ctx));
-        TEST_EQUAL(0, mbedtls_md_process(&ctx, buf));
+        TEST_EQUAL(0, mbedtls_md_finish(&ctx, out));
         mbedtls_md_free(&ctx);
     }
 
@@ -44,21 +38,27 @@
 void md_null_args()
 {
     mbedtls_md_context_t ctx;
+#if defined(MBEDTLS_MD_C)
     const mbedtls_md_info_t *info = mbedtls_md_info_from_type(*(mbedtls_md_list()));
+#endif
     unsigned char buf[1] = { 0 };
 
     mbedtls_md_init(&ctx);
 
     TEST_EQUAL(0, mbedtls_md_get_size(NULL));
+#if defined(MBEDTLS_MD_C)
     TEST_EQUAL(mbedtls_md_get_type(NULL), MBEDTLS_MD_NONE);
     TEST_ASSERT(mbedtls_md_get_name(NULL) == NULL);
 
     TEST_ASSERT(mbedtls_md_info_from_string(NULL) == NULL);
     TEST_ASSERT(mbedtls_md_info_from_ctx(NULL) == NULL);
     TEST_ASSERT(mbedtls_md_info_from_ctx(&ctx) == NULL);
+#endif /* MBEDTLS_MD_C */
 
     TEST_EQUAL(mbedtls_md_setup(&ctx, NULL, 0), MBEDTLS_ERR_MD_BAD_INPUT_DATA);
+#if defined(MBEDTLS_MD_C)
     TEST_EQUAL(mbedtls_md_setup(NULL, info, 0), MBEDTLS_ERR_MD_BAD_INPUT_DATA);
+#endif
 
     TEST_EQUAL(mbedtls_md_starts(NULL), MBEDTLS_ERR_MD_BAD_INPUT_DATA);
     TEST_EQUAL(mbedtls_md_starts(&ctx), MBEDTLS_ERR_MD_BAD_INPUT_DATA);
@@ -71,6 +71,7 @@
 
     TEST_EQUAL(mbedtls_md(NULL, buf, 1, buf), MBEDTLS_ERR_MD_BAD_INPUT_DATA);
 
+#if defined(MBEDTLS_MD_C)
 #if defined(MBEDTLS_FS_IO)
     TEST_EQUAL(mbedtls_md_file(NULL, "", buf), MBEDTLS_ERR_MD_BAD_INPUT_DATA);
 #endif
@@ -93,13 +94,13 @@
 
     TEST_EQUAL(mbedtls_md_hmac(NULL, buf, 1, buf, 1, buf),
                MBEDTLS_ERR_MD_BAD_INPUT_DATA);
-
-    TEST_EQUAL(mbedtls_md_process(NULL, buf), MBEDTLS_ERR_MD_BAD_INPUT_DATA);
-    TEST_EQUAL(mbedtls_md_process(&ctx, buf), MBEDTLS_ERR_MD_BAD_INPUT_DATA);
+#endif /* MBEDTLS_MD_C */
 
     /* Ok, this is not NULL arg but NULL return... */
     TEST_ASSERT(mbedtls_md_info_from_type(MBEDTLS_MD_NONE) == NULL);
+#if defined(MBEDTLS_MD_C)
     TEST_ASSERT(mbedtls_md_info_from_string("no such md") == NULL);
+#endif
 }
 /* END_CASE */
 
@@ -107,24 +108,31 @@
 void md_info(int md_type, char *md_name, int md_size)
 {
     const mbedtls_md_info_t *md_info;
+#if defined(MBEDTLS_MD_C)
     const int *md_type_ptr;
-    int found;
+#else
+    (void) md_name;
+#endif
 
     md_info = mbedtls_md_info_from_type(md_type);
     TEST_ASSERT(md_info != NULL);
+#if defined(MBEDTLS_MD_C)
     TEST_ASSERT(md_info == mbedtls_md_info_from_string(md_name));
+#endif
 
     TEST_EQUAL(mbedtls_md_get_type(md_info), (mbedtls_md_type_t) md_type);
     TEST_EQUAL(mbedtls_md_get_size(md_info), (unsigned char) md_size);
+#if defined(MBEDTLS_MD_C)
     TEST_EQUAL(0, strcmp(mbedtls_md_get_name(md_info), md_name));
 
-    found = 0;
+    int found = 0;
     for (md_type_ptr = mbedtls_md_list(); *md_type_ptr != 0; md_type_ptr++) {
         if (*md_type_ptr == md_type) {
             found = 1;
         }
     }
     TEST_EQUAL(found, 1);
+#endif /* MBEDTLS_MD_C */
 }
 /* END_CASE */
 
@@ -182,8 +190,10 @@
     TEST_ASSERT(md_info != NULL);
     TEST_EQUAL(0, mbedtls_md_setup(&ctx, md_info, 0));
     TEST_EQUAL(0, mbedtls_md_setup(&ctx_copy, md_info, 0));
+#if defined(MBEDTLS_MD_C)
     TEST_ASSERT(mbedtls_md_info_from_ctx(&ctx) == md_info);
     TEST_ASSERT(mbedtls_md_info_from_ctx(&ctx_copy) == md_info);
+#endif /* MBEDTLS_MD_C */
 
     TEST_EQUAL(0, mbedtls_md_starts(&ctx));
     TEST_ASSERT(ctx.md_ctx != NULL);
@@ -222,8 +232,10 @@
     TEST_ASSERT(md_info != NULL);
     TEST_EQUAL(0, mbedtls_md_setup(&ctx, md_info, 0));
     TEST_EQUAL(0, mbedtls_md_setup(&ctx_copy, md_info, 0));
+#if defined(MBEDTLS_MD_C)
     TEST_ASSERT(mbedtls_md_info_from_ctx(&ctx) == md_info);
     TEST_ASSERT(mbedtls_md_info_from_ctx(&ctx_copy) == md_info);
+#endif /* MBEDTLS_MD_C */
 
     halfway = src_str->len / 2;
 
@@ -249,7 +261,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_MD_C */
 void mbedtls_md_hmac(int md_type, int trunc_size,
                      data_t *key_str, data_t *src_str,
                      data_t *hash)
@@ -268,7 +280,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_MD_C */
 void md_hmac_multi(int md_type, int trunc_size, data_t *key_str,
                    data_t *src_str, data_t *hash)
 {
@@ -282,7 +294,9 @@
     md_info = mbedtls_md_info_from_type(md_type);
     TEST_ASSERT(md_info != NULL);
     TEST_EQUAL(0, mbedtls_md_setup(&ctx, md_info, 1));
+#if defined(MBEDTLS_MD_C)
     TEST_ASSERT(mbedtls_md_info_from_ctx(&ctx) == md_info);
+#endif
 
     halfway = src_str->len / 2;
 
@@ -309,7 +323,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
+/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_MD_C */
 void mbedtls_md_file(int md_type, char *filename,
                      data_t *hash)
 {