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