Add config.h option to hardcode choice of single MD algorithm
This commit introduces the configuration option
MBEDTLS_MD_SINGLE_HASH
which can be used to hardcode support for a single digest algorithm
at compile-time, at the benefit of reduced code-size.
To use, it needs to be defined to evaluate to a macro of the form
MBEDTLS_MD_INFO_{DIGEST}, and macros MBEDTLS_MD_INFO_{DIGEST}_FIELD
must be defined, giving rise to the various aspects (name, type,
size, ...) of the chosen digest algorithm. MBEDTLS_MD_INFO_SHA256
provides an example, but other algorithms can be added if needed.
At the moment, the effect of using MBEDTLS_MD_SINGLE_HASH is that
the implementation of the MD API (e.g. mbedtls_md_update()) need no
longer to through the abstraction of the mbedtls_md_info structures
by calling their corresponding function pointers fields (akin to
virtual functions in C++), but the directly call the corresponding
core digest function (such as mbedtls_sha256_update()).
Therefore, MBEDTLS_MD_SINGLE_HASH so far removes the second layer
of indirection in the chain
User calls MD API -> MD API calls underlying digest impl'n
-> Core digest impl'n does the actual work,
but the first indirection remains, as the MD API remains untouched
and cannot yet be inlined. Studying to what extend inlining the
shortened MD API implementations would lead to further code-savings
is left for a later commit.
diff --git a/library/md.c b/library/md.c
index 2271a76..abc2ad3 100644
--- a/library/md.c
+++ b/library/md.c
@@ -148,6 +148,7 @@
typedef int mbedtls_md_process_func_t( void *ctx,
const unsigned char *input );
+#if !defined(MBEDTLS_MD_SINGLE_HASH)
struct mbedtls_md_info_t
{
/** Digest identifier */
@@ -205,6 +206,8 @@
MBEDTLS_MD_INFO_CLONE_FUNC( MD ), \
MBEDTLS_MD_INFO_PROCESS_FUNC( MD ) }
+#endif /* !MBEDTLS_MD_SINGLE_HASH */
+
/*
*
* Definitions of MD information structures for various digests.
@@ -262,6 +265,7 @@
return( mbedtls_internal_md2_process( (mbedtls_md2_context *) ctx ) );
}
+#if !defined(MBEDTLS_MD_SINGLE_HASH)
const mbedtls_md_info_t mbedtls_md2_info = {
MBEDTLS_MD_MD2,
"MD2",
@@ -276,6 +280,7 @@
md2_clone_wrap,
md2_process_wrap,
};
+#endif /* !MBEDTLS_MD_SINGLE_HASH */
#endif /* MBEDTLS_MD2_C */
@@ -328,6 +333,7 @@
return( mbedtls_internal_md4_process( (mbedtls_md4_context *) ctx, data ) );
}
+#if !defined(MBEDTLS_MD_SINGLE_HASH)
const mbedtls_md_info_t mbedtls_md4_info = {
MBEDTLS_MD_MD4,
"MD4",
@@ -342,6 +348,7 @@
md4_clone_wrap,
md4_process_wrap,
};
+#endif /* MBEDTLS_MD_SINGLE_HASH */
#endif /* MBEDTLS_MD4_C */
@@ -394,6 +401,7 @@
return( mbedtls_internal_md5_process( (mbedtls_md5_context *) ctx, data ) );
}
+#if !defined(MBEDTLS_MD_SINGLE_HASH)
const mbedtls_md_info_t mbedtls_md5_info = {
MBEDTLS_MD_MD5,
"MD5",
@@ -408,6 +416,7 @@
md5_clone_wrap,
md5_process_wrap,
};
+#endif /* MBEDTLS_MD_SINGLE_HASH */
#endif /* MBEDTLS_MD5_C */
@@ -463,6 +472,7 @@
(mbedtls_ripemd160_context *) ctx, data ) );
}
+#if !defined(MBEDTLS_MD_SINGLE_HASH)
const mbedtls_md_info_t mbedtls_ripemd160_info = {
MBEDTLS_MD_RIPEMD160,
"RIPEMD160",
@@ -477,6 +487,7 @@
ripemd160_clone_wrap,
ripemd160_process_wrap,
};
+#endif /* !MBEDTLS_MD_SINGLE_HASH */
#endif /* MBEDTLS_RIPEMD160_C */
@@ -531,6 +542,7 @@
data ) );
}
+#if !defined(MBEDTLS_MD_SINGLE_HASH)
const mbedtls_md_info_t mbedtls_sha1_info = {
MBEDTLS_MD_SHA1,
"SHA1",
@@ -545,6 +557,7 @@
sha1_clone_wrap,
sha1_process_wrap,
};
+#endif /* !MBEDTLS_MD_SINGLE_HASH */
#endif /* MBEDTLS_SHA1_C */
@@ -610,6 +623,7 @@
data ) );
}
+#if !defined(MBEDTLS_MD_SINGLE_HASH)
#if !defined(MBEDTLS_SHA256_NO_SHA224)
const mbedtls_md_info_t mbedtls_sha224_info = {
MBEDTLS_MD_SHA224,
@@ -626,6 +640,7 @@
sha224_process_wrap,
};
#endif /* !MBEDTLS_SHA256_NO_SHA224 */
+#endif /* !MBEDTLS_MD_SINGLE_HASH */
static int sha256_starts_wrap( void *ctx )
{
@@ -638,8 +653,10 @@
return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
}
+#if !defined(MBEDTLS_MD_SINGLE_HASH)
const mbedtls_md_info_t mbedtls_sha256_info =
MBEDTLS_MD_INFO( MBEDTLS_MD_INFO_SHA256 );
+#endif /* !MBEDTLS_MD_SINGLE_HASH */
#endif /* MBEDTLS_SHA256_C */
@@ -701,6 +718,7 @@
data ) );
}
+#if !defined(MBEDTLS_MD_SINGLE_HASH)
const mbedtls_md_info_t mbedtls_sha384_info = {
MBEDTLS_MD_SHA384,
"SHA384",
@@ -715,6 +733,7 @@
sha384_clone_wrap,
sha384_process_wrap,
};
+#endif /* MBEDTLS_MD_SINGLE_HASH */
static int sha512_starts_wrap( void *ctx )
{
@@ -727,6 +746,7 @@
return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
}
+#if !defined(MBEDTLS_MD_SINGLE_HASH)
const mbedtls_md_info_t mbedtls_sha512_info = {
MBEDTLS_MD_SHA512,
"SHA512",
@@ -741,6 +761,7 @@
sha384_clone_wrap,
sha384_process_wrap,
};
+#endif /* MBEDTLS_MD_SINGLE_HASH */
#endif /* MBEDTLS_SHA512_C */
@@ -748,6 +769,8 @@
* Getter functions for MD info structure.
*/
+#if !defined(MBEDTLS_MD_SINGLE_HASH)
+
static inline mbedtls_md_type_t mbedtls_md_info_type(
mbedtls_md_handle_t info )
{
@@ -820,6 +843,96 @@
return( info->process_func );
}
+#else /* !MBEDTLS_MD_SINGLE_HASH */
+
+static inline mbedtls_md_type_t mbedtls_md_info_type(
+ mbedtls_md_handle_t info )
+{
+ ((void) info);
+ return( MBEDTLS_MD_INFO_TYPE( MBEDTLS_MD_SINGLE_HASH ) );
+}
+
+static inline const char * mbedtls_md_info_name(
+ mbedtls_md_handle_t info )
+{
+ ((void) info);
+ return( MBEDTLS_MD_INFO_NAME( MBEDTLS_MD_SINGLE_HASH ) );
+}
+
+static inline int mbedtls_md_info_size(
+ mbedtls_md_handle_t info )
+{
+ ((void) info);
+ return( MBEDTLS_MD_INFO_SIZE( MBEDTLS_MD_SINGLE_HASH ) );
+}
+
+static inline int mbedtls_md_info_block_size(
+ mbedtls_md_handle_t info )
+{
+ ((void) info);
+ return( MBEDTLS_MD_INFO_BLOCKSIZE( MBEDTLS_MD_SINGLE_HASH ) );
+}
+
+static inline mbedtls_md_starts_func_t *mbedtls_md_info_starts_func(
+ mbedtls_md_handle_t info )
+{
+ ((void) info);
+ return( MBEDTLS_MD_INFO_STARTS_FUNC( MBEDTLS_MD_SINGLE_HASH ) );
+}
+
+static inline mbedtls_md_update_func_t *mbedtls_md_info_update_func(
+ mbedtls_md_handle_t info )
+{
+ ((void) info);
+ return( MBEDTLS_MD_INFO_UPDATE_FUNC( MBEDTLS_MD_SINGLE_HASH ) );
+}
+
+static inline mbedtls_md_finish_func_t *mbedtls_md_info_finish_func(
+ mbedtls_md_handle_t info )
+{
+ ((void) info);
+ return( MBEDTLS_MD_INFO_FINISH_FUNC( MBEDTLS_MD_SINGLE_HASH ) );
+}
+
+static inline mbedtls_md_digest_func_t *mbedtls_md_info_digest_func(
+ mbedtls_md_handle_t info )
+{
+ ((void) info);
+ return( MBEDTLS_MD_INFO_DIGEST_FUNC( MBEDTLS_MD_SINGLE_HASH ) );
+}
+
+static inline mbedtls_md_ctx_alloc_func_t *mbedtls_md_info_ctx_alloc_func(
+ mbedtls_md_handle_t info )
+{
+ ((void) info);
+ return( MBEDTLS_MD_INFO_ALLOC_FUNC( MBEDTLS_MD_SINGLE_HASH ) );
+}
+
+static inline mbedtls_md_ctx_free_func_t *mbedtls_md_info_ctx_free_func(
+ mbedtls_md_handle_t info )
+{
+ ((void) info);
+ return( MBEDTLS_MD_INFO_FREE_FUNC( MBEDTLS_MD_SINGLE_HASH ) );
+}
+
+static inline mbedtls_md_clone_func_t *mbedtls_md_info_clone_func(
+ mbedtls_md_handle_t info )
+{
+ ((void) info);
+ return( MBEDTLS_MD_INFO_CLONE_FUNC( MBEDTLS_MD_SINGLE_HASH ) );
+}
+
+static inline mbedtls_md_process_func_t *mbedtls_md_info_process_func(
+ mbedtls_md_handle_t info )
+{
+ ((void) info);
+ return( MBEDTLS_MD_INFO_PROCESS_FUNC( MBEDTLS_MD_SINGLE_HASH ) );
+}
+
+#endif /* MBEDTLS_MD_SINGLE_HASH */
+
+#if !defined(MBEDTLS_MD_SINGLE_HASH)
+
/*
* Reminder: update profiles in x509_crt.c when adding a new hash!
*/
@@ -951,6 +1064,41 @@
}
}
+#else /* MBEDTLS_MD_SINGLE_HASH */
+
+const int *mbedtls_md_list( void )
+{
+ static int single_hash[2] =
+ { MBEDTLS_MD_INFO_TYPE( MBEDTLS_MD_SINGLE_HASH ),
+ MBEDTLS_MD_INVALID_HANDLE };
+
+ return( single_hash );
+}
+
+mbedtls_md_handle_t mbedtls_md_info_from_string( const char *md_name )
+{
+ static const char * const hash_name =
+ MBEDTLS_MD_INFO_NAME( MBEDTLS_MD_SINGLE_HASH );
+
+ if( md_name != NULL && strcmp( hash_name, md_name ) == 0 )
+ return( MBEDTLS_MD_UNIQUE_VALID_HANDLE );
+
+ return( MBEDTLS_MD_INVALID_HANDLE );
+}
+
+mbedtls_md_handle_t mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
+{
+ static const mbedtls_md_type_t hash_type =
+ MBEDTLS_MD_INFO_TYPE( MBEDTLS_MD_SINGLE_HASH );
+
+ if( hash_type == md_type )
+ return( MBEDTLS_MD_UNIQUE_VALID_HANDLE );
+
+ return( MBEDTLS_MD_INVALID_HANDLE );
+}
+
+#endif /* MBEDTLS_MD_SINGLE_HASH */
+
void mbedtls_md_init( mbedtls_md_context_t *ctx )
{
memset( ctx, 0, sizeof( mbedtls_md_context_t ) );