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.
This commit is contained in:
Hanno Becker 2019-08-13 15:43:26 +01:00
parent d03949e2a4
commit 1292c35c03
4 changed files with 180 additions and 0 deletions

View File

@ -3815,6 +3815,20 @@
//#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID //#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_MD_ID
//#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID //#define MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID
/* Set this to MBEDTLS_MD_INFO_{DIGEST} support of a single message
* digest at compile-time, at the benefit of code-size.
*
* On highly constrained systems with large control over the configuration of
* the connection endpoints, this option can be used to hardcode support for
* a single hash algorithm.
*
* You need to make sure that the corresponding digest algorithm attributes
* are defined through macros in md.c. See the definitions
* MBEDTLS_MD_INFO_SHA256_XXX for example.
*
*/
//#define MBEDTLS_MD_SINGLE_HASH MBEDTLS_MD_INFO_SHA256
/* \} SECTION: Compile-time SSL configuration */ /* \} SECTION: Compile-time SSL configuration */
/* Target and application specific configurations /* Target and application specific configurations

View File

@ -80,6 +80,8 @@ typedef enum {
#define MBEDTLS_MD_MAX_BLOCK_SIZE 64 #define MBEDTLS_MD_MAX_BLOCK_SIZE 64
#endif #endif
#if !defined(MBEDTLS_MD_SINGLE_HASH)
/** /**
* Opaque struct defined in md.c. * Opaque struct defined in md.c.
*/ */
@ -89,6 +91,14 @@ typedef struct mbedtls_md_info_t mbedtls_md_info_t;
typedef struct mbedtls_md_info_t const * mbedtls_md_handle_t; typedef struct mbedtls_md_info_t const * mbedtls_md_handle_t;
#define MBEDTLS_MD_INVALID_HANDLE ( (mbedtls_md_handle_t) NULL ) #define MBEDTLS_MD_INVALID_HANDLE ( (mbedtls_md_handle_t) NULL )
#else /* !MBEDTLS_MD_SINGLE_HASH */
typedef int mbedtls_md_handle_t;
#define MBEDTLS_MD_INVALID_HANDLE ( (mbedtls_md_handle_t) 0 )
#define MBEDTLS_MD_UNIQUE_VALID_HANDLE ( (mbedtls_md_handle_t) 1 )
#endif /* !MBEDTLS_MD_SINGLE_HASH */
/** /**
* The generic message-digest context. * The generic message-digest context.
*/ */

View File

@ -148,6 +148,7 @@ typedef void mbedtls_md_clone_func_t( void *st, const void *src );
typedef int mbedtls_md_process_func_t( void *ctx, typedef int mbedtls_md_process_func_t( void *ctx,
const unsigned char *input ); const unsigned char *input );
#if !defined(MBEDTLS_MD_SINGLE_HASH)
struct mbedtls_md_info_t struct mbedtls_md_info_t
{ {
/** Digest identifier */ /** Digest identifier */
@ -205,6 +206,8 @@ struct mbedtls_md_info_t
MBEDTLS_MD_INFO_CLONE_FUNC( MD ), \ MBEDTLS_MD_INFO_CLONE_FUNC( MD ), \
MBEDTLS_MD_INFO_PROCESS_FUNC( MD ) } MBEDTLS_MD_INFO_PROCESS_FUNC( MD ) }
#endif /* !MBEDTLS_MD_SINGLE_HASH */
/* /*
* *
* Definitions of MD information structures for various digests. * Definitions of MD information structures for various digests.
@ -262,6 +265,7 @@ static int md2_process_wrap( void *ctx, const unsigned char *data )
return( mbedtls_internal_md2_process( (mbedtls_md2_context *) ctx ) ); return( mbedtls_internal_md2_process( (mbedtls_md2_context *) ctx ) );
} }
#if !defined(MBEDTLS_MD_SINGLE_HASH)
const mbedtls_md_info_t mbedtls_md2_info = { const mbedtls_md_info_t mbedtls_md2_info = {
MBEDTLS_MD_MD2, MBEDTLS_MD_MD2,
"MD2", "MD2",
@ -276,6 +280,7 @@ const mbedtls_md_info_t mbedtls_md2_info = {
md2_clone_wrap, md2_clone_wrap,
md2_process_wrap, md2_process_wrap,
}; };
#endif /* !MBEDTLS_MD_SINGLE_HASH */
#endif /* MBEDTLS_MD2_C */ #endif /* MBEDTLS_MD2_C */
@ -328,6 +333,7 @@ static int md4_process_wrap( void *ctx, const unsigned char *data )
return( mbedtls_internal_md4_process( (mbedtls_md4_context *) ctx, data ) ); return( mbedtls_internal_md4_process( (mbedtls_md4_context *) ctx, data ) );
} }
#if !defined(MBEDTLS_MD_SINGLE_HASH)
const mbedtls_md_info_t mbedtls_md4_info = { const mbedtls_md_info_t mbedtls_md4_info = {
MBEDTLS_MD_MD4, MBEDTLS_MD_MD4,
"MD4", "MD4",
@ -342,6 +348,7 @@ const mbedtls_md_info_t mbedtls_md4_info = {
md4_clone_wrap, md4_clone_wrap,
md4_process_wrap, md4_process_wrap,
}; };
#endif /* MBEDTLS_MD_SINGLE_HASH */
#endif /* MBEDTLS_MD4_C */ #endif /* MBEDTLS_MD4_C */
@ -394,6 +401,7 @@ static int md5_process_wrap( void *ctx, const unsigned char *data )
return( mbedtls_internal_md5_process( (mbedtls_md5_context *) ctx, data ) ); return( mbedtls_internal_md5_process( (mbedtls_md5_context *) ctx, data ) );
} }
#if !defined(MBEDTLS_MD_SINGLE_HASH)
const mbedtls_md_info_t mbedtls_md5_info = { const mbedtls_md_info_t mbedtls_md5_info = {
MBEDTLS_MD_MD5, MBEDTLS_MD_MD5,
"MD5", "MD5",
@ -408,6 +416,7 @@ const mbedtls_md_info_t mbedtls_md5_info = {
md5_clone_wrap, md5_clone_wrap,
md5_process_wrap, md5_process_wrap,
}; };
#endif /* MBEDTLS_MD_SINGLE_HASH */
#endif /* MBEDTLS_MD5_C */ #endif /* MBEDTLS_MD5_C */
@ -463,6 +472,7 @@ static int ripemd160_process_wrap( void *ctx, const unsigned char *data )
(mbedtls_ripemd160_context *) ctx, data ) ); (mbedtls_ripemd160_context *) ctx, data ) );
} }
#if !defined(MBEDTLS_MD_SINGLE_HASH)
const mbedtls_md_info_t mbedtls_ripemd160_info = { const mbedtls_md_info_t mbedtls_ripemd160_info = {
MBEDTLS_MD_RIPEMD160, MBEDTLS_MD_RIPEMD160,
"RIPEMD160", "RIPEMD160",
@ -477,6 +487,7 @@ const mbedtls_md_info_t mbedtls_ripemd160_info = {
ripemd160_clone_wrap, ripemd160_clone_wrap,
ripemd160_process_wrap, ripemd160_process_wrap,
}; };
#endif /* !MBEDTLS_MD_SINGLE_HASH */
#endif /* MBEDTLS_RIPEMD160_C */ #endif /* MBEDTLS_RIPEMD160_C */
@ -531,6 +542,7 @@ static int sha1_process_wrap( void *ctx, const unsigned char *data )
data ) ); data ) );
} }
#if !defined(MBEDTLS_MD_SINGLE_HASH)
const mbedtls_md_info_t mbedtls_sha1_info = { const mbedtls_md_info_t mbedtls_sha1_info = {
MBEDTLS_MD_SHA1, MBEDTLS_MD_SHA1,
"SHA1", "SHA1",
@ -545,6 +557,7 @@ const mbedtls_md_info_t mbedtls_sha1_info = {
sha1_clone_wrap, sha1_clone_wrap,
sha1_process_wrap, sha1_process_wrap,
}; };
#endif /* !MBEDTLS_MD_SINGLE_HASH */
#endif /* MBEDTLS_SHA1_C */ #endif /* MBEDTLS_SHA1_C */
@ -610,6 +623,7 @@ static int sha224_process_wrap( void *ctx, const unsigned char *data )
data ) ); data ) );
} }
#if !defined(MBEDTLS_MD_SINGLE_HASH)
#if !defined(MBEDTLS_SHA256_NO_SHA224) #if !defined(MBEDTLS_SHA256_NO_SHA224)
const mbedtls_md_info_t mbedtls_sha224_info = { const mbedtls_md_info_t mbedtls_sha224_info = {
MBEDTLS_MD_SHA224, MBEDTLS_MD_SHA224,
@ -626,6 +640,7 @@ const mbedtls_md_info_t mbedtls_sha224_info = {
sha224_process_wrap, sha224_process_wrap,
}; };
#endif /* !MBEDTLS_SHA256_NO_SHA224 */ #endif /* !MBEDTLS_SHA256_NO_SHA224 */
#endif /* !MBEDTLS_MD_SINGLE_HASH */
static int sha256_starts_wrap( void *ctx ) static int sha256_starts_wrap( void *ctx )
{ {
@ -638,8 +653,10 @@ static int sha256_wrap( const unsigned char *input, size_t ilen,
return( mbedtls_sha256_ret( input, ilen, output, 0 ) ); return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
} }
#if !defined(MBEDTLS_MD_SINGLE_HASH)
const mbedtls_md_info_t mbedtls_sha256_info = const mbedtls_md_info_t mbedtls_sha256_info =
MBEDTLS_MD_INFO( MBEDTLS_MD_INFO_SHA256 ); MBEDTLS_MD_INFO( MBEDTLS_MD_INFO_SHA256 );
#endif /* !MBEDTLS_MD_SINGLE_HASH */
#endif /* MBEDTLS_SHA256_C */ #endif /* MBEDTLS_SHA256_C */
@ -701,6 +718,7 @@ static int sha384_process_wrap( void *ctx, const unsigned char *data )
data ) ); data ) );
} }
#if !defined(MBEDTLS_MD_SINGLE_HASH)
const mbedtls_md_info_t mbedtls_sha384_info = { const mbedtls_md_info_t mbedtls_sha384_info = {
MBEDTLS_MD_SHA384, MBEDTLS_MD_SHA384,
"SHA384", "SHA384",
@ -715,6 +733,7 @@ const mbedtls_md_info_t mbedtls_sha384_info = {
sha384_clone_wrap, sha384_clone_wrap,
sha384_process_wrap, sha384_process_wrap,
}; };
#endif /* MBEDTLS_MD_SINGLE_HASH */
static int sha512_starts_wrap( void *ctx ) static int sha512_starts_wrap( void *ctx )
{ {
@ -727,6 +746,7 @@ static int sha512_wrap( const unsigned char *input, size_t ilen,
return( mbedtls_sha512_ret( input, ilen, output, 0 ) ); return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
} }
#if !defined(MBEDTLS_MD_SINGLE_HASH)
const mbedtls_md_info_t mbedtls_sha512_info = { const mbedtls_md_info_t mbedtls_sha512_info = {
MBEDTLS_MD_SHA512, MBEDTLS_MD_SHA512,
"SHA512", "SHA512",
@ -741,6 +761,7 @@ const mbedtls_md_info_t mbedtls_sha512_info = {
sha384_clone_wrap, sha384_clone_wrap,
sha384_process_wrap, sha384_process_wrap,
}; };
#endif /* MBEDTLS_MD_SINGLE_HASH */
#endif /* MBEDTLS_SHA512_C */ #endif /* MBEDTLS_SHA512_C */
@ -748,6 +769,8 @@ const mbedtls_md_info_t mbedtls_sha512_info = {
* Getter functions for MD info structure. * Getter functions for MD info structure.
*/ */
#if !defined(MBEDTLS_MD_SINGLE_HASH)
static inline mbedtls_md_type_t mbedtls_md_info_type( static inline mbedtls_md_type_t mbedtls_md_info_type(
mbedtls_md_handle_t info ) mbedtls_md_handle_t info )
{ {
@ -820,6 +843,96 @@ static inline mbedtls_md_process_func_t *mbedtls_md_info_process_func(
return( info->process_func ); 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! * Reminder: update profiles in x509_crt.c when adding a new hash!
*/ */
@ -951,6 +1064,41 @@ mbedtls_md_handle_t mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
} }
} }
#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 ) void mbedtls_md_init( mbedtls_md_context_t *ctx )
{ {
memset( ctx, 0, sizeof( mbedtls_md_context_t ) ); memset( ctx, 0, sizeof( mbedtls_md_context_t ) );

View File

@ -2906,6 +2906,14 @@ int query_config( const char *config )
} }
#endif /* MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID */ #endif /* MBEDTLS_SSL_CONF_SINGLE_SIG_HASH_TLS_ID */
#if defined(MBEDTLS_MD_SINGLE_HASH)
if( strcmp( "MBEDTLS_MD_SINGLE_HASH", config ) == 0 )
{
MACRO_EXPANSION_TO_STR( MBEDTLS_MD_SINGLE_HASH );
return( 0 );
}
#endif /* MBEDTLS_MD_SINGLE_HASH */
/* If the symbol is not found, return an error */ /* If the symbol is not found, return an error */
return( 1 ); return( 1 );
} }