Test: Add rollback protection tests for SST

This patch adds a test suite to test the rollback protection feature
in the SST service.

Change-Id: I3f4bb980cad37c11bb279916fa3d689c0672a68a
Signed-off-by: Marc Moreno <marc.morenoberengue@arm.com>
diff --git a/test/framework/CMakeLists.inc b/test/framework/CMakeLists.inc
index d8abf61..e5b7d51 100644
--- a/test/framework/CMakeLists.inc
+++ b/test/framework/CMakeLists.inc
@@ -40,6 +40,11 @@
 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 3ed95dd..89369cb 100644
--- a/test/framework/secure_suites.c
+++ b/test/framework/secure_suites.c
@@ -29,6 +29,10 @@
     {&register_testsuite_s_sst_sec_interface, 0, 0, 0},
     {&register_testsuite_s_sst_reliability, 0, 0, 0},
 
+#if defined(SST_ROLLBACK_PROTECTION) && defined(SST_ENCRYPTION)
+    {&register_testsuite_s_rollback_protection, 0, 0, 0},
+#endif
+
     /* Secure Audit Logging test cases */
     {&register_testsuite_s_audit_interface, 0, 0, 0},
 
diff --git a/test/suites/sst/CMakeLists.inc b/test/suites/sst/CMakeLists.inc
index fdb3e65..f527bc5 100644
--- a/test/suites/sst/CMakeLists.inc
+++ b/test/suites/sst/CMakeLists.inc
@@ -31,6 +31,10 @@
 			"${SECURE_STORAGE_TEST_DIR}/secure/sst_sec_interface_testsuite.c"
 			"${SECURE_STORAGE_TEST_DIR}/secure/sst_reliability_testsuite.c"
 		)
+	if (SST_ROLLBACK_PROTECTION AND SST_ENCRYPTION AND TFM_LVL EQUAL 1)
+		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")
+	endif()
 
 	list(APPEND ALL_SRC_C_NS "${SECURE_STORAGE_TEST_DIR}/non_secure/ns_test_helpers.c"
 			"${SECURE_STORAGE_TEST_DIR}/non_secure/sst_ns_interface_testsuite.c"
diff --git a/test/suites/sst/secure/nv_counters/test_sst_nv_counters.c b/test/suites/sst/secure/nv_counters/test_sst_nv_counters.c
new file mode 100644
index 0000000..ca47569
--- /dev/null
+++ b/test/suites/sst/secure/nv_counters/test_sst_nv_counters.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "test_sst_nv_counters.h"
+
+#include <limits.h>
+#include "secure_fw/services/secure_storage/nv_counters/sst_nv_counters.h"
+#include "secure_fw/services/secure_storage/sst_utils.h"
+
+#define DISABLE_INCREMENT 0
+#define ENABLE_INCREMENT  1
+
+#define TOTAL_SST_NV_COUNTERS  3
+#define INIT_NV_COUNTERS_VALUE 42
+
+static uint8_t nv_increment_status = ENABLE_INCREMENT;
+static uint32_t test_nv_counters[TOTAL_SST_NV_COUNTERS] = {0};
+
+static uint32_t get_nv_counter_position(enum tfm_nv_counter_t counter_id)
+{
+    switch (counter_id) {
+    case TFM_SST_NV_COUNTER_1:
+        return 0;
+    case TFM_SST_NV_COUNTER_2:
+        return 1;
+    case TFM_SST_NV_COUNTER_3:
+        return 2;
+    default:
+        return TOTAL_SST_NV_COUNTERS;
+    }
+}
+
+/* Implementation of SST NV counter interfaces defined by sst_nv_counters.h */
+enum psa_sst_err_t sst_init_nv_counter(void)
+{
+    static uint8_t is_init = 0;
+
+    if (is_init == 0) {
+        test_nv_counters[0] = INIT_NV_COUNTERS_VALUE;
+        test_nv_counters[1] = INIT_NV_COUNTERS_VALUE;
+        test_nv_counters[2] = INIT_NV_COUNTERS_VALUE;
+        is_init = 1;
+    }
+
+    return PSA_SST_ERR_SUCCESS;
+}
+
+enum psa_sst_err_t sst_read_nv_counter(enum tfm_nv_counter_t counter_id,
+                                       uint32_t *val)
+{
+    uint32_t nv_pos;
+
+    nv_pos = get_nv_counter_position(counter_id);
+    if (nv_pos >= TOTAL_SST_NV_COUNTERS) {
+        return PSA_SST_ERR_SYSTEM_ERROR;
+    }
+
+    /* Reads counter value */
+    *val = test_nv_counters[nv_pos];
+
+    return PSA_SST_ERR_SUCCESS;
+}
+
+enum psa_sst_err_t sst_increment_nv_counter(enum tfm_nv_counter_t counter_id)
+{
+    uint32_t nv_pos;
+
+    if (nv_increment_status == DISABLE_INCREMENT) {
+        return PSA_SST_ERR_SYSTEM_ERROR;
+    }
+
+    nv_pos = get_nv_counter_position(counter_id);
+    if (nv_pos >= TOTAL_SST_NV_COUNTERS) {
+        return PSA_SST_ERR_SYSTEM_ERROR;
+    }
+
+    if (test_nv_counters[nv_pos] == UINT32_MAX) {
+        return PSA_SST_ERR_SYSTEM_ERROR;
+    }
+
+    /* Increments counter value */
+    test_nv_counters[nv_pos]++;
+
+    return PSA_SST_ERR_SUCCESS;
+}
+
+/* Implementation of SST NV counter interfaces defined by
+ * test_sst_nv_counters.h
+ */
+void test_sst_disable_increment_nv_counter(void)
+{
+    nv_increment_status = DISABLE_INCREMENT;
+}
+
+void test_sst_enable_increment_nv_counter(void)
+{
+    nv_increment_status = ENABLE_INCREMENT;
+}
+
+enum psa_sst_err_t test_sst_read_nv_counter(enum tfm_nv_counter_t counter_id,
+                                            uint32_t *val)
+{
+    return sst_read_nv_counter(counter_id, val);
+}
+
+enum psa_sst_err_t test_sst_increment_nv_counter(
+                                               enum tfm_nv_counter_t counter_id)
+{
+    return sst_increment_nv_counter(counter_id);
+}
+
+enum psa_sst_err_t test_sst_decrement_nv_counter(
+                                               enum tfm_nv_counter_t counter_id)
+{
+    uint32_t nv_pos;
+
+    nv_pos = get_nv_counter_position(counter_id);
+    if (nv_pos >= TOTAL_SST_NV_COUNTERS) {
+        return PSA_SST_ERR_SYSTEM_ERROR;
+    }
+
+    if (test_nv_counters[nv_pos] == 0) {
+        return PSA_SST_ERR_SYSTEM_ERROR;
+    }
+
+    /* Decrements counter value */
+    test_nv_counters[nv_pos]--;
+
+    return PSA_SST_ERR_SUCCESS;
+}
+
+enum psa_sst_err_t test_sst_set_nv_counter(enum tfm_nv_counter_t counter_id,
+                                           uint32_t value)
+{
+    uint32_t nv_pos;
+
+    nv_pos = get_nv_counter_position(counter_id);
+    if (nv_pos >= TOTAL_SST_NV_COUNTERS) {
+        return PSA_SST_ERR_SYSTEM_ERROR;
+    }
+
+    /* Sets counter value */
+    test_nv_counters[nv_pos] = value;
+
+    return PSA_SST_ERR_SUCCESS;
+}
diff --git a/test/suites/sst/secure/nv_counters/test_sst_nv_counters.h b/test/suites/sst/secure/nv_counters/test_sst_nv_counters.h
new file mode 100644
index 0000000..c57203d
--- /dev/null
+++ b/test/suites/sst/secure/nv_counters/test_sst_nv_counters.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TEST_SST_NV_COUNTERS_H__
+#define __TEST_SST_NV_COUNTERS_H__
+
+#include <stdint.h>
+#include "psa_sst_api.h"
+#include "platform/include/tfm_plat_nv_counters.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Reads the given non-volatile (NV) counter.
+ *
+ * \param[in]  counter_id  NV counter ID.
+ * \param[out] val         Pointer to store the current NV counter value.
+ *
+ * \return  PSA_SST_ERR_SUCCESS if the value is read correctly, otherwise
+ *          PSA_SST_ERR_SYSTEM_ERROR
+ */
+enum psa_sst_err_t test_sst_read_nv_counter(enum tfm_nv_counter_t counter_id,
+                                            uint32_t *val);
+
+/**
+ * \brief Increments the given non-volatile (NV) counter.
+ *
+ * \param[in] counter_id  NV counter ID.
+ *
+ * \return  When the NV counter reaches its maximum value, the
+ *          PSA_SST_ERR_SYSTEM_ERROR error is returned to indicate the value
+ *          cannot be incremented. Otherwise, PSA_SST_ERR_SUCCESS.
+ */
+enum psa_sst_err_t test_sst_increment_nv_counter(
+                                              enum tfm_nv_counter_t counter_id);
+
+/**
+ * \brief Decrements the given non-volatile (NV) counter.
+ *
+ * \param[in] counter_id  NV counter ID.
+ *
+ * \return  When the NV counter reaches its minimum value, the
+ *          PSA_SST_ERR_SYSTEM_ERROR error is returned to indicate the value
+ *          cannot be decremented. Otherwise, PSA_SST_ERR_SUCCESS.
+ */
+enum psa_sst_err_t test_sst_decrement_nv_counter(
+                                              enum tfm_nv_counter_t counter_id);
+/**
+ * \brief Disables SST increment nv counter function to force
+ *        PSA_SST_ERR_SYSTEM_ERROR return value as an indication that NV counter
+ *        reaches its maximum value.
+ */
+void test_sst_disable_increment_nv_counter(void);
+
+/**
+ * \brief Enables SST increment nv counter function to work normally.
+ */
+void test_sst_enable_increment_nv_counter(void);
+
+/**
+ * \brief Sets a new value into the given non-volatile (NV) counter.
+ *
+ * \param[in] counter_id  NV counter Id.
+ * \param[in] value       New NV counter value.
+ *
+ * \return  When the NV counter reaches its maximum value, the
+ *          PSA_SST_ERR_SYSTEM_ERROR error is returned to indicate the value
+ *          cannot be set. Otherwise, PSA_SST_ERR_SUCCESS.
+ */
+enum psa_sst_err_t test_sst_set_nv_counter(enum tfm_nv_counter_t counter_id,
+                                           uint32_t value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TEST_SST_NV_COUNTERS_H__ */
+
diff --git a/test/suites/sst/secure/sst_rollback_protection_testsuite.c b/test/suites/sst/secure/sst_rollback_protection_testsuite.c
new file mode 100644
index 0000000..e7400db
--- /dev/null
+++ b/test/suites/sst/secure/sst_rollback_protection_testsuite.c
@@ -0,0 +1,613 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "sst_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "nv_counters/test_sst_nv_counters.h"
+#include "psa_sst_api.h"
+#include "secure_fw/services/secure_storage/assets/sst_asset_defs.h"
+#include "secure_fw/services/secure_storage/sst_object_system.h"
+#include "s_test_helpers.h"
+#include "test/framework/test_framework_helpers.h"
+
+/* Test suite defines */
+#define READ_BUF_SIZE  1UL
+#define WRITE_BUF_SIZE 1UL
+
+/* Define default asset's token */
+#define ASSET_TOKEN      NULL
+#define ASSET_TOKEN_SIZE 0
+
+/*
+ * Summary of tests covered by the test suite.
+ *
+ * SST version | NVC1 | NVC2 | NVC3 |  Result  |  Test Num
+ * ------------|------|------|------|----------|------------
+ *      X      |   X  |   X  |   X  |  Valid   |     1
+ *      N      |   X  |   X  |   X  |  Invalid |     2
+ *      X      |   X  |   X  |   N  |  Valid   |     3
+ *      N      |   X  |   N  |   N  |  Valid   |     4
+ *      X      |   X  |   N  |   N  |  Valid   |     5
+ *      X      |   X  |   M  |   N  |  Valid   |     6
+ *      M      |   X  |   M  |   N  |  Invalid |     7
+ *      N      |   X  |   M  |   N  |  Invalid |     8
+ *
+ * Test 9 checks the SST result when the non-volatile (NV) counter 1 cannot be
+ * incremented (e.g it has reached its maximum value).
+ */
+
+/* List of tests */
+static void tfm_sst_test_4001(struct test_result_t *ret);
+static void tfm_sst_test_4002(struct test_result_t *ret);
+static void tfm_sst_test_4003(struct test_result_t *ret);
+static void tfm_sst_test_4004(struct test_result_t *ret);
+static void tfm_sst_test_4005(struct test_result_t *ret);
+static void tfm_sst_test_4006(struct test_result_t *ret);
+static void tfm_sst_test_4007(struct test_result_t *ret);
+static void tfm_sst_test_4008(struct test_result_t *ret);
+static void tfm_sst_test_4009(struct test_result_t *ret);
+
+static struct test_t interface_tests[] = {
+    {&tfm_sst_test_4001, "TFM_SST_TEST_4001",
+     "Check SST area version when NV counters 1/2/3 have the same value",
+     {0}},
+    {&tfm_sst_test_4002, "TFM_SST_TEST_4002",
+     "Check SST area version when it is different from NV counters 1/2/3",
+     {0}},
+    {&tfm_sst_test_4003, "TFM_SST_TEST_4003",
+     "Check SST area version when NV counters 1 and 2 are equals, 3 is "
+     "different, and SST area version match NV counters 1 and 2", {0}},
+    {&tfm_sst_test_4004, "TFM_SST_TEST_4004",
+     "Check SST area version when NV counters 2 and 3 are equals, 1 is "
+     "different and SST area version match NV counter 2 and 3", {0}},
+    {&tfm_sst_test_4005, "TFM_SST_TEST_4005",
+     "Check SST area version when NV counters 2 and 3 are equals, 1 is "
+     "different and SST area version match NV counter 1", {0}},
+    {&tfm_sst_test_4006, "TFM_SST_TEST_4006",
+     "Check SST area version when NV counters 1, 2 and 3 have different values "
+     "and SST area version match NV counter 1 value", {0}},
+    {&tfm_sst_test_4007, "TFM_SST_TEST_4007",
+     "Check SST area version when NV counters 1, 2 and 3 have different values "
+     "and SST area version match NV counter 2 value", {0}},
+    {&tfm_sst_test_4008, "TFM_SST_TEST_4008",
+     "Check SST area version when NV counters 1, 2 and 3 have different values "
+     "and SST area version match NV counter 3 value", {0}},
+    {&tfm_sst_test_4009, "TFM_SST_TEST_4009",
+     "Check SST area version when NV counter 1 cannot be incremented", {0}},
+};
+
+void register_testsuite_s_rollback_protection(struct test_suite_t *p_test_suite)
+{
+    uint32_t list_size = (sizeof(interface_tests) / sizeof(interface_tests[0]));
+
+    set_testsuite("SST rollback protection tests (TFM_SST_TEST_4XXX)",
+                  interface_tests, list_size, p_test_suite);
+}
+
+/**
+ * \brief Check SST area version when NV counters 1/2/3 have the same value.
+ *        It also checks that the 3 NV counters are aligned and they have been
+ *        increased by 1 unit.
+ */
+static void tfm_sst_test_4001(struct test_result_t *ret)
+{
+    struct sst_test_buf_t io_data;
+    enum psa_sst_err_t err;
+    uint32_t old_nvc_1, nvc_1, nvc_2, nvc_3;
+    uint8_t read_data = 'X';
+    uint8_t wrt_data = 'D';
+
+    /* Prepares test context */
+    if (prepare_test_ctx(ret) != 0) {
+        return;
+    }
+
+    /* Creates an asset in the SST area to generate a new SST area version */
+    err = psa_sst_create(SST_ASSET_ID_AES_KEY_192, ASSET_TOKEN,
+                         ASSET_TOKEN_SIZE);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Create should not fail for application S_APP_ID");
+        return;
+    }
+
+    /* Reads NV counter 1 to get the save the value to compare it later */
+    err = test_sst_read_nv_counter(TFM_SST_NV_COUNTER_1, &old_nvc_1);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Read should not fail");
+        return;
+    }
+
+    /* Sets data structure for write request */
+    io_data.data = &wrt_data;
+    io_data.size = WRITE_BUF_SIZE;
+    io_data.offset = 0;
+
+    /* Writes data into the asset */
+    err = psa_sst_write(SST_ASSET_ID_AES_KEY_192, ASSET_TOKEN, ASSET_TOKEN_SIZE,
+                        io_data.size, io_data.offset, io_data.data);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Write should not fail for application S_APP_ID");
+        return;
+    }
+
+    /* Validates the 3 NV counters have the same value and it has been increased
+     * by 1 unit.
+     */
+
+    /* Reads NV counter 1 to get the current value */
+    err = test_sst_read_nv_counter(TFM_SST_NV_COUNTER_1, &nvc_1);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Read should not fail");
+        return;
+    }
+
+    /* Checks if NV counter 1 value has been increased by 1 unit as result of
+     * process the write request.
+     */
+    if (nvc_1 != (old_nvc_1 + 1)) {
+        TEST_FAIL("NV counter 1 has been increased more than 1 unit");
+        return;
+    }
+
+    /* Reads NV counter 2 to get the current value */
+    err = test_sst_read_nv_counter(TFM_SST_NV_COUNTER_2, &nvc_2);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Read should not fail");
+        return;
+    }
+
+    if (nvc_1 != nvc_2) {
+        TEST_FAIL("NV counter 1 and 2 should have the same value");
+        return;
+    }
+
+    /* Reads NV counter 3 to get the current value */
+    err = test_sst_read_nv_counter(TFM_SST_NV_COUNTER_3, &nvc_3);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Read should not fail");
+        return;
+    }
+
+    if (nvc_2 != nvc_3) {
+        TEST_FAIL("NV counter 2 and 3 should have the same value");
+        return;
+    }
+
+    /* Simulates a reboot in the system by calling sst_system_prepare(). This
+     * function is called when the SST service is initialized.
+     *
+     * Prepare should not fail as the NV counters has the same values and
+     * the SST area authentication is aligned with those values.
+     */
+    err = sst_system_prepare();
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("AM prepare should not fail");
+        return;
+    }
+
+    /* Sets data structure for read request */
+    io_data.data = &read_data;
+    io_data.size = READ_BUF_SIZE;
+    io_data.offset = 0;
+
+    /* Reads data from the asset */
+    err = psa_sst_read(SST_ASSET_ID_AES_KEY_192, ASSET_TOKEN, ASSET_TOKEN_SIZE,
+                       io_data.size, io_data.offset, io_data.data);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Read should not fail for application S_APP_ID");
+        return;
+    }
+
+    if (read_data != wrt_data) {
+        TEST_FAIL("Read and write data values are different");
+        return;
+    }
+
+    ret->val = TEST_PASSED;
+}
+
+/**
+ * \brief Check SST area version when it is different from NV counters
+ *        1/2/3.
+ */
+static void tfm_sst_test_4002(struct test_result_t *ret)
+{
+    enum psa_sst_err_t err;
+
+    /* Prepares test context */
+    if (prepare_test_ctx(ret) != 0) {
+        return;
+    }
+
+    /* Creates an asset in the SST area to generate a new SST area version */
+    err = psa_sst_create(SST_ASSET_ID_AES_KEY_192, ASSET_TOKEN,
+                         ASSET_TOKEN_SIZE);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Create should not fail for application S_APP_ID");
+        return;
+    }
+
+    /* Increments all counters to make that SST area version old/invalid */
+    err = test_sst_increment_nv_counter(TFM_SST_NV_COUNTER_1);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Increment should not fail");
+        return;
+    }
+
+    err = test_sst_increment_nv_counter(TFM_SST_NV_COUNTER_2);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Increment should not fail");
+        return;
+    }
+
+    err = test_sst_increment_nv_counter(TFM_SST_NV_COUNTER_3);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Increment should not fail");
+        return;
+    }
+
+    /* Simulates a reboot in the system by calling sst_system_prepare(). This
+     * function is called when the SST service is initialized.
+     *
+     * Prepare should fail as the SST area version does not match the
+     * NV counters values.
+     */
+    err = sst_system_prepare();
+    if (err != PSA_SST_ERR_SYSTEM_ERROR) {
+        TEST_FAIL("AM prepare should fail as version is old");
+        return;
+    }
+
+    ret->val = TEST_PASSED;
+}
+
+/**
+ * \brief Check SST area version when NV counters 1 and 2 are equals, 3 is
+ *        different and SST area version match NV counter 1 and 2 values.
+ *        It simulates a power cut during write action while the counter 3 is
+ *        being increased.
+ */
+static void tfm_sst_test_4003(struct test_result_t *ret)
+{
+    enum psa_sst_err_t err;
+
+    /* Prepares test context */
+    if (prepare_test_ctx(ret) != 0) {
+        return;
+    }
+
+    /* Creates an asset in the SST area to generate a new SST area version */
+    err = psa_sst_create(SST_ASSET_ID_AES_KEY_192, ASSET_TOKEN,
+                         ASSET_TOKEN_SIZE);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Create should not fail");
+        return;
+    }
+
+    /* Decrements NV counters 3 to make it different from the other two counters
+     * and make the current SST area version match NV counter 1 and 2 values.
+     */
+    err = test_sst_decrement_nv_counter(TFM_SST_NV_COUNTER_3);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Decrement should not fail");
+        return;
+    }
+
+    /* Simulates a reboot in the system by calling sst_system_prepare(). This
+     * function is called when the SST service is initialized.
+     *
+     * Prepare should not fail as the SST area version match NV counters 1 and
+     * 2 values.
+     */
+    err = sst_system_prepare();
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("AM prepare should not fail");
+        return;
+    }
+
+    ret->val = TEST_PASSED;
+}
+
+/**
+ * \brief Check SST area version when NV counters 2 and 3 are equals, 1 is
+ *        different and SST area version match NV counter 2 and 3 values.
+ *        It simulates a power cut during write action before increment counter
+ *        2 and 3, and the new SST area version is corrupted and only the old
+ *        version match the NV counters.
+ */
+static void tfm_sst_test_4004(struct test_result_t *ret)
+{
+    enum psa_sst_err_t err;
+
+    /* Prepares test context */
+    if (prepare_test_ctx(ret) != 0) {
+        return;
+    }
+
+    /* Creates an asset in the SST area to generate a new SST area version */
+    err = psa_sst_create(SST_ASSET_ID_AES_KEY_192, ASSET_TOKEN,
+                         ASSET_TOKEN_SIZE);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Create should not fail");
+        return;
+    }
+
+    /* Increments NV counters 1 to make it different from the other two counters
+     * and make the current SST area version match NV counter 2 and 3 values.
+     */
+    err = test_sst_increment_nv_counter(TFM_SST_NV_COUNTER_1);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Increment should not fail");
+        return;
+    }
+
+    /* Simulates a reboot in the system by calling sst_system_prepare(). This
+     * function is called when the SST service is initialized.
+     *
+     * Prepare should not fail as the SST area version match the NV counter 2
+     * and 3 values.
+     */
+    err = sst_system_prepare();
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("AM prepare should not fail");
+        return;
+    }
+
+    ret->val = TEST_PASSED;
+}
+
+/**
+ * \brief Check SST area version when NV counters 2 and 3 are equals, 1 is
+ *        different and SST area version match NV counter 1 value.
+ *        It simulates a power cut during write action before increment counter
+ *        2 and 3, and the new SST area version is corrupted and only the old
+ *        version match the NV counters.
+ */
+static void tfm_sst_test_4005(struct test_result_t *ret)
+{
+    enum psa_sst_err_t err;
+
+    /* Prepares test context */
+    if (prepare_test_ctx(ret) != 0) {
+        return;
+    }
+
+    /* Creates an asset in the SST area to generate a new SST area version */
+    err = psa_sst_create(SST_ASSET_ID_AES_KEY_192, ASSET_TOKEN,
+                         ASSET_TOKEN_SIZE);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Create should not fail");
+        return;
+    }
+
+    /* Decrements NV counter 2 and 3 to make the SST area version match NV
+     * counter 1 only.
+     */
+    err = test_sst_decrement_nv_counter(TFM_SST_NV_COUNTER_2);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Decrement should not fail");
+        return;
+    }
+
+    err = test_sst_decrement_nv_counter(TFM_SST_NV_COUNTER_3);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Decrement should not fail");
+        return;
+    }
+
+    /* Simulates a reboot in the system by calling sst_system_prepare(). This
+     * function is called when the SST service is initialized.
+     *
+     * Prepare should not fail as the SST area version match the NV counter 1.
+     */
+    err = sst_system_prepare();
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("AM prepare should not fail");
+        return;
+    }
+
+    ret->val = TEST_PASSED;
+}
+
+/**
+ * \brief Check SST area version when NV counters 1, 2 and 3 have different
+ *        values and SST area version match NV counter 1 value.
+ */
+static void tfm_sst_test_4006(struct test_result_t *ret)
+{
+    enum psa_sst_err_t err;
+
+    /* Prepares test context */
+    if (prepare_test_ctx(ret) != 0) {
+        return;
+    }
+
+    /* Creates an asset in the SST area to generate a new SST area version */
+    err = psa_sst_create(SST_ASSET_ID_AES_KEY_192, ASSET_TOKEN,
+                         ASSET_TOKEN_SIZE);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Create should not fail");
+        return;
+    }
+
+    /* Decrements NV counter 2 (1 time) and 3 (2 times) to make the SST area
+     * version match NV counter 1 only.
+     */
+    err = test_sst_decrement_nv_counter(TFM_SST_NV_COUNTER_2);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Decrement should not fail");
+        return;
+    }
+
+    err = test_sst_decrement_nv_counter(TFM_SST_NV_COUNTER_3);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Decrement should not fail");
+        return;
+    }
+
+    err = test_sst_decrement_nv_counter(TFM_SST_NV_COUNTER_3);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Decrement should not fail");
+        return;
+    }
+
+    /* Simulates a reboot in the system by calling sst_system_prepare(). This
+     * function is called when the SST service is initialized.
+     *
+     * Prepare should not fail as the SST area version match the NV counter 1.
+     */
+    err = sst_system_prepare();
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("AM prepare should not fail");
+        return;
+    }
+
+    ret->val = TEST_PASSED;
+}
+
+/**
+ * \brief Check SST area version when NV counters 1, 2 and 3 have different
+ *        values and SST area version match NV counter 2 value.
+ */
+static void tfm_sst_test_4007(struct test_result_t *ret)
+{
+    enum psa_sst_err_t err;
+
+    /* Prepares test context */
+    if (prepare_test_ctx(ret) != 0) {
+        return;
+    }
+
+    /* Creates an asset in the SST area to generate a new SST area version */
+    err = psa_sst_create(SST_ASSET_ID_AES_KEY_192, ASSET_TOKEN,
+                         ASSET_TOKEN_SIZE);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Create should not fail");
+        return;
+    }
+
+    /* Increments NV counter 1 and decrements 3 to make the SST area
+     * version match NV counter 2 only.
+     */
+    err = test_sst_increment_nv_counter(TFM_SST_NV_COUNTER_1);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Increment should not fail");
+        return;
+    }
+
+    err = test_sst_decrement_nv_counter(TFM_SST_NV_COUNTER_3);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Decrement should not fail");
+        return;
+    }
+
+    /* Simulates a reboot in the system by calling sst_system_prepare(). This
+     * function is called when the SST service is initialized.
+     *
+     * Prepare should fail as the SST area version match the NV counter 2 and
+     * the other counters are different.
+     */
+    err = sst_system_prepare();
+    if (err != PSA_SST_ERR_SYSTEM_ERROR) {
+        TEST_FAIL("AM prepare should fail");
+        return;
+    }
+
+    ret->val = TEST_PASSED;
+}
+
+/**
+ * \brief Check SST area version when NV counters 1, 2 and 3 have different
+ *        values and SST area version match NV counter 3 value.
+ */
+static void tfm_sst_test_4008(struct test_result_t *ret)
+{
+    enum psa_sst_err_t err;
+
+    /* Prepares test context */
+    if (prepare_test_ctx(ret) != 0) {
+        return;
+    }
+
+    /* Creates an asset in the SST area to generate a new SST area version */
+    err = psa_sst_create(SST_ASSET_ID_AES_KEY_192, ASSET_TOKEN,
+                         ASSET_TOKEN_SIZE);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Create should not fail");
+        return;
+    }
+
+    /* Increments NV counter 1 (2 times) and 2 (1 time) to make the SST area
+     * version match NV counter 3 only.
+     */
+    err = test_sst_increment_nv_counter(TFM_SST_NV_COUNTER_1);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Increment should not fail");
+        return;
+    }
+
+    err = test_sst_increment_nv_counter(TFM_SST_NV_COUNTER_1);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Increment should not fail");
+        return;
+    }
+
+    err = test_sst_increment_nv_counter(TFM_SST_NV_COUNTER_2);
+    if (err != PSA_SST_ERR_SUCCESS) {
+        TEST_FAIL("Increment should not fail");
+        return;
+    }
+
+    /* Simulates a reboot in the system by calling sst_system_prepare(). This
+     * function is called when the SST service is initialized.
+     *
+     * Prepare should fail as the SST area version match the NV counter 2 and
+     * the other counters are different.
+     */
+    err = sst_system_prepare();
+    if (err != PSA_SST_ERR_SYSTEM_ERROR) {
+        TEST_FAIL("AM prepare should fail");
+        return;
+    }
+
+    ret->val = TEST_PASSED;
+}
+
+/**
+ * \brief Check SST area version when NV counter 1 cannot be incremented
+ *        (e.g it has reached its maximum value)
+ */
+static void tfm_sst_test_4009(struct test_result_t *ret)
+{
+     enum psa_sst_err_t err;
+
+    /* Prepares test context */
+    if (prepare_test_ctx(ret) != 0) {
+        return;
+    }
+
+    /* Disables increment function to simulate that NV counter 1 has
+     * reached its maximum value.
+     */
+    test_sst_disable_increment_nv_counter();
+
+    /* Creates an asset in the SST area to generate a new SST area version */
+    err = psa_sst_create(SST_ASSET_ID_AES_KEY_192, ASSET_TOKEN,
+                         ASSET_TOKEN_SIZE);
+    if (err != PSA_SST_ERR_SYSTEM_ERROR) {
+        TEST_FAIL("Create should fail as NV counter cannot be incremented");
+        return;
+    }
+
+    /* Enables counter again to not affect the next tests, if any */
+    test_sst_enable_increment_nv_counter();
+
+    ret->val = TEST_PASSED;
+}
diff --git a/test/suites/sst/secure/sst_tests.h b/test/suites/sst/secure/sst_tests.h
index 360550b..fc3ee3b 100644
--- a/test/suites/sst/secure/sst_tests.h
+++ b/test/suites/sst/secure/sst_tests.h
@@ -28,6 +28,17 @@
  */
 void register_testsuite_s_sst_reliability(struct test_suite_t *p_test_suite);
 
+#if defined(SST_ROLLBACK_PROTECTION) && defined(SST_ENCRYPTION) \
+    && (TFM_LVL == 1)
+/**
+ * \brief Register testsuite for the sst rollback protection tests.
+ *
+ * \param[in] p_test_suite  The test suite to be executed.
+ */
+void register_testsuite_s_rollback_protection(
+                                             struct test_suite_t *p_test_suite);
+#endif
+
 #ifdef __cplusplus
 }
 #endif