diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index be8033296..e34661bd4 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -392,6 +392,16 @@ #error "MBEDTLS_PLATFORM_SNPRINTF_ALT defined, but not all prerequisites" #endif +#if defined(MBEDTLS_PLATFORM_TF_SNPRINTF) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_TF_SNPRINTF defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TF_SNPRINTF) &&\ + ( defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) ||\ + defined(MBEDTLS_PLATFORM_STD_SNPRINTF) ) +#error "MBEDTLS_PLATFORM_TF_SNPRINTF and MBEDTLS_PLATFORM_SNPRINTF_ALT/MBEDTLS_PLATFORM_STD_SNPRINTF, cannot be defined simultaneously" +#endif + #if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) #error "MBEDTLS_PLATFORM_SNPRINTF_MACRO defined, but not all prerequisites" #endif @@ -399,7 +409,7 @@ #if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) &&\ ( defined(MBEDTLS_PLATFORM_STD_SNPRINTF) ||\ defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) ) -#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_SNPRINTF/MBEDTLS_PLATFORM_SNPRINTF_ALT cannot be defined simultaneously" +#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_SNPRINTF/MBEDTLS_PLATFORM_SNPRINTF_ALT/MBEDTLS_PLATFORM_TF_SNPRINTF cannot be defined simultaneously" #endif #if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) &&\ diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 1c98558eb..6737816a3 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -194,6 +194,22 @@ //#define MBEDTLS_PLATFORM_NV_SEED_ALT //#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT +/** + * \def MBEDTLS_PLATFORM_TF_SNPRINTF + * + * Uncomment to enable the reduced snprintf to be used for trusted firmware. + * + * \warning Only The following type specifiers are supported: + * %d or %i - signed decimal format + * %u - unsigned decimal format + * The print panics on all other formats specifiers. + * + * \warning MBEDTLS_PLATFORM_SNPRINTF_ALT cannot be defined at the same time as + * MBEDTLS_PLATFORM_TF_SNPRINTF! + * + */ +//#define MBEDTLS_PLATFORM_TF_SNPRINTF + /** * \def MBEDTLS_DEPRECATED_WARNING * diff --git a/include/mbedtls/platform.h b/include/mbedtls/platform.h index ed1077584..8e8a27e13 100644 --- a/include/mbedtls/platform.h +++ b/include/mbedtls/platform.h @@ -50,6 +50,7 @@ extern "C" { #include #include #include +#include #if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) #if defined(_WIN32) #define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use. */ diff --git a/library/platform.c b/library/platform.c index a295f9b9a..d17744922 100644 --- a/library/platform.c +++ b/library/platform.c @@ -98,6 +98,111 @@ int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ) } #endif +#if defined(MBEDTLS_PLATFORM_TF_SNPRINTF) + +static void unsigned_dec_print( char **s, size_t n, size_t *chars_printed, + unsigned int unum ) +{ + /* Enough for a 32-bit unsigned decimal integer (4294967295). */ + unsigned char num_buf[10]; + int i = 0, rem; + + do + { + rem = unum % 10; + num_buf[i++] = '0' + rem; + } while( unum /= 10 ); + + while( --i >= 0 ) + { + if( *chars_printed < n ) + *(*s)++ = num_buf[i]; + (*chars_printed)++; + } +} + +int tf_snprintf( char *s, size_t n, const char *fmt, ... ) +{ + va_list args; + int num; + unsigned int unum; + size_t chars_printed = 0; + + if( n == 1 ) + { + /* Buffer is too small to actually write anything else. */ + *s = '\0'; + n = 0; + } + else if( n >= 2 ) + { + /* Reserve space for the terminator character. */ + n--; + } + + va_start( args, fmt ); + while( *fmt ) { + + if( *fmt == '%' ) + { + fmt++; + /* Check the format specifier. */ + switch( *fmt ) + { + case 'i': + case 'd': + num = va_arg( args, int ); + + if( num < 0 ) + { + if( chars_printed < n ) + *s++ = '-'; + chars_printed++; + + unum = (unsigned int)-num; + } + else + { + unum = (unsigned int)num; + } + + unsigned_dec_print( &s, n, &chars_printed, unum ); + break; + case 'u': + unum = va_arg( args, unsigned int ); + unsigned_dec_print( &s, n, &chars_printed, unum ); + break; + default: + /* Return error on any other specifier. */ + chars_printed = -1; + goto exit; + } + fmt++; + continue; + } + + if( chars_printed < n ) + *s++ = *fmt; + fmt++; + chars_printed++; + } + +exit: + va_end( args ); + + if( n > 0 ) + *s = '\0'; + + return( chars_printed ); +} + +#if defined(MBEDTLS_PLATFORM_STD_SNPRINTF) +#undef MBEDTLS_PLATFORM_STD_SNPRINTF +#endif +#define MBEDTLS_PLATFORM_STD_SNPRINTF tf_snprintf; + +#endif /* MBEDTLS_PLATFORM_TF_SNPRINTF */ + #if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) #if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) /*