diff --git a/Makefile b/Makefile index 299ff3038703da6ba06365ab7d254bd8320e2969..c5c281aa9da0a284fcfb8dd8d6dd29e4e59d8166 100644 --- a/Makefile +++ b/Makefile @@ -163,6 +163,7 @@ include lib/stdlib/stdlib.mk 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 0000000000000000000000000000000000000000..a99ab7ab5d9dd12f02833db058c2a7e9b98dfcb0 --- /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 <debug.h> +#include <platform.h> +#include <stdarg.h> + +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 531505bfa83793aa3faf514d1e8dda8b91007afd..b416acfc27af7ee4e29e9d5c791973ee3575c686 100644 --- a/docs/auth-framework.md +++ b/docs/auth-framework.md @@ -909,9 +909,13 @@ int verify_hash(void *data_ptr, unsigned int data_len, ``` 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 aad49a7152ef58789eadb25371a9ee24240cf416..871831e2d8e646be1d8e8990b3c564829d0e973b 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 <assert.h> +#include <debug.h> /* mbed TLS headers */ #include <mbedtls/memory_buffer_alloc.h> +#include <mbedtls/platform.h> /* * mbed TLS heap @@ -29,6 +30,10 @@ void mbedtls_init(void) 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 646dabafb84ab374cef0cee5699fe2f6deb260c8..814cf8402a19f0019ffa0adf51d1fe35890ef1ad 100644 --- a/include/common/debug.h +++ b/include/common/debug.h @@ -64,6 +64,7 @@ void __dead2 do_panic(void); 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 7d8d17c357b1fd90faf76c10bc80e0e1abac0650..22e75742a34a11794f013dc9fa1a9fe722e1009f 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 3c207698b5f720d84e838f3530e95c69c92d1479..5cc1a0ac721d3ccdc456863c87623f25dcb0a422 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -76,6 +76,10 @@ ARM_XLAT_TABLES_LIB_V1 := 0 $(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