psasim: add support for psa_reset_key_attributes()

Signed-off-by: Tom Cosgrove <tom.cosgrove@arm.com>
diff --git a/tests/psa-client-server/psasim/src/psa_functions_codes.h b/tests/psa-client-server/psasim/src/psa_functions_codes.h
index 44b2a99..bc1b844 100644
--- a/tests/psa-client-server/psasim/src/psa_functions_codes.h
+++ b/tests/psa-client-server/psasim/src/psa_functions_codes.h
@@ -75,6 +75,7 @@
     PSA_MAC_VERIFY_SETUP,
     PSA_PURGE_KEY,
     PSA_RAW_KEY_AGREEMENT,
+    PSA_RESET_KEY_ATTRIBUTES,
     PSA_SIGN_HASH,
     PSA_SIGN_HASH_ABORT,
     PSA_SIGN_HASH_COMPLETE,
diff --git a/tests/psa-client-server/psasim/src/psa_sim_crypto_client.c b/tests/psa-client-server/psasim/src/psa_sim_crypto_client.c
index 9f3ef08..091e354 100644
--- a/tests/psa-client-server/psasim/src/psa_sim_crypto_client.c
+++ b/tests/psa-client-server/psasim/src/psa_sim_crypto_client.c
@@ -4953,6 +4953,60 @@
 }
 
 
+void psa_reset_key_attributes(
+    psa_key_attributes_t *attributes
+    )
+{
+    uint8_t *ser_params = NULL;
+    uint8_t *ser_result = NULL;
+    size_t result_length;
+
+    size_t needed = psasim_serialise_begin_needs() +
+                    psasim_serialise_psa_key_attributes_t_needs(*attributes);
+
+    ser_params = malloc(needed);
+    if (ser_params == NULL) {
+        goto fail;
+    }
+
+    uint8_t *pos = ser_params;
+    size_t remaining = needed;
+    int ok;
+    ok = psasim_serialise_begin(&pos, &remaining);
+    if (!ok) {
+        goto fail;
+    }
+    ok = psasim_serialise_psa_key_attributes_t(&pos, &remaining, *attributes);
+    if (!ok) {
+        goto fail;
+    }
+
+    ok = psa_crypto_call(PSA_RESET_KEY_ATTRIBUTES,
+                         ser_params, (size_t) (pos - ser_params), &ser_result, &result_length);
+    if (!ok) {
+        printf("PSA_RESET_KEY_ATTRIBUTES server call failed\n");
+        goto fail;
+    }
+
+    uint8_t *rpos = ser_result;
+    size_t rremain = result_length;
+
+    ok = psasim_deserialise_begin(&rpos, &rremain);
+    if (!ok) {
+        goto fail;
+    }
+
+    ok = psasim_deserialise_psa_key_attributes_t(&rpos, &rremain, attributes);
+    if (!ok) {
+        goto fail;
+    }
+
+fail:
+    free(ser_params);
+    free(ser_result);
+}
+
+
 psa_status_t psa_sign_hash(
     mbedtls_svc_key_id_t key,
     psa_algorithm_t alg,
diff --git a/tests/psa-client-server/psasim/src/psa_sim_crypto_server.c b/tests/psa-client-server/psasim/src/psa_sim_crypto_server.c
index 29fc521..03e36c0 100644
--- a/tests/psa-client-server/psasim/src/psa_sim_crypto_server.c
+++ b/tests/psa-client-server/psasim/src/psa_sim_crypto_server.c
@@ -5662,6 +5662,68 @@
 }
 
 // Returns 1 for success, 0 for failure
+int psa_reset_key_attributes_wrapper(
+    uint8_t *in_params, size_t in_params_len,
+    uint8_t **out_params, size_t *out_params_len)
+{
+    psa_key_attributes_t attributes;
+
+    uint8_t *pos = in_params;
+    size_t remaining = in_params_len;
+    uint8_t *result = NULL;
+    int ok;
+
+    ok = psasim_deserialise_begin(&pos, &remaining);
+    if (!ok) {
+        goto fail;
+    }
+
+    ok = psasim_deserialise_psa_key_attributes_t(&pos, &remaining, &attributes);
+    if (!ok) {
+        goto fail;
+    }
+
+    // Now we call the actual target function
+
+    psa_reset_key_attributes(
+        &attributes
+        );
+
+    // NOTE: Should really check there is no overflow as we go along.
+    size_t result_size =
+        psasim_serialise_begin_needs();
+        psasim_serialise_psa_key_attributes_t_needs(attributes);
+
+    result = malloc(result_size);
+    if (result == NULL) {
+        goto fail;
+    }
+
+    uint8_t *rpos = result;
+    size_t rremain = result_size;
+
+    ok = psasim_serialise_begin(&rpos, &rremain);
+    if (!ok) {
+        goto fail;
+    }
+
+    ok = psasim_serialise_psa_key_attributes_t(&rpos, &rremain, attributes);
+    if (!ok) {
+        goto fail;
+    }
+
+    *out_params = result;
+    *out_params_len = result_size;
+
+    return 1;   // success
+
+fail:
+    free(result);
+
+    return 0;       // This shouldn't happen!
+}
+
+// Returns 1 for success, 0 for failure
 int psa_sign_hash_wrapper(
     uint8_t *in_params, size_t in_params_len,
     uint8_t **out_params, size_t *out_params_len)
@@ -6992,6 +7054,10 @@
             ok = psa_raw_key_agreement_wrapper(in_params, in_params_len,
                                                &out_params, &out_params_len);
             break;
+        case PSA_RESET_KEY_ATTRIBUTES:
+            ok = psa_reset_key_attributes_wrapper(in_params, in_params_len,
+                                                  &out_params, &out_params_len);
+            break;
         case PSA_SIGN_HASH:
             ok = psa_sign_hash_wrapper(in_params, in_params_len,
                                        &out_params, &out_params_len);
diff --git a/tests/psa-client-server/psasim/src/psa_sim_generate.pl b/tests/psa-client-server/psasim/src/psa_sim_generate.pl
index 9dafd0c..5673b67 100755
--- a/tests/psa-client-server/psasim/src/psa_sim_generate.pl
+++ b/tests/psa-client-server/psasim/src/psa_sim_generate.pl
@@ -5516,3 +5516,17 @@
 psa_status_t psa_copy_key(mbedtls_svc_key_id_t source_key,
                           const psa_key_attributes_t *attributes,
                           mbedtls_svc_key_id_t *target_key);
+
+/** Reset a key attribute structure to a freshly initialized state.
+ *
+ * You must initialize the attribute structure as described in the
+ * documentation of the type #psa_key_attributes_t before calling this
+ * function. Once the structure has been initialized, you may call this
+ * function at any time.
+ *
+ * This function frees any auxiliary resources that the structure
+ * may contain.
+ *
+ * \param[in,out] attributes    The attribute structure to reset.
+ */
+void psa_reset_key_attributes(psa_key_attributes_t *attributes);