Stack_seal_mitigation: Secure harden the Main Stack Pointer (MSP)

Seal the MSP_S for both IPC mode and Library mode with the recommended
stack seal value during runtime. Check the comments in the header
file for more details.

Change-Id: Icc36f318d5416aa2c3df8b4d647d892caddd20c3
Signed-off-by: Ken Liu <ken.liu@arm.com>
diff --git a/secure_fw/spm/include/tfm_arch_v8m.h b/secure_fw/spm/include/tfm_arch_v8m.h
index 94a2e4f..a0912c4 100644
--- a/secure_fw/spm/include/tfm_arch_v8m.h
+++ b/secure_fw/spm/include/tfm_arch_v8m.h
@@ -11,6 +11,8 @@
 #include <stdbool.h>
 
 #include "cmsis_compiler.h"
+#include "tfm_core_trustzone.h"
+#include "utilities.h"
 
 #define EXC_RETURN_INDICATOR                    (0xFF << 24)
 #define EXC_RETURN_RES1                         (0x1FFFF << 7)
@@ -119,12 +121,29 @@
 }
 
 /**
- * \brief Set MSPLIM register.
+ * \brief Set MSPLIM register and seal the MSP.
+ *
+ * This function assumes that the caller is using PSP when calling this
+ * function.
  *
  * \param[in] msplim        Register value to be written into MSPLIM.
  */
-__STATIC_INLINE void tfm_arch_set_msplim(uint32_t msplim)
+__STATIC_INLINE void tfm_arch_init_secure_msp(uint32_t msplim)
 {
+    uint32_t mstk_adr = __get_MSP();
+
+    /*
+     * Seal the main stack and update MSP to point below the stack seal.
+     * Set MSPLIM. As the initial 'main()' code is running under privileged PSP
+     * manipulating MSP works here.
+     */
+    TFM_CORE_ASSERT((mstk_adr & 0x7) == 0);
+    mstk_adr -= TFM_STACK_SEALED_SIZE;
+
+    *((uint32_t *)mstk_adr)       = TFM_STACK_SEAL_VALUE;
+    *((uint32_t *)(mstk_adr + 4)) = TFM_STACK_SEAL_VALUE;
+
+    __set_MSP(mstk_adr);
     __set_MSPLIM(msplim);
 }