From b9b630d6286be77df901d0c9a0371180460bd2e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 16 Feb 2023 19:07:31 +0100 Subject: [PATCH] Define "light" subset of MD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See docs/architecture/psa-migration/md-cipher-dispatch.md Regarding testing, the no_md component was never very useful, as that's not something people are likely to want to do: it was mostly useful as executable documentation of what depends on MD. It's going to be even less useful when more and more modules auto-enable MD_LIGHT or even MD_C. So, recycle it to test the build with only MD_LIGHT, which is something that might happen in practice, and is necessary to ensure that the division is consistent. Signed-off-by: Manuel Pégourié-Gonnard --- include/mbedtls/build_info.h | 7 ++++++ include/mbedtls/mbedtls_config.h | 21 +++++++++++++++- include/mbedtls/md.h | 22 ++++++++++++++--- library/md.c | 16 +++++++++---- tests/scripts/all.sh | 20 ++++++++++------ tests/suites/test_suite_md.function | 37 +++++++++++++++++++++++------ 6 files changed, 101 insertions(+), 22 deletions(-) diff --git a/include/mbedtls/build_info.h b/include/mbedtls/build_info.h index bbfd5d48d..bc94acf10 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 + /* The PK wrappers need pk_write functions to format RSA key objects * when they are dispatching to the PSA API. This happens under USE_PSA_CRYPTO, * and also even without USE_PSA_CRYPTO for mbedtls_pk_sign_ext(). diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h index 9ae51c964..41a007ea9 100644 --- a/include/mbedtls/mbedtls_config.h +++ b/include/mbedtls/mbedtls_config.h @@ -2643,7 +2643,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, @@ -2672,6 +2672,25 @@ */ #define MBEDTLS_MD_C +/** + * \def MBEDTLS_MD_LIGHT + * + * Enable the "light" subset of MBEDTLS_MD_C: just hashing and basic + * meta-data. + * + * This is automatically enabled whenever MBEDTLS_MD_C is enabled, but it is + * possible to enable this with MBEDTLS_MD_C if support for HMAC or extra + * metadata functions is not needed. + * + * Requires: one of: MBEDTLS_MD5_C, MBEDTLS_RIPEMD160_C, MBEDTLS_SHA1_C, + * MBEDTLS_SHA224_C, MBEDTLS_SHA256_C, MBEDTLS_SHA384_C, + * MBEDTLS_SHA512_C. + * Module: library/md.c + * + * Uncomment to enabled the "light" subsect of MD. + */ +#define MBEDTLS_MD_LIGHT + /** * \def MBEDTLS_MD5_C * diff --git a/include/mbedtls/md.h b/include/mbedtls/md.h index bcf56a549..f9349e1d8 100644 --- a/include/mbedtls/md.h +++ b/include/mbedtls/md.h @@ -1,7 +1,15 @@ /** * \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. + * + * Availability of function in this modules is controled by two + * feature macros: + * - MBEDTLS_MD_C enables the whole module; + * - MBEDTLS_MD_LIGHT enables only functions for hashing an accessing + * some hash metadata; is it automatically set whenever MBEDTLS_MD_C + * is set. * * \author Adriaan de Jong */ @@ -107,6 +115,7 @@ typedef struct mbedtls_md_context_t { void *MBEDTLS_PRIVATE(hmac_ctx); } mbedtls_md_context_t; +#if defined(MBEDTLS_MD_C) /** * \brief This function returns the list of digests supported by the * generic digest module. @@ -130,6 +139,7 @@ const int *mbedtls_md_list(void); * \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); +#endif /* MBEDTLS_MD_C */ /** * \brief This function returns the message-digest information @@ -142,6 +152,7 @@ const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name); */ const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type); +#if defined(MBEDTLS_MD_C) /** * \brief This function returns the message-digest information * from the given context. @@ -154,6 +165,7 @@ const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type); */ const mbedtls_md_info_t *mbedtls_md_info_from_ctx( const mbedtls_md_context_t *ctx); +#endif /* MBEDTLS_MD_C */ /** * \brief This function initializes a message-digest context without @@ -248,6 +260,7 @@ unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info); */ mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info); +#if defined(MBEDTLS_MD_C) /** * \brief This function extracts the message-digest name from the * message-digest information structure. @@ -258,6 +271,7 @@ mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info); * \return The name of the message digest. */ const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info); +#endif /* MBEDTLS_MD_C */ /** * \brief This function starts a message-digest computation. @@ -337,7 +351,7 @@ MBEDTLS_CHECK_RETURN_TYPICAL int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, unsigned char *output); -#if defined(MBEDTLS_FS_IO) +#if defined(MBEDTLS_FS_IO) && defined(MBEDTLS_MD_C) /** * \brief This function calculates the message-digest checksum * result of the contents of the provided file. @@ -358,8 +372,9 @@ int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, siz MBEDTLS_CHECK_RETURN_TYPICAL int mbedtls_md_file(const mbedtls_md_info_t *md_info, const char *path, unsigned char *output); -#endif /* MBEDTLS_FS_IO */ +#endif /* MBEDTLS_FS_IO && MBEDTLS_MD_C */ +#if defined(MBEDTLS_MD_C) /** * \brief This function sets the HMAC key and prepares to * authenticate a new message. @@ -470,6 +485,7 @@ MBEDTLS_CHECK_RETURN_TYPICAL int mbedtls_md_hmac(const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen, const unsigned char *input, size_t ilen, unsigned char *output); +#endif /* MBEDTLS_MD_C */ #ifdef __cplusplus } diff --git a/library/md.c b/library/md.c index dd5553aa9..8aecd39f0 100644 --- a/library/md.c +++ b/library/md.c @@ -23,7 +23,7 @@ #include "common.h" -#if defined(MBEDTLS_MD_C) +#if defined(MBEDTLS_MD_LIGHT) #include "mbedtls/md.h" #include "md_wrap.h" @@ -110,6 +110,7 @@ const mbedtls_md_info_t mbedtls_sha512_info = { /* * Reminder: update profiles in x509_crt.c when adding a new hash! */ +#if defined(MBEDTLS_MD_C) static const int supported_digests[] = { #if defined(MBEDTLS_SHA512_C) @@ -191,6 +192,7 @@ const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name) #endif return NULL; } +#endif /* MBEDTLS_MD_C */ const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type) { @@ -228,6 +230,7 @@ const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type) } } +#if defined(MBEDTLS_MD_C) const mbedtls_md_info_t *mbedtls_md_info_from_ctx( const mbedtls_md_context_t *ctx) { @@ -237,6 +240,7 @@ const mbedtls_md_info_t *mbedtls_md_info_from_ctx( return ctx->MBEDTLS_PRIVATE(md_info); } +#endif /* MBEDTLS_MD_C */ void mbedtls_md_init(mbedtls_md_context_t *ctx) { @@ -586,7 +590,7 @@ int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, siz } } -#if defined(MBEDTLS_FS_IO) +#if defined(MBEDTLS_FS_IO) && defined(MBEDTLS_MD_C) int mbedtls_md_file(const mbedtls_md_info_t *md_info, const char *path, unsigned char *output) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; @@ -635,8 +639,9 @@ cleanup: return ret; } -#endif /* MBEDTLS_FS_IO */ +#endif /* MBEDTLS_FS_IO && MBEDTLS_MD_C */ +#if defined(MBEDTLS_MD_C) int mbedtls_md_hmac_starts(mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; @@ -773,6 +778,7 @@ cleanup: return ret; } +#endif /* MBEDTLS_MD_C */ unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info) { @@ -792,6 +798,7 @@ mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info) return md_info->type; } +#if defined(MBEDTLS_MD_C) const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info) { if (md_info == NULL) { @@ -800,5 +807,6 @@ const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info) return md_info->name; } - #endif /* MBEDTLS_MD_C */ + +#endif /* MBEDTLS_MD_LIGHT */ diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 7d91fa27d..c4a8fe652 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -1219,19 +1219,25 @@ component_test_psa_external_rng_no_drbg_use_psa () { 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 + scripts/config.py set MBEDTLS_MD_LIGHT + make CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" - msg "test: crypto_full minus MD" + # Make sure we don't have the HMAC functions + not grep mbedtls_md_hmac library/md.o + + msg "test: crypto_full with only the light subset of MD" make test } diff --git a/tests/suites/test_suite_md.function b/tests/suites/test_suite_md.function index ac3a8baf4..1e8622be0 100644 --- a/tests/suites/test_suite_md.function +++ b/tests/suites/test_suite_md.function @@ -3,11 +3,11 @@ /* END_HEADER */ /* BEGIN_DEPENDENCIES - * depends_on:MBEDTLS_MD_C + * depends_on:MBEDTLS_MD_LIGHT * END_DEPENDENCIES */ -/* BEGIN_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_MD_C */ void mbedtls_md_list() { const int *md_type_ptr; @@ -38,21 +38,27 @@ exit: 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); @@ -65,6 +71,7 @@ void md_null_args() 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 @@ -87,10 +94,13 @@ void md_null_args() TEST_EQUAL(mbedtls_md_hmac(NULL, buf, 1, buf, 1, 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 */ @@ -98,24 +108,31 @@ void md_null_args() 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 */ @@ -173,8 +190,10 @@ void md_text_multi(int md_type, char *text_src_string, 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); @@ -213,8 +232,10 @@ void md_hex_multi(int md_type, data_t *src_str, data_t *hash) 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; @@ -240,7 +261,7 @@ exit: } /* 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) @@ -259,7 +280,7 @@ void mbedtls_md_hmac(int md_type, int trunc_size, } /* 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) { @@ -273,7 +294,9 @@ void md_hmac_multi(int md_type, int trunc_size, data_t *key_str, 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; @@ -300,7 +323,7 @@ exit: } /* 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) {