diff --git a/ChangeLog b/ChangeLog index 4843341a97..209b1e25f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,8 @@ Features ability to override the whole module. * New server-side implementation of session tickets that rotate keys to preserve forward secrecy, and allows sharing across multiple contexts. + * Reduced ROM fooprint of SHA-256 and added an option to reduce it even + more (at the expense of performance) MBEDTLS_SHA256_SMALLER. API Changes * All public identifiers moved to the mbedtls_* or MBEDTLS_* namespace. diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 6c841ae0e2..f0d293c080 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -827,6 +827,22 @@ */ #define MBEDTLS_SELF_TEST +/** + * \def MBEDTLS_SHA256_SMALLER + * + * Enable an implementation of SHA-256 that has lower ROM footprint but also + * lower performance. + * + * The default implementation is meant to be a reasonnable compromise between + * performance and size. This version optimizes more aggressively for size at + * the expense of performance. Eg on Cortex-M4 it reduces the size of + * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about + * 30%. + * + * Uncomment to enable the smaller implementation of SHA256. + */ +//#define MBEDTLS_SHA256_SMALLER + /** * \def MBEDTLS_SSL_AEAD_RANDOM_IV * diff --git a/library/sha256.c b/library/sha256.c index f80c2b8aab..4e0b1f3280 100644 --- a/library/sha256.c +++ b/library/sha256.c @@ -62,22 +62,22 @@ static void mbedtls_zeroize( void *v, size_t n ) { */ #ifndef GET_UINT32_BE #define GET_UINT32_BE(n,b,i) \ -{ \ +do { \ (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ | ( (uint32_t) (b)[(i) + 1] << 16 ) \ | ( (uint32_t) (b)[(i) + 2] << 8 ) \ | ( (uint32_t) (b)[(i) + 3] ); \ -} +} while( 0 ) #endif #ifndef PUT_UINT32_BE #define PUT_UINT32_BE(n,b,i) \ -{ \ +do { \ (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} +} while( 0 ) #endif void mbedtls_sha256_init( mbedtls_sha256_context *ctx ) @@ -181,12 +181,26 @@ void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char da uint32_t A[8]; unsigned int i; - for( i = 0; i < 16; i++ ) - GET_UINT32_BE( W[i], data, 4 * i ); - for( i = 0; i < 8; i++ ) A[i] = ctx->state[i]; +#if defined(MBEDTLS_SHA256_SMALLER) + for( i = 0; i < 64; i++ ) + { + if( i < 16 ) + GET_UINT32_BE( W[i], data, 4 * i ); + else + R( i ); + + P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); + + temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3]; + A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1; + } +#else /* MBEDTLS_SHA256_SMALLER */ + for( i = 0; i < 16; i++ ) + GET_UINT32_BE( W[i], data, 4 * i ); + for( i = 0; i < 16; i += 8 ) { P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] ); @@ -210,6 +224,7 @@ void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char da P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] ); P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] ); } +#endif /* MBEDTLS_SHA256_SMALLER */ for( i = 0; i < 8; i++ ) ctx->state[i] += A[i]; diff --git a/library/version_features.c b/library/version_features.c index 429d54ed6f..d910b60dae 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -315,6 +315,9 @@ static const char *features[] = { #if defined(MBEDTLS_SELF_TEST) "MBEDTLS_SELF_TEST", #endif /* MBEDTLS_SELF_TEST */ +#if defined(MBEDTLS_SHA256_SMALLER) + "MBEDTLS_SHA256_SMALLER", +#endif /* MBEDTLS_SHA256_SMALLER */ #if defined(MBEDTLS_SSL_AEAD_RANDOM_IV) "MBEDTLS_SSL_AEAD_RANDOM_IV", #endif /* MBEDTLS_SSL_AEAD_RANDOM_IV */