Core: Enhance the psa_call to process invalid message

When the message is unrecognized by the RoT Service or incorrectly
formatted, return PSA_ERROR_PROGRAMMER_ERROR immediately.

Change-Id: If85dc271ed9ad7e8a22197352ca87065b7f27684
Signed-off-by: Shawn Shan <shawn.shan@arm.com>
diff --git a/secure_fw/core/ipc/tfm_psa_client_call.c b/secure_fw/core/ipc/tfm_psa_client_call.c
index 5f40ad4d..3d8f46f 100644
--- a/secure_fw/core/ipc/tfm_psa_client_call.c
+++ b/secure_fw/core/ipc/tfm_psa_client_call.c
@@ -151,6 +151,15 @@
     }
 
     /*
+     * Return PSA_ERROR_PROGRAMMER_ERROR immediately for the connection
+     * has been terminated by the RoT Service.
+     */
+    if (((struct tfm_conn_handle_t *)handle)->status ==
+                                              TFM_HANDLE_STATUS_CONNECT_ERROR) {
+        return PSA_ERROR_PROGRAMMER_ERROR;
+    }
+
+    /*
      * Read client invecs from the wrap input vector. It is a fatal error
      * if the memory reference for the wrap input vector is invalid or not
      * readable.
@@ -274,7 +283,7 @@
     }
 
     /* It is a fatal error if the connection is currently handling a request. */
-    if(((struct tfm_conn_handle_t *)handle)->status ==
+    if (((struct tfm_conn_handle_t *)handle)->status ==
                                                      TFM_HANDLE_STATUS_ACTIVE) {
         tfm_core_panic();
     }
diff --git a/secure_fw/core/ipc/tfm_svcalls.c b/secure_fw/core/ipc/tfm_svcalls.c
index ff9d4e6..27f1258 100644
--- a/secure_fw/core/ipc/tfm_svcalls.c
+++ b/secure_fw/core/ipc/tfm_svcalls.c
@@ -691,7 +691,6 @@
         if (msg->msg.type >= PSA_IPC_CALL) {
             /* Reply to a request message. Return values are based on status */
             ret = status;
-
             /*
              * The total number of bytes written to a single parameter must be
              * reported to the client by updating the len member of the
@@ -704,8 +703,13 @@
         }
     }
 
-    ((struct tfm_conn_handle_t *)(msg->handle))->status =
+    if (ret == PSA_ERROR_PROGRAMMER_ERROR) {
+        ((struct tfm_conn_handle_t *)(msg->handle))->status =
+                                                TFM_HANDLE_STATUS_CONNECT_ERROR;
+    } else {
+        ((struct tfm_conn_handle_t *)(msg->handle))->status =
                                                          TFM_HANDLE_STATUS_IDLE;
+    }
 
     if (is_tfm_rpc_msg(msg)) {
         tfm_rpc_client_call_reply(NULL, ret);
diff --git a/secure_fw/spm/spm_api.h b/secure_fw/spm/spm_api.h
index 7451ee0..e61b411 100644
--- a/secure_fw/spm/spm_api.h
+++ b/secure_fw/spm/spm_api.h
@@ -50,6 +50,7 @@
 
 #define TFM_HANDLE_STATUS_IDLE          0
 #define TFM_HANDLE_STATUS_ACTIVE        1
+#define TFM_HANDLE_STATUS_CONNECT_ERROR 2
 
 #ifndef TFM_PSA_API
 /**
@@ -119,9 +120,11 @@
 struct tfm_conn_handle_t {
     void *rhandle;                      /* Reverse handle value              */
     uint32_t status;                    /*
-                                         * Status of handle, two valid options:
-                                         * TFM_HANDLE_STATUS_ACTIVE and
-                                         * TFM_HANDLE_STATUS_IDLE
+                                         * Status of handle, three valid
+                                         * options:
+                                         * TFM_HANDLE_STATUS_ACTIVE,
+                                         * TFM_HANDLE_STATUS_IDLE and
+                                         * TFM_HANDLE_STATUS_CONNECT_ERROR
                                          */
     int32_t client_id;                  /*
                                          * Partition ID of the sender of the