Core: Add dependency support

According to PSA FF, if access between a client Secure Partition and an
RoT Service is not specified in the manifest, then the client is not
allowed to connect to the RoT Service.

Change-Id: Iae45242a143981658e3fd73576b5a8f7f054a7bd
Signed-off-by: Edison Ai <edison.ai@arm.com>
diff --git a/secure_fw/spm/spm_api.h b/secure_fw/spm/spm_api.h
index 35be8c2..9d748bc 100644
--- a/secure_fw/spm/spm_api.h
+++ b/secure_fw/spm/spm_api.h
@@ -628,6 +628,21 @@
                                      uint32_t version);
 
 /**
+ * \brief                   Check the client access authorization
+ *
+ * \param[in] sid           Target RoT Service identity
+ * \param[in] service       Target service context pointer, which can be get
+ *                          by partition management functions
+ * \param[in] ns_caller     Whether from NS caller
+ *
+ * \retval IPC_SUCCESS      Success
+ * \retval IPC_ERROR_GENERIC Authorization check failed
+ */
+int32_t tfm_spm_check_authorization(uint32_t sid,
+                                    struct tfm_spm_service_t *service,
+                                    int32_t ns_caller);
+
+/**
  * \brief                      Check the memory reference is valid.
  *
  * \param[in] buffer           Pointer of memory reference
diff --git a/secure_fw/spm/spm_api_ipc.c b/secure_fw/spm/spm_api_ipc.c
index 4933e97..6eed0c0 100644
--- a/secure_fw/spm/spm_api_ipc.c
+++ b/secure_fw/spm/spm_api_ipc.c
@@ -262,6 +262,38 @@
     return IPC_SUCCESS;
 }
 
+int32_t tfm_spm_check_authorization(uint32_t sid,
+                                    struct tfm_spm_service_t *service,
+                                    int32_t ns_caller)
+{
+    struct spm_partition_desc_t *partition = NULL;
+    int32_t i;
+
+    TFM_ASSERT(service);
+
+    if (ns_caller) {
+        if (!service->service_db->non_secure_client) {
+            return IPC_ERROR_GENERIC;
+        }
+    } else {
+        partition = tfm_spm_get_running_partition();
+        if (!partition) {
+            tfm_panic();
+        }
+
+        for (i = 0; i < partition->static_data->dependencies_num; i++) {
+            if (partition->static_data->p_dependencies[i] == sid) {
+                break;
+            }
+        }
+
+        if (i == partition->static_data->dependencies_num) {
+            return IPC_ERROR_GENERIC;
+        }
+    }
+    return IPC_SUCCESS;
+}
+
 /* Message functions */
 struct tfm_msg_body_t *tfm_spm_get_msg_from_handle(psa_handle_t msg_handle)
 {
diff --git a/secure_fw/spm/spm_db.h b/secure_fw/spm/spm_db.h
index c5869fc..593a180 100644
--- a/secure_fw/spm/spm_db.h
+++ b/secure_fw/spm/spm_db.h
@@ -41,6 +41,8 @@
     uint32_t partition_flags;
     uint32_t partition_priority;
     sp_entry_point partition_init;
+    uint32_t dependencies_num;
+    int32_t *p_dependencies;
 };
 
 /**
diff --git a/secure_fw/spm/tfm_spm_db.inc b/secure_fw/spm/tfm_spm_db.inc
index a854967..28f0e1a 100644
--- a/secure_fw/spm/tfm_spm_db.inc
+++ b/secure_fw/spm/tfm_spm_db.inc
@@ -11,6 +11,7 @@
 #define __TFM_SPM_DB_INC__
 
 #include "spm_api.h"
+#include "psa_manifest/sid.h"
 
 /**************************************************************************/
 /** IRQ count per partition */
@@ -448,6 +449,65 @@
 #endif /* !defined(TFM_PSA_API) */
 
 /**************************************************************************/
+/** Dependencies array for Secure Partition */
+/**************************************************************************/
+static int32_t dependencies_TFM_SP_STORAGE[] =
+{
+    TFM_CRYPTO_SID,
+};
+
+static int32_t dependencies_TFM_SP_INITIAL_ATTESTATION[] =
+{
+    TFM_CRYPTO_SID,
+};
+
+#ifdef TFM_PARTITION_TEST_CORE
+static int32_t dependencies_TFM_SP_CORE_TEST[] =
+{
+    SPM_CORE_TEST_2_INVERT_SID,
+    SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_SID,
+    SPM_CORE_TEST_2_SLAVE_SERVICE_SID,
+};
+#endif /* TFM_PARTITION_TEST_CORE */
+
+#ifdef TFM_PARTITION_TEST_SECURE_SERVICES
+static int32_t dependencies_TFM_SP_SECURE_TEST_PARTITION[] =
+{
+    TFM_CRYPTO_SID,
+    TFM_SST_SET_SID,
+    TFM_SST_GET_SID,
+    TFM_SST_GET_INFO_SID,
+    TFM_SST_REMOVE_SID,
+    TFM_SST_GET_SUPPORT_SID,
+    TFM_ITS_SET_SID,
+    TFM_ITS_GET_SID,
+    TFM_ITS_GET_INFO_SID,
+    TFM_ITS_REMOVE_SID,
+    TFM_ATTEST_GET_TOKEN_SID,
+    TFM_ATTEST_GET_TOKEN_SIZE_SID,
+    TFM_ATTEST_GET_PUBLIC_KEY_SID,
+    TFM_SST_TEST_PREPARE_SID,
+};
+#endif /* TFM_PARTITION_TEST_SECURE_SERVICES */
+
+#ifdef TFM_PARTITION_TEST_CORE_IPC
+static int32_t dependencies_TFM_SP_IPC_CLIENT_TEST[] =
+{
+    IPC_SERVICE_TEST_PSA_ACCESS_APP_READ_ONLY_MEM_SID,
+    IPC_SERVICE_TEST_PSA_ACCESS_APP_MEM_SID,
+    IPC_SERVICE_TEST_BASIC_SID,
+    IPC_SERVICE_TEST_APP_ACCESS_PSA_MEM_SID,
+};
+#endif /* TFM_PARTITION_TEST_CORE_IPC */
+
+#ifdef TFM_PARTITION_TEST_SST
+static int32_t dependencies_TFM_SP_SST_TEST[] =
+{
+    TFM_CRYPTO_SID,
+};
+#endif /* TFM_PARTITION_TEST_SST */
+
+/**************************************************************************/
 /** The static data of the partition list */
 /**************************************************************************/
 const struct spm_partition_static_data_t static_data_list[] =
@@ -487,6 +547,8 @@
                               ,
         .partition_priority   = TFM_PRIORITY(NORMAL),
         .partition_init       = tfm_sst_req_mngr_init,
+        .dependencies_num     = 1,
+        .p_dependencies       = dependencies_TFM_SP_STORAGE,
     },
 
     {
@@ -499,6 +561,8 @@
                               ,
         .partition_priority   = TFM_PRIORITY(NORMAL),
         .partition_init       = tfm_its_req_mngr_init,
+        .dependencies_num     = 0,
+        .p_dependencies       = NULL,
     },
 
 #ifdef TFM_PARTITION_AUDIT_LOG
@@ -512,6 +576,8 @@
                               ,
         .partition_priority   = TFM_PRIORITY(NORMAL),
         .partition_init       = audit_core_init,
+        .dependencies_num     = 0,
+        .p_dependencies       = NULL,
     },
 #endif /* TFM_PARTITION_AUDIT_LOG */
 
@@ -525,6 +591,8 @@
                               ,
         .partition_priority   = TFM_PRIORITY(NORMAL),
         .partition_init       = tfm_crypto_init,
+        .dependencies_num     = 0,
+        .p_dependencies       = NULL,
     },
 
 #ifdef TFM_PARTITION_PLATFORM
@@ -538,6 +606,8 @@
                               ,
         .partition_priority   = TFM_PRIORITY(NORMAL),
         .partition_init       = platform_sp_init,
+        .dependencies_num     = 0,
+        .p_dependencies       = NULL,
     },
 #endif /* TFM_PARTITION_PLATFORM */
 
@@ -551,6 +621,8 @@
                               ,
         .partition_priority   = TFM_PRIORITY(NORMAL),
         .partition_init       = attest_partition_init,
+        .dependencies_num     = 1,
+        .p_dependencies       = dependencies_TFM_SP_INITIAL_ATTESTATION,
     },
 
 #ifdef TFM_PARTITION_TEST_CORE
@@ -564,6 +636,8 @@
                               ,
         .partition_priority   = TFM_PRIORITY(NORMAL),
         .partition_init       = core_test_init,
+        .dependencies_num     = 3,
+        .p_dependencies       = dependencies_TFM_SP_CORE_TEST,
     },
 #endif /* TFM_PARTITION_TEST_CORE */
 
@@ -578,6 +652,8 @@
                               ,
         .partition_priority   = TFM_PRIORITY(NORMAL),
         .partition_init       = core_test_2_init,
+        .dependencies_num     = 0,
+        .p_dependencies       = NULL,
     },
 #endif /* TFM_PARTITION_TEST_CORE */
 
@@ -592,6 +668,8 @@
                               ,
         .partition_priority   = TFM_PRIORITY(NORMAL),
         .partition_init       = tfm_secure_client_service_init,
+        .dependencies_num     = 14,
+        .p_dependencies       = dependencies_TFM_SP_SECURE_TEST_PARTITION,
     },
 #endif /* TFM_PARTITION_TEST_SECURE_SERVICES */
 
@@ -606,6 +684,8 @@
                               ,
         .partition_priority   = TFM_PRIORITY(HIGH),
         .partition_init       = ipc_service_test_main,
+        .dependencies_num     = 0,
+        .p_dependencies       = NULL,
     },
 #endif /* TFM_PARTITION_TEST_CORE_IPC */
 
@@ -620,6 +700,8 @@
                               ,
         .partition_priority   = TFM_PRIORITY(NORMAL),
         .partition_init       = ipc_client_test_main,
+        .dependencies_num     = 4,
+        .p_dependencies       = dependencies_TFM_SP_IPC_CLIENT_TEST,
     },
 #endif /* TFM_PARTITION_TEST_CORE_IPC */
 
@@ -634,6 +716,8 @@
                               ,
         .partition_priority   = TFM_PRIORITY(NORMAL),
         .partition_init       = tfm_irq_test_1_init,
+        .dependencies_num     = 0,
+        .p_dependencies       = NULL,
     },
 #endif /* TFM_ENABLE_IRQ_TEST */
 
@@ -648,6 +732,8 @@
                               ,
         .partition_priority   = TFM_PRIORITY(NORMAL),
         .partition_init       = tfm_sst_test_init,
+        .dependencies_num     = 1,
+        .p_dependencies       = dependencies_TFM_SP_SST_TEST,
     },
 #endif /* TFM_PARTITION_TEST_SST */
 
diff --git a/secure_fw/spm/tfm_spm_db.inc.template b/secure_fw/spm/tfm_spm_db.inc.template
index 5e12dd0..5e84b5d 100644
--- a/secure_fw/spm/tfm_spm_db.inc.template
+++ b/secure_fw/spm/tfm_spm_db.inc.template
@@ -11,6 +11,7 @@
 #define __TFM_SPM_DB_INC__
 
 #include "spm_api.h"
+#include "psa_manifest/sid.h"
 
 /**************************************************************************/
 /** IRQ count per partition */
@@ -126,6 +127,26 @@
 #endif /* !defined(TFM_PSA_API) */
 
 /**************************************************************************/
+/** Dependencies array for Secure Partition */
+/**************************************************************************/
+{% for manifest in manifests %}
+    {% if manifest.manifest.dependencies %}
+        {% if manifest.attr.conditional %}
+#ifdef {{manifest.attr.conditional}}
+        {% endif %}
+static int32_t dependencies_{{manifest.manifest.name}}[] =
+{
+        {% for dependence in manifest.manifest.dependencies %}
+    {{dependence}}_SID,
+        {% endfor %}
+};
+        {% if manifest.attr.conditional %}
+#endif /* {{manifest.attr.conditional}} */
+        {% endif %}
+
+    {% endif %}
+{% endfor %}
+/**************************************************************************/
 /** The static data of the partition list */
 /**************************************************************************/
 const struct spm_partition_static_data_t static_data_list[] =
@@ -183,6 +204,12 @@
                               ,
         .partition_priority   = TFM_PRIORITY({{manifest.manifest.priority}}),
         .partition_init       = {{manifest.manifest.entry_point}},
+        .dependencies_num     = {{manifest.manifest.dependencies | length()}},
+    {% if manifest.manifest.dependencies %}
+        .p_dependencies       = dependencies_{{manifest.manifest.name}},
+    {% else %}
+        .p_dependencies       = NULL,
+    {% endif %}
     {{'},'}}
     {% if manifest.attr.conditional %}
 #endif /* {{manifest.attr.conditional}} */