Demonstrate better practices in HMAC examples
- avoid hardcoded sizes when there's a macro for that
- avoid mutable global variables
- zeroize potentially-sensitive local buffer on exit
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
diff --git a/programs/psa/hmac_non_psa.c b/programs/psa/hmac_non_psa.c
index 0b4eff5..66fcf7e 100644
--- a/programs/psa/hmac_non_psa.c
+++ b/programs/psa/hmac_non_psa.c
@@ -42,6 +42,8 @@
#include "mbedtls/md.h"
+#include "mbedtls/platform_util.h" // for mbedtls_platform_zeroize
+
#include <stdlib.h>
#include <stdio.h>
@@ -66,15 +68,12 @@
* This example program uses SHA-256, so a 32-byte key makes sense. */
const unsigned char key_bytes[32] = { 0 };
-/* Buffer for the output - using SHA-256, so 32-byte output */
-unsigned char out[32];
-
-/* Print the contents of the output buffer in hex */
-void print_out( const char *title )
+/* Print the contents of a buffer in hex */
+void print_buf( const char *title, unsigned char *buf, size_t len )
{
printf( "%s:", title );
- for( size_t i = 0; i < sizeof( out ); i++ )
- printf( " %02x", out[i] );
+ for( size_t i = 0; i < len; i++ )
+ printf( " %02x", buf[i] );
printf( "\n" );
}
@@ -100,29 +99,34 @@
int hmac_demo(void)
{
int ret;
+ const mbedtls_md_type_t alg = MBEDTLS_MD_SHA256;
+ unsigned char out[MBEDTLS_MD_MAX_SIZE]; // safe but not optimal
+
mbedtls_md_context_t ctx;
mbedtls_md_init( &ctx );
/* prepare context and load key */
- CHK( mbedtls_md_setup( &ctx, mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ), 1 ) );
+ // the last argument to setup is 1 to enable HMAC (not just hashing)
+ CHK( mbedtls_md_setup( &ctx, mbedtls_md_info_from_type( alg ), 1 ) );
CHK( mbedtls_md_hmac_starts( &ctx, key_bytes, sizeof( key_bytes ) ) );
/* compute HMAC(key, msg1_part1 | msg1_part2) */
CHK( mbedtls_md_hmac_update( &ctx, msg1_part1, sizeof( msg1_part1 ) ) );
CHK( mbedtls_md_hmac_update( &ctx, msg1_part2, sizeof( msg1_part2 ) ) );
CHK( mbedtls_md_hmac_finish( &ctx, out ) );
- print_out( "msg1" );
+ print_buf( "msg1", out, sizeof( out ) );
/* compute HMAC(key, msg2_part1 | msg2_part2) */
CHK( mbedtls_md_hmac_reset( &ctx ) ); // prepare for new operation
CHK( mbedtls_md_hmac_update( &ctx, msg2_part1, sizeof( msg2_part1 ) ) );
CHK( mbedtls_md_hmac_update( &ctx, msg2_part2, sizeof( msg2_part2 ) ) );
CHK( mbedtls_md_hmac_finish( &ctx, out ) );
- print_out( "msg2" );
+ print_buf( "msg2", out, sizeof( out ) );
exit:
mbedtls_md_free( &ctx );
+ mbedtls_platform_zeroize( out, sizeof( out ) );
return( ret );
}