Crypto: Add alternatives of mbed-crypto implementations

Select MBEDTLS_AES_SETKEY_DEC_ALT and MBEDTLS_AES_DECRYPT_ALTA when
AES-CCM is selected.

Add emtpy wrappers of mbedtls_internal_aes_decrypt() and
mbedtls_aes_setkey_dec() to replace mbed-crypto implementation when
the MBEDTLS_AES_SETKEY_DEC_ALT and MBEDTLS_AES_DECRYPT_ALTA are
enabled in AES-CCM mode. It can decrease memory footprint.

Add description of tfm_mbedcrypto_alt.c in Crypto document.

Change-Id: I3b9071735bfd6bafea8189dfde153d6050aefe27
Signed-off-by: David Hu <david.hu@arm.com>
diff --git a/docs/user_guides/services/tfm_crypto_integration_guide.rst b/docs/user_guides/services/tfm_crypto_integration_guide.rst
index ee391aa..f60bc76 100644
--- a/docs/user_guides/services/tfm_crypto_integration_guide.rst
+++ b/docs/user_guides/services/tfm_crypto_integration_guide.rst
@@ -59,6 +59,9 @@
 - ``tfm_crypto_api.c`` :  This module is contained in ``interface/src`` and
   implements the PSA Crypto API client interface exposed to the  Non-Secure
   Processing Environment.
+- ``tfm_mbedcrypto_alt.c`` : This module contains alternative implementations of
+  Mbed Crypto functions. Decryption code is skipped in AES CCM mode in Profile
+  Small by default.
 
 **************************
 Crypto service integration
diff --git a/platform/ext/common/tfm_profile_s_mbedcrypto_config.h b/platform/ext/common/tfm_profile_s_mbedcrypto_config.h
index 376a35c..ee57874 100644
--- a/platform/ext/common/tfm_profile_s_mbedcrypto_config.h
+++ b/platform/ext/common/tfm_profile_s_mbedcrypto_config.h
@@ -429,9 +429,9 @@
 //#define MBEDTLS_DES_CRYPT_ECB_ALT
 //#define MBEDTLS_DES3_CRYPT_ECB_ALT
 //#define MBEDTLS_AES_SETKEY_ENC_ALT
-//#define MBEDTLS_AES_SETKEY_DEC_ALT
+#define MBEDTLS_AES_SETKEY_DEC_ALT
 //#define MBEDTLS_AES_ENCRYPT_ALT
-//#define MBEDTLS_AES_DECRYPT_ALT
+#define MBEDTLS_AES_DECRYPT_ALT
 //#define MBEDTLS_ECDH_GEN_PUBLIC_ALT
 //#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT
 //#define MBEDTLS_ECDSA_VERIFY_ALT
diff --git a/secure_fw/services/crypto/CMakeLists.inc b/secure_fw/services/crypto/CMakeLists.inc
index c6bb1f8..09c53bb 100644
--- a/secure_fw/services/crypto/CMakeLists.inc
+++ b/secure_fw/services/crypto/CMakeLists.inc
@@ -53,6 +53,10 @@
                     "${CRYPTO_DIR}/tfm_crypto_secure_api.c"
       )
 
+  if (CRYPTO_ENGINE_MBEDTLS)
+    list(APPEND CRYPTO_C_SRC "${CRYPTO_DIR}/tfm_mbedcrypto_alt.c")
+  endif()
+
   #Append all our source files to global lists.
   list(APPEND ALL_SRC_C ${CRYPTO_C_SRC})
   unset(CRYPTO_C_SRC)
diff --git a/secure_fw/services/crypto/tfm_mbedcrypto_alt.c b/secure_fw/services/crypto/tfm_mbedcrypto_alt.c
new file mode 100644
index 0000000..9cf9277
--- /dev/null
+++ b/secure_fw/services/crypto/tfm_mbedcrypto_alt.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/*
+ * This file collects the alternative functions to replace the
+ * implementations in mbed-crypto if the corresponding mbed-crypto
+ * MBEDTLS__FUNCTION_NAME__ALT is selected.
+ */
+
+/*
+ * A dummy include. Just add a dependency to make sure this file is compiled
+ * after all crypto header files are installed and configuration flags are set.
+ */
+#include "tfm_mbedcrypto_include.h"
+#if defined(MBEDTLS_AES_DECRYPT_ALT) || defined(MBEDTLS_AES_SETKEY_DEC_ALT)
+#include "mbedtls/aes.h"
+#endif
+
+#if defined(MBEDTLS_AES_DECRYPT_ALT) && defined(MBEDTLS_CCM_C)
+#pragma message("mbedtls_internal_aes_decrypt() is replaced by an empty wrapper to decrease memory footprint")
+/*
+ * Replace the decryption process with an empty wrapper in AES-CCM mode.
+ * The decryption process is exactly the same as encryption process. Skip
+ * the decryption implementation to decrease memory footprint.
+ */
+int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
+                                 const unsigned char input[16],
+                                 unsigned char output[16])
+{
+    (void)ctx;
+    (void)input;
+    (void)output;
+
+    return MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE;
+}
+#endif
+
+#if defined(MBEDTLS_AES_SETKEY_DEC_ALT) && defined(MBEDTLS_CCM_C)
+#pragma message("mbedtls_aes_setkey_dec() is replaced by an empty wrapper to decrease memory footprint")
+/*
+ * Replace the decryption process with an empty wrapper in AES-CCM mode.
+ * The decryption process is exactly the same as encryption process. Skip
+ * the decryption key setting to decrease memory footprint.
+ */
+int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
+                           unsigned int keybits)
+{
+    (void)ctx;
+    (void)key;
+    (void)keybits;
+
+    return MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE;
+}
+#endif