Build: Add flag to protect NV counters when testing

Adds an SST_TEST_NV_COUNTERS build flag that enables a virtual
implementation of the SST NV counters interface and disables the
hardware NV counter implementation. This flag is automatically enabled
when running the regression tests to protect the hardware counters from
burn-out.

Change-Id: I7bd66ee45ea865dbf5af236123c4f7ef4391f249
Signed-off-by: Jamie Fox <jamie.fox@arm.com>
diff --git a/CommonConfig.cmake b/CommonConfig.cmake
index 1bbf95a..711b078 100644
--- a/CommonConfig.cmake
+++ b/CommonConfig.cmake
@@ -254,6 +254,14 @@
 	endif()
 endif()
 
+if (NOT DEFINED SST_TEST_NV_COUNTERS)
+	if (REGRESSION AND (TFM_LVL EQUAL 1))
+		set(SST_TEST_NV_COUNTERS ON)
+	else()
+		set(SST_TEST_NV_COUNTERS OFF)
+	endif()
+endif()
+
 if (NOT DEFINED MBEDTLS_DEBUG)
 	set(MBEDTLS_DEBUG OFF)
 endif()
diff --git a/docs/user_guides/services/tfm_sst_integration_guide.md b/docs/user_guides/services/tfm_sst_integration_guide.md
index 7a3fa71..a2ef1ce 100644
--- a/docs/user_guides/services/tfm_sst_integration_guide.md
+++ b/docs/user_guides/services/tfm_sst_integration_guide.md
@@ -252,10 +252,10 @@
 ### TF-M NV Counter Interface
 To have a platform independent way to access the NV counters, TF-M defines a
 platform NV counter interface. For API specification, please check:
-`platform/include/tfm_plat_crypto_keys.h`
+`platform/include/tfm_plat_nv_counters.h`
 
 The system integrators **may** implement this interface based on the target
-capabilities and set the **SST_ROLLBACK_PROTECTION** flag to compile in
+capabilities and set the `SST_ROLLBACK_PROTECTION` flag to compile in
 the rollback protection code.
 
 ### Secret Platform Unique Key
@@ -310,7 +310,7 @@
 ### SST Service Features Flags
 
 SST service defines a set of flags that can be used to compile in/out certain
-SST service features. The **CommonConfig.cmake** file sets the default values
+SST service features. The `CommonConfig.cmake` file sets the default values
 of those flags. However, those flags values can be overwritten by setting them
 in `platform/ext/<TARGET_NAME>.cmake` based on the target capabilities or needs.
 The list of SST services flags are:
@@ -340,6 +340,20 @@
    by default in the regression tests, if it is not defined by the platform.
    The SST regression tests reduce the life of the flash memory as they
    write/erase multiple times in the memory.
+ - `SST_TEST_NV_COUNTERS`: this flag enables the virtual implementation of the
+   SST NV counters interface in `test/suites/sst/secure/nv_counters`, which
+   emulates NV counters in RAM, and disables the hardware implementation of NV
+   counters provided by the secure service. This flag is enabled by default when
+   building the regression tests and disabled by default otherwise.
+   - This flag can be overridden to `OFF` when building the regression tests. In
+     this case, the SST rollback protection test suite will not be built, as it
+     relies on extra functionality provided by the virtual NV counters to
+     simulate different rollback scenarios. The remainder of the SST test suites
+     will run using the hardware NV counters. Please note that running the tests
+     in this configuration will quickly increase the hardware NV counter values,
+     which cannot be decreased again.
+   - Overriding this flag from its default value of `OFF` when not building the
+     regression tests is not currently supported.
 
 --------------
 
diff --git a/secure_fw/services/secure_storage/CMakeLists.inc b/secure_fw/services/secure_storage/CMakeLists.inc
index 6c5d717..eae93be 100644
--- a/secure_fw/services/secure_storage/CMakeLists.inc
+++ b/secure_fw/services/secure_storage/CMakeLists.inc
@@ -50,6 +50,10 @@
 	message(FATAL_ERROR "Incomplete build configuration: SST_RAM_FS is undefined. ")
 endif()
 
+if (NOT DEFINED SST_TEST_NV_COUNTERS)
+	message(FATAL_ERROR "Incomplete build configuration: SST_TEST_NV_COUNTERS is undefined.")
+endif()
+
 set (SECURE_STORAGE_C_SRC
 	"${SECURE_STORAGE_DIR}/tfm_sst_secure_api.c"
 	"${SECURE_STORAGE_DIR}/tfm_sst_req_mngr.c"
@@ -69,13 +73,14 @@
 		"${SECURE_STORAGE_DIR}/sst_encrypted_object.c"
 	)
 	set_property(SOURCE ${SECURE_STORAGE_C_SRC} APPEND PROPERTY COMPILE_DEFINITIONS SST_ENCRYPTION)
-	set_property(DIRECTORY ${TEST_DIR} APPEND PROPERTY COMPILE_DEFINITIONS SST_ENCRYPTION)
 
 	if (SST_ROLLBACK_PROTECTION)
-		if (NOT REGRESSION OR TFM_LVL GREATER 1)
-			# In case of regression test executed in TFM level 1, the SST rollback test suite has
-			# its own implementation of sst_nv_counters intefaces to be able to test different scenarios.
-			list (APPEND SECURE_STORAGE_C_SRC
+		# Only build the NV counters implementation if the SST_TEST_NV_COUNTERS
+		# flag is off. When this flag is on, a virtual implementation of the SST
+		# NV counters interface is used instead. Full documentation for this
+		# flag can be found in the SST Integration Guide.
+		if (NOT SST_TEST_NV_COUNTERS)
+			list(APPEND SECURE_STORAGE_C_SRC
 				"${SECURE_STORAGE_DIR}/nv_counters/sst_nv_counters.c")
 		endif()
 		set_property(SOURCE ${SECURE_STORAGE_C_SRC} APPEND PROPERTY COMPILE_DEFINITIONS SST_ROLLBACK_PROTECTION)
@@ -109,6 +114,7 @@
 message("- SST_VALIDATE_METADATA_FROM_FLASH: " ${SST_VALIDATE_METADATA_FROM_FLASH})
 message("- SST_CREATE_FLASH_LAYOUT: " ${SST_CREATE_FLASH_LAYOUT})
 message("- SST_RAM_FS: " ${SST_RAM_FS})
+message("- SST_TEST_NV_COUNTERS: " ${SST_TEST_NV_COUNTERS})
 
 #Setting include directories
 embedded_include_directories(PATH ${TFM_ROOT_DIR} ABSOLUTE)
diff --git a/test/framework/CMakeLists.inc b/test/framework/CMakeLists.inc
index e5b7d51..50fafb3 100644
--- a/test/framework/CMakeLists.inc
+++ b/test/framework/CMakeLists.inc
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2017-2018, Arm Limited. All rights reserved.
+# Copyright (c) 2017-2019, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -40,12 +40,6 @@
 list(APPEND ALL_SRC_C_S ${TEST_FRAMEWORK_C_SRC_S})
 list(APPEND ALL_SRC_C_NS ${TEST_FRAMEWORK_C_SRC_NS})
 
-#Add compile definitions
-if (SST_ROLLBACK_PROTECTION AND SST_ENCRYPTION AND TFM_LVL EQUAL 1)
-        set_property(SOURCE ${TEST_FRAMEWORK_C_SRC_S} APPEND PROPERTY COMPILE_DEFINITIONS SST_ROLLBACK_PROTECTION)
-endif()
-
 #Setting include directories
 embedded_include_directories(PATH ${TFM_ROOT_DIR} ABSOLUTE)
 embedded_include_directories(PATH ${TFM_ROOT_DIR}/interface/include ABSOLUTE)
-
diff --git a/test/framework/secure_suites.c b/test/framework/secure_suites.c
index 4caf4ae..0b4c918 100644
--- a/test/framework/secure_suites.c
+++ b/test/framework/secure_suites.c
@@ -31,7 +31,7 @@
     {&register_testsuite_s_psa_ps_interface, 0, 0, 0},
     {&register_testsuite_s_psa_ps_reliability, 0, 0, 0},
 
-#if defined(SST_ROLLBACK_PROTECTION) && defined(SST_ENCRYPTION)
+#ifdef SST_TEST_NV_COUNTERS
     {&register_testsuite_s_rollback_protection, 0, 0, 0},
 #endif
 
diff --git a/test/suites/sst/CMakeLists.inc b/test/suites/sst/CMakeLists.inc
index 51e1bcf..407f16b 100644
--- a/test/suites/sst/CMakeLists.inc
+++ b/test/suites/sst/CMakeLists.inc
@@ -33,9 +33,10 @@
 	list(APPEND ALL_SRC_C_S "${SECURE_STORAGE_TEST_DIR}/secure/psa_ps_s_interface_testsuite.c"
 				"${SECURE_STORAGE_TEST_DIR}/secure/psa_ps_s_reliability_testsuite.c")
 
-	if (SST_ROLLBACK_PROTECTION AND SST_ENCRYPTION AND TFM_LVL EQUAL 1)
+	if (SST_ENCRYPTION AND SST_ROLLBACK_PROTECTION AND SST_TEST_NV_COUNTERS)
 		list(APPEND ALL_SRC_C_S "${SECURE_STORAGE_TEST_DIR}/secure/sst_rollback_protection_testsuite.c"
 					"${SECURE_STORAGE_TEST_DIR}/secure/nv_counters/test_sst_nv_counters.c")
+		set_property(SOURCE ${ALL_SRC_C_S} APPEND PROPERTY COMPILE_DEFINITIONS SST_TEST_NV_COUNTERS)
 	endif()
 
 	if (NOT DEFINED TFM_NS_CLIENT_IDENTIFICATION)
diff --git a/test/suites/sst/secure/sst_tests.h b/test/suites/sst/secure/sst_tests.h
index cf0e98e..60cda80 100644
--- a/test/suites/sst/secure/sst_tests.h
+++ b/test/suites/sst/secure/sst_tests.h
@@ -28,8 +28,7 @@
  */
 void register_testsuite_s_psa_ps_reliability(struct test_suite_t *p_test_suite);
 
-#if defined(SST_ROLLBACK_PROTECTION) && defined(SST_ENCRYPTION) \
-    && (TFM_LVL == 1)
+#ifdef SST_TEST_NV_COUNTERS
 /**
  * \brief Register testsuite for the sst rollback protection tests.
  *