diff --git a/Makefile b/Makefile index 299ff30..c5c281a 100644 --- a/Makefile +++ b/Makefile @@ -163,6 +163,7 @@ BL_COMMON_SOURCES += common/bl_common.c \ common/tf_printf.c \ + common/tf_snprintf.c \ common/${ARCH}/debug.S \ lib/${ARCH}/cache_helpers.S \ lib/${ARCH}/misc_helpers.S \ diff --git a/common/tf_snprintf.c b/common/tf_snprintf.c new file mode 100644 index 0000000..a99ab7a --- /dev/null +++ b/common/tf_snprintf.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +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)++; + } +} + +/******************************************************************* + * Reduced snprintf to be used for Trusted firmware. + * The following type specifiers are supported: + * + * %d or %i - signed decimal format + * %u - unsigned decimal format + * + * The function panics on all other formats specifiers. + * + * It returns the number of characters that would be written if the + * buffer was big enough. If it returns a value lower than n, the + * whole string has been written. + *******************************************************************/ +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: + /* Panic on any other format specifier. */ + ERROR("tf_snprintf: specifier with ASCII code '%d' not supported.", + *fmt); + plat_panic_handler(); + } + fmt++; + continue; + } + + if (chars_printed < n) + *s++ = *fmt; + fmt++; + chars_printed++; + } + + va_end(args); + + if (n > 0) + *s = '\0'; + + return chars_printed; +} diff --git a/docs/auth-framework.md b/docs/auth-framework.md index 531505b..b416acf 100644 --- a/docs/auth-framework.md +++ b/docs/auth-framework.md @@ -909,9 +909,13 @@ ``` The key algorithm (rsa, ecdsa) must be specified in the build system using the -`MBEDTLS_KEY_ALG` variable, so the Makefile can include the corresponding +`TF_MBEDTLS_KEY_ALG` variable, so the Makefile can include the corresponding sources in the build. +Note: If code size is a concern, the build option `MBEDTLS_SHA256_SMALLER` can +be defined in the platform Makefile. It will make mbed TLS use an implementation +of SHA-256 with smaller memory footprint (~1.5 KB less) but slower (~30%). + - - - - - - - - - - - - - - - - - - - - - - - - - - _Copyright (c) 2015, ARM Limited and Contributors. All rights reserved._ diff --git a/drivers/auth/mbedtls/mbedtls_common.c b/drivers/auth/mbedtls/mbedtls_common.c index aad49a7..871831e 100644 --- a/drivers/auth/mbedtls/mbedtls_common.c +++ b/drivers/auth/mbedtls/mbedtls_common.c @@ -4,10 +4,11 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +#include /* mbed TLS headers */ #include +#include /* * mbed TLS heap @@ -29,6 +30,10 @@ if (!ready) { /* Initialize the mbed TLS heap */ mbedtls_memory_buffer_alloc_init(heap, MBEDTLS_HEAP_SIZE); + + /* Use reduced version of snprintf to save space. */ + mbedtls_platform_set_snprintf(tf_snprintf); + ready = 1; } } diff --git a/include/common/debug.h b/include/common/debug.h index 646daba..814cf84 100644 --- a/include/common/debug.h +++ b/include/common/debug.h @@ -64,6 +64,7 @@ void __dead2 __stack_chk_fail(void); void tf_printf(const char *fmt, ...) __printflike(1, 2); +int tf_snprintf(char *s, size_t n, const char *fmt, ...) __printflike(3, 4); #endif /* __ASSEMBLY__ */ #endif /* __DEBUG_H__ */ diff --git a/include/drivers/auth/mbedtls/mbedtls_config.h b/include/drivers/auth/mbedtls/mbedtls_config.h index 7d8d17c..22e7574 100644 --- a/include/drivers/auth/mbedtls/mbedtls_config.h +++ b/include/drivers/auth/mbedtls/mbedtls_config.h @@ -19,6 +19,8 @@ #define MBEDTLS_PLATFORM_MEMORY #define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS +/* Prevent mbed TLS from using snprintf so that it can use tf_snprintf. */ +#define MBEDTLS_PLATFORM_SNPRINTF_ALT #define MBEDTLS_PKCS1_V15 #define MBEDTLS_PKCS1_V21 diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 3c20769..5cc1a0a 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -76,6 +76,10 @@ $(eval $(call assert_boolean,ARM_XLAT_TABLES_LIB_V1)) $(eval $(call add_define,ARM_XLAT_TABLES_LIB_V1)) +# Use an implementation of SHA-256 with a smaller memory footprint but reduced +# speed. +$(eval $(call add_define,MBEDTLS_SHA256_SMALLER)) + # Enable PSCI_STAT_COUNT/RESIDENCY APIs on ARM platforms ENABLE_PSCI_STAT := 1 ENABLE_PMF := 1